I'm developing an app that needs to download a json file from a web server in the background and stored it in the external memory, every time you load the activity it will populate the data by reading the file first (and if there is no file it will use the assets file) but on the background (every time that certain amount of time have passed) it will update the file.
The thing is that I manage to do this and it works fine, but the other day I put the device in airplane mode and when you enter in the activity the download starts but due to the fact that there is no internet connection the download icon in the notification bar doesn't disappear and that is a bad behaviour for user experience.. So I am asking how to change this and only download the file if there is internet connection.
This is the code:
if (comprobarFecha()) {
downloadFile(getActivity());
}
String downloadCompleteIntentName = DownloadManager.ACTION_DOWNLOAD_COMPLETE;
IntentFilter downloadCompleteIntentFilter = new IntentFilter(downloadCompleteIntentName);
BroadcastReceiver mDownloadEstablecimientosComplete = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
DownloadManager dm = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
long downloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -2);
DownloadManager.Query query = new DownloadManager.Query();
Log.e("QUERY", "broadcast " + String.valueOf(downloadId));
query.setFilterById(downloadId);
Cursor cur = dm.query(query);
if (cur.moveToFirst()) {
int columnIndex = cur.getColumnIndex(DownloadManager.COLUMN_STATUS);
switch (cur.getInt(columnIndex)) {
case DownloadManager.STATUS_SUCCESSFUL:
// Como se ha completado con éxito borramos el archivo antiguo
Log.e(AppConstants.TAG_RECETA, "Descarga realizada con éxito");
File file = context.getExternalFilesDir(null);
String mFileNameNew = file.getPath() + "/" + AppConstants.TAG_RECETAS + "-1";
File establecimientosFileNew = new File(mFileNameNew);
// Existe uno nuevo
if (establecimientosFileNew.exists()) {
Log.e("entro", "existe uno nuevo");
String establecimientosFileOld = file.getPath() + "/" + AppConstants.TAG_RECETAS;
File mFileNameOld = new File(establecimientosFileOld);
if (mFileNameOld.exists()) {
// Borramos el viejo
mFileNameOld.delete();
// Renombramos el nuevo
Log.e("entro", "renombramos el nuevo");
establecimientosFileNew.renameTo(mFileNameOld);
Snackbar.make(mSnackBarView, "Recetas actualizadas", Snackbar.LENGTH_SHORT).show();
}
}
break;
case DownloadManager.STATUS_FAILED:
int columnReasonIndex = cur.getColumnIndex(DownloadManager.COLUMN_REASON);
Log.e(AppConstants.TAG_RECETAS, "Descarga fallida: " + cur.getInt(columnReasonIndex));
break;
}
}
cur.close();
cur = null;
}
};
getActivity().registerReceiver(mDownloadEstablecimientosComplete, downloadCompleteIntentFilter);
public void downloadFile(Context ctx) {
DownloadManager mDownloadManager = (DownloadManager) ctx.getSystemService(Context.DOWNLOAD_SERVICE);
String url_download = url + cod;
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url_download));
// Tipo de archivo
request.setMimeType("application/json");
// Solo descargamos con WIFI
request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE);
// Titulo
request.setTitle("Descarga recetas");
// No será visible en el historial de descargas
request.setVisibleInDownloadsUi(false);
//request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
// Guardamos el archivo
request.setDestinationInExternalFilesDir(ctx, null, TAG_RECETAS);
// Guardamos el id para notificación cuando acabe
long quequeId = mDownloadManager.enqueue(request);
Log.e("QUERY", "download " + String.valueOf(mDownloadManager.enqueue(request)));
}
If I create a method for detecting the internet connection first and only launch those methods if I have network service works as I expected..but I dont know if this is the way its supposed to work, I know that maybe this question is more about how broadcast receiver works than programation question
What I mean is that my solution is like this:
if (isNetworkAvailable()) {
inicializarFecha();
if (comprobarFecha()) {
downloadFile(getActivity());
}
String downloadCompleteIntentName = DownloadManager.ACTION_DOWNLOAD_COMPLETE;
IntentFilter downloadCompleteIntentFilter = new IntentFilter(downloadCompleteIntentName);
BroadcastReceiver mDownloadEstablecimientosComplete = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
....
private boolean isNetworkAvailable() {
ConnectivityManager connectivityManager
= (ConnectivityManager) getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
Thank you so much in advance :)
Finally I've made this method:
private boolean isNetworkAvailable() {
ConnectivityManager connectivityManager
= (ConnectivityManager) getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
and then:
if (isNetworkAvailable()) {
inicializarFecha();
if (comprobarFecha()) {
downloadFile(getActivity());
}
/* Gestionar la actualizacion del fichero de establecimientos */
String downloadCompleteIntentName = DownloadManager.ACTION_DOWNLOAD_COMPLETE;
final IntentFilter downloadCompleteIntentFilter = new IntentFilter(downloadCompleteIntentName);
BroadcastReceiver mDownloadEstablecimientosComplete = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
DownloadManager dm = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
long downloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
DownloadManager.Query query = new DownloadManager.Query();
query.setFilterById(downloadId);
Log.e("QUERY", "broadcast " + String.valueOf(downloadId));
Cursor cur = dm.query(query);
if (cur.moveToFirst()) {
int columnIndex = cur.getColumnIndex(DownloadManager.COLUMN_STATUS);
switch (cur.getInt(columnIndex)) {
case DownloadManager.STATUS_SUCCESSFUL:
// Como se ha completado con éxito borramos el archivo antiguo
Log.e(AppConstants.TAG_ESTABLECIMIENTOS, "Descarga realizada con éxito");
File file = context.getExternalFilesDir(null);
String mFileNameNew = file.getPath() + "/" + AppConstants.TAG_ESTABLECIMIENTOS + "-1";
File establecimientosFileNew = new File(mFileNameNew);
// Existe uno nuevo
if (establecimientosFileNew.exists()) {
Log.e("entro", "existe uno nuevo");
String establecimientosFileOld = file.getPath() + "/" + TAG_ESTABLECIMIENTOS;
File mFileNameOld = new File(establecimientosFileOld);
if (mFileNameOld.exists()) {
// Borramos el viejo
mFileNameOld.delete();
// Renombramos el nuevo
Log.e("entro", "renombramos el nuevo");
establecimientosFileNew.renameTo(mFileNameOld);
Snackbar.make(mSnackBarView, "Establecimientos actualizados", Snackbar.LENGTH_SHORT).show();
}
}
break;
case DownloadManager.STATUS_FAILED:
int columnReasonIndex = cur.getColumnIndex(DownloadManager.COLUMN_REASON);
Log.e(AppConstants.TAG_ESTABLECIMIENTOS, "Descarga fallida: " + cur.getInt(columnReasonIndex));
break;
}
}
cur.close();
cur = null;
}
};
getActivity().registerReceiver(mDownloadEstablecimientosComplete, downloadCompleteIntentFilter);
}
Now it's working fine, but the main question was why if you set airplane mode
request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE);
It will try to download the file anyway