GCM message stops foregrounded service - android

I am using an indefinitely running service (with its own process) and an extension of GcmListenerService to receive push messages. The push messages will initiate an operation within the service.
The problem is, that if the app is closed/removed from the recently used app, the service is still running, but will stop immediately if a new message is received. The process list shows that first the background process is terminated and then a usual application process starts without any processing of the push message.
AndroidManifest.xml
<application android:allowBackup="false" android:label="#string/app_name"
android:icon="#drawable/icon" android:theme="#style/AppTheme"
android:process="domain.android.Application"
android:name=".Application">
<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="domain.android" />
</intent-filter>
</receiver>
<service
android:name=".service.MyGcmListenerService"
android:exported="false" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
<service
android:name=".service.BackgroundService"
android:icon="#drawable/icon"
android:label="#string/service_name"
android:process="domain.android.service.BackgroundService"
android:exported="false"
android:enabled="true"/>
</application>
The GCM listener
public class MyGcmListenerService extends GcmListenerService {
#Override
public void onMessageReceived(String from, Bundle data) {
String code = data.getString("code");
if ("j".equals(code)) {
final String id = data.getString("id", null);
String status = data.getString("status", null);
Intent serviceIntent = new Intent(getBaseContext(), domain.android.service.BackgroundService.class);
serviceIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
serviceIntent.putExtra("method", "push");
serviceIntent.putExtra("id", id);
serviceIntent.putExtra("status", status);
serviceIntent.putExtra("notificationId", (new Date()).getTime());
startService(serviceIntent);
}
}
}
The service:
public class BackgroundService extends Service {
#Override
public int onStartCommand(Intent intent, int flags, final int startId) {
if (intent.hasExtra("method")) {
// Start processing
}
}
#Override
public void onCreate() {
Intent notificationIntent = new Intent(this, Main.class);
PendingIntent intent = PendingIntent.getActivity(getBaseContext(), 0, notificationIntent, 0);
android.app.Notification.Builder builder = new android.app.Notification.Builder(this)
.setContentIntent(intent)
.setContentTitle(getText(R.string.app_name))
.setContentText("Connected")
.setSmallIcon(R.drawable.marker_walker_white);
android.app.Notification notification = builder.build();
startForeground(1, notification);
}
}

Related

Service not get called in android

I'm building a simple reminder application that will remind you of your events.
I've just used "Alarm Manager" with "Broadcast Receiver " to trigger my service at a certain time in the future. The purpose of the service is to vibrate the device when the notification arrives. Notification is working fine but, the Service isn't working as expected. I know that I can simply put the code for vibration inside the "Broadcast Receiver" but NEED TO KNOW ABOUT THE SERVICE. Don't know what's wrong with my code help me out guys, THANKS in advance.
Broadcast Receiver as follows:
public class NotificationSetter extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("AlarmTriggered", "Alarm is triggered to start background service");
Intent serviceVibes = new Intent(context,BackgroundService.class);
context.startService(serviceVibes);
Toast.makeText(context, String.valueOf(Build.VERSION.SDK_INT), Toast.LENGTH_SHORT).show();
//creating the Notification
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, "Notify");
builder.setSmallIcon(R.drawable.reminder);
builder.setContentTitle("Reminding of your event");
builder.setContentText("Time to play Cricket");
builder.setAutoCancel(true);
NotificationManagerCompat compat = NotificationManagerCompat.from(context);
compat.notify(3000, builder.build());
}
}
My service class:
public class BackgroundService extends Service {
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("ServiceStarted", "Service is started using NotificationSetter");
Vibrator vibes = (Vibrator) getSystemService(VIBRATOR_SERVICE);
if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){
vibes.vibrate(VibrationEffect.createOneShot(2000,200));
}else {
vibes.vibrate(2000);
}
Toast.makeText(getApplicationContext(), String.valueOf(Build.VERSION.SDK_INT), Toast.LENGTH_SHORT).show();
return START_STICKY;
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
The Manifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.remindme">
<uses-permission android:name="android.permission.VIBRATE" />
<application
android:name="com.example.remindme.MyContext"
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=".StopAlarm"></activity>
<activity android:name=".GetEvent" />
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name="com.example.remindme.BackgroundService"
android:enabled="true"
android:exported="true">
</service>
<receiver android:name=".NotificationSetter"
android:enabled="true"
android:exported="true"/>
</application>
</manifest>
According to documentation, since Android 8.0 afterwards, an app cannot start a foreground service unless in a few conditions:
https://developer.android.com/about/versions/oreo/background
Check if your service is triggered when you have your app in foreground, meaning that your app has a visible Activity to user. If it works in this condition, then it means your problem lies in background execution limits introduced in Android 8.0. So to make your service work, you can start it as a foreground service by calling this line of code:
ContextCompat.startForegroundService(context, new Intent(context, YourBackgroundService.class));
A foreground service needs a notification to be shown at status bar. You can either grab an instance of your alarm notification and use it as the foreground service notification or create a new notification.

Android alarm manager pending intents lost

This is my first post and I am new to Android App development so please bear with me.
I have written (and use every day) a pretty good reminders App because all the others were either too complicated or too simple. It is also on the play store, although not easy to find, but thats another story.
While I am happy with the whole App the alarms which show a notification or sound an alarm do not always happen. If the alarm is soon then it will but more than say 2 hours from now it often gets missed. Using "adb shell dumpsys alarm" it looks as if they are being discarded?
I have googled for days and have tried so many things, from this forum too, but no luck so I thought I would post some code to see if anybody can please tell me were I am going wrong as it should work as far as I can see.
So here goes.
I use alarm manager to queue the pending intent to call my broadcast receiver which starts a service which starts an activity which creates a notification and optionally sounds an alarm.
I was skipping the service bit but after googling it seems I should use a service. And as mentioned, this works fine for alarms happening soon but not after a few hours or a day or more. Could be due to Doze mode or my app being stopped by Android?
I would really appreciate some help please as I am pulling my hair out!!
Thanks in advance.
Here is my manifest. Where I think the problem is?
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.wingwares.reminders">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.VIBRATE" />
<supports-screens
android:anyDensity="true"
android:normalScreens="true" />
<application
android:icon="#drawable/reminder2"
android:label="#string/app_name"
android:theme="#style/AppTheme">
<receiver android:name=".WidgetProvider">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="#xml/widget_info" />
</receiver>
<service
android:name=".WidgetService"
android:exported="false"
android:permission="android.permission.BIND_REMOTEVIEWS" />
<activity
android:name=".AppPreferences" />
<activity
android:name=".ListActivity"
android:label="#string/app_name"
android:screenOrientation="portrait"
android:windowSoftInputMode="stateAlwaysHidden">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".RemActivity"
android:label="#string/add_reminder"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustPan" />
<service
android:name=".AlarmService"
android:enabled="true"
android:exported="true" >
</service>
<receiver
android:name=".AlarmReceiver"
android:enabled="true"
android:exported="true" >
<intent-filter>
<action android:name="SET_ALERT" />
</intent-filter>
</receiver>
<activity
android:name=".AlarmDialog"
android:theme="#style/AlarmDialog" />
</application>
</manifest>
And my Alarm Manager from ListActivity
public void setAlert(Context context, boolean turnOn){
intent = new Intent(context, AlarmReceiver.class);
intent.putExtra("name", fullName());
intent.putExtra("notes", notes);
intent.putExtra("setalarm", setalarm);
intent.putExtra("millis", time.getMilliTime());
intent.putExtra("remId", remId);
pendingIntent = PendingIntent.getBroadcast(context, 8192 + remId, intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
if (turnOn) {
alertTime = time.getMilliTime() - (warning * 60000);
interval = getInterval();
//set repeating alarmManager just once
if (freq.equals(EVERY) && type.equals(FIXED) && date.equals(getOriginal()) && interval > 0) {
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, alertTime, interval, pendingIntent);
} else {
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, alertTime, pendingIntent);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, alertTime, pendingIntent);
} else {
alarmManager.set(AlarmManager.RTC_WAKEUP, alertTime, pendingIntent);
}
}
} else {
setalarm = false;
}
}
My broadcast receiver
public class AlarmReceiver extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent newIntent = new Intent(context, AlarmService.class);
//pass the extras on and show the dialog
newIntent.putExtras(intent);
startWakefulService(context, newIntent);
}
}
My Service
public class AlarmService extends IntentService {
public AlarmService (){
super("AlarmService");
}
#Override
protected void onHandleIntent(Intent intent) {
Intent newIntent = new Intent(this, AlarmDialog.class);
newIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
//pass the extras on and show the dialog
newIntent.putExtras(intent);
startActivity(newIntent);
AlarmReceiver.completeWakefulIntent(newIntent);
}
}
My Activity (the notification part)
public class AlarmDialog extends Activity
implements DialogInterface.OnCancelListener, DialogInterface.OnClickListener {
Bundle extras;
int remId;
String name, notes;
Boolean setalarm;
long alarmTime;
MediaPlayer player;
PendingIntent pendingIntent;
SharedPreferences mPrefs;
NotificationManager manager;
Notification notification;
static final int SNOOZE_BUTTON = -2;
static final int DISMISS_BUTTON = -1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//create notification and alert box if alarmManager selected
mPrefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
extras = getIntent().getExtras();
alarmTime = extras.getLong("millis");
remId = extras.getInt("remId");
name = extras.getString("name");
notes = extras.getString("notes");
setalarm = extras.getBoolean("setalarm");
//notification first
notification = new RemNotification(this, name).get();
if (notification != null) {
manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
manager.cancel(remId);
manager.notify(remId, notification);
}
}

Notification Not received when app closed in Lollipop using GCM

I'm new to android. In my app, I didn't receive notification when the app is closed. If it is running it received. I tried all the way but still I didn't get the solution. Please find what I make wrong
Here my code:
Manifest.xml:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="com.google.android.c2dm.permission.REGISTER" />
<uses-permission android:name="android.permission.EXPAND_STATUS_BAR" />
<permission android:name="com.h2o.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.h2o.permission.C2D_MESSAGE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<receiver
android:name="com.h2o.ExternalReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<action android:name="com.google.android.c2dm.intent.REGISTER" />
<category android:name="com.google.android.gcm.demo.app" />
</intent-filter>
</receiver>
<service
android:name="com.h2o.MessageReceivingService"
android:label="com.h2o.MessageReceivingService" >
<intent-filter>
<action android:name="com.h2o.ExternalReceiver" />
<category android:name="com.h2o"/>
</intent-filter>
</service>
Receiver:
public class ExternalReceiver extends WakefulBroadcastReceiver {
public void onReceive(Context context, Intent intent) {
// Explicitly specify that GcmIntentService will handle the intent.
ComponentName comp = new ComponentName(context.getPackageName(),MessageReceivingService.class.getName());
startWakefulService(context,(intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
}
}
Service:
public class MessageReceivingService extends Service{
private GoogleCloudMessaging gcm;
public static SharedPreferences savedValues;
public static void sendToApp(Bundle extras, Context context){
Intent newIntent = new Intent();
newIntent.setClass(context, AndroidMobilePushApp.class);
newIntent.putExtras(extras);
newIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(newIntent);
}
public void onCreate(){
super.onCreate();
final String preferences = getString(R.string.preferences);
savedValues = getSharedPreferences(preferences, Context.MODE_PRIVATE);
gcm = GoogleCloudMessaging.getInstance(getBaseContext());
SharedPreferences savedValues = PreferenceManager.getDefaultSharedPreferences(this);
if(savedValues.getBoolean(getString(R.string.first_launch), true)){
register();
SharedPreferences.Editor editor = savedValues.edit();
editor.putBoolean(getString(R.string.first_launch), false);
editor.commit();
}
if(savedValuess.getBoolean(getString(R.string.first_launch), true)){
// Let AndroidMobilePushApp know we have just initialized and there may be stored messages
sendToApp(new Bundle(), this);
}
}
protected static void saveToLog(Bundle extras, Context context){
SharedPreferences.Editor editor=savedValues.edit();
String numOfMissedMessages = context.getString(R.string.num_of_missed_messages);
int linesOfMessageCount = 0;
for(String key : extras.keySet()){
String line = String.format("%s=%s", key, extras.getString(key));
editor.putString("MessageLine" + linesOfMessageCount, line);
linesOfMessageCount++;
}
editor.putInt(context.getString(R.string.lines_of_message_count), linesOfMessageCount);
editor.putInt(context.getString(R.string.lines_of_message_count), linesOfMessageCount);
editor.putInt(numOfMissedMessages, savedValues.getInt(numOfMissedMessages, 0) + 1);
editor.commit();
postNotification(new Intent(context, AndroidMobilePushApp.class), context);
}
protected static void postNotification(Intent intentAction, Context context){
final NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
final PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intentAction, Notification.DEFAULT_LIGHTS | Notification.FLAG_AUTO_CANCEL);
final Notification notification = new NotificationCompat.Builder(context).setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("Message Received!")
.setContentText("")
.setContentIntent(pendingIntent)
.setAutoCancel(true)
.getNotification();
mNotificationManager.notify(R.string.notification_number, notification);
}
private void register() {
new AsyncTask(){
protected Object doInBackground(final Object... params) {
String token;
try {
token = gcm.register(getString(R.string.project_number));
Log.i("registrationId", token);
}
catch (IOException e) {
Log.i("Registration Error", e.getMessage());
}
return true;
}
}.execute(null, null, null);
}
public IBinder onBind(Intent arg0) {
return null;
}
}
Thanks in advance!
To be able to receive notifications when your application is closed, you have to register a service listener with the following permission
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"
See the documentation for more details
https://developer.android.com/reference/android/service/notification/NotificationListenerService.html
you need to define your broadcast receiver in manifest like this:
<receiver
android:name=".GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<!-- Receives the actual messages. -->
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.google.android.gcm.demo.app" />
</intent-filter>
and in the broadcast receiver class add the following codes:
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());
// Start the service, keeping the device awake while it is launching.
startWakefulService(context, (intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
}}
there is some problem with wakeful broadcast receiver, read this
Confusion about WakefulBroadcastReceiver
For best practice it is recommended that you should use Firebase cloud messaging (FCM) instead of GCM.

How to Auto-start an Android Application?

I'm not sure how to autostart an android application after the android emulator completes its booting. Does anyone have any code snippets that will help me?
You have to add a manifest permission entry:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
(of course you should list all other permissions that your app uses).
Then, implement BroadcastReceiver class, it should be simple and fast executable. The best approach is to set an alarm in this receiver to wake up your service (if it's not necessary to keep it running ale the time as Prahast wrote).
public class BootUpReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
PendingIntent pi = PendingIntent.getService(context, 0, new Intent(context, MyService.class), PendingIntent.FLAG_UPDATE_CURRENT);
am.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + interval, interval, pi);
}
}
Then, add a Receiver class to your manifest file:
<receiver android:enabled="true" android:name=".receivers.BootUpReceiver"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
Edit your AndroidManifest.xml to add RECEIVE_BOOT_COMPLETED permission
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
Edit your AndroidManifest.xml application-part for below Permission
<receiver android:enabled="true" android:name=".BootUpReceiver"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
Now write below in Activity.
public class BootUpReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent(context, MyActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
}
If by autostart you mean auto start on phone bootup then you should register a BroadcastReceiver for the BOOT_COMPLETED Intent. Android systems broadcasts that intent once boot is completed.
Once you receive that intent you can launch a Service that can do whatever you want to do.
Keep note though that having a Service running all the time on the phone is generally a bad idea as it eats up system resources even when it is idle. You should launch your Service / application only when needed and then stop it when not required.
I always get in here, for this topic. I'll put my code in here so i (or other) can use it next time. (Phew hate to search into my repository code).
Add the permission:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
Add receiver and service:
<receiver android:enabled="true" android:name=".BootUpReceiver"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<service android:name="Launcher" />
Create class Launcher:
public class Launcher extends Service {
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
new AsyncTask<Service, Void, Service>() {
#Override
protected Service doInBackground(Service... params) {
Service service = params[0];
PackageManager pm = service.getPackageManager();
try {
Intent target = pm.getLaunchIntentForPackage("your.package.id");
if (target != null) {
service.startActivity(target);
synchronized (this) {
wait(3000);
}
} else {
throw new ActivityNotFoundException();
}
} catch (ActivityNotFoundException | InterruptedException ignored) {
}
return service;
}
#Override
protected void onPostExecute(Service service) {
service.stopSelf();
}
}.execute(this);
return START_STICKY;
}
}
Create class BootUpReceiver to do action after android reboot.
For example launch MainActivity:
public class BootUpReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
Intent target = new Intent(context, MainActivity.class);
target.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(target);
}
}

How to start Alarm Manager on Device Reboot

I've have a simple app to schedule a notification 5 minutes after a button is pressed. It works fine for me. But if I restart the phone within that 5 minutes I don't get the notification. I have done a research on Alarm Manager and Scheduling Notifications on device reboots. I have a basic idea but I really don't know how to implement it into my project. I have 4 classes in my project. They are:
MainActivity
NotificationUtil
NotificationPublisher
NotificationView
This is the my NotificationUtil class:
public class NotificationUtil
{
public static void createNotification(Context context,Class<?> cls, String title, String content)
{
Intent intent = new Intent(context,cls);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
sendNotification(getNotification(pendingIntent,context,title,content),context);
}
private static void sendNotification(Notification notification,Context context)
{
Intent notificationIntent = new Intent(context, NotificationPublisher.class);
notificationIntent.putExtra(NotificationPublisher.NOTIFICATION_ID,1);
notificationIntent.putExtra(NotificationPublisher.NOTIFICATION,notification);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,0,notificationIntent,PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 5*60 * 1000,pendingIntent);
}
private static Notification getNotification(PendingIntent pendingIntent, Context context, String title, String content)
{
NotificationCompat.Builder builder = new NotificationCompat.Builder(context,"ChannelID");
builder.setSmallIcon(R.drawable.notification_bell);
builder.setContentTitle(title);
builder.setContentText("You have a Notification");
builder.setSubText("Tap To View");
builder.setStyle(new NotificationCompat.BigTextStyle().bigText(content));
builder.setContentIntent(pendingIntent);
return builder.build();
}
}
This is my NotificationPublisher class:
public class NotificationPublisher extends BroadcastReceiver {
public static String NOTIFICATION_ID = "notification_id";
public static String NOTIFICATION = "notification";
#Override
public void onReceive(final Context context, Intent intent) {
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = intent.getParcelableExtra(NOTIFICATION);
int notificationId = intent.getIntExtra(NOTIFICATION_ID, 1);
notificationManager.notify(notificationId, notification);
}
}
This is how I call the NotificationUtil class on button click in the MainActivity:
public class MainActivity extends AppCompatActivity {
private Button button;
private Context context;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = findViewById(R.id.notification);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
NotificationUtil.createNotification(MainActivity.this,NotificationView.class,"Notification","You have a new Task");
}
});
}
}
This is my manifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.notificationtest">
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<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"
tools:ignore="GoogleAppIndexingWarning">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".NotificationView"
android:parentActivityName=".MainActivity"/>
<receiver android:name=".NotificationPublisher">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<receiver android:name=".DeviceBootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
</manifest>
I have created a new DeviceBootReceiver class:
public class DeviceBootReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent)
{
if(intent.getAction().equals("android.intent.action.BOOT_COMPLETED"))
{
}
}
}
But I'm not sure what to put in the onReceive function. I tried putting this in the onReceive function
Intent pushIntent = new Intent(context, NotificationPublisher.class);
context.startService(pushIntent);
Works normal, but if I reboot my phone, after 5 minutes I get a message "The Application has stopped working"
I have a basic idea after having gone through these tutorials but I don't know how to implement them into my project
https://www.stacktips.com/tutorials/android/repeat-alarm-example-in-android
https://droidmentor.com/schedule-notifications-using-alarmmanager/
What I need is, to get the notification even after my phone is rebooted. If any one out there who could help me to achieve this, I would be grateful.
you need to create a BroadcastReceiver in order to be able to listen REBOOT event that is delivered by OS and then you can start your alarm manager there again
Well here is a complete example of an AutoStart Application.
Give permission of RECEIVE_BOOT_COMPLETED in manifest file, and register your broadcast for BOOT_COMPLETED.
AndroidManifest file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="pack.saltriver" android:versionCode="1" android:versionName="1.0">
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application android:icon="#drawable/icon" android:label="#string/app_name">
<receiver android:name=".autostart">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<activity android:name=".hello"></activity>
<service android:enabled="true" android:name=".service" />
</application>
</manifest>
autostart.java
public class autostart extends BroadcastReceiver
{
public void onReceive(Context context, Intent arg1)
{
// This callback will be fired automatically when device starts after boot
// Do your alarm alarm manager work here
}
}

Categories

Resources