草庐IT

java - 单击通知不会打开提到的 Activity

coder 2023-05-17 原文

我正在尝试打开一个 Activity单击通知时,下面是我的代码。

Intent intent = new Intent(this.getApplicationContext(), NotificationActivity.class);
intent.putExtra("msgBody",messageBody);
intent.putExtra(Constants.NOTIF_INTENT_TYPE,Constants.NOTIF_INTENT_TYPE);

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                |Intent.FLAG_ACTIVITY_SINGLE_TOP
                |Intent.FLAG_ACTIVITY_CLEAR_TOP); //Tried with many options here

PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 , intent,
                                         PendingIntent.FLAG_CANCEL_CURRENT);

Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                .setSmallIcon(R.drawable.otp_icon)
                .setContentTitle("Push MSG")
                .setContentText(messageBody)
                .setAutoCancel(true)
                .setSound(defaultSoundUri)
                .setContentIntent(pendingIntent);

NotificationManager notificationManager =
                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

notificationManager.notify(0, notificationBuilder.build());

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

    <uses-sdk
        android:minSdkVersion="17"
        android:targetSdkVersion="21" />

    <supports-screens
        android:anyDensity="true"
        android:largeScreens="true"
        android:normalScreens="true"
        android:smallScreens="true" />

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_LOGS" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

    <application
        android:name=".AndroidPushApp"
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher">
        <activity
            android:name=".PushSplashScreen"
            android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".MainApplicationScreen"
            android:screenOrientation="portrait"
            android:windowSoftInputMode="adjustResize">
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
            </intent-filter>
        </activity>
        <activity
            android:name=".StartActivity"
            android:launchMode="singleTask"
            android:screenOrientation="portrait"
            android:uiOptions="splitActionBarWhenNarrow"
            android:windowSoftInputMode="adjustResize">
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
            </intent-filter>
        </activity>

        <service android:name=".MyFirebaseMessagingService">
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT" />
            </intent-filter>
        </service>

        <service android:name=".MyFirebaseInstanceIDService">
            <intent-filter>
                <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
            </intent-filter>
        </service>

        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />

        <activity
            android:name=".NotificationActivity"
            android:exported="true"
            android:label="@string/title_activity">
            <intent-filter>
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
    </application>

</manifest>

每当我收到 FCM 的通知时,我都会调用此通知。 通知 Activity 每当我点击通知时都不会打开,而是应用程序正在打开(我通常的应用程序流程中的 splash screen->starting activity)。每当我在应用程序已经打开时收到通知,NotificationActivity正在打开,但不是当应用程序尚未打开时。有人可以帮我解决这个问题吗?

注:请我重申 NotificationActivity.class当应用程序尚未打开状态时单击通知时未打开。

最佳答案

根据 FCM用于接收和处理消息的文档,

If you want to receive notifications when your app is in the foreground, you need to add some message handling logic.

To receive messages, use a service that extends FirebaseMessagingService. Your service should override the onMessageReceived callback, which is provided for most message types, with the following exceptions:

1). Notifications delivered when your app is in the background. In this case, the notification is delivered to the device’s system tray. A user tap on a notification opens the app launcher by default.

2). Messages with both notification and data payload, both background and foreground. In this case, the notification is delivered to the device’s system tray, and the data payload is delivered in the extras of the intent of your launcher Activity.





所以基本上,我们有两种类型的有效载荷

1)。 通知负载

2)。 数据负载

3)。 两者(我们可以考虑的附加类型)。

现在让我们一一讨论这些有效载荷。在此之前,您需要了解如何将这些有效负载发送到您的应用程序。您所要做的就是使用任何可以执行的工具HTTP POST Request .就我而言,我使用的是 postman 工具,一个 Google Chrome 插件。

做之前HTTP Post RequestFCM ,你必须考虑三件事:

1)。 HTTP 发布请求 URL: https://fcm.googleapis.com/fcm/send

2)。请求头:

一世)。内容类型:应用程序/json

ii).授权:key = YOUR_SERVER_KEY

下面是相同的屏幕截图,以显示它的外观。



3)。正文:在这个我们将有 JSONNotificationData Payloads .
  • 所以从 开始通知负载 ,最简单的。在这种情况下,onMessageReceived()仅当应用程序在 Foreground 中时调用, 对于所有其他情况,它是 System Tray Notification ,打开 Launcher Activity单击时。当您不想控制 Notifications 时,这很有用由你自己处理的数据不多的时候Notification来了。您甚至可以控制声音、图标和 click_action(仅当应用程序在 Foreground 中时),而无需在您的 onMessageReceived() 中编写任何代码。 .此类主体的一个示例 HTTP POST Request附在下面的屏幕截图中。



  • 想要打开Activity发送 click_action 参数时,您必须在 onMessageReceived() 中使用以下代码.
    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        if (null != remoteMessage.getNotification().getClickAction()) {
                startActivity(remoteMessage.getNotification().getClickAction(), null, this);
        }
    }
    

    以下是您的 startActivity()方法 :
    public void startActivity(String className, Bundle extras, Context context) {
        Class cls = null;
        try {
            cls = Class.forName(className);
        } catch (ClassNotFoundException e) {
            //means you made a wrong input in firebase console
        }
        Intent intent = new Intent(context, cls);
        if (null != extras) {
            intent.putExtras(extras);
        }
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        context.startActivity(intent);
    }
    

    NOTE : This click_action key will work only when the app is in Foreground, for all other case when the app is in Background and closed, it doesn't work. It doesn't even open the Launcher Activity, in case of Background and Closed, if this parameter is specified.


  • 现在来了 数据负载 .这与我们在 GCM 中的类似.如果我们想处理所有 Notification,这一点非常重要。我们自己做的事情和我们在 GCM 的情况下所做的一样.此类主体的示例 HTTP POST Request如下所示。



  • 所以在这种情况下,onMessageReceived()每次都被调用,这将与 GCM 的工作方式相同,对我们所有人都有帮助。你必须Override onMessageReceived()如下所示。
    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        Map<String, String> data = remoteMessage.getData();
        if (null != data && 0 < data.size()) {
            if (data.containsKey("custom_key_1")) {
                sendNotification(data.get("custom_key_1"));
            }
        }
    }
    
    private void sendNotification(String messageBody) {
            Intent intent = new Intent(this, DesiredActivity.class);
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
                    PendingIntent.FLAG_ONE_SHOT);
    
            Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
            NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                    .setSmallIcon(R.drawable.ic_stat_ic_notification)
                    .setContentTitle("FCM Message")
                    .setContentText(messageBody)
                    .setAutoCancel(true)
                    .setSound(defaultSoundUri)
                    .setContentIntent(pendingIntent);
    
            NotificationManager notificationManager =
                    (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    
            notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
    }
    
  • 最后但并非最不重要的一点,我们可以同时发送 NotificationData Payloads以及。在这种情况下,onMessageReceived()当应用程序在 Foreground 中时调用.对于后台和关闭状态,Notification出现在类似于 Notification Payload 的系统托盘中但唯一的区别是我们可以拥有 data extras以及我们可以用来将用户重定向到所需的 Activity ,当点击 Notification 时.下面是这样一个主体的例子 HTTP POST Request . 此类主体的示例 HTTP POST Request如下所示。



  • 单击 Notification 时在系统托盘上,它将打开 Launcher Activity你需要Override onCreate()您的 Launcher Activity获取 data extras并将用户重定向到所需的 Activity .下面是代码,你必须写在onCreate()您的 Activity将用户重定向到所需的 Activity .
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if(getIntent().hasExtra("custom_key_1") && getIntent().getStringExtra("custom_key_1")
                .equals("custom_value_1")){
            startActivity(new Intent(this, DesiredActivity.class));
            finish();
            return;
        }
    
        // other operations
    }
    

    这种类型的另一种情况是,当您的 Launcher Activity定义为 launchMode="true"manifest而当 Notification到货了,你的Launcher ActivityForeground .所以当你点击通知时,你必须Override onNewIntent()您的 Launcher Activity 中的方法打开想要的 Activity .下面是相同的示例代码。
    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        if (getIntent().hasExtra("custom_key_1") && getIntent().getStringExtra("custom_key_1")
                    .equals("custom_value_1")) {
                startActivity(new Intent(this, DesiredActivity.class));
                finish();
        }
    }
    

    简而言之,我会说最好使用 数据负载 类型,因为它提供了对 Notification 的更多灵活性和控制更重要的是,我们都习惯了 GCM ,所以这种类型是我们都喜欢的。

    Note : Some devices are having issue receiving Notifications in Background as I found some queries over same here. Moreover at the time, I was investigating these cases, my ASUS phone was not receiving notifications in Background for any of the types mentioned above. So not sure what's the issue with these devices.

    关于java - 单击通知不会打开提到的 Activity ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40417127/

    有关java - 单击通知不会打开提到的 Activity的更多相关文章

    1. ruby-on-rails - Rails 常用字符串(用于通知和错误信息等) - 2

      大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje

    2. ruby - 使用 Vim Rails,您可以创建一个新的迁移文件并一次性打开它吗? - 2

      使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta

    3. ruby - Highline 询问方法不会使用同一行 - 2

      设置:狂欢ruby1.9.2高线(1.6.13)描述:我已经相当习惯在其他一些项目中使用highline,但已经有几个月没有使用它了。现在,在Ruby1.9.2上全新安装时,它似乎不允许在同一行回答提示。所以以前我会看到类似的东西:require"highline/import"ask"Whatisyourfavoritecolor?"并得到:Whatisyourfavoritecolor?|现在我看到类似的东西:Whatisyourfavoritecolor?|竖线(|)符号是我的终端光标。知道为什么会发生这种变化吗? 最佳答案

    4. ruby-on-rails - 项目升级后 Pow 不会更改 ruby​​ 版本 - 2

      我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby​​版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby​​版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘

    5. java - 等价于 Java 中的 Ruby Hash - 2

      我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

    6. java - 从 JRuby 调用 Java 类的问题 - 2

      我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

    7. java - 我的模型类或其他类中应该有逻辑吗 - 2

      我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我

    8. java - 什么相当于 ruby​​ 的 rack 或 python 的 Java wsgi? - 2

      什么是ruby​​的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht

    9. ruby-on-rails - 如何在发布新的 Ruby 或 Rails 版本时收到通知? - 2

      有人知道在发布新版本的Ruby和Rails时收到电子邮件的方法吗?他们有邮件列表,RubyonRails有一个推特,但我不想听到那些随之而来的喧嚣,我只想知道什么时候发布新版本,尤其是那些有安全修复的版本。 最佳答案 从therailsblog获取提要.http://weblog.rubyonrails.org/feed/atom.xml 关于ruby-on-rails-如何在发布新的Ruby或Rails版本时收到通知?,我们在StackOverflow上找到一个类似的问题:

    10. Observability:从零开始创建 Java 微服务并监控它 (二) - 2

      这篇文章是继上一篇文章“Observability:从零开始创建Java微服务并监控它(一)”的续篇。在上一篇文章中,我们讲述了如何创建一个Javaweb应用,并使用Filebeat来收集应用所生成的日志。在今天的文章中,我来详述如何收集应用的指标,使用APM来监控应用并监督web服务的在线情况。源码可以在地址 https://github.com/liu-xiao-guo/java_observability 进行下载。摄入指标指标被视为可以随时更改的时间点值。当前请求的数量可以改变任何毫秒。你可能有1000个请求的峰值,然后一切都回到一个请求。这也意味着这些指标可能不准确,你还想提取最小/

    随机推荐