我在通知栏中按通知时尝试打开片段。我的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);
任何人都可以告诉我如何链接下一个片段页面(当前代码在扩展片段的类中)
答案 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
,并根据我的intent
将Activity
设置为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(..)
。
例如,您点击通知,然后您的ProducerActivity
或EventListActivity
就会打开。
如果您的角色是消费者或志愿者(根据我的应用角色),则将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);
}