如何在待定意图中设置两个意图

How to set two intents in a pending intent

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

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

我有一个带通知的应用程序。每个通知都会打开一个不同的 Activity(也有不同的额外内容)。

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

我想在不修改现有活动的情况下实现它,因为它们不是 "guilty" 的更改。

理想情况下伪代码应该是这样的:

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

单击通知时启动两个意图。

编写某种 service/broadcast 接收器可能非常复杂,因为我需要为每个 Activity.

处理不同的参数

关于如何保持清洁有什么想法吗?

没有

我们解决这个问题的方法是,每个 Activity in out 应用程序都从某个基础 activity 扩展,并且在每个通知中我们传递一个额外的意图,基础 activity 处理它。

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

清单中:

<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);
        }
    }

}

我能够通过本质上链接意图来解决这个问题。让 PendingIntent 开始你的 NotificationsAnalyticsIntent;然后让 NotificationsAnalyticsIntent 启动 activity 意图。有几种方法可以 "tell" activity 启动通知意图。一种方法是将其作为字符串传递。

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. activity class 必须完全合格。确保 activityToStart.getName() returns com.example.app.SomeActivity
  2. 反思:barf:
  3. 无法开始 SomeActivity 没有一些额外的丑陋