Prevent activity run from recent app list in android - android

I have an activity A which start when a custom broadcast received. This activity is not the launcher activity.
receiver
#Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent(context,A.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.putExtras(intent.getExtras());
context.startActivity(i);
}
A receive the intent value (Intent has some values) and full fill some task. The whole procedure is working fine.
Problem is that, when i open recent application list (Long press home button) this activity appears (not a launcher activity) and when i click on it, activity start with intent value !!. So i can't check is this activity start from broadcast receiver or from other.
How can i fix this?? This activity should only start when a broadcast receive.
Edit
Manifest
android:name".A"
android:screenOrientation="portrait"
android:launchMode="singleInstance"
android:noHistory="true"
android:taskAffinity=""

Did you try:
android:name".A"
android:excludeFromRecents="true"
This will prevent your activity from being displayed in recent list.

See this
when your activity is the root of a new task, it will not appear in the recent list. if it's not the root , try adding taskAffinity property.

Related

i am Trying more Flags to prevent the Activity to be opened more than one time at the Same time

i tried Flags like
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |Intent.FLAG_ACTIVITY_CLEAR_TASK);
i Login to my application and open the home page > when i receive a notification and preessed on it to see details at home page it opened well But the previous
You can achieve this with the help of launch mode
go to manifest where your activity is declared.
And add following attribute to your activity declaration.
android:launchMode="singleTask"
And in your activity class ovveride following method
public void onNewIntent(Intent intent) {
setIntent(intent);
//do other stuff with new intent
}
I will also suggest you to read more about activity launch mode https://developer.android.com/guide/topics/manifest/activity-element.html

Animate Android app launched from Service

I am launching an activity from a Service using the normal pattern:
Intent i = new Intent(getApplicationContext(), MyActivity.class);
startActivity(i);
I want to animate that launch e.g. slide in from left.
From an Activity, you can use Activity.overridePendingTransition().
Is there a way to animate an activity launch from a Service?
I went with the workaround of placing my own activity into the launch process.
My Service launches my HelperActivity with extras in the intent identifying the task I wish to launch/bring to front.
HelperActivity launches the actual task in onCreate(), animating the change with overridePendingTransition(). Then calls finish() in order to remain hidden.
Obviously HelperActivity needs to remain hidden from the backstack, so the manifest reflects this.
There are also security concerns to this naive method - see related post by Commonsware:
Beware Accidental APIs
This type of activity should be as secure as possible. For my demo version, I'm happy to just set android:exported="false".
Manifest Code:
<activity
android:name=".SwitchAnimationHelperActivity"
android:excludeFromRecents="true"
android:exported="false"
android:noHistory="true" >
</activity>
HelperActivity Code:
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
String componentName = getIntent().getStringExtra("TASK_ID_API");
Intent newTask = new Intent(Intent.ACTION_MAIN);
newTask.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
newTask.setComponent(ComponentName.unflattenFromString(componentName));
startActivity(newTask);
overridePendingTransition(R.anim.anim_zoom_in, R.anim.anim_slide_out_left);
// job is done
finish();
}
So there it is - one way to animate the launch of a task from a Service.

android : How to work around the fact that a singleInstance activity cannot expect to rely onActivityResult when starting subActivity?

I am making an android application, which has the following execution flow:
A service registers a PendingIntent with the AlarmManager
When the alarm is launched, a Receiver receives the intent, and (given some conditions) calls startsActivity() for my Main Activity, which in the manifest has been declared as android:launchMode="singleInstance". Note that for this call to work, the intent passed should have an Intent.FLAG_ACTIVITY_NEW_TASK
When started, Main Activity modifies itself a bit, and calls startActivityForResult for an Activity, which we'll call WebviewActivity (because it contains a webview, but that's besides the point)
When the user is done interacting with theWebViewActivity, setResult() and finish() are called on it, and one would expect for MainActivity.onActivityResult() to be called.
But of course this does not happen, as has been documented in many discussions here, the reason apparently being that an Activity launched from a singleInstance Activity, runs in a different Task.
A solution I think would be to have the WebActivity start the MainActivity instead.
The question is, is there a way to maintain onActivityResult being called at the right time? In that case, which aspects from the starting point of the execution flow should change?
Please note that MainActivity should not have multiple instances at the same time (it is basically an interface to the service) but if its launchMode is set to standard, the Receiver, because of the FLAG_ACTIVITY_NEW_TASK that is required, will do just that.
Manifest declaration of MainActivity:
<activity android:name=".activities.MainActivity"
android:label="#string/app_name"
android:launchMode="singleInstance"
android:configChanges="keyboardHidden|orientation|screenSize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
android:uiOptions=”splitActionBarWhenNarrow”
</activity>
Receiver launches MainActivity by calling
onReceive(Context context, Intent intent)
{
intent.setClass(context, MainActivity.class);
int flag = Intent.FLAG_ACTIVITY_NEW_TASK;
intent.setFlags(flag);
context.startActivity(intent);
}
I use the following workaround for this problem:
Activity A is the caller
Activity B is the singleInstance activity from which I want the result
In activity A I register a broadcast receiver as following
PickReceiver receiver=new PickReceiver();
IntentFilter filter=new IntentFilter();
filter.addAction("ActivityA_pick");
registerReceiver(receiver,filter);
class PickReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
if(intent.getAction().equals("ActivityA_pick")){
//get data from intent extras
}
}
In ActivityB when it's time to send the data I use:
sendBroadcast("ActivityA_pick").putExtra("...data...");
finish();
This way i can get the result I want when I want a result from one of my own activities. If you want a result from the system or another app you can adjust this using a dummy activity that doesn't have launch mode singleInstance, have it start the activity for result and when it gets it onActivityResult it sends the broadcast to the caller.
Hope this helps
As the Main Activity is a single instance, is doing what it has been told.
So yes, you have to start the Main Activity from the Web Activity in order to be coherent with the tasks executions

Start Activity in a BroadcastReceiver

I've built a small app. The only thing it does is, catch an outgoing call and show some activity when it happens. There is just an Activity and a BroadcastReceiver.
I wanted to integrate my code with another application, I removed the BroadcastReceiver from the Manifest.xml and created (and registered) it dynamically from the main activity. My receiver fired well but the activity is not shows up.
What is the difference between the two methods?
How can I make the activity to show up?
from MainActivity.java:
callInterceptor = new InterceptOutgoingCall();
IntentFilter callInterceptorIntentFilter = new IntentFilter("android.intent.action.NEW_OUTGOING_CALL");
callInterceptorIntentFilter.setPriority(100);
registerReceiver(callInterceptor, callInterceptorIntentFilter);
and from the function receiver.onReceive(Context,Intent):
Intent alertIntent = new Intent(context, AlertActivity.class);
alertIntent.putExtra("callnumber", phonenbr);
alertIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(alertIntent);
my activity is declared in the manifest like this:
<activity android:name=".AlertActivity"
android:screenOrientation="portrait"/>
I found the answer at two threads:
Android launch an activity from a broadcast receiver
Activity started from notification opened on top of the activity stack
In the manifest, the activity should be declared with android:taskAffinity.
And when starting the intent I had to add a flag = Intent.FLAG_ACTIVITY_NEW_TASK

Prevent opening Activity for multiple times

I have a common menu on my app with icons. Clicking an icon will start an Activity. Is there a way to know if an activity is already running and prevent it from starting multiple times (or from multiple entries)? Also can I bring an activity that is in onPause state to the front?
Use this:
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
while starting Activity.
from documentation:
If set in an Intent passed to Context.startActivity(), this flag will
cause the launched activity to be brought to the front of its task's
history stack if it is already running.
In your activity declaration in Manifest file, add the tag android:launchMode="singleInstance"
I got it perfectly working by doing the following.
In the caller activity or service (even from another application)
Intent launchIntent = getPackageManager().getLaunchIntentForPackage(APP_PACKAGE_NAME);
//the previous line can be replaced by the normal Intent that has the activity name Intent launchIntent = new Intent(ActivityA.this, ActivityB.class);
launchIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT|Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(launchIntent);
and in the manifest of the receiver activity (the I want to prevent opening twice)
<activity android:name=".MainActivity"
android:launchMode="singleTask"
>
This works for me :
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
from official documentation
If set, and the activity being launched is already running in the
current task, then instead of launching a new instance of that
activity, all of the other activities on top of it will be closed and
this Intent will be delivered to the (now on top) old activity as a
new Intent.
also, you can use FLAG_ACTIVITY_NEW_TASK with it.
then the code will be :
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
Just use
Intent i = new Intent(ActivityA.this, ActivityB.class);
i.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(i);
create an instance of your activity which you dont want to start multiple times like
Class ExampleA extends Activity {
public static Activity classAinstance = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
classAinstance = this;
}
}
Now where ever u want to crosscheck i mean prevent it from starting multiple times, check like this
if(ExampleA.classAinstance == null) {
"Then only start your activity"
}
please add this in menifest file
<activity
android:name=".ui.modules.profile.activity.EditProfileActivity"
android:launchMode="singleTask" // <<this is Important line
/>

Categories

Resources