【问题标题】:Nativescript - How to bring app to foreground when notification is pressedNativescript - 按下通知时如何将应用程序置于前台
【发布时间】:2019-08-18 12:20:05
【问题描述】:

我正在编写一个原生 Android 代码来在按下通知时打开我的应用程序。如果应用程序已经打开(无论是在前台运行还是在后台运行),我想点击通知将应用程序带到最前面,而不是重新启动它,以便保留它的状态。

我尝试了以下代码(仅显示相关代码):



        ///////// Create an activity on tap (intent)
        const Intent = android.content.Intent;
        const PendingIntent = android.app.PendingIntent;
        // Create an explicit intent for an Activity in your app
        const intent = new Intent(context, com.tns.NativeScriptActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED | Intent.FLAG_ACTIVITY_NEW_TASK);


        const pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);

        ///////// Creating a notification 
        var NotificationCompat = android.support.v4.app.NotificationCompat;
        const builder = new NotificationCompat.Builder(context, CHANNEL_ID)
            .setSmallIcon(android.R.drawable.btn_star_big_on)
            .setContentTitle(title)
            .setContentText(message)
            .setStyle(
                new NotificationCompat.BigTextStyle()
                .bigText("By default, the notification's text content is truncated to fit one line.")
                )
            .setPriority(NotificationCompat.PRIORITY_HIGH)
            // Set the intent that will fire when the user taps the notification
            .setContentIntent(pendingIntent)
            .setAutoCancel(true);

        ///////// Show the notification
        notificationManager.notify(NOTIFICATION_ID, builder.build());

但这会打开应用程序而不保留其状态。

按照here 的建议,我还尝试模拟按下启动器中的应用程序图标 - 以便将应用程序带到前台并且不会重新创建 Nativescript 活动。

        const packageName = context.getPackageName();
        console.log('Package name: ',packageName);

        const emulateLaunchByAppIconIntent = context.getPackageManager()
            .getLaunchIntentForPackage(packageName)
            .setPackage(null)
            .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);

        const pendingIntent_emulated = PendingIntent.getActivity(context, 0, emulateLaunchByAppIconIntent, 0);


        ///////// Creating a notification 
        var NotificationCompat = android.support.v4.app.NotificationCompat;
        const builder = new NotificationCompat.Builder(context, CHANNEL_ID)
            .setSmallIcon(android.R.drawable.btn_star_big_on)
            .setContentTitle(title)
            .setContentText(message)
            .setStyle(
                new NotificationCompat.BigTextStyle()
                .bigText("By default, the notification's text content is truncated to fit one line.")
                )
            .setPriority(NotificationCompat.PRIORITY_HIGH)
            // Set the intent that will fire when the user taps the notification
            .setContentIntent(pendingIntent_emulated)
            .setAutoCancel(true);

        ///////// Show the notification
        notificationManager.notify(NOTIFICATION_ID, builder.build());

这确实使应用程序出现在前面,但没有保留其状态(即使应用程序已经在前台 - 它重新加载了应用程序)。

然后我尝试按下 Nativescript 应用程序图标(手动),当应用程序刚刚被发送到后台时 - 我发现它会重新启动应用程序,而不仅仅是将其带到前台。

我的问题是 - 为什么 Nativescript 应用程序会这样? 如何让 Android 仅将应用程序置于前台而不重新构建新的 nativescript 活动?

【问题讨论】:

  • 您是否尝试删除FLAG_ACTIVITY_NEW_TASK,只保留FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
  • 谢谢,我试试这个

标签: nativescript


【解决方案1】:

上述问题中的代码确实有效 - 并且确实将应用程序带到前台而不重新启动应用程序,保留其状态。

应用程序重新启动的原因,即使通过单击 Nativescript 应用程序图标(手动)与开发环境有关。

  1. 当我连接到运行 tns run android --bundle 的 Mac 时在物理设备上运行应用程序时发生这种情况,或者

  2. 在模拟器中运行应用程序(通过运行tns run android --bundle 或直接从应用程序图标启动应用程序)

在未连接到 nativescript 开发环境的物理设备上运行应用程序 - 显示了真实的行为 - 并且在单击通知后应用程序被带到前台而没有重新启动。

包含代码示例的更多信息:

我发现没有必要通过使用此代码模拟图标按下来启动应用程序

const emulateLaunchByAppIconIntent = context.getPackageManager()
   .getLaunchIntentForPackage(packageName)
   .setPackage(null)
   .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);

const pendingIntent_emulated = PendingIntent.getActivity(context, 0, emulateLaunchByAppIconIntent, 0);

作为下面代码中的PendingIntent.FLAG_UPDATE_CURRENTIntent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED,足以将应用程序带到前台而无需在单击通知后重新启动:

const openActivityIntent = new Intent(context, com.tns.NativeScriptActivity.class);
openActivityIntent.setFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED | Intent.FLAG_ACTIVITY_NEW_TASK);
const openActivityPendingIntent = PendingIntent.getActivity(context, 0, openActivityIntent, 0);

///////// Creating a notification
const notificationManager = <NotificationManager> context.getSystemService(NotificationManager.class);
var NotificationCompat = android.support.v4.app.NotificationCompat;

const builder = new NotificationCompat.Builder(context, CHANNEL_ID)
    .setSound(soundUri)
    .setSmallIcon(android.R.drawable.ic_lock_idle_alarm)
    .setContentTitle(title)
    .setContentText(message)
    .setStyle(
        new NotificationCompat.BigTextStyle()
        .bigText('More explaination text if needed. Disabled for now.')
        )
    .setPriority(NotificationCompat.PRIORITY_DEFAULT)
    // Set the intent that will fire when the user taps the notification
    .setContentIntent(openActivityPendingIntent)
    .setWhen(scheduledTime)
    .setAutoCancel(true)
    .build();


///////// Show the notification
notificationManager.notify(NOTIFICATION_ID, builder);

如果您遇到同样的问题,希望这对您有所帮助。

【讨论】:

    猜你喜欢
    • 2021-04-05
    • 1970-01-01
    • 2021-09-21
    • 2016-11-21
    • 2012-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多