Java 在通知单击时启动片段而不丢失状态
我有一个聊天应用程序,也可以通过点击通知直接启动。聊天片段也可以通过在应用程序内部单击手动启动 我想,如果用户在聊天片段上点击home按钮,然后点击通知,它应该在最后一个状态下启动,并且不调用活动的Java 在通知单击时启动片段而不丢失状态,java,android,firebase,android-fragments,push-notification,Java,Android,Firebase,Android Fragments,Push Notification,我有一个聊天应用程序,也可以通过点击通知直接启动。聊天片段也可以通过在应用程序内部单击手动启动 我想,如果用户在聊天片段上点击home按钮,然后点击通知,它应该在最后一个状态下启动,并且不调用活动的onDestroy然后onCreate 通过活动中的通知启动片段,如下所示 ((AppCompatActivity)context).getFragmentManager().beginTransaction().replace(R.id.Navigation_Main_Layout, screenF
onDestroy
然后onCreate
通过活动中的通知启动片段
,如下所示
((AppCompatActivity)context).getFragmentManager().beginTransaction().replace(R.id.Navigation_Main_Layout, screenFragment,"Chat").commit();
我正在处理来自FirebaseMessagingService的通知
public class FireBase_Messaging_Service extends FirebaseMessagingService {
public static final String TAG="###FireBase MSG###";
public static final int NOTIFICATION=5;
String UserName;
String ID;
String Msg;
Map<String,String> data;
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
Log.d(TAG,"From "+remoteMessage.getFrom());
if (remoteMessage.getData().size()>0){
data = remoteMessage.getData();
Log.d(TAG,"Message Data "+remoteMessage.getData());
data = remoteMessage.getData();
UserName = data.get("name");
ID = data.get("ID");
Msg = data.get("Message");
showNotification(Msg,ID,UserName);
}
if (remoteMessage.getNotification()!=null){
Log.d(TAG,"Message Notification Body "+remoteMessage.getNotification().getBody());
// Toast.makeText(this, "Notification "+remoteMessage.getNotification().getBody(), Toast.LENGTH_LONG).show();
}
}
private void showNotification(String Message,String ID,String UserName) {
Log.d(TAG,"Show Notification "+Message+" "+ID);
Intent intent=new Intent(this, Navigation_Drawer.class);
intent.putExtra("Type","Text");
//intent.putExtra("Type",MsgType);
intent.putExtra("ID",ID);
intent.putExtra("uname",UserName);
intent.putExtra("Message",Msg);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendingIntent=PendingIntent.getActivity(this,NOTIFICATION,intent,PendingIntent.FLAG_UPDATE_CURRENT);
int color = getResources().getColor(R.color.black);
String ChannelID = "Message";
notificationChannel(ChannelID,"Chat");
NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext(),ChannelID)
.setSmallIcon(R.drawable.default_x)
.setColor(color)
.setContentTitle(UserName)
.setContentText(Message)
.setChannelId(ChannelID)
.setTicker("My App")
.setDefaults(Notification.DEFAULT_VIBRATE | Notification.DEFAULT_SOUND | Notification.FLAG_SHOW_LIGHTS)
.setLights(0xff00ff00, 1000, 500) // To change Light Colors
.setStyle(new NotificationCompat.BigTextStyle().bigText(Message))//For Expandable View
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setContentIntent(pendingIntent)
.setAutoCancel(true);
NotificationManagerCompat managerCompat = NotificationManagerCompat.from(this);
managerCompat.notify(NOTIFICATION,builder.build());
}
@Override
public void onDeletedMessages() {
super.onDeletedMessages();
}
private void notificationChannel (String ChannelID, String channelName) {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(ChannelID,channelName, NotificationManager.IMPORTANCE_DEFAULT);
channel.setLightColor(Color.GREEN);
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.createNotificationChannel(channel);
}
}
}
公共类FireBase\u消息服务扩展了FirebaseMessagingService{
公共静态最终字符串标记=“####FireBase MSG###”;
公共静态最终int通知=5;
字符串用户名;
字符串ID;
串味精;
地图数据;
@凌驾
收到消息时公共无效(RemoteMessage RemoteMessage){
super.onMessageReceived(remoteMessage);
Log.d(标记“From”+remoteMessage.getFrom());
如果(remoteMessage.getData().size()>0){
data=remoteMessage.getData();
Log.d(标记“messagedata”+remoteMessage.getData());
data=remoteMessage.getData();
用户名=数据。获取(“名称”);
ID=data.get(“ID”);
Msg=data.get(“消息”);
showNotification(消息、ID、用户名);
}
if(remoteMessage.getNotification()!=null){
Log.d(标记“消息通知正文”+remoteMessage.getNotification().getBody());
//Toast.makeText(这是“通知”+remoteMessage.getNotification().getBody(),Toast.LENGTH_LONG.show();
}
}
私有void showNotification(字符串消息、字符串ID、字符串用户名){
Log.d(标签,“显示通知”+消息+“”+ID);
意向意向=新意向(此,导航\抽屉类);
意向。额外(“类型”、“文本”);
//intent.putExtra(“类型”,MsgType);
意向。额外(“ID”,ID);
intent.putExtra(“uname”,用户名);
intent.putExtra(“消息”,Msg);
intent.setFlags(intent.FLAG_ACTIVITY_NEW_TASK|intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingEvent PendingEvent=PendingEvent.getActivity(此、通知、意图、PendingEvent.FLAG_更新_当前);
int color=getResources().getColor(R.color.black);
字符串ChannelID=“消息”;
通知频道(ChannelID,“Chat”);
NotificationCompat.Builder=新建NotificationCompat.Builder(getApplicationContext(),ChannelID)
.setSmallIcon(R.drawable.default_x)
.setColor(颜色)
.setContentTitle(用户名)
.setContentText(消息)
.setChannelId(ChannelID)
.setTicker(“我的应用程序”)
.setDefaults(Notification.DEFAULT_振动| Notification.DEFAULT_声音| Notification.FLAG_显示灯)
.setLights(0xff00ff00,1000500)//更改灯光颜色
.setStyle(新的NotificationCompat.BigTextStyle().bigText(消息))//用于可扩展视图
.setPriority(NotificationCompat.PRIORITY_默认值)
.setContentIntent(挂起内容)
.setAutoCancel(真);
NotificationManagerCompat managerCompat=NotificationManagerCompat.from(this);
managerCompat.notify(通知,builder.build());
}
@凌驾
公共无效onDeletedMessages(){
super.onDeletedMessages();
}
私有void通知通道(字符串ChannelID,字符串channelName){
if(android.os.Build.VERSION.SDK\u INT>=android.os.Build.VERSION\u code.O){
NotificationChannel=新建NotificationChannel(ChannelID、channelName、NotificationManager.IMPORTANCE\u默认值);
channel.setLightColor(颜色为绿色);
NotificationManager NotificationManager=(NotificationManager)getSystemService(通知服务);
notificationManager.createNotificationChannel(频道);
}
}
}
在上面的代码中,我尝试了使用不同标志的Intent
,例如Intent.FLAG\u ACTIVITY\u NEW\u TASK,Intent
,FLAG\u ACTIVITY\u SINGLE\u TOP
,FLAG\u ACTIVITY\u protof\u
等。但是,它总是调用活动的(导航抽屉)onDestroy
首先,然后onCreate
。然后它从一开始就启动片段
如何避免应用程序重新创建活动
和片段
?据我所知,Android活动的预期行为与活动和片段的Android生命周期冲突。当用户按下后退或主页按钮时,该活动或片段将在该活动或片段实例的生命周期之后通过onPause
和onDestroy
。除非您在活动中调用finish
,这样可以避免在活动中调用ondestory
函数,否则无法避免此操作。但是,您不希望完成该活动,而是希望使用相同的活动,并且不希望重新创建该活动
所以我想用另一种方法来解决你的问题。大多数情况下,重新创建活动或片段的问题直接指示要获取的资源,而在初始化活动或片段时获取大量资源是一种开销。因此,当资源在保存的实例状态下已经可用时,我们可能会避免获取要在活动或片段中使用的资源
例如,当您在活动的onCreate
函数中获取保存在SQLite数据库中的某些数据时,您可能不希望在活动的方向更改时再次获取这些数据,这会强制重新创建活动。在这种情况下,您可能需要选择一个加载器(我说的是带有LoaderCallbacks
实现的CursorLoader
),该加载器
<activity
android:name=".Navigation_Drawer"
android:launchMode="singleTask"
android:theme="@style/AppTheme"/>