如何通过点击通知打开片段?

How to open fragment from the click of the notification?

这是我的 onMessageReceived 方法。我正在从通知中获取数据我想在单击此通知时打开片段并从中获取数据。

  @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        super.onMessageReceived(remoteMessage);

        Log.d("Firebase Push Received", "Frommm: " + remoteMessage.getFrom());
        Log.d("Firebase Push Received", "Notification " +
                " Data: " + remoteMessage.getData());


        // TODO(developer): Handle FCM messages here.
        Log.d(TAG, "From: " + remoteMessage.getFrom());

        // AGREGO EN EL PAYLOAD LA VARIABLE DATA PARA QUE APAREZCA EN EL FOREGROUND, SINO LEE LA VAR NOTIFICATION DEL PAYLOAD
        // Check if message contains a data payload.
        if (remoteMessage.getData().size() > 0) {
            String type = remoteMessage.getData().get("type");
            String title = remoteMessage.getData().get("title");
            String message = remoteMessage.getData().get("body");
            String id = remoteMessage.getData().get("id");
            Log.d(TAG, "type" + type);
            Log.d(TAG, "id" + id);


            Log.d(TAG, "notidata" + remoteMessage.getData());

            boolean flag = false;
            Intent notificationIntent;
            /*SharedPreferences notificationStatus = getApplicationContext().getSharedPreferences(Constants.NotificationStatus, MODE_PRIVATE);
            String status = notificationStatus.getString("status", "");

            if (status.equals("true")) {
                flag = true;
                notificationIntent = new Intent(this.getApplicationContext(), MainActivity.class);
                notificationIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

            } else {
                notificationIntent = new Intent(this.getApplicationContext(), StarterActivity.class);
            }
            if (flag) {
                notificationIntent.addCategory((Intent.CATEGORY_LAUNCHER));
                notificationIntent.setAction(Intent.ACTION_MAIN);
            }*/
            notificationIntent = new Intent(this.getApplicationContext(), MainActivity.class);

            notificationIntent.putExtra("id", id);
            notificationIntent.putExtra("type", type);
            notificationIntent.putExtra("isfrom", "notification");
            notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                    | Intent.FLAG_ACTIVITY_CLEAR_TASK);
            Bundle bundle = new Bundle();
            bundle.putString("lessonId", id);
            bundle.putString("type1", type);
            bundle.putString("isfrom", "notification");

            /*PendingIntent contentIntent = new NavDeepLinkBuilder(getApplicationContext())
                    .setGraph(R.navigation.nav_home)
                    .setDestination(R.id.playerController)
                    .setArguments(bundle)
                    .createPendingIntent();*/
            PendingIntent contentIntent = PendingIntent.getActivity(this.getApplicationContext(), 0, notificationIntent, PendingIntent.FLAG_ONE_SHOT);

            Notification notification = new NotificationCompat.Builder(this, getResources().getString(R.string.default_notification_channel_id))
                    .setContentTitle(title)
                    .setContentText(message)
                    .setSmallIcon(R.drawable.headblack)
                    .setDefaults(Notification.DEFAULT_SOUND)
                    .setContentIntent(contentIntent)
                    .build();

            NotificationManagerCompat manager = NotificationManagerCompat.from(getApplicationContext());
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                NotificationChannel channel = new NotificationChannel(getResources().getString(R.string.default_notification_channel_id), getResources().getString(R.string.channel_name), NotificationManager.IMPORTANCE_HIGH);
                manager.createNotificationChannel(channel);
            }
            manager.notify(R.string.default_notification_channel_id, notification);

        }

        // Check if message contains a notification payload.
        if (remoteMessage.getNotification() != null) {
            Log.d(TAG, "MessageNotificationBody: " + remoteMessage.getNotification().getBody());
        }

        // Also if you intend on generating your own notifications as a result of a received FCM
        // message, here is where that should be initiated. See sendNotification method below.
    }

这是我的主要activity..

        public class MainActivity extends AppCompatActivity {
    
      @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
                if (!isTaskRoot() && getIntent().hasCategory(Intent.CATEGORY_LAUNCHER)
                    && getIntent().getAction() != null
                    && getIntent().getAction().equals(Intent.ACTION_MAIN)
            ) {
                finish();
                processIntent(getIntent());
                return;
            }
    
            SharedPreferences notificationStatus = getApplicationContext().getSharedPreferences(Constants.NotificationStatus, MODE_PRIVATE);
            SharedPreferences.Editor edit = notificationStatus.edit();
            edit.putString("status", "true");
            edit.apply();
            progressBar = findViewById(R.id.spin_kit);
            progressBarHolder = findViewById(R.id.progressBarHolder);
            mAuth = FirebaseAuth.getInstance();
            mDatabase = FirebaseDatabase.getInstance().getReference();
    
            final FirebaseUser user = mAuth.getCurrentUser();
            ActionBar actionBar = getSupportActionBar();
            actionBar.hide();
            navView = findViewById(R.id.nav_view);
            navView.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED);
    
            AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(
                    R.id.navigation_home, R.id.navigation_lessons, R.id.navigation_prematch, R.id.navigation_journals, R.id.navigation_move)
                    .build();
    
            navController = Navigation.findNavController(this, R.id.nav_host_fragment);
            NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
            NavigationUI.setupWithNavController(navView, navController);
    
        }
    


    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        processIntent(intent);
    }
    


private void processIntent(Intent intent) {

        if (intent != null && intent.getExtras() != null) {
            mAuth = FirebaseAuth.getInstance();
            mDatabase = FirebaseDatabase.getInstance().getReference();

            final FirebaseUser user = mAuth.getCurrentUser();
            //   checkStatus();
            Bundle bundle = new Bundle();
            id = intent.getExtras().get("id").toString();

            type = intent.getExtras().get("type").toString();
}
        }

根据流程意图,我想使用 navcontroller 打开我的片段,但它会打开主片段activity 并加载主片段而不是我想在单击通知时实现的播放器片段.

播放器片段在主 activity 的导航图中。

大多数堆栈溢出答案都包含在这里不起作用的 navdeeplink 它打开主 activity 并加载主 activity 的数据而不是目标。

Anyone how to open a fragment when user click on the notification when activity is running and when activity is in the background ?

没有从通知中打开片段的直接方法。 在通知挂起的意图中添加 putextras 并在 activity 中获取它并导航相应的片段

notificationIntent.putExtra("redirect", "homefragment");

在你的activity

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

      String value= intent.getExtras().get("redirect").toString();
      if(value=="homefragment")
       {
              // redirect your fragment
       }

您可以在导航架构中使用显式深层链接

您可以查看这篇文章进行操作: Navigating with Deep Links

您还应该检查 Developer Docs。他们提供 in-depth 内部情况的描述

当用户尝试打开通知并尝试打开他想要加载数据的片段时,我尝试了这种方式并且表现良好..即使应用程序已关闭,甚至当应用程序处于 运行 状态时正在工作。

MainActivity

in on create

      Intent intent = getIntent();
                       if(intent !=null&&intent.getExtras()!=null)
                       {
                            id = intent.getExtras().get("id").toString();
                            type = intent.getExtras().get("type").toString();
//here i check if data is not null then i proceed to pass the data to the fragment using nav controller i defined earlier. 
                            bundle.putString("lessonId", id);
                            bundle.putString("type", type);
                            bundle.putLong("lastPosition", Math.round(lastPosition));
                            navController.navigate(R.id.player, bundle);
                        }

this works when I try to click the notification when the app is open, but when the app is not open it doesn't fetch the data from intent because it isn't the starter app.

所以我在 splash activity 中执行了相同的过程,并从通知中获取了数据,然后我将该数据从调用片段的地方传递到 main activity。

非常感谢你们的快速支持..!!