I have an issue that my sending Activity is still visible after I kill app. How to close all Activity's when the app is killed?
DETAILED DESCRIPTION
I have a sending Intent in onDownloadStart method that displays the user a list of possible apps to "send an image", here you go:
Intent sendIntent = new Intent();
sendIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_GRANT_READ_URI_PERMISSION);
sendIntent.setAction(Intent.ACTION_SEND);
File filePath = new File(String.valueOf(context.getFilesDir()));
File newFile = new File(filePath, fileName);
sendIntent.putExtra(Intent.EXTRA_STREAM, FileProvider.getUriForFile(context, context.getApplicationContext().getPackageName() + ".FileProvider", newFile));
sendIntent.setType(intentType);
context.startActivity(sendIntent);
This code IS working as I want with the ONE exception. The Activity with choosing the app to send the image is still visible when I kill the app. That's all - no errors in the console.
Your problem is here:
sendIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_GRANT_READ_URI_PERMISSION);
You start the Activity to choose an app to send in a new task. When you remove your task from the list of recent tasks (that's what "swiping your app from the recents list" does), the other task you started is still live.
Just remove Intent.FLAG_ACTIVITY_NEW_TASK from the setFlags() call and the chooser should end up running in your app's task, and therefore go away when you swipe your app's task from the list of recents.
Also, your use of the word Intent is confusing. An Intent is never visible. It is just a small bit of data used to request that Android launch a certain component. You mean Activity, not Intent.
Related
I have an app that sends a call intent to another app (CsipSimple).
Intent intent = new Intent("android.phone.extra.NEW_CALL_INTENT");
intent.setData(Uri.parse("csip:" + number));
startActivity(intent);
But every time a chooser dialog is poping up to choose the CsipSimple app. Is there a way to avoid this chooser and use directly a defined app.
I found that it is possible to define the class name of the activity:
intent.setClassName("com.csipsimple.ui.outgoingcall", "com.csipsimple.ui.outgoingcall.OutgoingCallChooser");
But this doesn't work, i assume that this can only work if the intent caller and CsipSimple are both in the same process.
I have a problem (2 problems to be exact) with launching intents from a Notification.
My current situation is that I have a family of apk that all can use a remote service launched by the first of them. The service creates an Notification and when clicked the opens back the application that launched the service. This works ok.
I wanted to improve that so when there is more than one application from the family installed, instead of just going to the apk that launched the service an chooser Intent would appear and the user would be able to choose the apk to come back to.
I managed to do this.
ArrayList<String> myApps = Lists.newArrayList(
"com.myapp1",
"com.myapp2",
"com.myapp3",
"com.myapp4"
);
List<Intent> targetedIntents = new ArrayList<Intent>();
Intent baseIntent = new Intent(Intent.ACTION_MAIN, null);
baseIntent.addCategory("android.intent.category.LAUNCHER");
final PackageManager packageManager = getApplicationContext().getPackageManager();
List<ResolveInfo> list = packageManager.queryIntentActivities(baseIntent, 0);
for (ResolveInfo resolveInfo : list) {
String packageName = resolveInfo.activityInfo.packageName;
if (packageName != null && myApps.contains(packageName)) {
Intent targetedIntent = new Intent();
targetedIntent.setPackage(packageName);
targetedIntent.setClassName(packageName, resolveInfo.activityInfo.name);
targetedIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
targetedIntents.add(targetedIntent);
}
}
Intent intent = Intent.createChooser(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=whatever")), "Select app to return to");
intent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedIntents.toArray(new Parcelable[]{}));
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, intent.getFlags());
notification.setLatestEventInfo(this, notificationTitle, notificationMessage, contentIntent);
This works mostly as it should. The chooser appears and the selected option launches the desired apk.
But I came across 2 problems:
I. When I create the intent chooser with only the intents that interest me, the chooser is empty with the message "no application can perform this action"
intent = Intent.createChooser(targetedIntents.get(0), "Select app to return to");
intent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedIntents.toArray(new Parcelable[]{}));
But if I put an existing apk there first (such as google play) everything works and my options show along with the google play option.
intent = Intent.createChooser(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=whatever")), "Select app to return to");
intent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedIntents.toArray(new Parcelable[]{}));
This is something I can live with, but it would be better if onlye the proper apks were there.
II. When I click the apk from the list, instead of coming back from the background (if the apk was already running there) it restarts it. I have the proper flags set.
Intent targetedIntent = new Intent();
targetedIntent.setPackage(packageName);
targetedIntent.setClassName(packageName, resolveInfo.activityInfo.name);
targetedIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
Before using the chooser I launched only one intent and it resummed the background apk normally.
intent = new Intent(this, MainActivity.class);
intent.setAction("android.intent.action.MAIN");
intent.addCategory("android.intent.category.LAUNCHER");
Not sure what I am doing wrong here that the apk restarts insted of resuming.
For the first problem (chooser issue), the reason you are getting the error "no application can perform this action" is because the Intent you are passing to getChooser() doesn't have an ACTION in it that Android can use to search for applications that can handle the Intent. getChooser will use the ACTION, CATEGORY and DATA in the Intent to search for suitable applications. It will then use package and component names to filter this list. In your case, because you've only provided the package and component names (but haven't specified ACTION), Android can't find any suitable applications. I'm not sure there's a way around this, since you want to build a list with different packages. You may just need to create your own chooser dialog (which is probably the correct thing to do here anyway, as you don't really get any advantages using the Android chooser because you've already decided what the list should contain).
For the second problem (if application is in background, it gets restarted) you need to use the following flags:
targetedIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
Specifying Intent.FLAG_ACTIVITY_NEW_TASK when launching the root activity of a task will bring an already existing task to the foreground.
NOTE: If you want to just bring the existing task to the foreground (in whatever state it happens to be), then just use Intent.FLAG_ACTIVITY_NEW_TASK and remove the other 2 flags.
With the code below I share some text from my app via an intent chooser. My problem is that if I for example choose to share the text as a message and when in the message app I just hit the home button and bring my app back to front. Then when I try to start a new intent chooser it immediately sends me back to the unfinished message app. I would rather that it forgot all about that and presented me with the list of choices again.
Is there a way to make it forget the old choice?
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TEXT, text);
startActivity(Intent.createChooser(intent, "Share text as..."));
Add the following
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
I have an application that open an external application to read PDF files. here is the code to open the external app.
if(file!=null){
PackageManager packageManager = getPackageManager();
Intent testIntent = new Intent(Intent.ACTION_VIEW);
testIntent.setType("application/pdf");
List list = packageManager.queryIntentActivities(testIntent, PackageManager.MATCH_DEFAULT_ONLY);
if (list.size() > 0 && file.isFile()) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
Uri uri = Uri.fromFile(file);
intent.setDataAndType(uri, "application/pdf");
startActivity(intent);
}else{
Toast.makeText(this, "problem loading file", Toast.LENGTH_LONG).show();
}
}
The problem is when I come back from my pdf application (adobe reader or any pdf reader app), in the first click of my back button I get a black screen and in second I can reach my activity? How could I possibly solve this problem?
I think this is probably the normal Activity lifecycle at work.
Once your Activity goes into the background, it is deemed no longer critical by the OS and its process may be killed in order to reclaim memory or resources for a foreground Activity. The black screen you see when pressing the back button is the window background of your application's theme which appears while your Activity is recreated and its state is restored.
This is normal behavior. Ensure that your Activity saves and restores its state efficently by implementing the appropriate lifecycle methods to reduce the time it takes to re-create.
See http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle
Is it possible to open up the default Android Messaging activity from inside an activity you write yourself? Like for example: I press a "Mail" button inside my program, and it opens the Android Messaging app just like as if I was to press the Messaging icon on the main screen.
I did something similar to this with the Contacts activity, but only the contact list comes up, no extra functionality like Adding/Modifying/Deleting, etc.
Any ideas?
edit: I found this way to open the "Compose New Message" Activity, I just need to back it up a step. Does anyone know the correct MIME type instead of this one?
Intent sendIntent = new Intent(Intent.ACTION_VIEW);
sendIntent.setType("vnd.android-dir/mms-sms");
m_activity.startActivity(sendIntent);
This starts the messaging app from another app:
Intent intent = new Intent("android.intent.action.MAIN");
intent.setComponent(new ComponentName("com.android.mms","com.android.mms.ui.ConversationList"));
startActivity(intent);
Just put it inside a button listener or whatever user input you want to open it from.
Enjoy :-)
If you want to open the messaging app to view messages and not for sending a message, this should do the job:
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
intent.setPackage("com.google.android.apps.messaging");
startActivity(intent);