All Projects → pwittchen → Reactivenetwork

pwittchen / Reactivenetwork

Licence: apache-2.0
Android library listening network connection state and Internet connectivity with RxJava Observables

Programming Languages

java
68154 projects - #9 most used programming language
kotlin
9241 projects
shell
77523 projects

Projects that are alternatives of or similar to Reactivenetwork

Reactivewifi
Android library listening available WiFi Access Points and related information with RxJava Observables
Stars: ✭ 186 (-92.51%)
Mutual labels:  rxjava, rxjava2, rxandroid, rxandroid2, wifi
Swipe
👉 detects swipe events on Android
Stars: ✭ 324 (-86.96%)
Mutual labels:  rxjava, rxjava2, rxandroid, rxandroid2
Rxbiometric
☝️ RxJava and RxKotlin bindings for Biometric Prompt (Fingerprint Scanner) on Android
Stars: ✭ 295 (-88.12%)
Mutual labels:  rxjava, rxjava2, rxandroid, rxandroid2
Rxbus
🚌 The RxBus as steady as an old dog.
Stars: ✭ 334 (-86.55%)
Mutual labels:  rxjava, rxjava2, rxandroid, rxandroid2
Prefser
Wrapper for Android SharedPreferences with object serialization and RxJava Observables
Stars: ✭ 228 (-90.82%)
Mutual labels:  rxjava, rxjava2, rxandroid, rxandroid2
Rxjavapriorityscheduler
RxPS - RxJavaPriorityScheduler - A RxJava Priority Scheduler library for Android and Java applications
Stars: ✭ 138 (-94.44%)
Mutual labels:  rxjava, rxjava2, rxandroid, rxandroid2
ReactiveBus
🚍 Reactive Event Bus for JVM (1.7+) and Android apps built with RxJava 2
Stars: ✭ 17 (-99.32%)
Mutual labels:  rxjava, rxandroid, rxjava2, rxandroid2
Fast Android Networking
🚀 A Complete Fast Android Networking Library that also supports HTTP/2 🚀
Stars: ✭ 5,346 (+115.22%)
Mutual labels:  rxjava, rxjava2, network, internet
Reactivebeacons
Android library scanning BLE beacons nearby with RxJava
Stars: ✭ 171 (-93.12%)
Mutual labels:  rxjava, rxjava2, rxandroid, rxandroid2
Mvvm Architecture Android Beginners
This repository contains a sample app that implements MVVM architecture using Kotlin, ViewModel, LiveData, and etc.
Stars: ✭ 176 (-92.91%)
Mutual labels:  rxjava, rxjava2, rxandroid
Linux Wifi Hotspot
Feature-rich wifi hotspot creator for Linux which provides both GUI and command-line interface. It is also able to create a hotspot using the same wifi card which is connected to an AP already ( Similar to Windows 10).
Stars: ✭ 434 (-82.53%)
Mutual labels:  network, wifi, internet
Rxbus
Event Bus By RxJava.
Stars: ✭ 2,126 (-14.41%)
Mutual labels:  rxjava, rxjava2, rxandroid
Rxbluetooth
Android reactive bluetooth
Stars: ✭ 405 (-83.7%)
Mutual labels:  rxjava, rxjava2, rxandroid
Rxjava2 Android Samples
RxJava 2 Android Examples - Migration From RxJava 1 to RxJava 2 - How to use RxJava 2 in Android
Stars: ✭ 4,950 (+99.28%)
Mutual labels:  rxjava, rxjava2, rxandroid
Freezer
A simple & fluent Android ORM, how can it be easier ? RxJava2 compatible
Stars: ✭ 326 (-86.88%)
Mutual labels:  rxjava, rxjava2, rxandroid
rxandroid2-retrofit2
Small tutorial to get started with RxAndroid 2 and Retrofit 2
Stars: ✭ 55 (-97.79%)
Mutual labels:  rxandroid, rxjava2, rxandroid2
Rxjava2 Operators Magician
你用不惯 RxJava,只因缺了这把钥匙 🔑 You are not used to RxJava, just because of the lack of this key.
Stars: ✭ 868 (-65.06%)
Mutual labels:  rxjava, rxjava2, rxandroid
Androidbasemvp
🚀一个快速搭建MVP+RxJava2+Retrofit 基础框架,主要是封装有Http网络请求、日志、缓存、加载等待、toast、页面状态布局管理、权限、RxBus、Glide图片加载等组件,方便快速开发新项目、减少开发成本。
Stars: ✭ 184 (-92.59%)
Mutual labels:  rxjava, rxjava2, rxandroid
Mvpframes
整合大量主流开源项目并且可高度配置化的 Android MVP 快速集成框架,支持 AndroidX
Stars: ✭ 100 (-95.97%)
Mutual labels:  rxjava, rxjava2, rxandroid
Android Clean Architecture Boilerplate
Apply clean architecture on Android
Stars: ✭ 141 (-94.32%)
Mutual labels:  rxjava, rxjava2, rxandroid

ReactiveNetwork

Android Arsenal

view website with documentation: RxJava1.x, RxJava2.x

ReactiveNetwork is an Android library listening network connection state and Internet connectivity with RxJava Observables. It's a successor of Network Events library rewritten with Reactive Programming approach. Library supports both new and legacy network monitoring strategies. Min sdk version = 9.

Current Branch Branch Artifact Id Build Status Coverage Maven Central
RxJava1.x reactivenetwork Build Status for RxJava1.x codecov Maven Central
☑️ RxJava2.x reactivenetwork-rx2 Build Status for RxJava2.x codecov Maven Central

Contents

Usage

Please note: Due to memory leak in WifiManager reported in issue 43945 in Android issue tracker it's recommended to use Application Context instead of Activity Context.

Observing network connectivity

We can observe Connectivity with observeNetworkConnectivity(context) method in the following way:

ReactiveNetwork
  .observeNetworkConnectivity(context)
  .subscribeOn(Schedulers.io())
  ... // anything else what you can do with RxJava
  .observeOn(AndroidSchedulers.mainThread())
  .subscribe(connectivity -> {
      // do something with connectivity
      // you can call connectivity.state();
      // connectivity.type(); or connectivity.toString();
  });

When Connectivity changes, subscriber will be notified. Connectivity can change its state or type.

Errors can be handled in the same manner as in all RxJava observables. For example:

ReactiveNetwork
  .observeNetworkConnectivity(context)
  .subscribeOn(Schedulers.io())
  .observeOn(AndroidSchedulers.mainThread())
  .subscribe(
       connectivity -> /* handle connectivity here */,
       throwable    -> /* handle error here */
   );

We can react on a concrete state, states, type or types changes with the filter(...) method from RxJava, hasState(NetworkInfo.State... states) and hasType(int... types) methods located in ConnectivityPredicate class.

ReactiveNetwork
  .observeNetworkConnectivity(context)
  .subscribeOn(Schedulers.io())
  .filter(ConnectivityPredicate.hasState(NetworkInfo.State.CONNECTED))
  .filter(ConnectivityPredicate.hasType(ConnectivityManager.TYPE_WIFI))
  .observeOn(AndroidSchedulers.mainThread())
  .subscribe(connectivity -> {
      // do something
  });

observeNetworkConnectivity(context) checks only connectivity with the network (not Internet) as it's based on BroadcastReceiver for API 20 and lower and uses NetworkCallback for API 21 and higher. Concrete WiFi or mobile network may be connected to the Internet (and usually is), but it doesn't have to.

You can also use method:

Observable<Connectivity> observeNetworkConnectivity(Context context, NetworkObservingStrategy strategy)

This method allows you to apply your own network observing strategy and is used by the library under the hood to determine appropriate strategy depending on the version of Android system.

Connectivity class

Connectivity class is used by observeNetworkConnectivity(context) and observeNetworkConnectivity(context, networkObservingStrategy) methods. It has the following API:

Connectivity create()
Connectivity create(Context context)

NetworkInfo.State state()
NetworkInfo.DetailedState detailedState()
int type()
int subType()
boolean available()
boolean failover()
boolean roaming()
String typeName()
String subTypeName()
String reason()
String extraInfo()

// and respective setters

class Builder

Network Observing Strategies

Right now, we have the following strategies for different Android versions:

  • LollipopNetworkObservingStrategy
  • MarshmallowNetworkObservingStrategy
  • PreLollipopNetworkObservingStrategy

All of them implements NetworkObservingStrategy interface. Concrete strategy is chosen automatically depending on the Android version installed on the device. With observeNetworkConnectivity(context, strategy) method we can use one of these strategies explicitly.

Observing Internet connectivity

Observing Internet connectivity continuously

We can observe connectivity with the Internet continuously in the following way:

ReactiveNetwork
  .observeInternetConnectivity()
  .subscribeOn(Schedulers.io())
  .observeOn(AndroidSchedulers.mainThread())
  .subscribe(isConnectedToInternet -> {
      // do something with isConnectedToInternet value
  });

An Observable will return true to the subscription (disposable) if device is connected to the Internet and false if not.

Internet connectivity will be checked as soon as possible.

Please note: This method is less efficient than observeNetworkConnectivity(context) method, because in default observing strategy, it opens socket connection with remote host (default is www.google.com) every two seconds with two seconds of timeout and consumes data transfer. Use this method if you really need it. Optionally, you can dispose subscription (disposable) right after you get notification that Internet is available and do the work you want in order to decrease network calls.

Methods in this section should be used if they are really needed due to specific use cases.

If you want to customize observing of the Internet connectivity, you can use InternetObservingSettings class and its builder. They allow to customize monitoring interval in milliseconds, host, port, timeout, initial monitoring interval, timeout, expected HTTP response code, error handler or whole observing strategy.

InternetObservingSettings settings = InternetObservingSettings.builder()
  .initialInterval(initialInterval)
  .interval(interval)
  .host(host)
  .port(port)
  .timeout(timeout)
  .httpResponse(httpResponse)
  .errorHandler(testErrorHandler)
  .strategy(strategy)
  .build();

ReactiveNetwork
  .observeInternetConnectivity(settings)
  .subscribeOn(Schedulers.io())
  .observeOn(AndroidSchedulers.mainThread())
  .subscribe(isConnectedToInternet -> {
      // do something with isConnectedToInternet value
  });

These methods are created to allow the users to fully customize the library and give them more control.

Please note, not all parameters are relevant for all strategies.

For more details check JavaDoc at: http://pwittchen.github.io/ReactiveNetwork/javadoc/RxJava2.x

Checking Internet Connectivity once

If we don't want to observe Internet connectivity in the interval with Observable<Boolean> observeInternetConnectivity(...) method, we can use Single<Boolean> checkInternetConnectivity(), which does the same thing, but only once. It may be helpful in the specific use cases.

Single<Boolean> single = ReactiveNetwork.checkInternetConnectivity();

single
  .subscribeOn(Schedulers.io())
  .observeOn(AndroidSchedulers.mainThread())
  .subscribe(isConnectedToInternet -> {
      // do something with isConnectedToTheInternet
  });

As in the previous case, you can customize this feature with the InternetObservingSettings class and its builder.

InternetObservingSettings settings = InternetObservingSettings.builder()
  .initialInterval(initialInterval)
  .interval(interval)
  .host(host)
  .port(port)
  .timeout(timeout)
  .httpResponse(httpResponse)
  .errorHandler(testErrorHandler)
  .strategy(strategy)
  .build();

Single<Boolean> single = ReactiveNetwork.checkInternetConnectivity(settings);

single
  .subscribeOn(Schedulers.io())
  .observeOn(AndroidSchedulers.mainThread())
  .subscribe(isConnectedToInternet -> {
      // do something with isConnectedToTheInternet
  });

Basic idea is the same. With just have Single<Boolean> return type instead of Observable<Boolean> and we don't have int initialIntervalInMs and int intervalInMs parameters.

As previously, these methods are created to allow the users to fully customize the library and give them more control.

For more details check JavaDoc at: http://pwittchen.github.io/ReactiveNetwork/javadoc/RxJava2.x

Internet Observing Strategies

Right now, we have the following strategies for observing Internet connectivity:

  • SocketInternetObservingStrategy - monitors Internet connectivity via opening socket connection with the remote host
  • WalledGardenInternetObservingStrategy - opens connection with a remote host and respects countries in the Walled Garden (e.g. China)

All of these strategies implements NetworkObservingStrategy interface. Default strategy used right now is WalledGardenInternetObservingStrategy, but with checkInternetConnectivity(strategy) and observeInternetConnectivity(strategy) method we can use one of these strategies explicitly.

Custom host

If you want to ping custom host during checking Internet connectivity, it's recommended to use SocketInternetObservingStrategy. You can do it as follows:

InternetObservingSettings settings = InternetObservingSettings.builder()
  .host("www.yourhost.com")
  .strategy(new SocketInternetObservingStrategy())
  .build();

ReactiveNetwork
  .observeInternetConnectivity(settings)
  .subscribeOn(Schedulers.io())
  .observeOn(AndroidSchedulers.mainThread())
  .subscribe(isConnectedToHost -> {
      // do something with isConnectedToHost
  });

If you want to use WalledGardenInternetObservingStrategy, please update HTTP response code via InternetObservingSettings. E.g set it to 200 because default is 204.

The same operation can be done with checkInternetConnectivity(strategy, host) method, which returns Single instead of Observable.

Chaining network and Internet connectivity streams

Let's say we want to react on each network connectivity change and if we get connected to the network, then we want to check if that network is connected to the Internet. We can do it in the following way:

ReactiveNetwork
  .observeNetworkConnectivity(getApplicationContext())
  .flatMapSingle(connectivity -> ReactiveNetwork.checkInternetConnectivity())
  .subscribeOn(Schedulers.io())
  .observeOn(AndroidSchedulers.mainThread())
  .subscribe(isConnected -> {
    // isConnected can be true or false
});

In case we're getting too many events related to the network changes or we want to discard previous observables (there's only one in the code snippet above) after subscribing them, we can use switchMapSingle operator instead of flatMapSingle in order to get the updates from the latest observable only. In this case, it will be observable created by checkInternetConnectivity method.

ClearText Traffic

Someties, while trying to connect to the remote server we may encounter the following message:

ClearText HTTP traffic not permitted

Due to this fact, observing Internet feature won't work properly.

It's related to Network Security Configuration. Starting with Android 9.0 (API level 28), cleartext support is disabled by default.

You have a few options to solve this issue.

Option #1

Create res/xml/network_security_config.xml file:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">Your URL(ex: 127.0.0.1)</domain>
    </domain-config>
</network-security-config>

Link it in your AndroidManifest.xml file:

<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
    <uses-permission android:name="android.permission.INTERNET" />
    <application
        ...
        android:networkSecurityConfig="@xml/network_security_config"
        ...>
        ...
    </application>
</manifest>

Option #2

Set usesCleartextTraffic parameter in <application> tag in AndroidManifest.xml file to true.

<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
    <uses-permission android:name="android.permission.INTERNET" />
    <application
        ...
        android:usesCleartextTraffic="true"
        ...>
        ...
    </application>
</manifest>

For more details, check Android documentation linked above or this StackOverflow thread: https://stackoverflow.com/a/50834600/1150795.

Integration with other libraries

We can integrate ReactiveNetwork with other libraries. Especially those, which support RxJava2. In this section, we can find examples showing how to integrate this library with the OkHttp and Retrofit.

Integration with OkHttp

In order to integrate library with OkHttp, we need to wrap HTTP request with reactive type (e.g. Observable)

private Observable<Response> getResponse(String url) {
  OkHttpClient client = new OkHttpClient();
  Request request = new Request.Builder().url(url).build();

  return Observable.create(emitter -> {
    try {
        Response response = client.newCall(request).execute();
        emitter.onNext(response);
    } catch (IOException exception) {
        emitter.onError(exception);
    } finally {
        emitter.onComplete();
    }
  });
}

Next, we can chain two streams:

ReactiveNetwork
   .observeNetworkConnectivity(getApplicationContext())
   .flatMap(connectivity -> {
     if (connectivity.state() == NetworkInfo.State.CONNECTED) {
       return getResponse("http://github.com");
     }
     return Observable.error(() -> new RuntimeException("not connected"));
   })
   .subscribeOn(Schedulers.io())
   .observeOn(AndroidSchedulers.mainThread())
   .subscribe(
       response  -> /* handle response here */,
       throwable -> /* handle error here */)
   );

In the example above, whenever we get connected to the network, then request will be performed.

For more details regarding OkHttp, please visit its official website: http://square.github.io/okhttp/.

Integration with Retrofit

We can integrate ReactiveNetwork with the Retrofit.

First, we need to configure Retrofit:

Retrofit retrofit = new Retrofit.Builder()
   .baseUrl("https://api.github.com/")
   .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
   .addConverterFactory(GsonConverterFactory.create())
   .build();

As you see, we need RxJava2CallAdapterFactory here.

Next, we need to define appropriate interface with RxJava Single types:

public interface GitHubService {
 @GET("users/{user}/repos")
 Single<List<Repo>> listRepos(@Path("user") String user);
}

and instantiate the service:

GitHubService service = retrofit.create(GitHubService.class);

Next, we want to call endpoint defined with the Retrofit whenever we get connected to the network. We can do it as follows:

ReactiveNetwork
   .observeNetworkConnectivity(getApplicationContext())
   .flatMapSingle(connectivity -> service.listRepos("pwittchen"))
   .subscribeOn(Schedulers.io())
   .observeOn(AndroidSchedulers.mainThread())
   .subscribe(
       repos     -> /* handle repos here */,
       throwable -> /* handle error here */
   );

For more details regarding Retrofit, please visit its official website: http://square.github.io/retrofit/

ProGuard configuration

-dontwarn com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
-dontwarn io.reactivex.functions.Function
-dontwarn rx.internal.util.**
-dontwarn sun.misc.Unsafe

Examples

Exemplary application is located in app directory of this repository.

If you want to know, how to use this library with Kotlin, check app-kotlin directory.

Download

You can depend on the library through Maven:

<dependency>
    <groupId>com.github.pwittchen</groupId>
    <artifactId>reactivenetwork-rx2</artifactId>
    <version>x.y.z</version>
</dependency>

or through Gradle:

dependencies {
  implementation 'com.github.pwittchen:reactivenetwork-rx2:x.y.z'
}

Note #1: Please, replace x.y.z with the latest version number, which is Maven Central

Note #2: If you are using Gradle version lower than 3.0, replace implementation with compile

Tests

Tests are available in library/src/test/java/ directory and can be executed on JVM without any emulator or Android device from Android Studio or CLI with the following command:

./gradlew test

To generate test coverage report, run the following command:

./gradlew test jacocoTestReport

Code style

Code style used in the project is called SquareAndroid from Java Code Styles repository by Square available at: https://github.com/square/java-code-styles.

Static code analysis

Static code analysis runs Checkstyle, PMD, Lint, ErrorProne and NullAway. It can be executed with command:

./gradlew check

Reports from analysis are generated in library/build/reports/ directory.

Who is using this library?

These apps are using (or used) ReactiveNetwork library:

Are you using this library in your app and want to be listed here? Send me a Pull Request or an e-mail to [email protected]

Getting help

Do you need help related to using or configuring this library?

You can do the following things:

Don't worry. Someone should help you with solving your problems.

Tutorials

If you speak Spanish (Español), check out this tutorial: ReactiveNetwork - Como funciona y como se integra en una app made by Video Tutorials Android.

Caveats

Since version 0.4.0, functionality releated to observing WiFi Access Points and WiFi signal strength (level) is removed in favor of ReactiveWiFi library. If you want to use this functionality, check ReactiveWiFi project.

Changelog

See CHANGELOG.md file.

JavaDoc

JavaDoc is available at: http://pwittchen.github.io/ReactiveNetwork/javadoc/RxJava2.x

It can be generated as follows:

./gradlew androidJavadocs

In order to update JavaDoc on GitHub pages, use the following bash script:

./update_javadocs.sh

Then commit and push your changes to gh-pages branch.

Documentation

view website with documentation: RxJava1.x, RxJava2.x

It can be generated as follows:

Copy the latest README.md file from RxJava1.x or RxJava2.x branch. Then checkout to gh-pages branch and put it into appropriate directory inside docs/ directory.

You can do it as follows via bash script:

./update_docs.sh
git push

Install docsify with the following command:

npm i docsify-cli -g

Go into appropriate directory and type:

docsify init .

Right now it's already generated, so we can just update the README.md file and adjust generated files manually.

Next, we can just save changes, commit and push them to remote repository.

Releasing

See RELEASING.md file.

Contributors

References

Mentions

Supporters

Thanks for JetBrains for sponsoring IntelliJ IDEA license for open-source development

jetbrains logos

License

Copyright 2016 Piotr Wittchen

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].