问题
I'm currently developing an instant message application based on FCM (Firebase Cloud Message). My problem lies in the follow scenario:
- User is connected to an intermitent network - i.e. a wi-fi that, although holds the connection with the device, might lose internet connection from time to time with the internet provider;
- User attempts to send a message (a POST request using volley) when the device is connected to the wi-fi but with no internet connection;
What is the best way to tackle this issue? So far, I've implemented a listener for network change using BroadcastReceiver, however, it is not enough to deal with the scenario described above once the wi-fi connection is not lost.
回答1:
I created my own utility class for that. Whenever I want to make a network call I use the callbacks whenever its a success or a failure. The Library in use is MaterialDialog
public class NetworkUtil {
public static boolean isOnline() {
InetAddress inetAddress = null;
try {
Future<InetAddress> future = Executors.newSingleThreadExecutor().submit(new Callable<InetAddress>() {
@Override
public InetAddress call() {
try {
return InetAddress.getByName("google.com");
} catch (UnknownHostException e) {
return null;
}
}
});
inetAddress = future.get(2000, TimeUnit.MILLISECONDS);
future.cancel(true);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
return inetAddress != null && !inetAddress.equals("");
}
public static MaterialDialog checkConnectivity(final Activity activity, final NetworkUtilCallback callback) {
MaterialDialog dialog = MaterialDialogUtil.builDialogPositiveNegative(activity,
activity.getString(R.string.no_internet),
activity.getString(R.string.instruction_no_internet),
"RETRY",
"CANCEL",
new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(MaterialDialog dialog, DialogAction which) {
dialog.dismiss();
if (!isOnline()) {
checkConnectivity(activity, callback);
} else {
callback.onSuccess();
}
}
},
new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(MaterialDialog dialog, DialogAction which) {
dialog.dismiss();
callback.onCancel();
}
});
if (!isOnline()) {
dialog.show();
} else {
callback.onSuccess();
}
return dialog;
}
public interface NetworkUtilCallback {
void onSuccess();
void onCancel();
}
回答2:
In your manifest
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
And the condition to check before performing server requests!
public static boolean hasInternetConnection()
{
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo wifiNetwork = cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
if (wifiNetwork != null && wifiNetwork.isConnected())
{
return true;
}
NetworkInfo mobileNetwork = cm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
if (mobileNetwork != null && mobileNetwork.isConnected())
{
return true;
}
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
if (activeNetwork != null && activeNetwork.isConnected())
{
return true;
}
return false;
}
来源:https://stackoverflow.com/questions/38506108/how-to-handle-no-internet-connection-scenario-when-sending-requests