Skip to content

Commit ac40c56

Browse files
author
Kaushik Gopal
committed
Merge branch 'kg/feat/subject_network_detector'
* kg/feat/subject_network_detector: ref: change network detector to Rx 2 feat: add example for network connectivity detection
2 parents c864c8f + 54891b9 commit ac40c56

File tree

6 files changed

+185
-0
lines changed

6 files changed

+185
-0
lines changed

app/src/main/AndroidManifest.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
</intent-filter>
2222
</activity>
2323
</application>
24+
2425
<uses-permission android:name="android.permission.INTERNET"/>
26+
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
2527

2628
</manifest>

app/src/main/java/com/morihacky/android/rxjava/fragments/MainFragment.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,11 @@ void demoVolleyRequest() {
109109
clickedOn(new VolleyDemoFragment());
110110
}
111111

112+
@OnClick(R.id.btn_demo_networkDetector)
113+
void demoNetworkDetector() {
114+
clickedOn(new NetworkDetectorFragment());
115+
}
116+
112117
private void clickedOn(@NonNull Fragment fragment) {
113118
final String tag = fragment.getClass().toString();
114119
getActivity().getSupportFragmentManager()
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
package com.morihacky.android.rxjava.fragments;
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+
import android.os.Bundle;
10+
import android.os.Handler;
11+
import android.os.Looper;
12+
import android.support.annotation.Nullable;
13+
import android.view.LayoutInflater;
14+
import android.view.View;
15+
import android.view.ViewGroup;
16+
import android.widget.ArrayAdapter;
17+
import android.widget.ListView;
18+
import butterknife.Bind;
19+
import butterknife.ButterKnife;
20+
import com.morihacky.android.rxjava.R;
21+
import io.reactivex.android.schedulers.AndroidSchedulers;
22+
import io.reactivex.disposables.Disposable;
23+
import io.reactivex.processors.PublishProcessor;
24+
import java.util.ArrayList;
25+
import java.util.List;
26+
27+
public class NetworkDetectorFragment
28+
extends BaseFragment {
29+
30+
@Bind(R.id.list_threading_log) ListView logsList;
31+
32+
private LogAdapter adapter;
33+
private BroadcastReceiver broadcastReceiver;
34+
private List<String> logs;
35+
private Disposable disposable;
36+
private PublishProcessor<Boolean> publishProcessor;
37+
38+
@Override
39+
public void onDestroy() {
40+
super.onDestroy();
41+
ButterKnife.unbind(this);
42+
}
43+
44+
@Override
45+
public View onCreateView(LayoutInflater inflater,
46+
@Nullable ViewGroup container,
47+
@Nullable Bundle savedInstanceState) {
48+
View layout = inflater.inflate(R.layout.fragment_network_detector, container, false);
49+
ButterKnife.bind(this, layout);
50+
return layout;
51+
}
52+
53+
@Override
54+
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
55+
super.onActivityCreated(savedInstanceState);
56+
setupLogger();
57+
}
58+
59+
@Override
60+
public void onStart() {
61+
super.onStart();
62+
63+
publishProcessor = PublishProcessor.create();
64+
65+
disposable = publishProcessor
66+
.startWith(getConnectivityStatus(getActivity()))
67+
.distinctUntilChanged()
68+
.observeOn(AndroidSchedulers.mainThread())
69+
.subscribe(online -> {
70+
if (online) {
71+
log("You are online");
72+
}
73+
else {
74+
log("You are offline");
75+
}
76+
});
77+
78+
listenToNetworkConnectivity();
79+
}
80+
81+
@Override
82+
public void onStop() {
83+
super.onStop();
84+
85+
disposable.dispose();
86+
getActivity().unregisterReceiver(broadcastReceiver);
87+
}
88+
89+
private void listenToNetworkConnectivity() {
90+
91+
broadcastReceiver = new BroadcastReceiver() {
92+
@Override
93+
public void onReceive(Context context, Intent intent) {
94+
publishProcessor.onNext(getConnectivityStatus(context));
95+
}
96+
};
97+
98+
final IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
99+
getActivity().registerReceiver(broadcastReceiver, intentFilter);
100+
}
101+
102+
private boolean getConnectivityStatus(Context context) {
103+
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
104+
NetworkInfo networkInfo = cm.getActiveNetworkInfo();
105+
return networkInfo != null && networkInfo.isConnected();
106+
}
107+
108+
// -----------------------------------------------------------------------------------
109+
// Method that help wiring up the example (irrelevant to RxJava)
110+
111+
private void log(String logMsg) {
112+
113+
if (isCurrentlyOnMainThread()) {
114+
logs.add(0, logMsg + " (main thread) ");
115+
adapter.clear();
116+
adapter.addAll(logs);
117+
}
118+
else {
119+
logs.add(0, logMsg + " (NOT main thread) ");
120+
121+
// You can only do below stuff on main thread.
122+
new Handler(Looper.getMainLooper()).post(() -> {
123+
adapter.clear();
124+
adapter.addAll(logs);
125+
});
126+
}
127+
}
128+
129+
private void setupLogger() {
130+
logs = new ArrayList<>();
131+
adapter = new LogAdapter(getActivity(), new ArrayList<>());
132+
logsList.setAdapter(adapter);
133+
}
134+
135+
private boolean isCurrentlyOnMainThread() {
136+
return Looper.myLooper() == Looper.getMainLooper();
137+
}
138+
139+
private class LogAdapter
140+
extends ArrayAdapter<String> {
141+
142+
public LogAdapter(Context context, List<String> logs) {
143+
super(context, R.layout.item_log, R.id.item_log, logs);
144+
}
145+
}
146+
}

app/src/main/res/layout/fragment_main.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,5 +120,12 @@
120120
android:layout_width="match_parent"
121121
android:text="@string/btn_demo_pagination"
122122
/>
123+
124+
<Button
125+
android:id="@+id/btn_demo_networkDetector"
126+
android:layout_height="wrap_content"
127+
android:layout_width="match_parent"
128+
android:text="@string/btn_demo_networkDetector"
129+
/>
123130
</LinearLayout>
124131
</ScrollView>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
3+
<LinearLayout
4+
xmlns:android="http://schemas.android.com/apk/res/android"
5+
android:layout_width="match_parent"
6+
android:layout_height="match_parent"
7+
android:orientation="vertical"
8+
>
9+
10+
<TextView
11+
android:layout_width="match_parent"
12+
android:layout_height="wrap_content"
13+
android:gravity="center"
14+
android:padding="10dp"
15+
android:text="@string/msg_demo_network_detector"
16+
/>
17+
18+
<ListView
19+
android:id="@+id/list_threading_log"
20+
android:layout_width="match_parent"
21+
android:layout_height="match_parent"
22+
/>
23+
</LinearLayout>

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
<string name="btn_demo_volley">Volley request demo</string>
2323
<string name="btn_demo_pagination">Paging example</string>
2424
<string name="btn_demo_pagination_more">MOAR</string>
25+
<string name="btn_demo_networkDetector">Network Detector (Subject)</string>
2526

2627
<string name="msg_demo_pagination">This is a demo of how you can do a list pagination with Rx. We page 10 items at a time and there are 55 items altogether</string>
2728
<string name="msg_demo_volley">This is a Volley request demo</string>
@@ -38,6 +39,7 @@
3839
<string name="msg_demo_form_comb_latest">Monitor the state of multiple observables with the combineLatest operator. Only after all the 3 inputs contain valid entries will the submit button light up</string>
3940
<string name="msg_demo_timing">BTN 1: run single task once (after 2s complete)\nBTN 2: run task every 1s (start delay of 1s) toggle \nBTN 3: run task every 1s (start immediately) toggle \nBTN 4: run task 5 times every 3s (then complete) \nBTN 5: run task A, pause for sometime, then proceed with Task B</string>
4041
<string name="msg_demo_rotation_persist">This is an example of starting an Observable and using the result across rotations. There are many ways to do this, we use a retained fragment in this example</string>
42+
<string name="msg_demo_network_detector">This is a demo of how to use Subjects to detect Network connectivity\nToggle your Wifi/Network on or off and notice the logs</string>
4143

4244
<string name="msg_pseudoCache_demoInfo_concat">Concat merges the results sequentially. But notice that the latter subscription starts only AFTER the first one completes. Some unnecessary waiting there.</string>
4345
<string name="msg_pseudoCache_demoInfo_concatEager">Concat eager is cooler. Both subscriptions start at the same time (parallely) but the order of emission is respected.</string>

0 commit comments

Comments
 (0)