Activity with ProgressBar -> Service -> AsyncTask for downloading - but how to update the progress?

后端 未结 3 994
小蘑菇
小蘑菇 2021-02-03 16:32

this is the current state/situation: I have an Activity which binds a Service which creates AsyncTasks which downloads various web resources. That works well, but of course the

相关标签:
3条回答
  • 2021-02-03 16:52

    Very nice explained indeed just missing the example :) I went throw it and here it is.

    public class Detail extends Activity {
    
        private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                if(intent.getAction().equals(DownloadService.CUSTOM_INTENT)) {
                    mProgressDialog.setProgress(intent.getFlags());
                }
            }
        };
    
        // Flag if receiver is registered 
        private boolean mReceiversRegistered = false;
        // Define a handler and a broadcast receiver
        private final Handler mHandler = new Handler();
    
        @Override
        protected void onResume() {
          super.onResume();
    
          // Register Sync Recievers
          IntentFilter intentToReceiveFilter = new IntentFilter();
          intentToReceiveFilter.addAction(DownloadService.CUSTOM_INTENT);
          this.registerReceiver(mIntentReceiver, intentToReceiveFilter, null, mHandler);
          mReceiversRegistered = true;
        }
    
        @Override
        public void onPause() {
          super.onPause();
    
          // Make sure you unregister your receivers when you pause your activity
          if(mReceiversRegistered) {
            unregisterReceiver(mIntentReceiver);
            mReceiversRegistered = false;
          }
        }
    }
    
    
    
    
    
    
    
    
    public class DownloadService extends Service {
        private static final String CLASS_NAME = DownloadService.class.getSimpleName();
        private List<Download> downloads = new ArrayList<Download>();
        private int currentPosition;
        public static final String sdcardPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/";
        private Context ctx;
        @Override
        public IBinder onBind(Intent arg0) {
            ctx = getApplicationContext();
            return mBinder;
        }
    
    
        private class DownloadFile extends AsyncTask<String, Integer, String> {
    
            @Override
            protected String doInBackground(String... _url) {
                Log.d(Constants.LOG_TAG, CLASS_NAME + " Start the background GetNewsTask \nURL :" + _url[0]);
                int count;
                File finalFile = new File(sdcardPath + Constants.APK_LOCAL_PATH + "/" + splitName(_url[0]));
                try {
                    if (!finalFile.exists()) {
                        Log.i(Constants.LOG_TAG, CLASS_NAME + " Donwloading apk from the Web");
                        URL url = new URL(_url[0]);
                        URLConnection conexion = url.openConnection();
                        conexion.connect();
                        // this will be useful so that you can show a tipical 0-100%
                        // progress bar
                        int lenghtOfFile = conexion.getContentLength();
                        // downlod the file
                        InputStream input = new BufferedInputStream(url.openStream());
                        File dir = new File(sdcardPath + Constants.APK_LOCAL_PATH);
                        if (!dir.exists())
                            dir.mkdirs();
                        OutputStream output = new FileOutputStream(sdcardPath + Constants.APK_LOCAL_PATH + "/" + splitName(_url[0]));
                        byte data[] = new byte[1024];
                        long total = 0;
                        while ((count = input.read(data)) != -1) {
                            total += count;
                            // publishing the progress....
                            publishProgress((int) (total * 100 / lenghtOfFile));
                            output.write(data, 0, count);
                        }
                        output.flush();
                        output.close();
                        input.close();
                    } else {
                        Log.i(Constants.LOG_TAG, CLASS_NAME + " Apk in SDcard");
                        publishProgress(100);
                    }
                } catch (Exception e) {
                }
    
                return null;
    
            }
    
            @Override
            protected void onProgressUpdate(Integer... progress) {
                Intent i = new Intent();
                i.setAction(CUSTOM_INTENT);
                i.setFlags(progress[0]);
                ctx.sendBroadcast(i);
            }
        }
    
        private String splitName(String url) {
            String[] output = url.split("/");
            return output[output.length - 1];
        }
    
        public static final String CUSTOM_INTENT = "es.tempos21.sync.client.ProgressReceiver";
    
        private final IDownloadService.Stub mBinder = new IDownloadService.Stub() {
    
            public void downloadAsynFile(String url) throws DeadObjectException {
                try {
                    DownloadFile d = new DownloadFile();
                    d.execute(url);
                } catch (Exception e) {
                    Log.e(Constants.LOG_TAG, CLASS_NAME + " " +e.getMessage());         }
            }
    
    
            }
    };
    
    
    interface IDownloadService {
    
        void downloadAsynFile(String url);    
    }
    
    0 讨论(0)
  • 2021-02-03 16:57

    You can show progress just as easily via a Toast, which obviates all of the UI concerns:

    public class foo extends Service {
    private Toast toast;
    
    @SuppressLint("ShowToast")
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        super.onStartCommand(intent, flags, startId);
        ctxt = getApplicationContext();
        toast = Toast.makeText(ctxt, "", Toast.LENGTH_SHORT);
        ...
    }
    
    public void functionCalledByYourAsyncWithUpdates(String progress){
        toast.setText (progress);
        toast.show;
    }
    }
    
    0 讨论(0)
  • 2021-02-03 17:02

    Have the Service notify the then-running Activity about the progress from onProgressUpdate(). That could be via a broadcast Intent, or via a callback object registered by the Activity (and unregistered when the Activity is destroyed, such as on a screen rotation).

    0 讨论(0)
提交回复
热议问题