Foreground service not running when App exits - java

How can I keep the foreground service running even when the user quits the app?
I've tried running the service in another process, but the service still stops after I quit the app.
My AndroidManifest.xml:
<application
android:allowBackup="true"
android:dataExtractionRules="#xml/data_extraction_rules"
android:fullBackupContent="#xml/backup_rules"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.Test"
tools:targetApi="31">
<service
android:name=".Service"
android:enabled="true"
android:process=":service"
android:exported="false" />
<activity
android:process=":activity"
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
Service.java:
public class CountdownService extends Service {
NotificationManager notificationManager;
private String createNotificationChannel(String channelId, String channelName) {
NotificationChannel chan = new NotificationChannel(channelId,
channelName, NotificationManager.IMPORTANCE_NONE);
chan.setLightColor(Color.BLUE);
chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.createNotificationChannel(chan);
return channelId;
}
NotificationCompat.Builder builder;
#NonNull
private Notification getNotification() {
String channelId = createNotificationChannel("id", "name");
builder = new NotificationCompat.Builder(this, channelId);
return builder.setOngoing(true)
.setSmallIcon(R.mipmap.ic_launcher)
.setPriority(PRIORITY_MIN)
.setCategory(Notification.CATEGORY_SERVICE)
.setContentText("Content Text")
.setSubText("Sub Text")
.setContentTitle("Content Title")
.build();
}
#Override
public void onCreate() {
super.onCreate();
startForeground(1, getNotification());
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
And in MainActivity, I start the service like this:
Intent intent = new Intent(this, Service.class);
startForegroundService(intent);
I found that this application has only one process 'service' in the phone settings, but there is no 'activity' process, what is the problem? thanks.

Define what you mean by "exit." If you mean they go into recents and swipe the app away, or go into settings and force quit, no. That's the user saying "I want this app to end". That will kill all services. Something that could run even when the user says it shouldn't is basically malware.

Related

AlarmManager and BroadcastReceiver in Android Oreo+

I am making an application that notifies the user at certain times of the day. Like an alarm clock. The code works normally in versions prior to Android Oreo.
From what I read, Android Oreo and later versions kill actions in the background and that's why I'm having the error below.
2020-07-13 20:31:06.766 1609-1737/? W/BroadcastQueue: Background execution not allowed: receiving Intent { act=android.intent.action.PACKAGE_REPLACED dat=package:studio.com.archeagemanager flg=0x4000010 (has extras) } to air.br.com.alelo.mobile.android/co.acoustic.mobile.push.sdk.wi.AlarmReceiver
It is as if the BroadcastService is simply not triggered when it should be. But when I open the app, it starts up instantly.
AndroidManifest.xml
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="owner.custom.permission" />
<permission
android:name="owner.custom.permission"
android:protectionLevel="signatureOrSystem">
</permission>
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<application
android:allowBackup="true"
android:icon="#mipmap/app_icon_new"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity
android:name=".SplashScreenActivity"
android:theme="#style/AppCompat.TelaCheia">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:screenOrientation="portrait"
android:theme="#style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<receiver
android:name=".AlarmReceiver"
android:enabled="true"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
TabFragEventA.java (Here I put only the function that initiates the alarm)
public void startAlarm(int eventID) {
String[] NOTIFICATION_TITLES = {"Ocleera Rift", "Ocleera Rift", "Mistmerrow Conflict", "Mistmerrow Conflict",
"Mistmerrow Conflict", "Nation Construction Quests", "Diamond Shores", "Diamond Shores", "Battle of the Golden Plains",
"Battle of the Golden Plains", "Karkasse Ridgelands", "Kraken", "The Mirage Isle Fish Fest", "Red Dragon",
"Abyssal Attack", "Lusca Awakening", "Delphinad Ghostship", "Cattler Wrangler", "Legendary Chef", "+1"};
String notificationTitle = getString(R.string.contentTitle);
String notificationText = NOTIFICATION_TITLES[eventID] + getString(R.string.contentNotificationText);
int alarmHour = localHour.get(eventID);
int alarmMinute = localMinute.get(eventID);
// Decrease 5 minutes
if(alarmMinute == 0) {
alarmHour = alarmHour - 1;
alarmMinute = 55;
} else {
alarmMinute = alarmMinute - 5;
}
// Setting the alarm moment
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, alarmHour);
calendar.set(Calendar.MINUTE, alarmMinute);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
// Analyze if the alarm moment has passed
Calendar actualTime = Calendar.getInstance();
if(actualTime.getTimeInMillis() >= calendar.getTimeInMillis()) {
calendar.add(Calendar.DAY_OF_MONTH, 1);
}
Intent intent = new Intent(getActivity().getApplicationContext(), AlarmReceiver.class);
intent.putExtra("contentTitle", notificationTitle);
intent.putExtra("contentText", notificationText);
/*if(eventID == 11 || eventID == 13) {
intent.putExtra("specificDayWeek", true);
} else {
intent.putExtra("specificDayWeek", false);
}*/
if(eventID == 12) {
intent.putExtra("castleSupply", true);
intent.putIntegerArrayListExtra("castleSupplyDayWeek", (ArrayList<Integer>) CastleSupply);
}
else if(eventID == 13) {
intent.putExtra("castleClaim", true);
intent.putIntegerArrayListExtra("castleClaimDayWeek", (ArrayList<Integer>) CastleClaim);
}
else if(eventID == 14) {
intent.putExtra("abyssalAttack", true);
intent.putIntegerArrayListExtra("abyssalDaysWeek", (ArrayList<Integer>) AbyssalDayWeek);
}
else if(eventID == 15) {
intent.putExtra("luscaAwakening", true);
intent.putIntegerArrayListExtra("luscaAwakeningDayWeek", (ArrayList<Integer>) LuscaAwakening);
} else {
intent.putExtra("abyssalAttack", false);
}
intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
// PendingIntent pendingIntent = PendingIntent.getBroadcast(getActivity().getApplicationContext(), eventID, intent, PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getActivity().getApplicationContext(), eventID, intent, 0);
AlarmManager alarmManager = (AlarmManager) getActivity().getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
}
AlarmReceiver.java
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String contentTitle = intent.getStringExtra("contentTitle");
String contentText = intent.getStringExtra("contentText");
String CHANNEL_ID = "my_channel_01";
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = "Channel Name";
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel mChannel = new NotificationChannel(CHANNEL_ID, name, importance);
notificationManager.createNotificationChannel(mChannel);
}
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context, CHANNEL_ID)
.setSmallIcon(R.drawable.icon_notification)
.setContentTitle(contentTitle)
.setContentText(contentText)
.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.drawable.icon_notification))
.setContentIntent(pendingIntent)
.setAutoCancel(true)
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
.setVibrate(new long[]{800, 500, 600, 300});
notificationManager.notify(0, notificationBuilder.build());
Log.d("ALARMRECEIVER", "INSIDE");
}
}
I would like to know what to do to make the Broadcast Receiver work in the background. Or an alternative to set this alarm clock on Android Oreo + so that it notifies the user even with the application closed or in the background.
Android has a doze mode in which it goes to sleep after some inactivity, Even if you manage to do this on some phones chinese ROMs will trouble you for sure ( in which removing from recent apps works as force stopping application)
For your problem there are solutions Like Work manager , Foregroundservices ,jobscheduler it should work but again can't say for all the ROMs. I think right now there isn't a proper solution to this background processing.
But One thing you can do is sending a FCM notification from server with high priority.
You can see that Facebook and whatsapp can work in background because they are whitelisted by the companies. You can whitelist your application by enabling auto start from settings.But you need to do it manually which isnt a case when we talk about fb and whatsapp
Check this website for more details : https://dontkillmyapp.com/
With this issue Most affected are alarm clocks, health trackers, automation apps, calendars or simply anything which needs to do some job for you at a particular moment when you don’t use your phone.
With Android 6 (Marshmallow), Google has introduced Doze mode to the base Android, in an attempt to unify battery saving across the various Android phones.
Unfortunately, some manufacturers (e.g. Xiaomi, Huawei, OnePlus or even Samsung..) did not seem to catch that ball and they all have their own battery savers, usually very poorly written, saving battery only superficially with side effects.
Starting from Android oreo and up no more background services are supported. the suggestion from the developer documentation is to use a foreground service. To keep the foreground service running you need to hook it up with a notification. you can configure the notification to hide or not visible in the UI at all lately.
check this solution
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
context = this;
String input = intent.getStringExtra("inputExtra");
createNotificationChannel();
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("GPS Service")
.setContentText("GPS Service")
// .setLargeIcon(emailObject.getSenderAvatar())
.setStyle(new NotificationCompat.BigTextStyle()
.bigText("Ready\nAndroi " + android.os.Build.VERSION.SDK_INT))
.setPriority(Notification.PRIORITY_HIGH)
.setOngoing(true)
.build();
startForeground(1, notification);
getLocation();
//do heavy work on a background thread
locationModel = new LocationModel("", "", "", "", "");
LongOperation longOperation = new LongOperation();
longOperation.execute();
//stopSelf();
return START_STICKY;
}
and in the main activity onCreate
if (!isMyServiceRunning(ForegroundService.class)) {
BroadcastReceiver br = new GPSBroadcastReceiver();
IntentFilter filter = new IntentFilter(CONNECTIVITY_ACTION);
filter.addAction(Intent.ACTION_BOOT_COMPLETED);
getApplicationContext().registerReceiver(br, filter);
}
checking whether the service is running
private boolean isMyServiceRunning(Class<?> serviceClass) {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
here is an example from one of my projects. Foreground service is the way to go!
some helpful sources.
foreground service example 1
foreground service example 2
repeating alarm manager example
If you are writing an Clock apps, use AlarmManager.setAlarmClock. It be allowed to trigger even if the system is in a low-power idle (a.k.a. doze) mode. When you set an AlarmClock, it's visible to the user. And SystemUI may show different icons or alarms.
If you just want to be triggered at certain time to do some work, there is no good way to escape the background limit.

Notification using Firebase and Android

I am trying to make an android application where I receive notification using firebase. I followed resources available over the internet.
All I want to do is send notification from firebase, the message that I receive I want to display it in TextView in main activity.
Currently I am testing in an emulator. There are few problems that I am not able to resolve.
I am able to send notification from firebase but:
When the application is running in foreground I don't receive a notification in the android notification panel and nothing happens in the main activity too. That is the text in TextView does not change.
When the application is running in background I do receive the notification in android notification panel with message sent from firebase, clicking the notification main activity opens but the text in TextView does not change.
Firebase Messaging Service
public class VAFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "VAFirebaseMessagingS";
public VAFirebaseMessagingService() {}
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
Log.d(TAG, "From: " + remoteMessage.getFrom());
if(remoteMessage.getData().size() > 0) {
Log.d(TAG, "Message data payload: " + remoteMessage.getData());
sendNotification(remoteMessage.getData().get("text"));
}
if(remoteMessage.getNotification() != null) {
Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
sendNotification(remoteMessage.getNotification().getBody());
}
}
private void sendNotification(String messageBody) {
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra(Intent.EXTRA_TEXT, messageBody);
PendingIntent pendingIntent = PendingIntent
.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this);
notificationBuilder.setSmallIcon(R.drawable.ic_stat_name);
notificationBuilder.setContentTitle("PFIVA");
notificationBuilder.setContentText(messageBody);
notificationBuilder.setAutoCancel(true);
notificationBuilder.setSound(defaultSoundUri);
notificationBuilder.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notificationBuilder.build());
}
}
Main Activity
public class MainActivity extends AppCompatActivity {
private TextView userFeedbackQuery;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
userFeedbackQuery = (TextView) findViewById(R.id.pfiva_user_feedback_query);
final Intent intent = getIntent();
if(intent.hasExtra(Intent.EXTRA_TEXT)) {
String userFeedbackQueryText = intent.getStringExtra(Intent.EXTRA_TEXT);
userFeedbackQuery.setText(userFeedbackQueryText);
}
}
}
Android Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="de.pfiva.mobile.voiceassistant">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".activities.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".messaging.FirebaseInstanceService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
<service
android:name=".messaging.VAFirebaseMessagingService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
</application>
</manifest>
Please can someone guide what is wrong here? How can i solve the above two problems.
Thanks
After suggestions i made the below changes in Messaging Service, basically added notification channel.
private void sendNotification(String messageBody) {
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra(Intent.EXTRA_TEXT, messageBody);
PendingIntent pendingIntent = PendingIntent
.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, CHANNEL_ID);
notificationBuilder.setSmallIcon(R.drawable.ic_stat_name);
notificationBuilder.setContentTitle("PFIVA");
notificationBuilder.setContentText(messageBody);
notificationBuilder.setPriority(NotificationCompat.PRIORITY_HIGH);
notificationBuilder.setAutoCancel(true);
notificationBuilder.setSound(defaultSoundUri);
notificationBuilder.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// Create the NotificationChannel, but only on API 26+ because
// the NotificationChannel class is new and not in the support library
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, CHANNEL_NAME, importance);
notificationManager.createNotificationChannel(channel);
}
notificationManager.notify(0, notificationBuilder.build());
}
Problem i face now is that when the app is running in background, i do receive notification in notification panel and clicking on it open main activity but the text in TextView is not updated.
Two ideas to solve your issue:
Have you register your VAFirebaseMessagingService in your AndroidManifest.xml:
Since Android 8, you must use an Notification Channel to send push notifications. Android

firebase push notification doesnt shows in all devices

I'm trying to send a push notification to all devices from firebase but at first i tried only in my phone, it doesn't work, after that i tried in another phone and it doesn't work either. Finally with the 3rd one it work and it work at the second one magically. What i have to do to the push notifications work in all devices?
Manifest ->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.startingandroid.firebasecloudmessaging">
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".SplashActivity" android:label="">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".MainActivity" android:label="FCM"></activity>
<service
android:name=".MyFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
<service
android:name=".MyFirebaseInstanceIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
</application></manifest>
MyFirebaseInstanceIDService ->
public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService {
private static final String TAG = "MyFirebaseIIDService";
#Override
public void onTokenRefresh() {
//Getting registration token
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
//Displaying token in logcat
Log.e(TAG, "Refreshed token: " + refreshedToken);
}
private void sendRegistrationToServer(String token) {
//You can implement this method to store the token on your server
//Not required for current project
} }
MyFirebaseMessagingService ->
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "StartingAndroid";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
//It is optional
Log.e(TAG, "From: " + remoteMessage.getFrom());
Log.e(TAG, "Notification Message Body: " + remoteMessage.getNotification().getBody());
//Calling method to generate notification
sendNotification(remoteMessage.getNotification().getTitle(),remoteMessage.getNotification().getBody());
}
//This method is only generating push notification
private void sendNotification(String title, String messageBody) {
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,
PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(title)
.setContentText(messageBody)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notificationBuilder.build());
}}
SplashActivity
public class SplashActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
getSupportActionBar().hide();
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_splash);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Intent i = new Intent(SplashActivity.this,
MainActivity.class);
startActivity(i);
finish();
}
}, 4000);
}}

GCM Broadcast receiver not detcting gcm notification when the app is closed

I have a broadcast receiver which detects oncoming notifications when the app is open and in background but when the recent app is cleared the receiver is not working please suggest me ideas.
public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// Explicitly specify that GcmIntentService will handle the intent.
ComponentName comp = new ComponentName(context.getPackageName(),
GcmIntentService.class.getName());
JSONObject json = new JSONObject();
try {
json.putOpt("userid", StorePreference.GetSharedPreferenceDetails(context, "memberid"));
json.putOpt("rid",StorePreference.GetSharedPreferenceDetails(context, "partnerid"));
json.putOpt("message", "Received");
BoundService.getInstance().onlinestatus(json);
} catch (Exception e) {
e.printStackTrace();
}
startWakefulService(context, (intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
}
}
Manifest decleration:
<receiver
android:name="com.twogether.receivers.GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name = "com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.google.android.gcm.demo.app" />
</intent-filter>
</receiver>
Try to register your receiver in manifest, use GcmListenerService to receive messages.
google example https://github.com/googlesamples/google-services has example to do this.
<!-- gcm_receiver, this is android source-->
<receiver
android:name="com.google.android.gms.gcm.GcmReceiver"
android:exported="true"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.myapp.gcm" />
</intent-filter>
</receiver>
<!-- gcm_listener service -->
<service
android:name="com.qblinks.qmote.GcmListenerService"
android:exported="false" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
// Use this service to receive message
public class GcmListenerService extends com.google.android.gms.gcm.GcmListenerService {
public void onMessageReceived(String from, Bundle data) {
String message = data.getString("message");
Log.v(TAG, "From: " + from);
Log.v(TAG, "Message: " + message);
sendNotification(message);
}
private void sendNotification(String message) {
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.notification)
.setContentTitle("this is title")
.setStyle(new NotificationCompat.BigTextStyle().bigText(message))//multi line
.setSound(defaultSoundUri); // ring or vibrate if no ring
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(Const.NOTIFICATION_GCM /* ID of notification */, notificationBuilder.build());
}
}
When the app is close you need to wake the app up, means you need to have the permission to do that
<uses-permission android:name="android.permission.WAKE_LOCK" />
and after you can set:
AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
manager.set(AlarmManager.RTC, System.currentTimeMillis() + 5000, yourIntent);

How can I keep my app's notification displayed when my app is updated on Google Play store?

My app has a function of set-notification. Here is my code.
#SuppressWarnings("deprecation")
public static void setNotification(Context _context) {
NotificationManager notificationManager =
(NotificationManager) _context.getSystemService(Context.NOTIFICATION_SERVICE);
int icon_id = R.drawable.icon;
Notification notification = new Notification(icon_id,
_context.getString(R.string.app_name), System.currentTimeMillis());
//
Intent intent = new Intent(_context, MainActivity.class);
notification.flags = Notification.FLAG_ONGOING_EVENT;
PendingIntent contextIntent = PendingIntent.getActivity(_context, 0, intent, 0);
notification.setLatestEventInfo(_context,
_context.getString(R.string.app_name),
_context.getString(R.string.notify_summary), contextIntent);
notificationManager.notify(R.string.app_name, notification);
}
This code works fine. If my app is closed, notification keeps displayed.
But even if notification was set, the notification is cancelled when user will update my app version by Google Play store.
I know that...
The notification is cancelled when my app is uninstalled.
In fact an update is "uninstall and install".
How can I keep displayed when my app version is updated?
If I understood right you want displaying a notification after updating.
So you can implement receiver that listens updating of app or rebooting of device and shows notification again.
add to you manifest:
<receiver
android:name=".UpdatingReceiver"
android:enabled="true"
android:exported="false" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.PACKAGE_REPLACED" />
<data android:scheme="package" />
</intent-filter>
</receiver>
and implement receiver:
public class UpdatingReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction()) || Intent.ACTION_PACKAGE_REPLACED.equals(intent.getAction())) {
// check is need to show notification
}
}

Categories

Resources