Refering to this post I need to ask something else.
I have an application "A" which download and install another app "B".
I want B to "transfer" data to A and then A will use this data to do work.
I know that we can transfer data with intent.
After installing B app with A, Android provide a choice with "Ok" or "Launch" ; my question is :
Is that possible to pass data from B to A when we click on "Ok"? (So we stay in A app without launching B)
If yes, how? Is that possible to "invisible" launch B? How should I code B to get this comportement?
I know that might be hard to understand, you can try to check my previous draw (here again).
EDIT:
I use this code to launch B installation from A.
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Uri uri = Uri.fromFile(new File(Environment.getExternalStorageDirectory().toString() + "/downloadedfile.apk"));
Intent.setDataAndType(uri, "application/vnd.android.package-archive");
getApplicationContext().startActivity(intent);
There are many ways to handle this, here is one that (I believe) is quite simple to implement. Since your A app [presumably] knows what it is installing:
App A: Add a BroadcastReceiver to react to the installation, though by default it is off.
Android: BroadcastReceiver on application install / uninstall
App B: Add a Service for background communication.
Note: A Service must be exported to be accessible to other apps via explicit intent, but this creates a security concern, as it is open to all other apps.
When a user of App A clicks to install App B:
Start the BroadcastReceiver with a filter set to detect the install:
stackoverflow...android-broadcastreceiver-on-application-install-uninstall
App A starts the install.
When the BroadcastReceiver detects the package has been added (the package name will be in the received intent,) it can stop the BroadcastReceiver, and can send an explicit Intent naming the Service in AppB. You can pass whatever data you need in the intent.
When the AppB service receives the intent, it can act in any way you'd like.
Service is always created using a non-null Intent, though the 'action' of explicit Intents is null.
Service.onStartCommand() might receive a null Intent if the service was re-created.
I'd fill in more of the code, but I have a day job ;)
Note:
Intent.ACTION_PACKAGE_ADDED called when a package is installed.
Intent.ACTION_PACKAGE_INSTALL was never used, and was deprecated in API 14.
http://developer.android.com/reference/android/content/BroadcastReceiver.html
http://developer.android.com/reference/android/content/Intent.html
Related
I'm trying to have other apps share PDF files with mine, I have an intent filter for android.intent.action.SEND type pdf files but some apps send the intent with the FLAG_ACTIVITY_CLEAR_TASK which closes the activity that was already running.
Is there any way to ignore this flag? I want to keep the current activity running when shared to my app.
EDIT: a good example
I share a PDF with google drive pdf viewer, my activity that is already running picks it up and the intent is received in "onNewIntent" (desired).
When I do the same thing with Samsungs "my files" my activity gets restarted and the intent is given to "onCreate" (not desired)
I share a PDF with google drive pdf viewer, my activity that is already running picks it up and the intent is received in "onNewIntent" (desired).
When I do the same thing with Samsungs "my files" my activity gets restarted and the intent is given to "onCreate" (not desired)
Your app should work correctly regardless of how it's invoked. What difference does it make to you whether it's a new instance receiving the intent or the existing one? You're not always going to have an existing instance around, right? If you share from Google before starting your activity, you'll be in the same position, won't you?
I want to fire an intent to another application's activity .
What i am thinking is to use intent filter of the other's.
Or can i access the other application package in some other way?
Suppose My app is 'A' and another app also exist in phone which is 'B'
Q1. Can I access or call classes of B and its method by any means?
Q2. And If it can be done by Implicit Intents then What happens in that case where I cant have access of B's Source code, means I cannot find the B's class Intent filter.
Our activity can be launched from a GCM notification. We set extras in the GCM intent to ensure the user is taken to the message thread for that GCM notification, and we call removeExtra afterwards to remove it from the intent.
If the user launches our app from the recent history menu, then the activity is started with the same intent as from the previous launch (e.g. from the GCM notification).
This scenario is quite easy to detect:
Intent i = getIntent();
// If the caller intent is from the recent apps and has the RECIPIENT_ID_KEY
// extra we should remove it to avoid open the messages thread again
if (((i.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0) &&
i.hasExtra(MyConstants.RECIPIENT_ID_KEY)) {
i.removeExtra(MyConstants.RECIPIENT_ID_KEY);
}
However, we also want this to work if the activity has been destroyed by the OS. At the moment, when the Developer option "Do not keep activities" is set (only available on OS 4.0+), then the activity keeps being recreated with the same intent when pressing the Back button from another one of our screens, resulting in bad things happening.
I considered adding a unique extra in our GCM intent and saving that in Shared Preferences once we have processed it. However, we also need this to work when sharing an image into our app through a SEND image/jpg intent. We don't control that intent, so how will we know if we've already processed it? I guess we could use the file/URI information, although that means if a user shares the same image twice in a row, we'll ignore the second one.
Is there a clean and simple way to solve this problem?
We currently support OS 2.3+, and our application is available all around the world. Here's the relevant section of my AndroidManifest.xml:
<activity
android:name=".ui.MyClass"
android:configChanges="orientation|screenSize"
android:launchMode="singleTop"
android:windowSoftInputMode="stateHidden" >
I was interested in how to solve the part:
However, we also need this to work when sharing an image into our app
through a SEND image/jpg intent.
As soon as I handle the images I put an extra flag on the Intent. As you can imagine, I check for that flag before doing the files processing. This worked even if the Intent was created by another application.
I have application A and application B.
I launch B with an intent from A in this way:
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setClassName("com.applicationB", "com.applicationB.MainActivity");
intent.putExtra(EXTRA_NAME,"name");
startActivity(intent);
When the user closes application A I want application B to close too. App B has JNI and uses exec() command.
I've tried android:sharedUserId but I got this error when app A tries to launch B with the code above:
Error running exec(). Command: [....] Working Directory: null Environment: (not null, it shows all the environment.
Any ideas?
you must use android IPC mechanisms like broadcast receiver
when application A closes it should send a broadcast and application B should register for a broadcast receiver to capture broadcasts from application A
see the documents for more info http://developer.android.com/reference/android/content/BroadcastReceiver.html
If both applications are programmed by yourself, you could consider to add a BroadcastReceiver in app B, that takes care, that all activities get closed. Before app A closes, call that receiver and it's done.
If you are not sure which activity is shown, you could extend the Activity class with a BroadcastReceiver, so that all activities get notified.
If app B is not programmed by you, you could use killbackgroundProcesses(), e.g.
ActivityManager activityManager = (ActivityManager)this.getSystemService(ACTIVITY_SERVICE);
activityManager.killBackgroundProcesses(myProcessId);
... however, this works only if app B is in fact in background. Additionally this is not the best option to close an app 'cause you do not know what the app is currently doing.
Edit: found my favorite example on that topic :-) check http://www.hrupin.com/2011/10/how-to-finish-all-activities-in-your-android-application-through-simple-call - it shows how to close all activities from within the app. However, it's not a big step doing this from another one ...
I have a free and a premium version of the same app (almost same code, same classes with "if"s here and there, different packages in the manifest, same process name in the manifest). The main activity calls a service to execute some stuff, using an IMPLICIT intent.
When I install both apps on the phone, it turns out that the premium activity actually starts a "free" service sometimes and a "premium" service another.
I have been playing around with categories and the packagemanager but it seems too complicated.
Questions :
how does Android handle multiple components responding to a same Intent?
how would you do what I am trying to do: I have the same service in multiple apps and I only want one instance being called from all the apps?
I guess you could add an extra boolean isPremium to the intent. Naturally you will need some more of those "if's".
Activity:
//send broadcast
Intent serviceStarted = new Intent(Actions.ACTION_START_SERVICE);
serviceStarted.putExtra(Extras.EXTRA_PREMIUM_VERSION, PREMIUM_VERSION);
sendBroadcast(serviceStarted);
Receiver:
if (!intent.getExtras().getBoolean(Extras.EXTRA_PREMIUM_VERSION)) {
Log.v(TAG, " - ignoring wrong version");
return;
}