Search code examples
androidintentfilterandroid-download-managerandroid-broadcastreceiver

Download file from internet and register broadcast receiver only with network available


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 :)


Solution

  • 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