Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to launch an intent for a third party app?

I managed to start an app with an intent, like this:

public void startNewActivity(String packageName) {
    Intent intent = mContext.getPackageManager().getLaunchIntentForPackage(packageName);
    if (intent == null) {
        // Bring user to the market or let them choose an app?
        intent = new Intent(Intent.ACTION_VIEW);
        intent.setData(Uri.parse("market://details?id=" + packageName));
    }
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    mContext.startActivity(intent);
}

Called this way:

this.startNewActivity("com.seleuco.mame4droid");

This works, but I wanted to run an intent to not just start the app but also directly run a game.

MAME4Droid's manifest says this:

    <activity android:name="com.seleuco.mame4droid.MAME4droid" android:label="@string/app_name"
      android:configChanges="keyboardHidden|orientation|screenSize"
      android:launchMode="singleTask"
      android:windowSoftInputMode="stateAlwaysHidden" android:theme="@style/Theme.MAME4droid">
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <data android:host="" android:scheme="file" />
            <data android:mimeType="application/zip" />
        </intent-filter>
    </activity>

But I can't figure out the right way to call the VIEW action.

I tried this: (commented lines are variations I tried)

public void startMAME4DroidGame(String game) {
    Toast.makeText(mContext, game, Toast.LENGTH_SHORT).show();
    String packageName = "com.seleuco.mame4droid";
    try {
            //Intent intent = new Intent(packageName + "/com.seleuco.mame4droid.MAME4droid");
            Intent intent = new Intent("com.seleuco.mame4droid/android.intent.action.VIEW");
            //intent.setAction(Intent.ACTION_VIEW);
            //intent.setData(Uri.parse("file://" + game));
            intent.setData(Uri.parse("file:" +   // also tried with "file://" +
            "/sdcard/"+Environment.DIRECTORY_DOWNLOADS+"/"+game));
            mContext.startActivity(intent);
    } catch(Exception e) {
            Toast.makeText(mContext, e.getMessage(), Toast.LENGTH_SHORT).show();
    }
}

Resulting in:

    No activity found to handle Intent
    { act=com.seleuco.mame4droid.MAME4Droid/android.intent.action.VIEW 
    dat=file:///sdcard/Download/starforc.zip }

What would be correct way to craft an Intent to target that particular activity?

like image 473
Sebastián Grignoli Avatar asked Nov 18 '25 10:11

Sebastián Grignoli


2 Answers

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.

like image 55
lelloman Avatar answered Nov 20 '25 22:11

lelloman


If you own both applications you can simply add a url schema (deep link) to your first app (e.g. mame4droid://) and handle everything with that. It lets you open that activity using a simple url e.g. mame4droid://openMyAct/file-uri You have to register this schema in first application's AndroidManifest and handle those intent to do whatever you want.

Another way which needs both apks signed by the same signature is what you are trying to do, are you sure that both apks are signed by the same signature?

Also if you just want to open that kind of file you have to register an extension (as you did) and do something like

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), fileMimeType);
startActivity(intent);
like image 24
Amin Avatar answered Nov 20 '25 23:11

Amin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!