Firebase通知,在后台或被关闭时不显示,但数据已发送。
Firebase通知,在后台或被关闭时不显示,但数据已发送。
我有一个应用程序,它从基于php的服务器接收推送通知,推送通知是一个包含URL的数据有效负载,当点击时会自动在Webview中打开。
我的应用程序能够工作,但不是我想要的方式。
我能够从php服务器发送推送通知,但是通知只在应用程序前台显示,当应用程序在后台时不显示。
当我检查logcat时,我发现即使应用程序在后台,JSON数据也是从服务器发送的。 可能是什么原因导致应用在后台或关闭时无法显示推送通知?
以下是我的FirebaseMessaging类:
public class MyFirebaseMessagingService extends FirebaseMessagingService{ private final String CHANNEL_ID="notificcation"; @Override public void onNewToken(String s) { super.onNewToken(s); Log.e("NEW_TOKEN",s); } @Override public void onMessageReceived(RemoteMessage remoteMessage) { super.onMessageReceived(remoteMessage); handleMessage(remoteMessage.getData().get(Config.STR_KEY)); } private void handleMessage(String message) { Intent pushNotification=new Intent(Config.STR_PUSH); pushNotification.putExtra(Config.STR_MESSAGE,message); LocalBroadcastManager.getInstance(this).sendBroadcast(pushNotification); } }
这是我的PHP脚本
$key, 'data'=>array('title'=>$title,'body'=>$message,'webUrl'=>$url)); $payload=json_encode($fields); $curl_session=curl_init(); curl_setopt($curl_session, CURLOPT_URL, $path_to_fcm); curl_setopt($curl_session, CURLOPT_POST, true); curl_setopt($curl_session, CURLOPT_HTTPHEADER, $headers); curl_setopt($curl_session, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl_session, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl_session, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); curl_setopt($curl_session, CURLOPT_POSTFIELDS, $payload); $result=curl_exec($curl_session); mysqli_close($con); ?>
我的主活动
public class MainActivity extends AppCompatActivity { private WebView webView; private ProgressDialog dialog; private BroadcastReceiver mRegistrationBroadcastReciever; private final String CHANNEL_ID="notificcation"; String app_server_url="http:/xxxxxxxxxxx/insert.php"; @Override public void onBackPressed() { AlertDialog.Builder builder=new AlertDialog.Builder(this); if(webView.canGoBack()){ webView.goBack(); }else{ builder.setTitle("是否要离开应用程序?"); builder.setMessage("你确定吗?"); builder.setPositiveButton("退出", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { finish(); } }); builder.setNegativeButton("取消", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }); AlertDialog dialog=builder.show(); } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); SharedPreferences sharedPreferences=getApplicationContext().getSharedPreferences(getString(R.string.FCM_PREF), Context.MODE_PRIVATE); final String token=sharedPreferences.getString(getString(R.string.FCM_TOKEN),""); StringRequest stringRequest=new StringRequest(Request.Method.POST, app_server_url, new Response.Listener() { @Override public void onResponse(String response) { } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { } }) { @Override protected Map getParams() throws AuthFailureError { Map params=new HashMap (); params.put("fcm_token",token); return params; } }; MySingleton.getmInstance(MainActivity.this).addToRequestque(stringRequest); webView=(WebView)findViewById(R.id.webView); webView.getSettings().setJavaScriptEnabled(true); webView.setWebChromeClient(new WebChromeClient()); webView.loadUrl("http://default_website"); webView.setWebViewClient(new WebViewClient(){ @Override public void onPageFinished(WebView view, String url) { if(dialog.isShowing()) dialog.dismiss(); } }); mRegistrationBroadcastReciever=new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if(intent.getAction().equals(Config.STR_PUSH)) { String message=intent.getStringExtra(Config.STR_MESSAGE); showNotification("文章",message); } } }; onNewIntent(getIntent()); } @Override protected void onNewIntent(Intent intent) { dialog=new ProgressDialog(this); if(intent.getStringExtra(Config.STR_KEY)!=null) { dialog.show(); dialog.setMessage("请等待"); webView.loadUrl(intent.getStringExtra(Config.STR_KEY)); } } private void showNotification(String title, String message) { notificationChannel(); Bitmap picture = BitmapFactory.decodeResource(getResources(),R.mipmap.app_launcher); Intent intent =new Intent(getBaseContext(),MainActivity.class); intent.putExtra(Config.STR_KEY,message); intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); PendingIntent contentIntent=PendingIntent.getActivity(getBaseContext(),0,intent,PendingIntent.FLAG_UPDATE_CURRENT); NotificationCompat.Builder builder=new NotificationCompat.Builder(getBaseContext(),CHANNEL_ID); builder.setAutoCancel(true) .setWhen(System.currentTimeMillis()) .setDefaults(Notification.DEFAULT_ALL) .setSmallIcon(R.drawable.ic_sms_black_24dp) .setContentTitle(title) .setContentText(message) .setLargeIcon(picture) .setPriority(NotificationCompat.PRIORITY_HIGH) .setContentIntent(contentIntent); NotificationManager notificationManager = (NotificationManager)getBaseContext().getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.notify(1,builder.build()); } private void notificationChannel (){ if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O) { CharSequence name="个人通知"; String description="包括"; int importance=NotificationManager.IMPORTANCE_DEFAULT; NotificationChannel notificationChannel=new NotificationChannel(CHANNEL_ID,name,importance); notificationChannel.setDescription(description); NotificationManager notificationManager=(NotificationManager)getSystemService(NOTIFICATION_SERVICE); notificationManager.createNotificationChannel(notificationChannel); } } @Override protected void onPause() { LocalBroadcastManager.getInstance(this).unregisterReceiver(mRegistrationBroadcastReciever); super.onPause(); } @Override protected void onResume() { super.onResume(); LocalBroadcastManager.getInstance(this).registerReceiver(mRegistrationBroadcastReciever,new IntentFilter("registration Complete")); LocalBroadcastManager.getInstance(this).registerReceiver(mRegistrationBroadcastReciever,new IntentFilter(Config.STR_PUSH)); } }
问题原因:代码中使用了LocalBroadcastManager发送通知,但是在后台或者被关闭的情况下无法显示通知,只能发送数据。
解决方法:
1. 在MyFirebaseMessagingService中编写showNotification方法,并直接调用它。
2. 如果仍然需要在Activity中进行一些操作,可以使用以下代码块:
MyFirebaseMessagingService => onMessageReceived() if (!isAppIsInBackground(getApplicationContext())) { Intent pushNotification = new Intent(Config.STR_PUSH); pushNotification.putExtra(Config.STR_MESSAGE, message); LocalBroadcastManager.getInstance(this).sendBroadcast(pushNotification); } else { showNotification("Article", message); }
3. 添加以下方法用于检查应用是否在后台运行:
public static boolean isAppIsInBackground(Context context) { boolean isInBackground = true; ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT_WATCH) { ListrunningProcesses = am.getRunningAppProcesses(); for (ActivityManager.RunningAppProcessInfo processInfo : runningProcesses) { if (processInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) { for (String activeProcess : processInfo.pkgList) { if (activeProcess.equals(context.getPackageName())) { isInBackground = false; } } } } } else { List taskInfo = am.getRunningTasks(1); ComponentName componentInfo = taskInfo.get(0).topActivity; if (componentInfo.getPackageName().equals(context.getPackageName())) { isInBackground = false; } } return isInBackground; }
最后,别忘了在MyFirebaseMessagingService中定义showNotification方法:
private void showNotification(String title, String message)