【问题标题】:Android onNewIntent() not triggered when activity is invisible活动不可见时未触发Android onNewIntent()
【发布时间】:2018-08-27 14:39:52
【问题描述】:

我有 2 个活动,第一个是 MainActivity。在Manifest 中,Second Activity 的启动模式设置为SingleInstance。MainActivity 中的按钮启动SecondActivity,其中有一个触发通知的按钮。唯一的问题是 SecondActivity 不可见时没有调用 SecondActivity 的 onNewIntent() 方法。为什么当应用程序处于后台时不调用 onNewIntent() 方法或SecondActivity 对用户是不可见的?

代码:

清单:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.globemaster.com.trials">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity"
       >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".SecondActivity"
            android:launchMode="singleInstance"
            android:parentActivityName=".MainActivity"/>
    </application>

</manifest>

Java:

MainActivity.java:

 Intent intent=new Intent(MainActivity.this,SecondActivity.class);
 startActivity(intent);

SecondActivity.java:

public class SecondActivity extends AppCompatActivity {
    int count=0;int id=3;Notification notification;
    NotificationManager notificationManager;
    Intent intent,intent1;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_second);
        findViewById(R.id.send).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                count++;
                intent1=new Intent(getApplicationContext(),SecondActivity.class);
                if (count>1){
                    intent1.putExtra("click",true);
                    }
                PendingIntent pendingIntent=PendingIntent.getActivity(getApplicationContext(),0,intent1,PendingIntent.FLAG_UPDATE_CURRENT);
                if (notificationManager==null)
                {
                    notificationManager= (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
                    }
                Notification.Builder builder=new Notification.Builder(getApplicationContext());
                builder.setSmallIcon(R.drawable.ic_launcher_background);
                builder.setContentTitle("My Notification");
                builder.setContentText("You have "+count+" message");
                builder.setContentIntent(pendingIntent);
                notification=builder.build();
                notificationManager.notify(3,notification);
                }        });
    }
    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        Log.e("OnNewIntent","Called");
        if (intent!=null&&intent.hasExtra("click")&&intent.getBooleanExtra("click",false))
        {
            Toast.makeText(getApplicationContext(), "Notification Clicked", Toast.LENGTH_SHORT).show();
        }
        else {
            Toast.makeText(getApplicationContext(), "False", Toast.LENGTH_SHORT).show();
        }
    }
}

【问题讨论】:

    标签: android notifications onnewintent


    【解决方案1】:

    根据documentation

    如果 Activity 在其包中将 launchMode 设置为“singleTop”,或者客户端在调用 startActivity(Intent) 时使用了 Intent.FLAG_ACTIVITY_SINGLE_TOP 标志,则会调用此方法。

    基于此,您可以尝试以下任一方法:

    • 将清单中的android:launchMode设置为singleTop;或
    • 在调用startActivity之前通过intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)将标志添加到Intent

    如果你:

    • 需要singleInstance 行为;和
    • 希望在后台的Activity 出现在前台时得到通知(例如在singleInstance 案例中);和
    • 不需要明确的Intent

    那么就可以实现onResume方法,当用户返回Activity时会调用该方法。

    测试后编辑

    我在测试中观察到的是,如果singleInstance Activity 在后台并且Intents 被传递给它(例如通过startActivity),这些将排队直到Activity进入前台,然后:

    • 为每个Intent 调用onNewIntent;那么
    • onResume 被调用一次

    这与文档相矛盾,但可以用来解决您的问题。

    documentation中所述:

    请注意,getIntent() 仍然返回原始 Intent。您可以使用setIntent(Intent) 将其更新为这个新的 Intent。

    因此,如果您愿意在Activity 出现在前台时处理Intents,您可以将上面的onNewIntent 替换为:

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
    
        setIntent(intent);
    }
    
    @Override
    protected void onResume() {
        super.onResume();
    
        Intent intent = getIntent();
        if (intent != null && intent.hasExtra("click") && intent.getBooleanExtra("click", false)) {
            Toast.makeText(getApplicationContext(), "Notification Clicked", Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(getApplicationContext(), "False", Toast.LENGTH_SHORT).show();
        }
    }
    

    【讨论】:

    • 我试过 singleTop.SingleTop 意味着它应该在堆栈的顶部。所以我将它设置为singleInstance。所以第一次创建活动时会创建一个singleInstance。我想知道为什么当活动不可见时不会触发onNewIntent方法。
    • 如果您将launchMode 设置为singleInstance,那么文档的该部分表明您不应期望调用onNewIntent。您是否尝试在Intent 上设置标志?
    • 编辑在这种情况下提出onResume 作为onNewIntent 的替代品。
    • 在 onResume() 中,我可以通过调用 getIntent().getExtras() 从 Intent 中检索额外内容?
    • 我已经编辑了我的答案以显示如何使用onResume,这也阐明了是否/何时可以使用getIntent
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多