Skip to content

Commit 808ccce

Browse files
authored
add a ConnectivityReceiver/ConnectivityListener pair (#276)
* add a ConnectivityReceiver/ConnectivityListener pair and a ConnectivityActivity in the test app * typos
1 parent 89d0ca4 commit 808ccce

7 files changed

Lines changed: 302 additions & 0 deletions

File tree

mapbox/app/src/main/AndroidManifest.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,13 @@
162162
android:name="android.support.PARENT_ACTIVITY"
163163
android:value=".MainActivity"/>
164164
</activity>
165+
<activity
166+
android:name=".connectivity.ConnectivityActivity"
167+
android:label="@string/title_connectivity">
168+
<meta-data
169+
android:name="android.support.PARENT_ACTIVITY"
170+
android:value=".MainActivity"/>
171+
</activity>
165172

166173
<!--
167174
Service to asynchronously fetch a location address using a Geocoder. Setting the

mapbox/app/src/main/java/com/mapbox/services/android/testapp/MainActivity.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import com.mapbox.services.android.BuildConfig;
1717
import com.mapbox.services.android.telemetry.permissions.PermissionsListener;
1818
import com.mapbox.services.android.telemetry.permissions.PermissionsManager;
19+
import com.mapbox.services.android.testapp.connectivity.ConnectivityActivity;
1920
import com.mapbox.services.android.testapp.directions.DirectionsV5Activity;
2021
import com.mapbox.services.android.testapp.directions.RouteUtilsV5Activity;
2122
import com.mapbox.services.android.testapp.distance.DistanceActivity;
@@ -150,6 +151,11 @@ protected void onCreate(Bundle savedInstanceState) {
150151
getString(R.string.title_off_route_detection),
151152
getString(R.string.description_off_route_detection),
152153
OffRouteDetectionActivity.class
154+
),
155+
new SampleItem(
156+
getString(R.string.title_connectivity),
157+
getString(R.string.description_connectivity),
158+
ConnectivityActivity.class
153159
)
154160
));
155161

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
package com.mapbox.services.android.testapp.connectivity;
2+
3+
import android.os.Bundle;
4+
import android.support.v7.app.AppCompatActivity;
5+
import android.util.Log;
6+
import android.view.View;
7+
import android.widget.Button;
8+
import android.widget.TextView;
9+
10+
import com.mapbox.services.android.telemetry.connectivity.ConnectivityListener;
11+
import com.mapbox.services.android.telemetry.connectivity.ConnectivityReceiver;
12+
import com.mapbox.services.android.testapp.R;
13+
14+
public class ConnectivityActivity extends AppCompatActivity
15+
implements ConnectivityListener {
16+
17+
private static final String LOG_TAG = ConnectivityActivity.class.getSimpleName();
18+
private ConnectivityReceiver connectivityReceiver;
19+
20+
private Button buttonAuto;
21+
private Button buttonYes;
22+
private Button buttonNo;
23+
private TextView textUpdate;
24+
25+
@Override
26+
protected void onCreate(Bundle savedInstanceState) {
27+
super.onCreate(savedInstanceState);
28+
setContentView(R.layout.activity_connectivity);
29+
textUpdate = (TextView) findViewById(R.id.text_update);
30+
setupButtons();
31+
32+
// Set up the ConnectivityReceiver
33+
Log.d(LOG_TAG, "Setting up ConnectivityReceiver.");
34+
connectivityReceiver = new ConnectivityReceiver(getApplicationContext());
35+
connectivityReceiver.addConnectivityListener(this);
36+
setInitialState();
37+
}
38+
39+
private void setupButtons() {
40+
buttonAuto = (Button) findViewById(R.id.button_auto);
41+
buttonAuto.setOnClickListener(new View.OnClickListener() {
42+
@Override
43+
public void onClick(View view) {
44+
setInitialState();
45+
}
46+
});
47+
48+
buttonYes = (Button) findViewById(R.id.button_yes);
49+
buttonYes.setOnClickListener(new View.OnClickListener() {
50+
@Override
51+
public void onClick(View view) {
52+
buttonAuto.setEnabled(true);
53+
buttonYes.setEnabled(false);
54+
buttonNo.setEnabled(true);
55+
connectivityReceiver.setConnectedFlag(true);
56+
}
57+
});
58+
59+
buttonNo = (Button) findViewById(R.id.button_no);
60+
buttonNo.setOnClickListener(new View.OnClickListener() {
61+
@Override
62+
public void onClick(View view) {
63+
buttonAuto.setEnabled(true);
64+
buttonYes.setEnabled(true);
65+
buttonNo.setEnabled(false);
66+
connectivityReceiver.setConnectedFlag(false);
67+
}
68+
});
69+
}
70+
71+
private void setInitialState() {
72+
buttonAuto.setEnabled(false);
73+
buttonYes.setEnabled(true);
74+
buttonNo.setEnabled(true);
75+
connectivityReceiver.setConnectedFlag(null);
76+
}
77+
78+
@Override
79+
protected void onStart() {
80+
super.onStart();
81+
82+
Log.d(LOG_TAG, "Requesting connectivity updates.");
83+
connectivityReceiver.requestConnectivityUpdates();
84+
}
85+
86+
@Override
87+
protected void onStop() {
88+
super.onStop();
89+
90+
Log.d(LOG_TAG, "Removing connectivity updates.");
91+
connectivityReceiver.removeConnectivityUpdates();
92+
}
93+
94+
@Override
95+
public void onConnectivityChanged(boolean connected) {
96+
textUpdate.setText(String.format("Connectivity changed to %b.", connected));
97+
}
98+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<LinearLayout
3+
xmlns:android="http://schemas.android.com/apk/res/android"
4+
xmlns:tools="http://schemas.android.com/tools"
5+
android:id="@+id/activity_connectivity"
6+
android:orientation="vertical"
7+
android:layout_width="match_parent"
8+
android:layout_height="match_parent"
9+
android:paddingBottom="@dimen/activity_vertical_margin"
10+
android:paddingLeft="@dimen/activity_horizontal_margin"
11+
android:paddingRight="@dimen/activity_horizontal_margin"
12+
android:paddingTop="@dimen/activity_vertical_margin"
13+
tools:context="com.mapbox.services.android.testapp.connectivity.ConnectivityActivity">
14+
15+
<LinearLayout
16+
android:orientation="vertical"
17+
android:layout_width="match_parent"
18+
android:layout_height="wrap_content">
19+
20+
<Button
21+
android:id="@+id/button_auto"
22+
android:text="Auto"
23+
android:layout_width="match_parent"
24+
android:layout_height="wrap_content"/>
25+
26+
<Button
27+
android:id="@+id/button_yes"
28+
android:text="Always connected"
29+
android:layout_width="match_parent"
30+
android:layout_height="wrap_content"/>
31+
32+
<Button
33+
android:id="@+id/button_no"
34+
android:text="Always disconnected"
35+
android:layout_width="match_parent"
36+
android:layout_height="wrap_content"/>
37+
38+
</LinearLayout>
39+
40+
<TextView
41+
android:id="@+id/text_update"
42+
android:text="Waiting for a connectivity update."
43+
android:paddingTop="@dimen/activity_vertical_margin"
44+
android:layout_width="match_parent"
45+
android:layout_height="wrap_content"/>
46+
47+
</LinearLayout>

mapbox/app/src/main/res/values/strings.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
<string name="title_turf_inside">Turf inside</string>
4343
<string name="title_turf_midpoint">Turf midpoint</string>
4444
<string name="title_off_route_detection">Off route detection</string>
45+
<string name="title_connectivity">Connectivity state</string>
4546

4647
<!-- Descriptions -->
4748
<string name="description_location">Shows how to obtain location from different engines.</string>
@@ -63,6 +64,7 @@
6364
<string name="description_turf_inside">Use Turf to determine if something is within a polygon.</string>
6465
<string name="description_turf_midpoint">Use Turf to get a midpoint.</string>
6566
<string name="description_off_route_detection">Uses the Route Utils class to determine if a users off route.</string>
67+
<string name="description_connectivity">Keep track of the connectivity status.</string>
6668

6769
<string-array name="turf_calculation_items">
6870
<item>Select calculation</item>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.mapbox.services.android.telemetry.connectivity;
2+
3+
/**
4+
* Callback to use with the ConnectivityReceiver
5+
*/
6+
7+
public interface ConnectivityListener {
8+
9+
void onConnectivityChanged(boolean connected);
10+
11+
}
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
package com.mapbox.services.android.telemetry.connectivity;
2+
3+
import android.content.BroadcastReceiver;
4+
import android.content.Context;
5+
import android.content.Intent;
6+
import android.content.IntentFilter;
7+
import android.net.ConnectivityManager;
8+
import android.net.NetworkInfo;
9+
10+
import java.util.concurrent.CopyOnWriteArrayList;
11+
12+
/**
13+
* ConnectivityReceiver is a BroadcastReceiver that helps you keep track of the connectivity
14+
* status. When used statically (getSystemConnectivity) the ConnectivityReceiver will always
15+
* return the connectivity status as reported by the Android system.
16+
*
17+
* When instantiating ConnectivityReceiver, you have the option to set a connectedFlag. You can
18+
* override the connectivity value reported by the system by setting this flag to true or false. If
19+
* left in its default value (null), ConnectivityReceiver will report the system value.
20+
*
21+
* ConnectivityReceiver also lets you subscribe to connecitivity changes using a
22+
* ConnectivityListener.
23+
*/
24+
public class ConnectivityReceiver extends BroadcastReceiver {
25+
26+
private Context context;
27+
private CopyOnWriteArrayList<ConnectivityListener> connectivityListeners;
28+
private Boolean connectedFlag;
29+
30+
/**
31+
* ConnectivityReceiver constructor
32+
*
33+
* @param context Android context. To avoid memory leaks, you might want to pass the application
34+
* context and make sure you call removeConnectivityUpdates() when you don't need
35+
* further updates (https://github.com/mapbox/mapbox-gl-native/issues/7176)
36+
*/
37+
public ConnectivityReceiver(Context context) {
38+
this.context = context;
39+
connectivityListeners = new CopyOnWriteArrayList<>();
40+
connectedFlag = null;
41+
}
42+
43+
/**
44+
* Get the connectivity state as reported by the Android system
45+
*
46+
* @param context Android context
47+
* @return the connectivity state as reported by the Android system
48+
*/
49+
private static boolean getSystemConnectivity(Context context) {
50+
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
51+
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
52+
return activeNetwork != null && activeNetwork.isConnectedOrConnecting();
53+
}
54+
55+
/**
56+
* Get the connectivity state. This can be overriden using the connectedFlag.
57+
*
58+
* @return the connectivity state
59+
*/
60+
private boolean getManagedConnectivity() {
61+
if (connectedFlag == null) {
62+
return getSystemConnectivity(context);
63+
}
64+
65+
return connectedFlag;
66+
}
67+
68+
/**
69+
* Get the connectivity state as reported by the Android system
70+
*
71+
* @param context Android context
72+
* @return the connectivity state as reported by the Android system
73+
*/
74+
public static boolean isConnected(Context context) {
75+
return getSystemConnectivity(context);
76+
}
77+
78+
/**
79+
* Get the connectivity state. This can be overriden using the connectedFlag.
80+
*
81+
* @return the connectivity state
82+
*/
83+
public boolean isConnected() {
84+
return getManagedConnectivity();
85+
}
86+
87+
/**
88+
* Get the connectedFlag value
89+
*
90+
* @return the connectedFlag value, true/false if the connectivity state has ben overriden,
91+
* null otherwise.
92+
*/
93+
public Boolean getConnectedFlag() {
94+
return connectedFlag;
95+
}
96+
97+
/**
98+
* Set the connectedFlag value
99+
*
100+
* @param connectedFlag Set it to true/false to override the connectivity state
101+
*/
102+
public void setConnectedFlag(Boolean connectedFlag) {
103+
this.connectedFlag = connectedFlag;
104+
}
105+
106+
public void addConnectivityListener(ConnectivityListener listener) {
107+
if (!connectivityListeners.contains(listener)) {
108+
connectivityListeners.add(listener);
109+
}
110+
}
111+
112+
public boolean removeConnectivityListener(ConnectivityListener listener) {
113+
return connectivityListeners.remove(listener);
114+
}
115+
116+
public void requestConnectivityUpdates() {
117+
context.registerReceiver(this, new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE"));
118+
}
119+
120+
public void removeConnectivityUpdates() {
121+
context.unregisterReceiver(this);
122+
}
123+
124+
@Override
125+
public void onReceive(Context context, Intent intent) {
126+
boolean connected = getManagedConnectivity();
127+
for (ConnectivityListener listener : connectivityListeners) {
128+
listener.onConnectivityChanged(connected);
129+
}
130+
}
131+
}

0 commit comments

Comments
 (0)