#android #push-notification #intentservice
#Android #push-уведомление #intentservice
Вопрос:
Когда я пытаюсь получить уведомление на устройстве, когда я открываю приложение, я получаю уведомление, и после закрытия я также получаю уведомление, но оно будет работать примерно 40-60 секунд, после чего оно выдаст эту ошибку —
W/ActivityManager: Background start not allowed: service Intent
{ act=com.google.firebase.MESSAGING_EVENT pkg=packagename cmp=packageName/.Services.MyFirebaseMessagingService (has extras) } to packageName/.Services.MyFirebaseMessagingService from pid=1990 uid=10541 pkg=packageName
2019-03-20 17:25:15.158 1990-1990/packageName E/FirebaseInstanceId: Error while delivering the message: ServiceIntent not found.`
Я получаю уведомление на переднем плане, но когда я на какое-то время отключу приложение, я получу примерно через 40-60 секунд, через некоторое время я не буду получать уведомления
Примечание: Это не проблема с Android v8
или Orio
, я пытаюсь с Android v7
или v9
, так что это проблема со всеми устройствами
я перепробовал все возможные решения, но у меня ничего не получалось. Поэтому я буду рад, если кто-нибудь сможет мне с этим помочь
Вот мой класс firbaseMessaging:
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "FirebaseService";
UserSessionManager session;
private NotificationUtils notificationUtils;
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.e(TAG, "NBody: " remoteMessage.getFrom() ", " remoteMessage.getData() ", " remoteMessage.getNotification());
if (remoteMessage == null) {
Log.e("TAGGG","Nothing to recieve");
return;
}
/* Check if message contains a notification payload. */
if (remoteMessage.getNotification() != null) {
Log.e(TAG, "Notification Body: " remoteMessage);
handleNotification(remoteMessage.getNotification().getBody());
}
/* Check if message contains a data payload.*/
if (remoteMessage.getData().size() > 0) {
Log.e(TAG, "Data Payload: " remoteMessage.getData().toString());
try {
JSONObject json = new JSONObject(remoteMessage.getData().toString());
handleDataMessage(json);
} catch (Exception e) {
Log.e(TAG, "Exception: " e.getMessage());
}
}
}
private void handleNotification(String message) {
if (NotificationUtils.isAppIsInBackground(getApplicationContext())) {
/* app is in foreground, broadcast the push message */
Intent pushNotification = new Intent(Config.PUSH_NOTIFICATION);
pushNotification.putExtra("message", message);
LocalBroadcastManager.getInstance(this).sendBroadcast(pushNotification);
/* play notification sound */
NotificationUtils notificationUtils = new NotificationUtils(getApplicationContext());
notificationUtils.playNotificationSound();
} else {
Log.d("INBACKGROUND","Not is background");
}
}
private void handleDataMessage(JSONObject json) {
try {
JSONObject data = json.getJSONObject("data");
String title = data.getString("title");
String message = data.getString("message");
String action = data.getString("action");
String destination = data.getString("action_destination");
Preference.storeLoadStatus("UnDone");
Preference.storeNotificationType(action);
if (NotificationUtils.isAppIsInBackground(getApplicationContext())) {
/* app is in foreground, broadcast the push message */
Intent pushNotification = new Intent(Config.PUSH_NOTIFICATION);
pushNotification.putExtra("message", message);
pushNotification.putExtra("action", action);
pushNotification.putExtra("destination", destination);
LocalBroadcastManager.getInstance(this).sendBroadcast(pushNotification);
/* play notification sound */
NotificationUtils notificationUtils = new NotificationUtils(getApplicationContext());
notificationUtils.playNotificationSound();
} else {
/* app is in background, show the notification in notification tray*/
session = new UserSessionManager(getApplicationContext());
Intent resultIntent;
if (!session.checkLogin()) {
resultIntent = new Intent(getApplicationContext(), NewHomeActivity.class);
} else {
resultIntent = new Intent(getApplicationContext(), Main2Activity.class);
}
resultIntent.putExtra("message", message);
resultIntent.putExtra("action", action);
resultIntent.putExtra("destination", destination);
Timestamp timestamp = new Timestamp(System.currentTimeMillis());
String ts = timestamp.toString();
showNotificationMessage(getApplicationContext(), title, message, ts, resultIntent);
// check for image attachment
}
} catch (Exception e) {
Log.e(TAG, "Exception: " e.getMessage());
}
}
/**
* Showing notification with text only
*/
private void showNotificationMessage(Context context, String title, String message, String timeStamp, Intent intent) {
notificationUtils = new NotificationUtils(context);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setAction("android.intent.action.MAIN");
intent.addCategory("android.intent.category.LAUNCHER");
notificationUtils.showNotificationMessage(title, message, timeStamp, intent); ;
}
/**
* Showing notification with text and image
*/
private void showNotificationMessageWithBigImage(Context context, String title, String message, String timeStamp, Intent intent, String imageUrl) {
notificationUtils = new NotificationUtils(context);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
notificationUtils.showNotificationMessage(title, message, timeStamp, intent, imageUrl);
}
}
Вот утилиты уведомлений
public class NotificationUtils {
private static final int NOTIFICATION_ID = 1;
private static String TAG = NotificationUtils.class.getSimpleName();
private Context mContext;
public NotificationUtils(Context mContext) {
this.mContext = mContext;
}
/**
* Method checks if the app is in background or not
*/
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<ActivityManager.RunningAppProcessInfo> runningProcesses = null;
if (am != null) {
runningProcesses = am.getRunningAppProcesses();
}
if (runningProcesses != null) {
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<ActivityManager.RunningTaskInfo> taskInfo = null;
if (am != null) {
taskInfo = am.getRunningTasks(1);
}
ComponentName componentInfo = null;
if (taskInfo != null) {
componentInfo = taskInfo.get(0).topActivity;
}
if (componentInfo != null amp;amp; componentInfo.getPackageName().equals(context.getPackageName())) {
isInBackground = false;
}
}
return !isInBackground;
}
// Clears notification tray messages
public static void clearNotifications(Context context) {
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancelAll();
}
public static long getTimeMilliSec(String timeStamp) {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
try {
Date date = format.parse(timeStamp);
return date.getTime();
} catch (ParseException e) {
e.printStackTrace();
}
return 0;
}
public void showNotificationMessage(String title, String message, String timeStamp, Intent intent) {
showNotificationMessage(title, message, timeStamp, intent, null);
}
public void showNotificationMessage(final String title, final String message, final String timeStamp, Intent intent, String imageUrl) {
Log.d("ShowNotification1", "Message");
// Check for empty push message
if (TextUtils.isEmpty(message))
return;
// notification icon
final int icon = R.mipmap.ic_launcher;
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
final PendingIntent resultPendingIntent =
PendingIntent.getActivity(
mContext,
0,
intent,
PendingIntent.FLAG_UPDATE_CURRENT
);
final NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
mContext);
final Uri alarmSound = Uri.parse(PreferenceManager.getDefaultSharedPreferences(mContext).
getString("pref_tone", "content://settings/system/notification_sound"));
if (!TextUtils.isEmpty(imageUrl)) {
if (imageUrl != null amp;amp; imageUrl.length() > 4 amp;amp; Patterns.WEB_URL.matcher(imageUrl).matches()) {
Bitmap bitmap = getBitmapFromURL(imageUrl);
if (bitmap != null) {
showBigNotification(bitmap, mBuilder, icon, title, message, timeStamp, resultPendingIntent, alarmSound);
} else {
showSmallNotification(mBuilder, icon, title, message, timeStamp, resultPendingIntent, alarmSound);
}
}
} else {
showSmallNotification(mBuilder, icon, title, message, timeStamp, resultPendingIntent, alarmSound);
playNotificationSound();
}
}
private void showSmallNotification(NotificationCompat.Builder mBuilder, int icon, String title, String message, String timeStamp, PendingIntent resultPendingIntent, Uri alarmSound) {
Notification notification;
//notification = mBuilder.setSmallIcon(icon).setTicker(title).setWhen(0)
notification = new NotificationCompat.Builder(mContext)
.setAutoCancel(true)
.setContentTitle(title)
.setContentIntent(resultPendingIntent)
.setSound(alarmSound)
// .setStyle(inboxStyle)
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(message))
.setWhen(getTimeMilliSec(timeStamp))
.setSmallIcon(R.drawable.mtruck_new_logo)
.setLargeIcon(BitmapFactory.decodeResource(mContext.getResources(), R.drawable.mtruck_new_logo))
.setContentText(message)
.build();
// startForeground(NOTIFICATION_ID, notification);
NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(Config.NOTIFICATION_ID, notification);
}
private void showBigNotification(Bitmap bitmap, NotificationCompat.Builder mBuilder, int icon, String title, String message, String timeStamp, PendingIntent resultPendingIntent, Uri alarmSound) {
NotificationCompat.BigPictureStyle bigPictureStyle = new NotificationCompat.BigPictureStyle();
bigPictureStyle.setBigContentTitle(title);
bigPictureStyle.setSummaryText(Html.fromHtml(message).toString());
bigPictureStyle.bigPicture(bitmap);
Notification notification;
notification = mBuilder.setSmallIcon(icon).setTicker(title).setWhen(0)
.setAutoCancel(true)
.setContentTitle(title)
.setContentIntent(resultPendingIntent)
.setSound(alarmSound)
.setStyle(bigPictureStyle)
.setWhen(getTimeMilliSec(timeStamp))
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(mContext.getResources(), icon))
.setContentText(message)
.build();
NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(Config.NOTIFICATION_ID_BIG_IMAGE, notification);
}
/**
* Downloading push notification image before displaying it in
* the notification tray
*/
public Bitmap getBitmapFromURL(String strURL) {
try {
URL url = new URL(strURL);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap myBitmap = BitmapFactory.decodeStream(input);
return myBitmap;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
// Playing notification sound
public void playNotificationSound() {
try {
Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Ringtone r = RingtoneManager.getRingtone(mContext, notification);
r.play();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Вот класс MyFirebaseInstance
public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService {
private static final String TAG = MyFirebaseInstanceIDService.class.getSimpleName();
@Override
public void onTokenRefresh() {
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
// Saving reg id to shared preferences
storeRegIdInPref(refreshedToken);
sendRegistrationToServer(refreshedToken);
// Notify UI that registration has completed, so the progress indicator can be hidden.
Intent registrationComplete = new Intent(Config.REGISTRATION_COMPLETE);
registrationComplete.putExtra("token", refreshedToken);
LocalBroadcastManager.getInstance(this).sendBroadcast(registrationComplete);
}
private void sendRegistrationToServer(String refreshToken) {
// sending gcm token to server
Log.d("TOKEN: ", refreshToken);
}
private void storeRegIdInPref(String token) {
SharedPreferences pref = getApplicationContext().getSharedPreferences(Config.SHARED_PREF, 0);
SharedPreferences.Editor editor = pref.edit();
editor.putString("regId", token);
editor.commit();
}
}
Вот разрешение манифеста и библиотека firebase:
<service android:name=".Services.MyFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
<!--<service android:name=".Services.BackgroundServices" />-->
<service android:name=".Services.MyFirebaseInstanceIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
Библиотеки Firbase
implementation 'com.google.firebase:firebase-messaging:17.4.0'
implementation 'com.google.firebase:firebase-core:16.0.8'
Спасибо
Комментарии:
1. можете ли вы упомянуть класс FirebaseMessageService?
2. @Abhinav Gupta Я добавил классы, которые я использую
3. Вы проверили какие-либо требуемые разрешения, службы и
meta
-ы в соответствии с документами Firebase? Похоже, это вызвано тем, что он находится в фоновом режиме.4. Я добавил манифест и fcm @ Meow Cat 2012
Ответ №1:
Сделайте это :
if (remoteMessage.getData().size() > 0) {
Log.e(TAG, "Data Payload: " remoteMessage.getData().get("body"));
try {
JSONObject json = new JSONObject(remoteMessage.getData().get("body"));
handleDataMessage(json);
} catch (Exception e) {
Log.e(TAG, "Exception: " e.getMessage());
}
}
вместо :
if (remoteMessage.getData().size() > 0) {
Log.e(TAG, "Data Payload: " remoteMessage.getData().toString());
try {
JSONObject json = new JSONObject(remoteMessage.getData().toString()); // this can be null that's why you are not receiving notification
handleDataMessage(json);
} catch (Exception e) {
Log.e(TAG, "Exception: " e.getMessage());
}
}
в mainfest
файле сделайте это :
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
тогда
<service android:name=".service.MyFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<service android:name=".service.MyFirebaseInstanceIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
В gradle
:
implementation 'com.google.firebase:firebase-messaging:17.4.0'
implementation 'com.google.firebase:firebase-core:16.0.7'
Комментарии:
1. Я попробовал это, и это тоже не работает, это не проблема, поскольку он даже не вызывает onMessage, это проблема с ActivityManager: фоновый запуск не разрешен: намерение службы
2. @Govind пожалуйста, проверьте и обновите ответ в данных удаленного сообщения, сделайте то, что я упомянул, потому что я также получаю эту ошибку.
3. Попробовал ваше решение, но не работает, та же проблема @Abhinav Gupta
4. Есть ли кто-нибудь, кто может мне помочь с этим?
5. Кто-нибудь, кто может помочь? Пожалуйста