I am trying to start an activity from the Android Jobservice and it was not starting.
When I start an activity from the notification builder with addAction method I am able to do it but the same I have to do it without any user consent and here I am fail.
final Intent intent1 = Intent intent = new Intent(context, onActivity.class);
final PendingIntent pendingIntent = PendingIntent.getActivity(this, "1",
intent1 , PendingIntent.FLAG_ONE_SHOT);
if(acceptvalid) {
mBuilder.setContentTitle(getString(R.string.app_name))
.setContentText(getString(R.string.on))
.setSmallIcon(R.drawable.icon)
.setDefaults(Notification.DEFAULT_ALL)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setAutoCancel(true)
.addAction(R.drawable.ic_yes, getString(android.R.string.yes), installPendingIntent);
notificationManager.notify(1, mBuilder.build());
} else {
try{
installPendingIntent.send();
} catch (PendingIntent.CanceledException e) {
LOG.error("error starting activity.", e);
}
}
the above if loop code works for me and else is not working. I even tried the below code in else loop
intent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
this.startActivity(intent1 );
Some one can point out my error or give any suggestion.
Thank you in advance.
From Android 10 background apps are not allowed to start activities directly. Instead they need to show notification to user and get user consent. An exception to this is If your app has SYSTEM_ALERT_WINDOW permission granted.
See
https://developer.android.com/guide/components/activities/background-starts
Related
Here's code that's supposed to dismiss the alarm by it's label:
Intent intent = new Intent(AlarmClock.ACTION_DISMISS_ALARM);
intent.putExtra(AlarmClock.EXTRA_ALARM_SEARCH_MODE, AlarmClock.ALARM_SEARCH_MODE_LABEL);
//intent.putExtra(AlarmClock.ALARM_SEARCH_MODE_TIME,1);
//intent.putExtra(AlarmClock.EXTRA_IS_PM, true);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(AlarmClock.EXTRA_MESSAGE, "Label");
if(intent.resolveActivity(getPackageManager()) != null){
startActivity(intent);
} else {
Toast.makeText(SetAlarmActivity.this, "There is no app that support this action", Toast.LENGTH_SHORT).show();
}
Unfortunately, it just opens the default alarm app and doesn't even dismiss the alarm I need. How to make it work correctly?
That code is doing what it's supposed to do. It's opening the intent you specified- the alarm clock app.
I'm assuming you set an alarm via AlarmManager and want to cancel that? If so, the code is:
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent myIntent = new Intent(getApplicationContext(), YourBroadcastReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
getApplicationContext(), REQUEST_CODE, myIntent, 0);
alarmManager.cancel(pendingIntent);
Make sure the request code is the same as you started.
If you actually set an alarm via the alarm app and wanted to cancel it- I'm not sure there is a way without involving the user.
I am using the onDestroy method, which I have learned is not always called when app is closed. And this has created a problem for me, where I would like to have the notification pop up every time the app closed. Is there a better way to do this? By the way, onStop and onPause are not options for me, because my app runs as a background service. Interestingly, my onDestroy method works everytime my background service is running, but whenever it is turned off, and just the app interface is open, my onDestroy never is called. This seems weird because I thought that onDestroy isn't called if the device is lacking resources, and running my service would be taking up more resources than not. Idk. Any help on this would be greatly appreciated!
`#Override
public void onDestroy(){
super.onDestroy();
Log.d("asdasd","asdasdasdasdasd");
if(notif.isChecked()) {
Intent intent1 = new Intent(this, MainActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent1, 0);
Notification noti = new Notification.Builder(this)
.setContentTitle("S-Dimmer")
.setContentText(getResources().getString(R.string.sDimmerStopped))
.setSmallIcon(R.drawable.ic_action_name1)
.setContentIntent(pIntent).getNotification();
noti.flags = Notification.FLAG_NO_CLEAR;
NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
nm.notify(0, noti);
doas.isRunning = false;
}
}`
This method is not always called, so you should try from background service, as there's also some destruction process alert.
So please try to do what ever you want there in the services.
Please check out this ..
onDestroy() may or may not be called on any given activity or service. The general rule is that either onDestroy() is called, or your process is terminated, or your code crashed.
You don't. Your process may be terminated for any reason, at any time, by the user or by the OS. You may or may not be called with onDestroy() when that occurs. While you may be able to improve your success rate a little via onTaskRemoved() on a Service, this itself has proven unreliable, and it will not cover all scenarios.
you are doing it wrong way. In onDestroy method all other stuffs should implemented before super.onDestory()
try this
#Override
public void onDestroy(){
Log.d("asdasd","asdasdasdasdasd");
if(notif.isChecked()) {
Intent intent1 = new Intent(this, MainActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent1, 0);
Notification noti = new Notification.Builder(this)
.setContentTitle("S-Dimmer")
.setContentText(getResources().getString(R.string.sDimmerStopped))
.setSmallIcon(R.drawable.ic_action_name1)
.setContentIntent(pIntent).getNotification();
noti.flags = Notification.FLAG_NO_CLEAR;
NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
nm.notify(0, noti);
doas.isRunning = false;
}
super.onDestroy();
}`
onTaskRemoved()
{
if(notif.isChecked()) {
Intent intent1 = new Intent(this, MainActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent1, 0);
Notification noti = new Notification.Builder(this)
.setContentTitle("S-Dimmer")
.setContentText(getResources().getString(R.string.sDimmerStopped))
.setSmallIcon(R.drawable.ic_action_name1)
.setContentIntent(pIntent).getNotification();
noti.flags = Notification.FLAG_NO_CLEAR;
NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
nm.notify(0, noti);
doas.isRunning = false;
}
}
I'm writing here because I'm facing a probleme that I could not resolve even after many researches and tries.
I'm currently developing an Android Library which consists only of java classes and fragment. The problem is I need to send Local Notifications to the user, and clicking on the notifications should send the user back to the activity where he was. At this point, my library sends the notifications just fine. But the click on the notification doesn't have any action.
In my notification reciver class (which extends the BroadcastReceiver class), when the notification appears, I create a Pending Intent but I don't know what I can give as parameters to send the user to the activity. I tried using intent filters but it give me no results
So how can I have the notification sending back the user to the application ? The best would be if I was able to have the notification sending back the user to the activity where the notification is created (but it's a fragment so...)
In an usual app, I would've an intent sending back the user to an activity class but my library needs to have only fragments.
Maybe there is no problem and the solution is easy since I'm new to notifications
If someone here have an idea thanks for helping me ! :D
And if my problem isn't clear (Because of my bad english as an example) don't hesitate to ask me to add informations ^^
**Edit from 29 April : **
I managed to achieve it by giving to my broadcast pending intent the canonical name of my class using :
mContext.getClass().getCanonicalName();
Once in my broadcast receiver class I just get the class from the name of the sending class :
Class<?> activityClass = null;
try {
activityClass = Class.forName(stringSourceClass);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Check out below code...
public BroadcastReceiver batteryReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
try {
String title = context.getString(R.string.app_name);
Intent intent1 = new Intent(context, YourActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(),1,intent1,PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle(title)
.setContentText("Hello")
.setAutoCancel(false)
.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(1, notificationBuilder.build());
} catch (Exception e) {
}
}
};
check the Building a notification page:
Intent resultIntent = new Intent(this, ResultActivity.class);
...
// Because clicking the notification opens a new ("special") activity, there's
// no need to create an artificial back stack.
PendingIntent resultPendingIntent =
PendingIntent.getActivity(
this,
0,
resultIntent,
PendingIntent.FLAG_UPDATE_CURRENT
);
just put your activity in resultIntent
how can I have the notification sending back the user to the
application ?
That's pretty simple:
1. While creating intent for pending intent call addAction ("action_name") method;
2. In activity you want to call (in manifest file) inside intent-filter tag add <action android:name="action_name>.
Now when your notification try to launch activity it would send intent message to system, which would search activity with proper action and launch it.
P.S. action name must be unique for every application
I have sync adapter that performs some operation in background. To notify my main activity about sync operation status, I used broadcast receivers, so my activity is able to receive messages from sync adapter. It works fine. However, I also need to display notification on android status bar, that indicates some sync results.
So I wrote simple method reponsible to disaply system notification:
private void sendNotification(Context ctx, String message)
{
Intent intent = new Intent(ctx, this.getClass());
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent.FLAG_ONE_SHOT);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(ctx)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("Mobile Shopping")
.setContentText(message)
.setAutoCancel(true)
.setDefaults(Notification.DEFAULT_SOUND | Notification.FLAG_SHOW_LIGHTS)
.setLights(0xff00ff00, 300, 100)
.setPriority(Notification.PRIORITY_DEFAULT);
//.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 , notificationBuilder.build());
}
Then, above method is called in onPerform sync:
#Override
public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult)
{
.................
sendNotification(context, message);
}
Context is retrieved from constructor. It works without any problems, notification is showing.
However I also need to show main activity after user cicks on notification. So I believe I need to create PendingIntent and pass it to my notification builder (as it's commented in my code). But to pass main activity object to my sync adapter? Notification can be also displayed after auto sync finished.
Any tips?
So, I figured it out. Solution is to create pending intent this way:
Intent notificationIntent = new Intent(ctx, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(ctx, 0, notificationIntent, 0);
So after user clicks to notification, main activity will be shown.
I wrote an app and I set an alarm manager which set to send a notification every 3 hours. Assume my notification has to be send at 11:10 and my phone is getting off at 11:00. So, I will not receive any notification. When my phone is turned on, I will receive the next notification at 2:10, so everything is working correctly.
Although, it was observed that I will not receive any notification after my phone is getting off for two round of notification. Do you have any suggestion?
The code is provided:
Intent intentAlarm = new Intent(this, NotifyBroadcast.class);
PendingIntent pintentAlarm = PendingIntent.getBroadcast(this, 0, intentAlarm, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager mgr = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
// Start every 30 seconds
mgr.setRepeating(AlarmManager.RTC_WAKEUP, Calendar.getInstance().getTimeInMillis(), 300, pintentAlarm);
// NotifyBroadcast:
public class NotifyBroadcast extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
NotificationManager mNotificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Intent resultIntent = new Intent(context, MainActivity.class);
PendingIntent resultPendingIntent =
PendingIntent.getActivity(
context,
0,
resultIntent,
0
);
Notification notification = new Notification(R.drawable.ic_launcher, "Let me know what is your emotion buddy!", System.currentTimeMillis());
notification.defaults |= Notification.DEFAULT_SOUND;
notification.sound = Uri.parse("file:///sdcard/notification/notification.mp3");
//notification.flags = Notification.FLAG_AUTO_CANCEL;
notification.setLatestEventInfo(context, "emotion interface", "Let me know what is your emotion buddy!", resultPendingIntent);
int mId = 001;
// mId allows you to update the notification later on.
mNotificationManager.notify(mId, notification);
// mNotificationManager.notify(mId,mBuilder.build());
// mNotificationManager.cancel(mId);
}
}
I didn't understand following part very well :
I will not receive any notification after my phone is getting off for two round of notification .
Just check that you are relaunching your service after reboot. For that you need to add a receiver that launches your Service again after the reboot. You need to handle that on android.intent.action.BOOT_COMPLETED intent broadcast. Some of the questions that might help you are:
Android: make notification persist across phone reboot
android notification after reboot
Android: why did the Alarm notification stop after system reboot
Hope this helps in some way.