Firebase通知,在后台或被关闭时不显示,但数据已发送。

11 浏览
0 Comments

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 {
            Mapparams=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));
}
 }

0
0 Comments

问题原因:代码中使用了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) {
        List runningProcesses = 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)

0