Android: Starting an Activity for a Different Third Party App

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



Leave a reply



Submit