【问题标题】:How to set two intents in a pending intent如何在待处理的意图中设置两个意图
【发布时间】:2015-05-27 10:47:41
【问题描述】:

当用户点击通知时,可以设置多个启动意图。

让我解释一下我的具体问题:

我有一个带有通知的应用程序。每个通知都会打开一个不同的 Activity(也有不同的附加功能)。

现在我想提取有关通知使用情况的信息。因此,每次打开通知时,我都想启动一个带有一些附加功能的服务。

我想在不修改现有活动的情况下实现它,因为它们不会对更改“有罪”。

理想情况下,伪代码可能是这样的:

Intent originalActivityIntent=...;
Intent notificationsAnalyticsIntent=getRegisterNotificationClick(notificationId,username);
PendingIntent pi= PendingIntent.multiple(
                                   context,
                                   originalActivityIntent,
                                   notificationsAnalyticsIntent)

点击通知时同时启动两个意图。

编写某种服务/广播接收器可能非常复杂,因为我需要为每个 Activity 处理不同的参数。

关于如何保持清洁的任何想法?

【问题讨论】:

    标签: java android android-intent android-notifications


    【解决方案1】:

    没有。

    我们解决这个问题的方法是每个Activity in out 应用程序都从一些基本活动扩展而来,并且在每个通知中,我们在基本活动处理它的意图中传递了一个额外的内容。

    【讨论】:

    • 感谢您的回答,我有不完美但对我有效的解决方案,请检查线程中的答案。
    • 这是一个非常不错的解决方案,但可能存在一些性能问题(打开另一个冗余意图)和一些 UI 问题(可能会看到“分析活动屏幕”)
    【解决方案2】:

    达成了一个非常干净的解决方案。不完美,但它可以工作并保持代码干净,它只需要创建一个适配器活动,并且它对你的应用程序的其余部分是透明的。

    在清单中:

    <activity
        android:name="com.tests.AnalyticsActivity"
        android:noHistory="true">
    </activity>
    

    还有java代码:

    public class AnalyticsActivity extends Activity {
    
        private static final String KEY_INTERNAL_COMPONENT = "com.tests.AnalyticsReceiver.COMPONENT";
        private static final String KEY_NOTIFICATION_TYPE = "com.tests.AnalyticsReceiver.NOTIFICATION_TYPE";
        private static final String KEY_USERNAME = "com.tests.AnalyticsReceiver.USERNAME";
    
        public static Intent getLaunchIntent(
                Context context, Intent intent, long notificationType, String username) {
            intent.putExtra(KEY_INTERNAL_COMPONENT, intent.getComponent());
            intent.setComponent(new ComponentName(context, AnalyticsActivity.class));
            intent.putExtra(KEY_NOTIFICATION_TYPE, notificationType);
            intent.putExtra(KEY_USERNAME,username);
            return intent;
        }
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            if(savedInstanceState==null){
                Intent intent=getIntent();
                long notifType=intent.getLongExtra(KEY_NOTIFICATION_TYPE, 0);
                String username=intent.getStringExtra(KEY_USERNAME);
                Log.e("RegisterEvent", "notif=" + notifType + ",username=" + username);
                ComponentName componentName=intent.getParcelableExtra(KEY_INTERNAL_COMPONENT);
                intent.setComponent(componentName);
                startActivity(intent);
            }
        }
    
    }
    

    【讨论】:

      【解决方案3】:

      我能够通过本质上链接意图来解决这个问题。让 PendingIntent 启动您的NotificationsAnalyticsIntent;然后让NotificationsAnalyticsIntent 启动活动意图。有几种方法可以“告诉”通知意图启动哪个活动。一种方法是将其作为字符串传递。

      Intent intent = NotificationsAnalyticsIntent.newIntent(applicationContext, SomeActivity.class);
      PendingIntent pendingIntent = PendingIntent.getService(applicationContext, 0, intent, 0);
      ...
      
      public class NotificationsAnalyticsIntent extends IntentService {
      
          private static final String EXTRA_ACTIVITY_TO_START = "extra_activity_to_start";
      
          public static Intent newIntent(final Context context, final Class activityToStart) {
              Intent intent = new Intent(context, NotificationsAnalyticsIntent.class);
              intent.putExtra(EXTRA_ACTIVITY_TO_START, activityToStart.getSimpleName());
              return intent;
          }
      
          public NotificationsAnalyticsIntent() {
              super(NotificationsAnalyticsIntent.class.getSimpleName());
          }
      
          @Override
          protected void onHandleIntent(@Nullable final Intent intent) {
              // .... do notification stuff
              // TODO
      
              // .... then start activity
              String activityToStart = intent.getStringExtra(EXTRA_ACTIVITY_TO_START);
              try {
                  Class<?> aClass = Class.forName(activityToStart);
                  Method method = aClass.getMethod("newIntent", Context.class);
                  Context params = getApplicationContext();
                  Intent activityIntent = (Intent) method.invoke(null, (Object) params);
                  startActivity(activityIntent);
      
              } catch (ClassNotFoundException | InvocationTargetException | NoSuchMethodException | IllegalAccessException e) {
                  // TODO 
              }
      
          }
      }
      

      几个限制:

      1. 活动类必须完全合格。确保 activityToStart.getName() 返回com.example.app.SomeActivity
      2. 反射:barf:
      3. SomeActivity 不能在没有额外丑陋的情况下以自己的意图附加内容开始

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-12-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多