【问题标题】:Send LocalBroadcast if activity is running else send notification from a background service如果活动正在运行,则发送 LocalBroadcast 否则从后台服务发送通知
【发布时间】:2015-10-30 07:58:27
【问题描述】:

如果 Activity 正在运行,我需要使用 LocalBroadcast 从后台服务更新我的 Activity。如果应用程序或活动当前没有运行,我想添加一个待处理通知。

我浏览了以下帖子 -

Check if activity is running from service

Activity or Notification via Ordered Broadcast

我有以下疑问 -

  • 如何检查应用程序/活动是否从后台服务运行?
  • 如果我在活动的 onPause() 和 onResume() 中注册和取消注册广播侦听器,是否还需要检查活动是否正在运行?
  • 根据上面的链接#2 - If the activity is not on-screen, its receiver will not be registered, so the event will go to the default handler, in the form of your manifest-registered BroadcastReceiver, which will raise the Notification - 如果可能,如何实现?

如果有其他解决方案,也请分享。

【问题讨论】:

  • 在 onPause() 和 onResume() 中注册和取消注册广播监听器是一个很好的解决方案,你可以在你的服务中注册监听器,每次活动进入后台,调用服务中注册的监听器并设置添加待处理通知的内容
  • @Leon_SFS,您能否详细说明registering listener in service的意思
  • 我的意思是您的服务上的广播侦听器,活动发送广播,服务获取它并知道活动已关闭
  • 哦,这意味着只要活动关闭,我们就会知道服务中的状态。谢谢!

标签: android android-notifications localbroadcastmanager


【解决方案1】:

过去一周我遇到了同样的情况。我找到了一个更好的解决方案,可能会对您有所帮助。

查找activity是否是service中当前正在运行的activity

boolean isNotificationRequired = true;
ActivityManager am = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1);
Log.d("TEST", "CURRENT Activity ::" + taskInfo.get(0).topActivity.getClassName());
ComponentName componentInfo = taskInfo.get(0).topActivity;
componentInfo.getPackageName();

在清单文件中添加

<uses-permission android:name="android.permission.GET_TASKS" />

如果活动是当前正在运行的活动,则立即执行操作。

if(taskInfo.get(0).topActivity.getClassName().equals(YOUR_CURRENT_ACTIVITY.class.getName())
{
     //Perform the Operations
     isNotificationRequired = false;
}

现在仅当 isNotificationRequired 为 true 时才发送通知。

if(isNotificationRequired){
        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
                this).setSmallIcon(R.drawable.ic_launcher)
                .setContentTitle("Notification Title")
                .setContentText("Notification Message");
        PendingIntent notifyIntent = PendingIntent.getActivity(this, requestcode,
                resultIntent, PendingIntent.FLAG_ONE_SHOT);
        mBuilder.setContentIntent(notifyIntent);
        mBuilder.setAutoCancel(true);
        mBuilder.setDefaults(Notification.DEFAULT_VIBRATE
                | Notification.DEFAULT_SOUND | Notification.DEFAULT_LIGHTS);
        NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

        mNotificationManager.notify(requestcode, mBuilder.build());    
}

否则,请发送广播并更新您的活动。

(对我来说,如果我发送现有的意图,它没有在接收器中正确接收。所以我创建了新的意图并在这个 newIntent 的 putExtras() 中传递了现有的意图的数据。)

else {
            Log.i("TEST", "Sending broadcast to activity");
            Intent newIntent = new Intent();
            newIntent.setAction("TestAction");
            sendBroadcast(newIntent);
     }

然后在您的活动中通过创建广播接收器来处理广播。不要忘记实例化。无需在 manifest.xml 中提及您的接收者。

public class YourCurrentRunningActivity extends Activity {
    YourBroadcastReceiver receiver = new YourBroadcastReceiver();

    protected void onCreate(Bundle savedInstanceState) {
    (this).registerReceiver(receiver, new IntentFilter("TestAction"));

     public class YourBroadcastReceiver extends BroadcastReceiver {

         @Override
         public void onReceive(Context arg0, Intent arg1) {
              // Perform the Actions u want.
         }
     }
}

然后您可以像这样在 onStop()/onPause()/onDestroy() 中取消注册接收器:

this.unregisterReceiver(receiver);

【讨论】:

  • 谢谢!这种方法的一个缺点是 - 不建议使用 ActivityManager - As of LOLLIPOP, this method is no longer available to third party applications: the introduction of document-centric recents means it can leak person information to the caller. For backwards compatibility, it will still return a small subset of its data: at least the caller's own tasks, and possibly some other tasks such as home that are known to not be sensitive
  • 我终于接受了你的建议,除了检查活动。
  • 很高兴听到。你能告诉我你是如何在不使用 ActivityManager 的情况下找到当前活动的吗?
  • 如上面的 cmets 中所述 - 您可以使用另一个广播接收器,该接收器在您的活动的 onPause() 中触发,您可以在您的服务中获取此信息。还有另一种方法,这可能不是推荐的做法 - 您可以在活动中使用静态变量并在 onPause() 和 onResume() 中设置/重置它;你可以在你的服务中读取这个变量。
猜你喜欢
  • 1970-01-01
  • 2018-08-14
  • 1970-01-01
  • 2021-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多