如何在android中按下通知时打开片段页面

时间:2014-10-28 12:40:33

标签: android android-fragments android-notifications android-pendingintent

我在通知栏中按通知时尝试打开片段。我的app结构是:

  • 带导航抽屉菜单的基本活动
  • 从菜单

    打开的一些片段
    b.setOnClickListener(new OnClickListener() {
    
            @SuppressWarnings({ "deprecation", "static-access" })
            public void onClick(View v) {
    
            w_nm=(NotificationManager) getActivity().getSystemService(getActivity().NOTIFICATION_SERVICE);
    
             Notification notify=new Notification(R.drawable.notnificationlogo,waternoti,System.currentTimeMillis());
    
             Intent notificationIntent = new Intent(getActivity(), Abc.class);
    
    
    
             PendingIntent pending=PendingIntent.getActivity(getActivity(), 0,notificationIntent, 0);
    
    
             notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
                     | Intent.FLAG_ACTIVITY_SINGLE_TOP );
    
            notify.flags = Notification.DEFAULT_LIGHTS | Notification.FLAG_AUTO_CANCEL;
    
               notify.setLatestEventInfo(getActivity(),waternoti,waternoti1, pending);
    
             w_nm.notify(0, notify);
    

任何人都可以告诉我如何链接下一个片段页面(当前代码在扩展片段的类中)

5 个答案:

答案 0 :(得分:36)

您需要像往常一样开始基本活动,但添加一些额外信息以了解将打开哪个菜单片段的意图。 在这里,您可以看到如何完成:https://stackoverflow.com/a/8610916/1652236

这取决于您在活动中检索的额外信息' onCreate()'您将用于启动/加载片段的方法。

请参阅此处,例如如何处理片段:http://www.tutorialspoint.com/android/android_fragments.htm http://developer.android.com/guide/components/fragments.html

意图启动此过程将类似于:

Intent notificationIntent = new Intent(getActivity(), Abc.class);
notificationIntent.putExtra("menuFragment", "favoritesMenuItem");

并在您的基础活动中:

@Override
protected void onCreate(final Bundle savedInstanceState)
{
    String menuFragment = getIntent().getStringExtra("menuFragment");

    FragmentManager fragmentManager = getFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

    // If menuFragment is defined, then this activity was launched with a fragment selection
    if (menuFragment != null) {

        // Here we can decide what do to -- perhaps load other parameters from the intent extras such as IDs, etc
        if (menuFragment.equals("favoritesMenuItem")) {
            FavoritesFragment favoritesFragment = new FavoritesFragment();
            fragmentTransaction.replace(android.R.id.content, favoritesFragment);
         }
    } else {
         // Activity was not launched with a menuFragment selected -- continue as if this activity was opened from a launcher (for example)
         StandardFragment standardFragment = new StandardFragment();
         fragmentTransaction.replace(android.R.id.content, standardFragment);
    }
}

答案 1 :(得分:8)

notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
             | Intent.FLAG_ACTIVITY_SINGLE_TOP )

当你的意图设置Flags:FLAG_ACTIVITY_SINGLE_TOP时,在创建活动时不会调用“onCreate()”,你应该在名为“onNewIntent()”的方法中接收params。

答案 2 :(得分:4)

欢迎使用2019和导航组件:)

如果您使用的是Navigation组件,则可以使用NavDeepLinkBuilder打开特定的目的地:


val pendingIntent = NavDeepLinkBuilder(context)
                     .setComponentName(MainActivity::class.java)
                     .setGraph(R.navigation.nav_graph)
                     .setDestination(R.id.destination)
                     .setArguments(bundle)
                     .createPendingIntent()

...

notificationBuilder.setContentIntent(pendingIntent)

...

请注意,仅当目的地不在启动器活动中时,才使用setComponentName

答案 3 :(得分:2)

你还应该添加 .commit(); ft1.addToBackStack(null); ,这样它就不会在prevoius上重叠,如果你不打广告 ft1.addToBackStack(null); 在你的应用程序将退出,所以根据你的功能添加它

String menuFragment = getIntent().getStringExtra("menuFragment");

ft1 = getSupportFragmentManager().beginTransaction();

ft1.addToBackStack(null);

ft1.replace(R.id.frame_container, favoritesFragment).commit();

答案 4 :(得分:0)

这是一个详细的答案,我相信如果您认真遵循。您将解决您的问题。

当您从 notification 发送Firebase时,该方法首先运行

public class FirebaseMessageService extends FirebaseMessagingService {

private static final String TAG = "MyFirebaseMsgService";
Map<String, String> data;
// [START receive_message]
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {

    if (remoteMessage.getData().size() > 0) {
        removeUserInfoByKeyAsStatic(getApplicationContext(), USER_KNOW_CREATED_EVENT_NOTIFICATION_DATA);
        Log.d(TAG, "Message data payload: " + remoteMessage.getData());
        data = remoteMessage.getData();


        HashMap<String, String> copyData = new HashMap<>(data);

        //Calling method to generate notification
        sendNotification(data.get("body"), data.get("title"), copyData);
    }

}

然后运行上面的sendNotification(..)方法。在这种方法中,我将notification data设置为SharedPref。不要对此感到冒犯。我们会在使用后立即将其删除。

我使用了login data,并根据我的intentActivity设置为roleID

private void sendNotification(String messageBody, String messageTitle, HashMap<String, String> data) {

    // this methods checks my notification data is null ? isNullOrEmptyExt : "simple java is null control method"
    if (!isNullOrEmptyExt(data.get("data"))) { 

        Intent intent;
        final User myInfos = getMyInfos(getApplicationContext()); // this gives me login user data.
        boolean isConsumerOrVolunteer = myInfos.getRoleID() == Constants.ROLES.CONSUMER || myInfos.getRoleID() == Constants.ROLES.VOLUNTEER;
        // I want to show here. You can select diffrent Activity with your data..
        if (isConsumerOrVolunteer) {
            // this set my notification data to SharedPref
            setUserInfoByKeyAsStatic(getApplicationContext(), USER_KNOW_CREATED_EVENT_NOTIFICATION_DATA, data.get("data"));
            intent = new Intent(this, EventListActivity.class);
        } else {
            intent = new Intent(this, ProducerActivity.class);
        }

        // after from here are the generally same. tricks above
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
                PendingIntent.FLAG_ONE_SHOT);

        String channelId = getString(R.string.default_notification_channel_id);
        Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        NotificationCompat.Builder notificationBuilder =
                new NotificationCompat.Builder(this, channelId)
                        .setSmallIcon(R.mipmap.ic_launcher)
                        .setContentTitle(messageTitle)
                        .setContentText(messageBody)
                        .setAutoCancel(true)
                        .setSound(defaultSoundUri)
                        .setContentIntent(pendingIntent);

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

        // Since android Oreo notification channel is needed.
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(channelId,
                    "Channel human readable title",
                    NotificationManager.IMPORTANCE_DEFAULT);
            notificationManager.createNotificationChannel(channel);
        }

        notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());

    }

}

发送notification时,以上两种方法将运行。因此,此后,您将单击电话上的通知。..右键。此单击操作将打开您之前在Intent(ActivityName)方法中设置的sendNotification(..)

例如,您点击通知,然后您的ProducerActivityEventListActivity就会打开。

如果您的角色是消费者或志愿者(根据我的应用角色),则将notification data设置为SharedPref

   boolean isConsumerOrVolunteer = myInfos.getRoleID() == Constants.ROLES.CONSUMER || myInfos.getRoleID() == Constants.ROLES.VOLUNTEER;
    // I want to show here. You can select diffrent Activity with your data..
    if (isConsumerOrVolunteer) {
        // this set my notification data to SharedPref
        setUserInfoByKeyAsStatic(getApplicationContext(), USER_KNOW_CREATED_EVENT_NOTIFICATION_DATA, data.get("data"));
        intent = new Intent(this, EventListActivity.class);
    } else {
        intent = new Intent(this, ProducerActivity.class);
    }

因此,您打开了EventListActivity。让我们看看我们将在EventListActivity

中做什么
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_event_list_main);

    GsonBuilder gsonBuilder = new GsonBuilder();
    gson = gsonBuilder.create();

    // this gives me data from `SharePref`
    String notificationEventDataString = getUserInfoByKeyAsStatic(this, USER_KNOW_CREATED_EVENT_NOTIFICATION_DATA);

    // then check the datastring that comes from SharedPref - simple java null check method
    if(!isNullOrEmptyExt(notificationEventDataString)){
        Bundle bundle = new Bundle();
        bundle.putParcelable(EVENT, gson.fromJson(notificationEventDataString, Event.class));
        removeUserInfoByKeyAsStatic(this, USER_KNOW_CREATED_EVENT_NOTIFICATION_DATA);
        openFragmentWithoutAnimation(this, R.id.drawer_layout, bundle, EventPreviewFragment.class, EVENT_PREVIEW_FRAGMENT);
    }

您从SharedPref获取数据。这不会为空,因为当您收到通知时,我们已经在sendNotification(..)方法中对其进行了设置。

因此,您将data放在bundle上,并用Fragment打开bundle data。在删除包含我的SharedPref

notification data数据之后

我还与您共享我的自定义方法

这是片段打开方法

public static void openFragmentWithoutAnimation(Context context, int replaceLayout, Bundle bundle, Class<?> fragment, String fragmentTag) {
    Fragment dynamicFragment = null;
    try {
        Class<?> clazz = Class.forName(fragment.getName());
        dynamicFragment = (Fragment) clazz.newInstance();
        System.out.println(clazz.getSuperclass());
        System.out.println(clazz.getName());
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (InstantiationException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    }

    AppCompatActivity activity = null;
    if (context instanceof AppCompatActivity) {
        activity = ((AppCompatActivity) context);
    }
    if (activity.getSupportFragmentManager().findFragmentByTag(fragmentTag) == null) {
        FragmentTransaction transaction = activity.getSupportFragmentManager().beginTransaction();
        if (bundle != null) {
            dynamicFragment.setArguments(bundle);
        }
        transaction.add(replaceLayout, dynamicFragment, fragmentTag);
        transaction.addToBackStack(fragmentTag);
        transaction.commit();
    }
}

这些是SharedPref集并获取方法

public static void setUserInfoByKeyAsStatic(Context context, String key, String value){
    final SharedPreferences prefs = context.getSharedPreferences(
            USER_INFO_PREFS_KEY, Context.MODE_PRIVATE);// Saved token can be accessed only from this app or other apps that shared same id with this app.
    SharedPreferences.Editor editor = prefs.edit();
    editor.putString(key, value);
    editor.apply();
}

public static String getUserInfoByKeyAsStatic(Context context, String key){
    final SharedPreferences controlPrefs = context.getSharedPreferences(
            USER_INFO_PREFS_KEY, Context.MODE_PRIVATE);
    return controlPrefs.getString(key,null);
}

theese是null检查方法

public static boolean isNullOrEmpty(String value){

    if(value == null){
        return true;
    }else return value.isEmpty() || value.equals("null");

}

public static boolean isNullOrEmptyExt(String value){

    if(value == null){
        return true;
    }else return value.isEmpty() || value.equals("null") || value.equals(JSON_ARRAY_EMPTY) || value.equals(JSON_OBJECT_EMPTY);

}