Alarm Manager in Broadcast Receiver - broadcast

It's possible to have Alarm Manager with Broadcast Receiver in One class without Activity like this:
public class AlarmReceiver extends BroadcastReceiver {
private static final int MY_NOTIFICATION_ID=1;
NotificationManager notificationManager;
Notification myNotification;
private final String myBlog = "http://android-er.blogspot.com/";
#Override
public void onReceive(Context context, Intent intent) {
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 11);
calendar.set(Calendar.MINUTE, 43);
calendar.set(Calendar.SECOND, 0);
Intent intent1 = new Intent(context, AlarmReceiver.class);
PendingIntent pendingIntent1 = PendingIntent.getBroadcast(context, 1,
intent1, 0);
AlarmManager alarmManager = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
pendingIntent1);
Intent myIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(myBlog));
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0,
myIntent, Intent.FLAG_ACTIVITY_NEW_TASK);
myNotification = new NotificationCompat.Builder(context)
.setContentTitle("Exercise of Notification!")
.setContentText("http://android-er.blogspot.com/")
.setTicker("Notification!").setWhen(System.currentTimeMillis())
.setContentIntent(pendingIntent)
.setDefaults(Notification.DEFAULT_SOUND).setAutoCancel(true)
.setSmallIcon(R.drawable.ic_launcher).build();
notificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(MY_NOTIFICATION_ID, myNotification);
}
}
and I would like to this Alarm Manager work without app on.

without app on , without Activity and without Service. No you can't. you need a context in which you will define your broadcast receiver. you can use the context of an activity or a service or the application.
You can creat the class like this , but then you should instantiate it somewhere in an activity ...

Related

Push notification after successful payment for mobile apps

I need help how to send push notifications on successful payment with transaction I'd to user
Use one of the background workers if you want to check the status of your transaction in background. I will use WorkManager.
implementation "android.arch.work:work-runtime:1.0.1"
public class SynchronizeWorker extends Worker {
static final String TAG = "MYWORKER";
public SynchronizeWorker(#NonNull Context context, #NonNull WorkerParameters workerParams) {
super(context, workerParams);
}
private Notification getNotification() {
NotificationManager mNotificationManager =
(NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel("default",
"WTF_CHANNEL",
NotificationManager.IMPORTANCE_DEFAULT);
channel.setDescription("WTF_CHANNEL_DESCRIPTION");
mNotificationManager.createNotificationChannel(channel);
}
// specify the class of the activity you want to open after click on notification
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(
getApplicationContext(),
0,
intent,
0);
return new NotificationCompat.Builder(getApplicationContext(), "default")
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(getApplicationContext().getResources().getString(R.string.notification_header))
.setContentText(getApplicationContext().getResources().getString(R.string.notification_text))
.setAutoCancel(true)
.setWhen(System.currentTimeMillis())
.setContentIntent(pendingIntent)
.build();
}
#NonNull
#Override
public Result doWork() {
Log.d(TAG, "status checking started");
// check your transaction status here and show notification
try {
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
Log.d(TAG, "status checking finished");
}
Log.d(TAG, "status checking finished");
NotificationManagerCompat
.from(getApplicationContext())
.notify((int)(Math.random() * 10), getNotification());
return Result.success();
}
}
And then enqueue worker where you want to check status
OneTimeWorkRequest myWorkRequest = new OneTimeWorkRequest.Builder(SynchronizeWorker.class).build();
WorkManager.getInstance().enqueue(myWorkRequest);
I understand that it is probably not exactly what you want, but hope it will help somehow:)

Notification "setSound()" in Android 8

Here's the question, the code of notification can't work with Android 8.
I can't set the notification sound myself. The only result it shows is the system sound "Bee".
Here's my code:
if(Build.VERSION.SDK_INT>=26) {
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
String id = "channel_1";
String description = "123";
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel mChannel = new NotificationChannel(id, "123", importance);
mChannel.enableLights(true);
mChannel.enableVibration(true);
mChannel.setLightColor(Color.GREEN);
mChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
AudioAttributes aa = new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_NOTIFICATION)
.setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
.build();
mChannel.setSound(Uri.parse("android.resource://com.example.lenovo.projectmonitor/" + R.raw.video11),aa);
manager.createNotificationChannel(mChannel);
Notification notification = new NotificationCompat.Builder(NotificationService.this, "channel_1")
.setContentTitle("new alarm")
.setContentText(nameAll.get(0))
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))
.setContentIntent(pi)
.setAutoCancel(true)
.build();
manager.notify(1, notification);
}
use setSound method in both NotificationChannel and NotificationCompat.Builder class. example
private void createNotificationChannel() {
// 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) {
CharSequence name = context.getString(R.string.channel_name);
String description = context.getString(R.string.channel_description);
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel channel = new NotificationChannel(channelId, name, importance);
channel.setDescription(description);
channel.setSound(null, null);
// Register the channel with the system; you can't change the importance
// or other notification behaviors after this
NotificationManager notificationManager = context.getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
}
}
and creating buileder:
public void buildNotification(Class className, int smallIconId) {
createNotificationChannel();
// Create an Intent for the activity you want to start
Intent intent = new Intent(context, className);
intent.setAction(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
// Create the TaskStackBuilder and add the intent, which inflates the back stack
// TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
// stackBuilder.addNextIntentWithParentStack(intent);
//// Get the PendingIntent containing the entire back stack
// PendingIntent pendingIntent =
// stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder
.setSmallIcon(smallIconId)
.setContentTitle("Recording Audio..")
// .setContentText("Much longer text that cannot fit one line...")
// .setStyle(new NotificationCompat.BigTextStyle()
// .bigText("Much longer text that cannot fit one line..."))
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setSound(null)
.setContentIntent(pendingIntent)
.setAutoCancel(true);
// notificationId is a unique int for each notification that you must define
// notificationManager.notify(notificationId, mBuilder.build());
// mBuilder.setContentTitle("changed it");
// notificationManager.notify(notificationId, mBuilder.build());
// mHandler.postDelayed(new Runnable() {
// #Override
// public void run() {
// }
// }, 3000);
}

Android: How to fix BroadcastReceiver in JobIntentService?

I have an Activity with an AlarmManager that fires a BroadcastReceiver. The BroadcastReceiver fires a JobIntentService to send a Notification to the user.
When the user taps "CLEAR ALL" or swipes to dismiss the Notification, I want the setDeleteIntent() to reset a counter variable "totalMessages" to zero that I set up in a SharedPreferences file. It is not resetting to zero. What am I missing here?
public class AlarmService extends JobIntentService {
static final int JOB_ID = 9999;
public static final String NOTIFICATIONS_COUNTER = "NotificationsCounter";
private static final int REQUEST_CODE_DELETE_INTENT = 1;
int totalMessages = 0;
static void enqueueWork(Context context, Intent work) {
enqueueWork(context, AlarmService.class, JOB_ID, work);
}
#Override
protected void onHandleWork(#NonNull Intent intent) {
IntentFilter filter = new IntentFilter();
filter.addAction("notification_cleared");
registerReceiver(receiver, filter);
sendNotification();
}
private void sendNotification() {
int notifyID = 1;
NotificationManager notificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
SharedPreferences sp = getSharedPreferences(NOTIFICATIONS_COUNTER, Context.MODE_PRIVATE);
totalMessages = sp.getInt("total-messages", 0); //initialize to 0 if it doesn't exist
SharedPreferences.Editor editor = sp.edit();
editor.putInt("total-messages", ++totalMessages);
editor.apply();
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
.setDefaults(Notification.DEFAULT_ALL)
.setSmallIcon(R.drawable.ic_announcement_white_24dp)
.setContentText("")
Intent i = new Intent(this, AlarmService.class);
i.setAction("notification_cleared");
PendingIntent deleteIntent = PendingIntent.getBroadcast(this,REQUEST_CODE_DELETE_INTENT,i,PendingIntent.FLAG_CANCEL_CURRENT);
mBuilder.setDeleteIntent(deleteIntent);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
mBuilder.setSubText(String.valueOf(totalMessages));
}
else {
mBuilder.setNumber(totalMessages);
}
if (notificationManager != null) {
notificationManager.notify(notifyID, mBuilder.build());
}
}
private final BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action != null) {
if (action.equals("notification_cleared")) {
// Reset the Notifications counter ("total-messages") to zero since the user
// clicked on "CLEAR ALL" Notification or swiped to delete a Notification.
SharedPreferences sp1 = getSharedPreferences(NOTIFICATIONS_COUNTER, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp1.edit();
editor.clear();
editor.apply();
totalMessages = sp1.getInt("total-messages", 0); //initialize to 0 if it doesn't exist
editor.putInt("total-messages", totalMessages);
editor.apply();
}
}
}
};
#Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(receiver);
}
}
The problem is that your broadcast receiver's implementation to clear notifications is within the life-cycle of job. JobIntentService is tasked to show notification and go away thus the broadcast receiver. But when the user clicks on the CLEAR from notification, the pending intent is broadcasted but then there's no one to listen to it.
For a solution, I would suggest you to create a separate broadcast receiver and register it in your AndroidManifest.xml. By then your broadcast will always be listened and you can perform what ever within..

Android AlarmManager Pass extra from activity to service

I have tried to follow many links but no matter what my extras keep being null. First I have an activity (MainActivity) that will set up a notification using a service (NotifyService). I can get the service to be and the notification to appear at the appropriate time. However passing a string seems to be a problem.
In MainActivity onCreate() I have:
Intent myIntent = new Intent(this, NotifyService.class);
//this is what I would like to pass over
myIntent.putExtra("newtitle" ,"this is the new title");
myIntent.putExtra("newcontent" ,"this is the new content");
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
PendingIntent pendingIntent = PendingIntent.getService(this, 0, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MINUTE, 25);
calendar.set(Calendar.HOUR, 11);
calendar.set(Calendar.AM_PM, Calendar.PM);
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
Toast.makeText(MainActivity.this, "Set Alarm", Toast.LENGTH_LONG).show();
In My NotifyService onCreate I have:
Intent intent = new Intent(this.getApplicationContext(),MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,intent, PendingIntent.FLAG_UPDATE_CURRENT);
//this will be null or give me errors every time
// if (intent.getExtras().containsKey("newtitle"))
// title=(String) intent.getExtras().get("newtitle");
// if (intent.getExtras().containsKey("newcontent"))
// content=(String) intent.getExtras().get("newcontent");
NotificationCompat.Action action = new NotificationCompat.Action.Builder(
R.drawable.basketball, getString(R.string.wearTitle), pendingIntent
).build();
Uri sound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Notification notification = new NotificationCompat.Builder(this)
.setContentText(content)
.setContentTitle(title)
.setSmallIcon(R.drawable.basketball)
.setSound(sound)
.extend(new NotificationCompat.WearableExtender().addAction(action))
.build();
NotificationManagerCompat notificationManagerCompat = NotificationManagerCompat.from(this);
notificationManagerCompat.notify(001, notification);
Mainly I've been following this tutorial: https://www.youtube.com/watch?v=tyVaPHv-RGo.
I've also looked at this link: How can I correctly pass unique extras to a pending intent?
I have tried many things with the PendingIntent flags but still no luck. I've seen it done with intents and services but nothing with pending intents.
Thanks a lot
Turns out instead on using it on create, I have to use onStartCommand. Here's the code:
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
Toast.makeText(this, "Starting..", Toast.LENGTH_SHORT).show();
Log.d("0",intent.getStringExtra("newtitle"));
title = intent.getStringExtra("newtitle");
content = intent.getStringExtra("newcontent");
Intent myintent = new Intent(this.getApplication(), MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,myintent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Action action = new NotificationCompat.Action.Builder(
R.drawable.basketball, getString(R.string.wearTitle), pendingIntent
).build();
Uri sound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Notification notification = new NotificationCompat.Builder(this)
.setContentText(content)
.setContentTitle(title)
.setSmallIcon(R.drawable.basketball)
.setSound(sound)
.extend(new NotificationCompat.WearableExtender().addAction(action))
.build();
NotificationManagerCompat notificationManagerCompat = NotificationManagerCompat.from(this);
notificationManagerCompat.notify(001, notification);
return PendingIntent.FLAG_UPDATE_CURRENT; // or whatever your flag
}
Got it from: Pass data from Activity to Service using an Intent

NotificationCompat.Builder and startForeground

This works: IntentService with NotificationCompat.Builder providing a notification to use with NotificationManager.notify() .setContentIntent(pendingIntent) is needed. When notify is sent, the notification appears in the notification AND IS PERSISTENT (stays alive until the user clicks it, at which point it starts the activity specified in .setContentIntent). Good!
What does not work: I would like the service to be long-lived like a phone-service, so startForeground() would seem advised. However, when I include that, the associated notification does indeed appear in the tray as it should, but it is NOT PERSISTENT and disappears when the IntentService ends (unlike above). (The associated notification also uses .setContentIntent and starts another Activity.)
Any thoughts? It is critical that the service not die until it detects a certain (rare) "event". It is also critical that the notification remains alive until the user responds by clicking it!
Here is the boiled-down code (latter case): Thanks!
public class SService extends IntentService {
public SService() {
super("SService");
}
#Override
protected void onHandleIntent(Intent sIntent) {
//Notification construction:
Notification notif;
Context context = this;
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Intent bIntent = new Intent(context, BarNotifActivity.class);
PendingIntent pbIntent = PendingIntent.getActivity(context, 0, bIntent,0);
Notification barNotif;
NotificationCompat.Builder bBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle(getString(R.string.bar_title))
.setContentText(getString(R.string.bar_text))
//.setAutoCancel(true)
.setOngoing(true)
.setContentIntent(pbIntent);
barNotif = bBuilder.build();
this.startForeground(1, barNotif);
long[] vibration = {0, 300, 1000, 300, 1000, 300, 1000, 300, 1000};
Intent mIntent = new Intent(context, NotifReceiverActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(context, 0, mIntent,0);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle(getString(R.string.alert_text))
.setContentText(getString(R.string.alert_text))
.setTicker("**Notification Arrived!**")
.setVibrate(vibration)
//.setAutoCancel(true)
.setOngoing(true)
.setContentIntent(pIntent);
notif = mBuilder.build();
notif.flags |= Notification.FLAG_AUTO_CANCEL;
notif.flags |= Notification.FLAG_INSISTENT;
try {
Thread.sleep(7000); //Pause 7 sec.
} catch (InterruptedException e) {
e.printStackTrace();
}
mNotificationManager.notify(1, notif);
}
}