How to prevent an app opened repeat - android

I use the following code to add an icon to Notification status, a user can click the icon to open the app ui.SMSMain.class, and the two ui.SMSMain.class apps will be opened if the user click the icon two times.
I hope the app only can be opened one time, how can I do?
private static void ShowNotification() {
NotificationManager notificationManager = (NotificationManager) myContext.getSystemService(android.content.Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(R.drawable.smsforward,
myContext.getString(R.string.app_name),
System.currentTimeMillis());
notification.flags |= Notification.FLAG_ONGOING_EVENT;
notification.flags |= Notification.FLAG_NO_CLEAR;
CharSequence contentTitle =myContext.getString(R.string.NotificationTitle);
CharSequence contentText = myContext.getString(R.string.NotificationContent);
Intent notificationIntent = new Intent(myContext, ui.SMSMain.class);
PendingIntent contentItent = PendingIntent.getActivity(myContext, 0,
notificationIntent, 0);
notification.setLatestEventInfo(myContext, contentTitle, contentText,contentItent);
notificationManager.notify(NotificationID, notification);
}

add launchMode attribute to your activity in the manifest as SingleTop
<activity
android:name="Tracking"
android:label="#string/app_name"
android:launchMode="singleTop">
....
this will allow only one instance of the activity, also it is better to use flag PendingIntent.FLAG_UPDATE_CURRENT in your pendingIntent
PendingIntent contentItent = PendingIntent.getActivity(myContext, 0,
notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
though, I am not sure if 0 actual refer to UPDATE_CURRENT
Update
you may need to choose among singleTop or singleTask according to your needs
for singleTop: if an instance of activity already exists at the top of the current task and system routes intent to this activity, no new instance will be created
for singleTask: A new task will always be created and a new instance will be pushed to the task as the root one. However, if any activity instance exists in any tasks, the system routes the intent to that activity instance through the onNewIntent() method call.
for more information about LaunchMode.
I believe that singleTop suits your problem better.

Related

Transaction to a specific fragment if we receive a push notification while app is running

Is it possible not launch new activity if we receive a push notification while the app is running?
My activity works with fragments and I want to do transition to a determinate fragment when the notification is received. My activity have data that I need to show the fragments. The problem is that when I receive the push notification while the app is running the method onDestroy is called and here I clear the data and then the app crash because the data are null. How can I do to not create new activity when the app receive a push notification while is running? In case the app is running I want that if you click the notification do a transition fragment, not create again the activity.
Thanks in advance.
First of all, I think that you mean "notification" to be a "message", but not android.app.Notification class.
And second, I don't think it's a best practise to raise new GUI when receiving a message, which would interrupt the user interaction. For details, please refer to: http://developer.android.com/training/notify-user/index.html and http://developer.android.com/design/patterns/notifications.html.
At last, if you really wanna do what you stated in your thread, I wonder why the data used to generate the show-data fragment is held in the activity. Try holding the data in an android.app.IntentService object, and then generate transfer the data to new activity, and then use android.app.Fragment.setArguments method to transfer the data from activity to fragment.
I think that this code will help you. This which you need is PendingIntent, it make transaction to desired activity.
/**
* Issues a notification to inform the user that server has sent a message.
*/
private static void generateNotification(Context context, String title,
String message) {
//get the default notification sound URI
Uri uriNotificationSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
//make intent to the application. if the application is opened just maximize it.
Intent homeIntent = new Intent(context, 'your desired activity');
homeIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
homeIntent, 0);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("eCommCongress")
.setContentText(message)
.setLights(Color.GREEN, 1500, 1500)
.setSound(uriNotificationSound)
.setAutoCancel(true)
.setContentIntent(contentIntent);
NotificationManager mNotificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
// mId allows you to update the notification later on.
mNotificationManager.notify(counter, mBuilder.build());
counter++;
}
It is perfectly possible and I do such a thing in one of my apps. First, you need to declare your activity as android:launchMode="singleTop",
Then, when you build you must configure your pending intent not to fire a new instance of your activity:
mNotificationManager = (NotificationManager)
this.getSystemService(Context.NOTIFICATION_SERVICE);
Intent intent = new Intent("YOUR ACTION HERE");
intent.setClassName(this, MainActivity.class.getName());
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent resultPendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this);
mBuilder.setContentIntent(resultPendingIntent);
Notification notification = mBuilder.build();
notification.defaults |= Notification.DEFAULT_VIBRATE | Notification.DEFAULT_LIGHTS;
notification.flags |= Notification.FLAG_SHOW_LIGHTS | Notification.FLAG_AUTO_CANCEL;
mNotificationManager.notify(idNotificacion,notification);
Now all you have to do is to override your onNewIntent inside your Activity and do whatever you want with your fragment:
#Override
protected void onNewIntent(Intent intent) {
MiLog.i(getApplicationContext(),"IntentShit","new intent received");
MiLog.i(getApplicationContext(),"IntentShit","Action: "+intent.getAction());
if(intent.getAction()!=null && intent.getAction().equals("YOUR ACTION HERE"){
//DO your stuff here
}
}
You should also take a look at this page for more info:
http://www.intridea.com/blog/2011/6/16/android-understanding-activity-launchmode

Launch An Activity Afresh(Don't Retain State) On A Notification Click

I want to launch an Activity(Afresh, Without any previously retained state) on a notification click. IF this Activity is already in the stack, bring this to top but without any previous state.
So Far i have tried setting Flags to Passed Intent.
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|INTENT.FLAG_ACTIVITY_SINGLE_TOP)
But They Don't serve the purpose. Any suggestions how i could achieve this.
If you remove |Intent.FLAG_ACTIVITY_SINGLE_TOP from your launch this should restart the activity.
Specifying |Intent.FLAG_ACTIVITY_SINGLE_TOP in the launch flags causes the existing instance to be reused. If you remove it the existing instance will be finished and a new instance will be launched.
Here You Go.
NotificationManager notificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(icon, message, when);
Intent notificationIntent = new Intent(context, HomeActivity.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent intent = PendingIntent.getActivity(context, 0,
notificationIntent, 0);
notification.setLatestEventInfo(context, title, message, intent);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(0, notification);
to open application in anystate.
Intent LaunchIntent = getPackageManager().getLaunchIntentForPackage("com.package.address");
startActivity(LaunchIntent);

Click on Notification doesn't start activity

I am creating a notification from a service; the notification is shown, but when I click on it, nothing happens: It was supposed to open an activity.
My code:
NotificationManager notificationManager = (NotificationManager)
getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(icon, "test", when);
Intent notificationIntent = new Intent(this, MainActivity.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent intent = PendingIntent.getActivity(this, 0,
notificationIntent,PendingIntent.FLAG_CANCEL_CURRENT);
notification.setLatestEventInfo(this, "title", "message", intent);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(0, notification);
However if I use pretty much the same code from inside an activity, I can click on the notification, and my activity is shown. What am I doing wrong?
EDIT:
It turns out that there was nothing wrong with this code, there was a different issue:
When my service finished, it created the notification with the code above. However, the service also broadcasted that it was finished, and the receiver created another notification, which used a different code to create the notification (with no PendingIntents, so no defined action when the notification is clicked), and that notification must have placed itself instead of the original, correct one.
On top of using Notification.Builder for above Android 3.0, or NotificationCompat.Builder in support library v4 as #Raghunandan suggests in the comment, I had the same problem with a possible common solution to your problem.
This is specific to 4.4 as seen here:Issue 63236:Notification with TaskStackBuilder.getPendingIntent() is not open the Activity and here Issue 61850: KitKat notification action Pending Intent fails after application re-install
One confirmed solution is to perform cancel() operation on an identical PendingIntent with the one you are about to create.
What worked for me was to modify the target Activity's manifest definition and add
android:exported="true" within "activity" tags for the target Activity. That would be MainActivity in your case I assume.
Example:
<activity
android:name="com.your.MainActivity"
android:exported="true" >
.
.
</activity>
This works with api level 8.
private int NOTIFICATION_ID = 1;
private Notification mNotification;
private NotificationManager mNotificationManager;
private PendingIntent mContentIntent;
private CharSequence mContentTitle;
you can create notification like this :
mNotificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
//create the notification
int icon = R.drawable.ic_launcher;
CharSequence tickerText = mContext.getString(R.string.noti_comes); //Initial text that appears in the status bar
long when = System.currentTimeMillis();
mNotification = new Notification(icon, tickerText, when);
//create the content which is shown in the notification pulldown
mContentTitle = mContext.getString(R.string.noti_comes_t); //Full title of the notification in the pull down
CharSequence contentText = clck_see_noti; //Text of the notification in the pull down
//you can set your click event to go to activity
mContentIntent = PendingIntent.getActivity(mContext, 0, new Intent(mContext, MainActivity.class), 0);
//add the additional content and intent to the notification
mNotification.setLatestEventInfo(mContext, mContentTitle, contentText, mContentIntent);
//make this notification appear in the 'Ongoing events' section
mNotification.flags = Notification.DEFAULT_LIGHTS | Notification.FLAG_AUTO_CANCEL ;
//show the notification
mNotificationManager.notify(NOTIFICATION_ID, mNotification);
and do not forget the your service is registering in the manifest
<service
android:name="com.xx.your_service"
android:enabled="true"
>
</service>
If you define an Activity that is not registered into the AndroidManifest.xml the notification will not show any error message, and nothin happen.
Intent notificationIntent = new Intent(this, MainActivity.class);
be sure to have the Activity to start from the notification registered into the AndroidManifest.xml
This guy had a similar problem "I misspelled my activity name in the manifest.":
launch activity from service when notification is clicked
Im my case my project use Android Annotations. So my error was when I created the Intent, I always set this:
Intent notificationIntent = new Intent(this, MainActivity.class);
But is necessary to set the Android Annotation's generated class:
Intent notificationIntent = new Intent(this, MainActivity_.class);
That's solves my problem

PendingIntent on Notification foreground service android

I have an activity in my app. When i click one option, start running my service foreground with a notification like this:
PendingIntent pi = PendingIntent.getActivity(getApplicationContext(), 0,
new Intent(getApplicationContext(), Radio.class),
PendingIntent.FLAG_UPDATE_CURRENT);
Notification notification = new Notification();
notification.tickerText = "Connecting RadiO!.. Wait..";
notification.icon = R.drawable.ic_launcher;
notification.flags |= Notification.FLAG_ONGOING_EVENT;
notification.setLatestEventInfo(getApplicationContext(), "radiO!",
"Playing: " + songName, pi);
startForeground(1, notification);
Then, still running my activity, I click on my notification and I opened it without closing the previous activity. I must not have the same activity twice.
What you are doing is creating a new instance of the activity you are trying to execute each time you click on the notification, in order to avoid it and reuse an already existing activity(if any), just set the activity as singleTask in the AndroidManifest.xml as shown below:
<activity
android:name=".YourActivity"
android:launchMode="singleTask"/>
Hope this helps.
Regards!

How to restore previous activity by clicking on notification

When my notification goes off I want to restore the activity that was put into the background, not start a new activity. I've seen some answers about using FLAGS but I don't know how to implement it
contentIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | INTENT.FLAG_ACTIVITY_SINGLE_TOP);
Where do I put this in my code? I tried but it didn't work. Please help!
ns = Context.NOTIFICATION_SERVICE;
mNotificationManager = (NotificationManager) getSystemService(ns);
icon = R.drawable.icon;
tickerText = "Short Msg";
when = System.currentTimeMillis();
notification = new Notification(icon, tickerText, when);
context = getApplicationContext();
contentTitle = "MyApp";
contentText = "Reopen App";
notification.defaults |= Notification.DEFAULT_SOUND;
notification.defaults |= Notification.DEFAULT_VIBRATE;
notificationIntent = new Intent(this, StartTimer.class);
contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
Figured it out, set the Activity to SingleTop or SingleInstance in Android Manifest, then instead of creating a new activity it just reopen the one still active.
Note that answer marked as correct is not completely correct as "singleTop" still may create multiple instances of your activity under certain conditions.
The launch modes that really are garanteed to create a UNIQUE instance of your activity at any condition are "singleTask" and "singleInstance".
These two options creates one and only task for your activity being the root of the task, with the difference that "singleInstance" don't allow other activities on top of yours, while "singleTask" does.
Source:
http://developer.android.com/guide/topics/manifest/activity-element.html#lmode

Categories

Resources