Android: Starting An Activity For A Different Third Party App
Yes, it's possible but you need to know the correct component name. Launch the last.fm app regularly and check the logfile for the cmp=... information that's been used when the app is started. Use this as well in your app then.
I start the Z-DeviceTest app from the market from within my app without a problem like this:
final Intent intentDeviceTest = new Intent("android.intent.action.MAIN");
intentDeviceTest.setComponent(new ComponentName("zausan.zdevicetest","zausan.zdevicetest.zdevicetest"));
startActivity(intentDeviceTest);
in my case the info I took from the logcat was:
// dat=content://applications/applications/zausan.zdevicetest/zausan.zdevicetest.zdevicetest
// cmp=zausan.zdevicetest/.zdevicetest
in order to know how to start the app with the right component/class... do the same for the last.fm app
Edit:
I've tested to launch Last.fm from my own app, and this works fine without any errors:
final Intent intentDeviceTest = new Intent("android.intent.action.MAIN");
intentDeviceTest.setComponent(new ComponentName("fm.last.android","fm.last.android.LastFm"));
startActivity(intentDeviceTest);
How to launch an intent for a third party app?
An Intent with action VIEW and as data the URI of the file does the trick. I just tried with:
adb shell am start -a android.intent.action.VIEW -d file:///storage/emulated/0/MAME4droid/roms/myrom.zip -n com.seleuco.mame4droid/com.seleuco.mame4droid.MAME4droid
where storage/emulated/0/MAME4droid/roms/myrom.zip
is the file of my rom. It opens the app and the game starts.
It works also from an app:
final Intent intent = new Intent(Intent.ACTION_VIEW)
.setData(Uri.parse("content:///storage/emulated/0/MAME4droid/roms/myrom.zip"))
.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
.setClassName("com.seleuco.mame4droid", "com.seleuco.mame4droid.MAME4droid");
context.startActivity(intent);
However on Android 24+ I had to declare a file provider in the manifest:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
</provider>
And the xml with the path:
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path name="external_files" path="."/>
</paths>
Not sure why but when I launch the Intent from the app, only content
scheme works, file
doesn't.
How to run activity from 3rd party library?
You're doing it wrong. You NEVER create an Activity with new. It won't initialize correctly. Instead, you create an Intent to launch that Activity and call context.startActivity() to create and launch it.
void launchThirdPartyActivity(Context context) {
Intent intent = new Intent(context, THIRD_PARTY_ACTIVITY.class);
context.startActivity(intent);
}
That should work if the activity is in a library. If you're trying to launch an Activity in another app on the device, you'd use one of the other Intent constructors (which one depends on how/what you're trying to launch- a specific activity in a specific app? An activity that can perform an action (like share or view) on a specific data type? Something else?)
Letting a third party app start my activity directly?
You would most likely need for them to call your activity directly
Class yourClass = Class.forName("com.yourdomain.yourapp.YourClass");
Intent intent = new Intent(this, yourClass);
If they don't have a jar to link against. Otherwise, they could just use
Intent intent = new Intent(this, YourClass.class);
And then put some extras in there. The whole concept of the browsable intent (along with the others) is to provide users with a choice of how they would like to view/use something. This is similar to what happens when you click "share" from the media viewer. The whole concept is to give them choice. If somebody wants to just start your activity, they will need to explicitly call it.
Edit: My reflection example above won't directly work unless the Dalvik class loader knows about your class (which it probably won't). You will actually need to specifically tell the VM to load a class from a foreign package. You can do that with the following code
Context foreignContext = createPackageContext("com.yourdomain.yourapp", Context.CONTEXT_IGNORE_SECURITY | Context.CONTEXT_INCLUDE_CODE);
Class<?> yourClass = foreignContext.getClassLoader().loadClass("com.yourdomain.yourapp.YourClass");
Now that they have the class object, they can then fire the intent like before. So the complete code is something like
Context foreignContext = createPackageContext("com.yourdomain.yourapp", Context.CONTEXT_IGNORE_SECURITY | Context.CONTEXT_INCLUDE_CODE);
Class<?> yourClass = foreignContext.getClassLoader().loadClass("com.yourdomain.yourapp.YourClass");
Intent intent = new Intent(this, yourClass);
startActivity(intent);
How to open specific third party activity?
First, you must make sure that the target activity is exported. It must be exported explicitly with android:export="true", or implicitly, with an intent-filter. You can't send an Intent to any random Activity of any app.
Open third party app from intent
I am working on an app were I am going to open other apps.
I am interpreting this as meaning that you are creating a launcher, akin to the ones found on home screens.
Can you refer to it useing only the packagename, or do you need the Main Activity intent.
Launchers use an ACTION_MAIN
/CATEGORY_LAUNCHER
Intent
.
Are there any simple ways of finding the right intent, and then refer to it.
Use PackageManager
to find all the possible ACTION_MAIN
/CATEGORY_LAUNCHER
activities on the device, and then display those to the user to choose from. You can then construct a suitable Intent
for starting up their specific choice.
Here is a sample project that implements a launcher.
To come up with the list of things that could be launched, that sample app uses:
PackageManager pm=getPackageManager();
Intent main=new Intent(Intent.ACTION_MAIN, null);
main.addCategory(Intent.CATEGORY_LAUNCHER);
List<ResolveInfo> launchables=pm.queryIntentActivities(main, 0);
And here is the actual launching logic, based upon the user clicking on one of those "launchables" in a ListActivity
:
@Override
protected void onListItemClick(ListView l, View v,
int position, long id) {
ResolveInfo launchable=adapter.getItem(position);
ActivityInfo activity=launchable.activityInfo;
ComponentName name=new ComponentName(activity.applicationInfo.packageName,
activity.name);
Intent i=new Intent(Intent.ACTION_MAIN);
i.addCategory(Intent.CATEGORY_LAUNCHER);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
i.setComponent(name);
startActivity(i);
}
How to start activity in another application?
If you guys are facing "Permission Denial: starting Intent..." error or if the app is getting crash without any reason during launching the app - Then use this single line code in Manifest
android:exported="true"
Please be careful with finish(); , if you missed out it the app getting frozen. if its mentioned the app would be a smooth launcher.
finish();
The other solution only works for two activities that are in the same application. In my case, application B doesn't know class com.example.MyExampleActivity.class
in the code, so compile will fail.
I searched on the web and found something like this below, and it works well.
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.example", "com.example.MyExampleActivity"));
startActivity(intent);
You can also use the setClassName method:
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setClassName("com.hotfoot.rapid.adani.wheeler.android", "com.hotfoot.rapid.adani.wheeler.android.view.activities.MainActivity");
startActivity(intent);
finish();
You can also pass the values from one app to another app :
Intent launchIntent = getApplicationContext().getPackageManager().getLaunchIntentForPackage("com.hotfoot.rapid.adani.wheeler.android.LoginActivity");
if (launchIntent != null) {
launchIntent.putExtra("AppID", "MY-CHILD-APP1");
launchIntent.putExtra("UserID", "MY-APP");
launchIntent.putExtra("Password", "MY-PASSWORD");
startActivity(launchIntent);
finish();
} else {
Toast.makeText(getApplicationContext(), " launch Intent not available", Toast.LENGTH_SHORT).show();
}
launch activities from different package
I am assuming that by "packages" you mean applications.
We have:
- ApplicationA with FirstActivity
- ApplicationB with SecondActivity
If, in the ApplicationB's AndroidManifest.xml file, in the declaration of SecondActivity you add an intent filter such as:
<activity android:name=".SecondActivity">
<intent-filter>
<action android:name="applicationB.intent.action.Launch" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
You can create an Intent to launch this SecondActivity from the FirstActivity with:
Intent intent = new Intent("applicationB.intent.action.Launch");
startActivity(intent);
What this all means is:
- The SecondActivity has a filter for the intent action of "applicationB.intent.action.Launch"
- When you create an intent with that action and call 'startActivity' the system will find the activity (if any) that responds to it
The documentation for this is at: https://developer.android.com/reference/android/content/Intent.html
Related Topics
Using Android Studio with Vuforia
Resources and Layout Direction Rendered Incorrectly Only on Android 8.0 and Above
CSS3 Animation Flicker on Android 2.2 (Webkit-Transform:Translate(..) Scale(..) at The Same Time)
Get Font Scaling Factor to Calculate the Fontsize
Android.App.Application Cannot Be Instantiated Due to Nullpointerexception
Android: HTML in Textview with Link Clickable
How to Update Google Play Services for Android Studio 2.2 Emulators
Mobile Keyboard Pushes Up Content Because of an Absolutely Positioned Drawer
Best Way to Show a Loading/Progress Indicator
When Should I Recycle a Bitmap Using Lrucache
Get Color Value Programmatically When It's a Reference (Theme)
Android M Write to Sd Card - Permission Denied
@Font-Face Not Working in Chrome for Android
Android Input Connection Error
Call an Activity Method from a Broadcastreceiver Class
How to Keep The Oauth Consumer Secret Safe, and How to React When It's Compromised
Background-Attachment: Fixed Interfering with Background-Size