当前位置: 首页 > 知识库问答 >
问题:

当应用程序未运行时,无法从通知中调用活动方法

宋智明
2023-03-14

我有一个警报提醒,显示带有额外数据的通知。我想做的是通过intent将额外数据从我的通知发送到我的主要活动,然后打开应用程序并调用该活动中的特定方法(位置信息)。该方法将根据我传递的位置ID打开一个新的活动。

当我的应用程序在后台运行时效果很好,但当它被杀死时,即当应用程序完全关闭时,它会打开应用程序的主要活动,但不会调用该方法。

我的通知代码用于有意发送数据:

Intent intent = new Intent(this, MainActivity.class);
intent.putExtra("fromNotification", true);
intent.putExtra("locationId", locationId);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP 
              | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 111, intent, 
              PendingIntent.FLAG_UPDATE_CURRENT);

我这样称呼我的方法:

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    setIntent(intent);
    if (getIntent().hasExtra("fromNotification")) {
        String locationId = getIntent().getStringExtra("locationId");
        CallFetchLocationInfoFromMapsFragment(locationId);
    }
}

我还尝试在我的主要活动onCreate的末尾添加这个,这本应该是解决方案,但它没有起到任何作用:

if (getIntent().hasExtra("fromNotification")) {
    String locationId = getIntent().getStringExtra("locationId");
    CallFetchLocationInfoFromMapsFragment(locationId);
}

我尝试了更多的解决方案(包括这个,这个,这个,这个,这个,这个,这个,还有更多),但都没能成功。

清单(仅为主要活动部分):

<application
    android:name="com.weekendcoder.kemo.hotels.app.AppController"
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:screenOrientation="portrait"
        android:theme="@style/AppTheme.NoActionBar"
        android:launchMode="singleTask">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    ...
</application>

这是我理想工作流程的描述——如果我点击通知,它会打开我的MainActivity,它有一个maps片段。在我的地图上加载所有内容后,我想从我的主要活动的地图开始一个新的活动-我想使用我从通知中收到的id打开locationDetails活动。由于调试在我关闭应用程序后立即停止,我无法确定问题所在,但我尝试添加了以下内容:

if (getIntent().hasExtra("fromNotification")) 
{
    Toast.makeText(MainActivity.this, "Notification!", Toast.LENGTH_LONG).show();
}

在我的onCreate开始时,它确实显示了祝酒词。我不能在onCreate开始时使用这个条件,因为地图没有加载和设置,所以我在onCreate结束时添加了它。在这种情况下,它永远不会被调用。

我可以通过直接从通知打开新活动来实现,但这不是我的理想解决方案。我想能够调用活动中的任何方法从通知时,应用程序关闭。

我还尝试添加了以下内容:

if (getIntent().hasExtra("fromNotification")) {
    String locationId = getIntent().getStringExtra("locationId ");
    CallFetchLocationInfoFromMapsFragment(locationId);
    Toast.makeText(MainActivity.this, "Notification id: " locationId, Toast.LENGTH_LONG).show();
}else{
    Toast.makeText(MainActivity.this, "No notification", Toast.LENGTH_LONG).show();
}

在onCreate结束时,我只是想看看是否可以显示这个值,但我一直收到“No notification”toast。

当我在onCreate开始时设置相同的if条件时,它崩溃了:

08-14 18:06:03.319 18591-18591/com.weekendcoder.kemo.hotels D/SQLiteHandler: Fetching notification settings from sqlite db
08-14 18:06:03.329 18591-18591/com.weekendcoder.kemo.hotels W/Settings: Setting airplane_mode_on has moved from android.provider.Settings.System to android.provider.Settings.Global, returning read-only value.
08-14 18:06:03.384 18591-18591/com.weekendcoder.kemo.hotels D/AndroidRuntime: Shutting down VM
08-14 18:06:03.384 18591-18591/com.weekendcoder.kemo.hotels W/dalvikvm: threadid=1: thread exiting with uncaught exception (group=0x41cdc700)
08-14 18:06:03.389 18591-18591/com.weekendcoder.kemo.hotels E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.weekendcoder.kemo.hotels/com.weekendcoder.kemo.hotels.MainActivity}: java.lang.NullPointerException
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2295)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2349)
    at android.app.ActivityThread.access$700(ActivityThread.java:159)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1316)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:176)
    at android.app.ActivityThread.main(ActivityThread.java:5419)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:525)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1046)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:862)
    at dalvik.system.NativeStart.main(Native Method)
 Caused by: java.lang.NullPointerException
    at com.weekendcoder.kemo.hotels.sliderfragments.MapsFragment.fetchlocationDetails(MapsFragment.java:545)
    at com.weekendcoder.kemo.hotels.MainActivity.CallFetchlocationDetailsFromMapsFragment(MainActivity.java:661)
    at com.weekendcoder.kemo.hotels.MainActivity.onCreate(MainActivity.java:324)
    at android.app.Activity.performCreate(Activity.java:5372)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1104)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2257)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2349) 
    at android.app.ActivityThread.access$700(ActivityThread.java:159) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1316) 
    at android.os.Handler.dispatchMessage(Handler.java:99) 
    at android.os.Looper.loop(Looper.java:176) 
    at android.app.ActivityThread.main(ActivityThread.java:5419) 
    at java.lang.reflect.Method.invokeNative(Native Method) 
    at java.lang.reflect.Method.invoke(Method.java:525) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1046) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:862) 
    at dalvik.system.NativeStart.main(Native Method) 

编辑:

有一个可行的解决方案,但我对此不满意,希望找到更智能/更安全的解决方案。解决方案是在开始时获取id,然后添加以下内容:

if (locationId != null) {
    final Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            //Do something after 100ms
            CallFetchLocationInfoFromMapsFragment(locationId);
        }
    }, 5000);
}

这将允许我的应用程序等待5秒,然后在所有其他方法执行后调用该方法。这是可行的,但我不确定这是最好的方式继续下去,有些设备可能会慢一些。最好找到一种方法来检查onCreated是否完全完成了执行,然后调用这个方法。

共有2个答案

居晗日
2023-03-14

我想你需要这个

if (getIntent().hasExtra("fromNotification")) {
    String locationId = getIntent().getStringExtra("locationId");
    CallFetchLocationInfoFromMapsFragment(locationId);
}

同时为清单中的活动设置单一任务启动模式

<activity android:name=".YourActivity"
        android:launchMode="singleTask">
    ...
</activity>
齐坚成
2023-03-14

在评论(上图)中的讨论中,您表示您正在使用LaunchMode="singleTask"。这是一种特殊的启动模式,对于您的应用程序来说应该不是必需的。它通常会产生比它解决的问题更多的问题。请删除特殊的启动模式,看看这是否有帮助。完成此操作后,在应用程序未运行时点击通知应该会启动应用程序并创建Mainactive的新实例。

您也可能无法在onCreate()中执行您想执行的操作,因为尚未设置您的片段。你可能只需要记住你想在onCreate()中做什么(开始位置详细信息),但实际上要等到你设置好你的片段后再去做。

 类似资料:
  • 仅当打开应用并执行通知单击时,通知单击才会启动指定的活动。如果应用程序处于后台/未运行,并且执行了通知单击,则会打开应用程序的 MainActivity。简而言之,这就像应用程序在活动堆栈之后正常打开,而不是在 PendingIntent 中打开指定的活动。 我想根据它们的类型将通知单击重定向到两个不同的活动(批准详细活动和对话详细活动)。 我使用FCM进行推送通知。我在这里粘贴我的Manifes

  • 当我打开我的android应用程序并测试解析推送通知时,它工作了。但是当我把我的应用程序从多任务中杀死并再次测试时,应用程序崩溃了。 错误日志 08-18 21:16:21.694 244 06-24406/?E/AndroidRuntime:致命异常:main process:com.myatminsoe.mKeyboard,PID:24406 java.lang.runtimeExceptio

  • 当app不再活动(即使是最近的任务)时,如何从FCM接收推送通知。我看到gmail、whatsapp都有这个功能。我正在使用FCM进行推送通知。我使用了WakefulBroadcast接收器来唤醒设备。我怎么用这个? 服务类别:

  • 当应用程序被强制退出时,似乎不会调用函数。我的印象是,无论应用程序处于何种状态,都会调用该函数,但似乎只有在应用程序已经在后台运行时才会调用该函数。如果应用程序尚未使用新的iOS 7远程通知后台模式运行,是否有办法在后台唤醒该应用程序?

  • 下面是我的函数的简化版本: 我没有任何特定的java代码,因为我现在只需要显示通知。有没有人想过用一种简单的方法来存档这个问题?

  • 我正在尝试在windows Phone7.5中实现推送通知 更新: 我知道通道活动时间长达30天,当我只使用模拟器时是否相同? 应用程序应与通道相关联,以便接收通知,即使在应用程序未运行时,如果通知通道处于活动状态,则应用程序也将接收toast