【问题标题】:Interacting with AsyncTask from Notification Bar从通知栏与 AsyncTask 交互
【发布时间】:2014-03-02 07:38:30
【问题描述】:

所以我有一个 AsyncTask 处理上传到服务器,同时调用 NotificationHelper 类来更新通知栏以显示当前上传百分比。这部分工作正常,我唯一遇到的问题是让动作正常工作并能够使用动作发送的意图(最近的尝试是在父活动中使用广播管理器,但我从未收到消息)。如果有人能指出我正确的方向,那将不胜感激。

这里是一些代码:

 mNotificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);

    Intent intent = new Intent("com.example.sibmedemo.sibme");
    intent.putExtra("message","pause");
    PendingIntent pIntent = PendingIntent.getActivity(mContext, 0, intent, 0);

    mBuilder = new Notification.Builder(mContext)
            .setContentTitle("Upload File")
            .setContentText("Upload in progress")
            .setSmallIcon(R.drawable.ic_launcher)
            .addAction(R.drawable.ic_launcher,"Pause",pIntent)
            .addAction(R.drawable.ic_launcher,"Cancel",pIntent);

    mBuilder.setProgress(100,0,false);
    mNotificationManager.notify(0,mBuilder.build());

我认为我的主要问题是我没有正确理解pendingIntents 是如何工作的,或者它们是如何在android Activity 中交换的,对此问题的任何澄清都会有所帮助。

--------使用解决方案后的工作代码----------- 主要活动-----------

public class FileUploadActivityV2 extends Activity {

public static int flags = 0;
public BroadcastReceiver receiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {

        Log.i("message", "got a message");

        if(intent.getStringExtra("message").equalsIgnoreCase("pause"))
            flags = 1;

        goAsync();
    }
};

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_file_upload_activity_v2);

    registerReceiver(receiver, new IntentFilter("sibme"));

    flags = 0;
    (new UploadTask(this)).execute();
}

是的,我知道我应该负责 brodcastReceiver 的生命周期,但到目前为止,这对于测试是可以接受的。对于任何想知道的人来说,goAsync() 函数是 Android API 的一部分,它只是声明一旦接收器调用了 onReceive 函数,就可以回收接收器以备将来使用。

在 AsyncTask 类中---------

    @Override
    protected Long doInBackground(Integer... integers) {

    while(FileUploadActivityV2.flags == 0)
    {
        try{
            Thread.sleep(1000);
            Log.i("Running", "Running in background");
        }catch(Exception e){

        }
    }

    return null;
}

在通知助手类内部------

    public void createNotification() {
    mNotificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);

    Intent intent = new Intent("sibme");
    intent.putExtra("message","pause");
    PendingIntent pIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);

    mBuilder = new Notification.Builder(mContext)
            .setContentTitle("Upload File")
            .setContentText("Upload in progress")
            .setSmallIcon(R.drawable.ic_launcher)
            .addAction(R.drawable.ic_launcher,"Pause",pIntent)
            .addAction(R.drawable.ic_launcher,"Cancel",pIntent);

    mBuilder.setProgress(100,0,false);
    mNotificationManager.notify(0,mBuilder.build());

}

【问题讨论】:

  • 你在哪里设置 contentintent?
  • 我不确定您所说的内容意图是什么意思。
  • 那么,您希望能够从通知中取消或暂停您的异步任务,对吧?
  • 你为什么使用getActivity?当你想开始一个新的活动时使用它。如果您想在单击按钮时发送广播,请使用 getBroadcast。

标签: android android-asynctask broadcastreceiver android-notifications android-pendingintent


【解决方案1】:

了解PendingIntent 很重要。这是 Android 拥有的强大组件之一,除了通知操作处理之外,还可以用于许多目的。

您可以将待处理意图视为表示您要执行的操作(发送广播/启动活动/启动服务)+ 执行此操作的意图的对象。它的强大之处在于您可以向另一个进程/应用程序提供待处理的意图(在您的情况下,另一个进程是操作系统NotificationManager),并且您可以让其他进程能够唤醒您的应用程序并为您自动启动您提供的未决意图的意图。

因此,挂起的意图以某种方式在通知中用作“远程侦听器”,无需运行即可检测事件(在您的情况下,事件是通知按钮单击)

由于PendingIntent 作为在不同应用程序之间共享的对象的性质 - 您可以通过静态方法(PendingIntent.getService() / PendingIntent.getActivity() 等)获得引用/创建新的对象,返回新实例或现有的托管实例由系统。

让我们来看看你的代码:

通过调用PendingIntent.getActivity(),您可以创建待处理的意图,AlarmManager 可以启动您在意图中提供的特定活动(在您的情况下为“com.example.sibmedemo.sibme”)。我猜您想对暂停和取消操作做出不同的反应。 这就是为什么您需要为它们中的每一个设置不同的待处理意图。您可以通过不止一种方式区分这两种操作:

  • 为每个活动/服务启动不同的活动/服务或发送广播 (PendingIntent.getBroadcast())
  • 启动相同的活动,但使用different request code

无论如何 - 您必须创建不同的意图,因此 - 两个不同的待处理意图来表示您要为不同的操作执行的不同操作。

希望它对你有帮助,也许对其他人有帮助。

【讨论】:

  • 虽然我很欣赏这项工作,但我已经从我自己的研究中知道了其中的大部分内容,这就是为什么我最初将广播与广播接收器一起使用,然后再将我的代码恢复为这个。此外,两个按钮的两个意图当前相同的原因仅用于测试目的,一旦我完成示例,就会更改。虽然这些信息很有帮助,但我的主要问题更多的是实现这一点并与 AsyncTask 交互。
  • @Salvite:那么你应该发布异步任务代码,并解释你的问题到底是什么:你想做什么却没有成功?
【解决方案2】:

要与在后台工作的 asynctask 进行交互,您可以在 publishProgress() 中这样做(我从未尝试过)。否则,您只需执行前后执行。如果不是这种情况,我唯一能想到的是一个类 int 变量,其值根据用户单击的按钮而改变。然后可以在 doInBackground 中检查这一点并采取适当的措施。

【讨论】:

  • 我还想在我的代码中补充一点,由于意图和意图过滤器没有正确匹配,我的广播接收器无法正常工作,是的,int 标志是用于与按预期执行 doInBackground 函数。感谢所有帮助过的人,我将编辑这篇文章,以便立即显示更正的代码供其他人查看。
  • 酷,很高兴它有帮助!
猜你喜欢
  • 2017-07-21
  • 1970-01-01
  • 2020-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-19
相关资源
最近更新 更多