使用BroadcastReceiver更新ProgressBar

时间:2019-04-03 03:54:24

标签: java android android-service android-progressbar

我正在尝试从ProgressBar任务更新Service。我实现了BroadcastReceiver,以便可以与UI线程进行交互。我在主要活动中更新ProgressBar,并从MyService活动中接收数据。 MyService活动将执行Async任务,并更新应通过OnProgressUpdate方法发送回的意图。

  

这是我的代码:

MainActivity:

package com.example.services;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.IntentFilter;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.content.Intent;
import android.view.View;
import android.widget.ProgressBar;

import static android.content.Intent.ACTION_ATTACH_DATA;

public class MainActivity extends AppCompatActivity {

    private MyBroadRequestReceiver receiver;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        IntentFilter filter = new IntentFilter(ACTION_ATTACH_DATA);
        receiver = new MyBroadRequestReceiver();
        registerReceiver( receiver, filter);
    }

    public void startService(View view) {
        startService(new Intent(getBaseContext(), MyService.class));
        //pb.setProgress();
    }
    public void stopService(View view) {
        stopService(new Intent(getBaseContext(), MyService.class));
    }
    public class MyBroadRequestReceiver extends BroadcastReceiver{

        @Override
        public void onReceive(Context context, Intent intent) {
            ProgressBar pb = (ProgressBar) findViewById(R.id.progressbar);
            int progress = intent.getFlags();
            pb.setProgress(progress);

        }

    }
}

我的服务:

package com.example.services;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.widget.ProgressBar;
import android.widget.Toast;
import java.net.MalformedURLException;
import java.net.URL;
import android.os.AsyncTask;
import android.util.Log;
import java.util.Timer;
import java.util.TimerTask;

public class MyService extends Service {

    int counter = 0;
    static final int UPDATE_INTERVAL = 1000;
    private Timer timer = new Timer();

    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
        doSomethingRepeatedly();

        try {
            new DoBackgroundTask().execute(
                    new URL("http://www.amazon.com/somefiles.pdf"),
                    new URL("http://www.wrox.com/somefiles.pdf"),
                    new URL("http://www.google.com/somefiles.pdf"),
                    new URL("http://www.learn2develop.net/somefiles.pdf"));
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (timer != null){
            timer.cancel();
        }
        Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
    }

    private void doSomethingRepeatedly() {
        timer.scheduleAtFixedRate(new TimerTask() {
            public void run() {
                Log.d("MyService", String.valueOf(++counter));

            }
        }, 0, UPDATE_INTERVAL);
    }

    private class DoBackgroundTask extends AsyncTask<URL, Integer, Long> {
        protected Long doInBackground(URL... urls) {
            int count = urls.length;
            long totalBytesDownloaded = 0;
            for (int i = 0; i < count; i++) {
                totalBytesDownloaded += DownloadFile(urls[i]);
                //Intent broadcastIntent = new Intent();
                //broadcastIntent.setAction(Intent.ACTION_ATTACH_DATA);
                //sendBroadcast(broadcastIntent);
                publishProgress((int) (((i + 1) / (float) count) * 100));
            }
            return totalBytesDownloaded;
        }

        protected void onProgressUpdate(Integer... progress) {
            Log.d("Downloading files", String.valueOf(progress[0]) + "% downloaded");
            Intent broadcastIntent = new Intent();
            broadcastIntent.setAction("com.example.services.MainActivity");
            //broadcastIntent.putExtra("progress",progress);
            broadcastIntent.setFlags(progress[0]);
            sendBroadcast(broadcastIntent);
            Toast.makeText(getBaseContext(),
                    String.valueOf(progress[0]) + "% downloaded-"+counter,
                    Toast.LENGTH_LONG).show();

        }

        protected void onPostExecute(Long result) {
            Toast.makeText(getBaseContext(), "Downloaded " + result + " bytes",
                    Toast.LENGTH_LONG).show();
            //stopSelf();
        }
    }

    private int DownloadFile(URL url) {
        try {
            //---simulate taking some time to download a file---
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //---return an arbitrary number representing
        // the size of the file downloaded---
        return 100;
    }
}

请看看我的onProgressUpdate,并告诉我是否正在这样做。我的ProgressBar根本没有更新。

4 个答案:

答案 0 :(得分:0)

因为您没有startService ononCreate()方法。服务将无法运行。

答案 1 :(得分:0)

所有这些都不是您解决问题的好方法。请浏览Google Android文档Backgournd guide

我建议您切换到DownloadManager。

答案 2 :(得分:0)

您的意图过滤器定义为“ ACTION_ATTACH_DATA”

IntentFilter filter = new IntentFilter(ACTION_ATTACH_DATA);

所以,像这样发送广播:

Intent i = new Intent(ACTION_ATTACH_DATA);
sendBroadcast(i);

此外,不要忘记在onDestroy上取消注册广播

答案 3 :(得分:0)

您的代码存在一些问题。

首先,如果您需要通过服务更新活动的进度条,那么有效的方法是使用LocalBroadcastManager而不是常规广播(称为全局广播)。

第二,因为在服务中,您使用broadcastIntent.setAction("com.example.services.MainActivity");,然后在活动中,必须使用相同的操作来接收广播。

IntentFilter filter = new IntentFilter("com.example.services.MainActivity");

代替

IntentFilter filter = new IntentFilter(ACTION_ATTACH_DATA);

最后,由于在服务中使用AsyncTask,为避免服务的泄漏上下文,建议的方法是将asynctask声明为静态类。

全部放在一起。

MyService.java

public class MyService extends Service {

    int counter = 0;
    static final int UPDATE_INTERVAL = 1000;
    private Timer timer = new Timer();

    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
        doSomethingRepeatedly();

        try {
            new DoBackgroundTask(this).execute(
                    new URL("http://www.amazon.com/somefiles.pdf"),
                    new URL("http://www.wrox.com/somefiles.pdf"),
                    new URL("http://www.google.com/somefiles.pdf"),
                    new URL("http://www.learn2develop.net/somefiles.pdf"));
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }

        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (timer != null) {
            timer.cancel();
        }
        Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
    }

    private void doSomethingRepeatedly() {
        timer.scheduleAtFixedRate(new TimerTask() {
            public void run() {
                Log.d("MyService", String.valueOf(++counter));

            }
        }, 0, UPDATE_INTERVAL);
    }

    // Declare asynctask as static class.
    private static class DoBackgroundTask extends AsyncTask<URL, Integer, Long> {

        // Using WeakReference to keep the context of the service to avoid leaking.
        private WeakReference<Context> mContext;

        DoBackgroundTask(Context context) {
            mContext = new WeakReference<>(context);
        }

        protected Long doInBackground(URL... urls) {
            int count = urls.length;
            long totalBytesDownloaded = 0;
            for (int i = 0; i < count; i++) {
                totalBytesDownloaded += DownloadFile(urls[i]);
                //Intent broadcastIntent = new Intent();
                //broadcastIntent.setAction(Intent.ACTION_ATTACH_DATA);
                //sendBroadcast(broadcastIntent);
                publishProgress((int) (((i + 1) / (float) count) * 100));
            }
            return totalBytesDownloaded;
        }

        protected void onProgressUpdate(Integer... progress) {
            Log.d("Downloading files", String.valueOf(progress[0]) + "% downloaded");
            Intent broadcastIntent = new Intent();
            broadcastIntent.setAction("com.example.services.MainActivity");
            //broadcastIntent.putExtra("progress",progress);
            broadcastIntent.setFlags(progress[0]);

            Context context = mContext.get();
            if (context != null) {
                LocalBroadcastManager.getInstance(context).sendBroadcast(broadcastIntent);

                int counter = ((MyService)context).counter;
                Toast.makeText(context,
                        String.valueOf(progress[0]) + "% downloaded-" + counter,
                        Toast.LENGTH_LONG).show();
            }
        }

        protected void onPostExecute(Long result) {
            Context context = mContext.get();
            if (context != null) {
                Toast.makeText(context, "Downloaded " + result + " bytes",
                        Toast.LENGTH_LONG).show();
                //stopSelf();
            }
        }

        private int DownloadFile(URL url) {
            try {
                //---simulate taking some time to download a file---
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //---return an arbitrary number representing
            // the size of the file downloaded---
            return 100;
        }
    }
}

MainActivity.java

public class MainActivity extends AppCompatActivity {

    private MyBroadRequestReceiver receiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    protected void onStart() {
        super.onStart();
        // Register broadcast receiver.
        IntentFilter filter = new IntentFilter("com.example.services.MainActivity");
        receiver = new MyBroadRequestReceiver();
        LocalBroadcastManager.getInstance(this).registerReceiver(receiver, filter);
    }

    @Override
    protected void onStop() {
        // Unregister broadcast receiver.
        LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver);
        super.onStop();
    }

    public void startService(View view) {
        startService(new Intent(getBaseContext(), MyService.class));
    }

    public void stopService(View view) {
        stopService(new Intent(getBaseContext(), MyService.class));
    }

    public class MyBroadRequestReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            ProgressBar pb = (ProgressBar) findViewById(R.id.progressbar);
            int progress = intent.getFlags();
            pb.setProgress(progress);
        }
    }
}