Oreo Scheduling a Notification in an hour - android

In Android Oreo, I'm trying to schedule notifications at known future times. I wrote a small piece of code to test if I can schedule a notification in an hour when the app might be closed. When I try to do this, nothing happens. I really appreciate the help.
public class MainActivity extends AppCompatActivity {
private NotificationManager manager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
NotificationChannel notificationChannel = new NotificationChannel("default",
"primary", NotificationManager.IMPORTANCE_DEFAULT);
manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager.createNotificationChannel(notificationChannel);
Intent notifyIntent = new Intent(this, MyReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 1, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
long milisInFuture = 1000 * 60 * 60;
alarmManager.set(AlarmManager.RTC_WAKEUP, milisInFuture, pendingIntent);
}
public class MyNewIntentService extends JobIntentService {
#Override
protected void onHandleWork(#NonNull Intent intent) {
Notification notification = new Notification.Builder(getApplicationContext(), "default")
.setContentTitle("title")
.setContentText("body")
.setSmallIcon(android.R.drawable.stat_notify_chat)
.setAutoCancel(true)
.build();
manager.notify(123, notification);
}
}
public class MyReceiver extends BroadcastReceiver {
public MyReceiver() {
}
#Override
public void onReceive(Context context, Intent intent) {
Intent intent1 = new Intent(context, MyNewIntentService.class);
context.startService(intent1);
}
}
}
Here is the manifest if that helps.
<?xml version="1.0" encoding="utf-8"?>
<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=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".MainActivity$MyNewIntentService"
android:permission="android.permission.BIND_JOB_SERVICE"></service>
</application>
</manifest>

UPDATE:
Don't forget to add the receiver in the manifest xml file.
For this question:
Add in AndroidManifest.xml inside application tag:
<receiver android:name=".MyReceiver" />
Example:
I am keeping this example, it updates the notification from Broadcast Receiver class.
Create a broadcast receiver class as shown, (Don't forget to add the receiver in the manifest xml file)
public class NotificationUpdate extends BroadcastReceiver {
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
public void onReceive(Context context, Intent intent) {
//NEED A RESCHEDULE?
updateNotification(context);
}
#RequiresApi(api = Build.VERSION_CODES.O)
private void updateNotification(Context context){
Notification notification = new Notification.Builder(context.getApplicationContext(), "default")
.setContentTitle("title")
.setContentText("body")
.setSmallIcon(android.R.drawable.stat_notify_chat)
.setAutoCancel(true)
.build();
NotificationManager manager=(NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
if(manager!=null) manager.notify(123, notification);
}
}
Example Call from an Activity:
public class MainActivity extends AppCompatActivity {
final long intervalPeriod=60*1000;
AlarmManager mAlarmManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
NotificationChannel notificationChannel = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
notificationChannel = new NotificationChannel("default",
"primary", NotificationManager.IMPORTANCE_DEFAULT);
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (manager != null) manager.createNotificationChannel(notificationChannel);
mAlarmManager=(AlarmManager)getApplicationContext().getSystemService(ALARM_SERVICE);
PendingIntent intent=PendingIntent.getBroadcast(getApplicationContext(),1234,
new Intent(getApplicationContext(),NotificationUpdate.class),0);
mAlarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+intervalPeriod, intent);
}
}

Related

Alarms, whose trigger times are longer apart don't execute

My goal is to have the program set alarms and once each of the alarms is triggered, a specific audio is played.
The problem is that this works if the trigger time differences created by set_alarm are small, for instance if the first and the last trigger are less than 10 minutes apart.
But if the trigger time distance is greater than that, the triggers won't be activated after some time, ie no sound is played.
What do I need to change?
What I tried:
Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="myPackage">
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.SET_ALARM"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<application
...
android:supportsRtl="true">
<service android:name=".BService" android:stopWithTask="false" />
<activity
android:name=".MainActivity">
</activity>
<receiver android:name=".AudPlayer" android:exported="true" >
<intent-filter>
<action android:name="my.tag"></action>
<category android:name="android.intent.category.DEFAULT"></category>
</intent-filter>
</receiver>
</application>
</manifest>
MainActivity
package myPackage;
import ...
public class MainActivity extends AppCompatActivity {
AudPlayer ap;
Intent i_neu;
boolean running = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
intent = new Intent(this, AudPlayer.class);
ap = new AudPlayer();
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
IntentFilter intentFilter = new IntentFilter("my.tag");
intentFilter.addCategory(Intent.CATEGORY_DEFAULT);
registerReceiver(ap, intentFilter);
final ImageButton btnGO = (ImageButton) findViewById(R.id.btnGO);
btnGO.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (!running) {
running = true;
view.setSystemUiVisibility(View.SYSTEM_UI_FLAG_IMMERSIVE);
i_neu = new Intent(getApplicationContext(), BService.class);
Bundle ints = new Bundle();
ints.putInt(...);
i_neu.putExtras(ints);
startService(i_neu);
} else {
stopService(i_neu);
running = false;
}
}
});
}
}
BService
package package;
import ...
public class BService extends Service {
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#RequiresApi(api = Build.VERSION_CODES.O)
private void notificationDialog() {
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
...
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
notificationBuilder.setAutoCancel(true)
...
.setWhen(System.currentTimeMillis())
...
Notification not = notificationBuilder.build();
notificationManager.notify(1, not);
startForeground(1,not);
}
AudPlayer ap;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
final int whatever = intent.getIntExtra("whatever",0);
...
ap = new AudPlayer();
ap.init(this);
Calendar time = Calendar.getInstance();
time.setTimeInMillis(SystemClock.elapsedRealtime());
ap.set_alarm(this,time.getTimeInMillis(),R.raw.beginn);
time.setTimeInMillis(SystemClock.elapsedRealtime()+whatever);
....
ap.set_alarm(this,time.getTimeInMillis(),R.raw.beginn);
time.setTimeInMillis(SystemClock.elapsedRealtime()+whatever2);
ap.set_alarm(this,time.getTimeInMillis(),R.raw.beginn);
return START_STICKY;
}
}
AudPlayer
package myPackage;
import ...
public class AudPlayer extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "T");
wl.acquire();
final int ResID = intent.getIntExtra("ResID",0);
final long When = intent.getLongExtra("When",0);
MediaPlayer mediaPlayer = MediaPlayer.create(context, ResID);
AudioManager mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
mediaPlayer.start();
while (mediaPlayer.isPlaying()) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
wl.release();
}
AlarmManager alarmMgr;
Intent intent;
Bundle Resids;
public void init(Context context)
{
alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
intent = new Intent(context, AudPlayer.class);
Resids = new Bundle();
}
public void setAlarm(Context context, long When, int ResID)
{
Resids.putInt("ResID",ResID);
Resids.putLong("When",When);
intent.putExtras(Resids);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, (int)When, intent, PendingIntent.FLAG_ONE_SHOT);
alarmMgr.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, When, pendingIntent);
}
}

Service not starting in Android from AlarmManager after app is closed

Can anyone please correct my approach or suggest me the right ways for doing it.I have tried using broadcast receivers in place of services but that approach is not working for it.i.e I used getBroadcast() in place of getService() but didnt work.
It is working when the app is not closed from the application window but as soon as it is closed , the phone doesnt show notifications and ring as it was working in the case when the app wasn't closed.
MainActivity.class
`public class MainActivity extends AppCompatActivity {
TimePicker timePicker;
Button button;
AlarmManager alarmManager;
PendingIntent alarmIntent;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
timePicker = findViewById(R.id.timePicker);
button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Calendar calendar = Calendar.getInstance();
if (Build.VERSION.SDK_INT >= 23) {
calendar.set(
calendar.get(Calendar.YEAR),
calendar.get(Calendar.MONTH),
calendar.get(Calendar.DAY_OF_MONTH),
timePicker.getHour(),
timePicker.getMinute(),
0
);
} else {
calendar.set(
calendar.get(Calendar.YEAR),
calendar.get(Calendar.MONTH),
calendar.get(Calendar.DAY_OF_MONTH),
timePicker.getCurrentHour(),
timePicker.getCurrentMinute(),
0
);
}
Intent intent = new Intent(MainActivity.this,MyIntentService.class);
//This is the intent which will be fired
alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmIntent = PendingIntent.getService(getApplicationContext(), 0, intent, 0);
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), alarmIntent);
Log.e("TAG:","AlarmSet.");
// Log is showing the right statement i.e the alarm was set but it wasnt triggered when the app was closed from the application window
}
});
}
#Override
protected void onStart() {
super.onStart();
}
#Override
protected void onPause() {
super.onPause();
Log.e("TAG","OnPause.");
}
#Override
protected void onStop() {
super.onStop();
Log.e("TAG","OnStop.");
}
#Override
protected void onDestroy() {
super.onDestroy();
Log.e("TAG","OnDestroy.");
}
}`
IntentService.class
`public class MyIntentService extends IntentService {
public MyIntentService() {
super("MyIntentService");
}
#Override
protected void onHandleIntent(#Nullable Intent intent) {
Log.e("TAG", "Starting service for notification and song");
Random random = new Random();
final Notification notification = new NotificationCompat.Builder(getApplicationContext(), "notify")
.setContentTitle("New Notification")
.setContentText("TIme for task.")
.setSmallIcon(R.mipmap.ic_launcher_round)
.setPriority(Notification.PRIORITY_MAX)
.build();
final NotificationManager notificationManager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(random.nextInt(), notification);
MediaPlayer mediaPlayer = MediaPlayer.create(getApplicationContext(), Settings.System.DEFAULT_RINGTONE_URI);
mediaPlayer.start();
}
}`
Manifest file
`
<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=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".MyIntentService"
android:enabled="true"
android:exported="true" />
</application>
</manifest>`

firebase notification not showing in snackbar while app closed android

i want to show firebase push notification(sending firebase console) in activity's snackbar by broadcast receiver which i get from FirebaseMessagingService but i am unable to show.please help me.
Manifest:
<service android:name=".MyFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
firebase message service:
public class MyFirebaseMessagingService extends FirebaseMessagingService {
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
if(remoteMessage.getData().size()>0){
Log.v("Message data", remoteMessage.getData().toString());
}
if(remoteMessage.getNotification()!=null){
Log.v("MessageNotification", remoteMessage.getNotification().getBody().toString());
}
if(remoteMessage!=null){
sendNotification(remoteMessage.toString());
}
}
private void sendNotification(String messageBody){
Intent intent=new Intent(this,NotificationShowActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("FireBaseNotification",messageBody);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.notification_icon)
.setContentTitle("Notification")
.setContentText(messageBody)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
notificationShow Activity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_notification_show);
linearLayout=(RelativeLayout)findViewById(R.id.activity_notification_show);
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(broadcastReceiver);
}
#Override
protected void onStop() {
super.onStop();
}
#Override
protected void onDestroy() {
super.onDestroy();
}
#Override
protected void onResume() {
super.onResume();
registerReceiver(broadcastReceiver,new IntentFilter(MyFirebaseMessagingService.NOTIFICATION_SERVICE));
}
//broadcastReceiver
private BroadcastReceiver broadcastReceiver=new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String message=intent.getStringExtra("FireBaseNotification");
if(message!=null){
Toast.makeText(NotificationShowActivity.this,message,Toast.LENGTH_LONG).show();
}
}
};
}
To catch FCM messages in background your should use receiver, not service.
public class NotificationsReceiver extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
//handle your data
abortBroadcast(); //stop sending this broadcast to other receivers.
}
}
In your manifest (important - set priority to 999, to be first in receivers queue):
<receiver
android:name=".fcm.NotificationsReceiver"
android:exported="true"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter android:priority="999">
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</receiver>

Notification on every 5 minutes

I want to give the notification to user on every 5 minutes I am using following code.
it shows me notification first time but not give next time.
public void startAlarm() {
AlarmManager alarmManager = (AlarmManager) this.getSystemService(this.ALARM_SERVICE);
long whenFirst = System.currentTimeMillis(); // notification time
Intent intent = new Intent(this, NotifyUser.class);
PendingIntent pendingIntent = PendingIntent.getService(this, 0, intent, 0);
alarmManager.setRepeating(AlarmManager.RTC, whenFirst, 60*5000, pendingIntent);
}
public class NotifyUser extends Service {
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
super.onCreate();
loadNotification();
}
private void loadNotification() {
NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Notification notify = new Notification(R.drawable.ic_launcher/*android.R.drawable.stat_notify_more*/, "Hanumanji waiting for you", System.currentTimeMillis());
Context context = NotifyUser.this;
CharSequence title = "Hanumanji is waiting for you";
CharSequence details = "Do Hanuman Chalisa Parayan with ShlokApp.";
Intent intent = new Intent(context, NotifyUser.class);
PendingIntent pending = PendingIntent.getActivity(context, 0, intent, 0);
notify.setLatestEventInfo(context, title, details, pending);
notify.sound = Uri.parse("android.resource://pro.shlokapp.hanumanchalisa/"+ R.raw.game_sound_pause);
nm.notify(0, notify);
}
public int onStartCommand(Intent intent, int flags, int startId) {
return 1;
}
public void onStart(Intent intent, int startId) {
// TO DO
}
public IBinder onUnBind(Intent arg0) {
// TO DO Auto-generated method
return null;
}
public void onStop() {}
public void onPause() {}
#Override
public void onDestroy() {}
#Override
public void onLowMemory() {}
}
it shows me notification first time but not give next time. : The reason is you use nm.notify(0, notify);
Do not use 0 as it will show latest notification.
Below code works like a charm :
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MyTimerTask myTask = new MyTimerTask();
Timer myTimer = new Timer();
myTimer.schedule(myTask, 5000, 1500);
}
class MyTimerTask extends TimerTask {
public void run() {
generateNotification(getApplicationContext(), "Hello");
}
}
private void generateNotification(Context context, String message) {
int icon = R.drawable.ic_launcher;
long when = System.currentTimeMillis();
String appname = context.getResources().getString(R.string.app_name);
NotificationManager notificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
int currentapiVersion = android.os.Build.VERSION.SDK_INT;
Notification notification;
PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
new Intent(context, MainActivity.class), 0);
// To support 2.3 os, we use "Notification" class and 3.0+ os will use
// "NotificationCompat.Builder" class.
if (currentapiVersion < android.os.Build.VERSION_CODES.HONEYCOMB) {
notification = new Notification(icon, message, 0);
notification.setLatestEventInfo(context, appname, message,
contentIntent);
notification.flags = Notification.FLAG_AUTO_CANCEL;
notificationManager.notify((int) when, notification);
} else {
NotificationCompat.Builder builder = new NotificationCompat.Builder(
context);
notification = builder.setContentIntent(contentIntent)
.setSmallIcon(icon).setTicker(appname).setWhen(0)
.setAutoCancel(true).setContentTitle(appname)
.setContentText(message).build();
notificationManager.notify((int) when, notification);
}
}
}
Use Timer class. Change the timer interval as per your needs.
Hope this helps.
in this post How exactly to use Notification.Builder there is an example. I used it to make the notification in my app. It also use the NotificationBuilder from the support library.
I think in your code above, you are just updating the notification, that is already there. Try to check it by displaying a number that is increased by one every time you set/update a new notification.
Hope this will help you =).
MainActivity.java // It contains on a textview tvTime
public class MainActivity extends Activity {
private SampleAlarmReceiver alarm;
private ListView listView;
private ArrayList<String> times;
private ArrayAdapter mAdapter;
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
displayTime();
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.listView);
alarm = new SampleAlarmReceiver();
alarm.setAlarm(this);
times = new ArrayList<>();
Calendar c = Calendar.getInstance();
String time = c.get(Calendar.HOUR) + ":" + c.get(Calendar.MINUTE) + ":" + c.get(Calendar.SECOND);
times.add(time);
mAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, times);
listView.setAdapter(mAdapter);
}
#Override
protected void onResume() {
super.onResume();
LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
new IntentFilter("display_time"));
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
// When the user clicks START ALARM, set the alarm.
case R.id.start_action:
alarm.setAlarm(this);
return true;
// When the user clicks CANCEL ALARM, cancel the alarm.
case R.id.cancel_action:
alarm.cancelAlarm(this);
return true;
}
return false;
}
#Override
protected void onDestroy() {
super.onDestroy();
LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
}
#SuppressLint("SetTextI18n")
public void displayTime() {
Calendar c = Calendar.getInstance();
String time = c.get(Calendar.HOUR) + ":" + c.get(Calendar.MINUTE) + ":" + c.get(Calendar.SECOND);
times.add(time);
mAdapter.notifyDataSetChanged();
}
}
SampleAlarmReceiver.java
public class SampleAlarmReceiver extends WakefulBroadcastReceiver {
// The app's AlarmManager, which provides access to the system alarm services.
private AlarmManager alarmMgr;
// The pending intent that is triggered when the alarm fires.
private PendingIntent alarmIntent;
#Override
public void onReceive(Context context, Intent intent) {
Intent intent1 = new Intent("display_time");
// You can also include some extra data.
LocalBroadcastManager.getInstance(context).sendBroadcast(intent1);
}
// BEGIN_INCLUDE(set_alarm)
/**
* Sets a repeating alarm that runs once a day at approximately 8:30 a.m. When the
* alarm fires, the app broadcasts an Intent to this WakefulBroadcastReceiver.
*
* #param context given context
*/
public void setAlarm(Context context) {
alarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, SampleAlarmReceiver.class);
alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP,
5 * 60 * 1000, // After five minute
5 * 60 * 1000, // Every five minute
alarmIntent);
// Enable {#code SampleBootReceiver} to automatically restart the alarm when the
// device is rebooted.
ComponentName receiver = new ComponentName(context, SampleBootReceiver.class);
PackageManager pm = context.getPackageManager();
pm.setComponentEnabledSetting(receiver,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP);
}
/**
* Cancels the alarm.
*
* #param context given context
*/
public void cancelAlarm(Context context) {
// If the alarm has been set, cancel it.
if (alarmMgr != null) {
alarmMgr.cancel(alarmIntent);
}
// Disable {#code SampleBootReceiver} so that it doesn't automatically restart the
// alarm when the device is rebooted.
ComponentName receiver = new ComponentName(context, SampleBootReceiver.class);
PackageManager pm = context.getPackageManager();
pm.setComponentEnabledSetting(receiver,
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
}
}
SampleBootReceiver.java
public class SampleBootReceiver extends BroadcastReceiver {
SampleAlarmReceiver alarm;
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED"))
{
alarm = new SampleAlarmReceiver();
alarm.setAlarm(context);
}
}
}
main.xml // its a menu used in MainActivity
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/start_action"
android:title="Start Alarm"
app:showAsAction="ifRoom|withText" />
<item
android:id="#+id/cancel_action"
android:title="Stop Alarm"
app:showAsAction="ifRoom|withText" />
</menu>
manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.alarmmanager">
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".SampleAlarmReceiver" />
<receiver
android:name=".SampleBootReceiver"
android:enabled="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
</manifest>

Android Status bar notification every day at time

In my app, users have to fill in 9 different times with timepickers. These times are stored in a SQLite database. I want that users get a status bar notification when one of the times has been reached.
Example:
Users fill the first time in at 09:00.
If it is 09:00 in real time, users need to get a statusbar notification. I want that they don't need to start the app, it has to be automatic.
After spending more then 4 hours today at stackoverflow and other websites, I didn't succeed. I have tried the following code, but I didn't succeed. The notification is now set to 12:00. When the time reached 12:00, I didn't get a message.
MainActivity:
public class MainActivity extends Activity {
AlarmManager am;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Intent alarmIntent = new Intent(this, TimeAlarm.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 12);
calendar.set(Calendar.MINUTE, 00);
calendar.set(Calendar.SECOND, 00);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 5000, pendingIntent); } }
TimeAlarm.class:
public class TimeAlarm extends BroadcastReceiver {
NotificationManager nm;
#Override
public void onReceive(Context context, Intent intent) {
Intent startServiceIntent = new Intent(context, NotificationService.class);
context.startService(startServiceIntent);
}
}
NotificationService.class:
public class NotificationService extends Service {
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
handleIntent(intent);
return START_NOT_STICKY;
}
private NotificationManager nm;
private WakeLock mWakeLock;
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onDestroy() {
super.onDestroy();
mWakeLock.release();
}
private void showNotification() {
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("Test")
.setContentText("Test message");
Intent resultIntent = new Intent(this, MainActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(MainActivity.class);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(1, mBuilder.build());
}
private class PollTask extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
showNotification();
return null;
}
#Override
protected void onPostExecute(Void result) {
stopSelf();
}
}
private void handleIntent(Intent intent) {
PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
"NotificationsService");
mWakeLock.acquire();
ConnectivityManager cm = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
if (!cm.getBackgroundDataSetting()) {
stopSelf();
return;
}
new PollTask().execute();
}
AndroidManifest:
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.test.app"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission
android:name="com.test.app.permission.C2D_MESSAGE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<!-- This app has permission to register and receive data message. -->
<uses-permission
android:name="com.google.android.c2dm.permission.RECEIVE" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#android:style/Theme.Black.NoTitleBar.Fullscreen" >
<activity
android:name="com.test.app.MainActivity"
android:label="#string/app_name"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name="com.test.app.TimeAlarm">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
</manifest>
Try changing START_NOT_STICKY to START_STICKY;. If your service isn't sticky android does not try to restart it if it has to be killed to make room for other apps in memory.

Categories

Resources