Search code examples
javaandroidandroid-intentintentfilter

How to open my app implicitly with my scheme?


I have the app "A" the need to be opened from the others apps "B,C,D" by implicit intent

So, in my app "A" I have defined intent filter

<intent-filter>
    <action android:name="android.intent.action.VIEW"/>

    <category android:name="android.intent.category.DEFAULT"/>
    <category android:name="android.intent.category.BROWSABLE"/>
    <!-- Accepts URIs that begin with "example://gizmos” -->
    <data
        android:host="applink"
        android:scheme="mobileapp"/>
</intent-filter>

and in app "B" I have defined the implicit intent

Intent LaunchIntent = getPackageManager().getLaunchIntentForPackage("package.name.of.destination.app");
startActivity(LaunchIntent);

And I get such error

2018-06-26 19:35:44.155 2270-2270/com.example.ezplan.deleteit E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.ezplan.deleteit, PID: 2270
java.lang.IllegalStateException: Could not execute method for android:onClick
    at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:390)
    at android.view.View.performClick(View.java:6597)
    at android.view.View.performClickInternal(View.java:6574)
    at android.view.View.access$3100(View.java:778)
    at android.view.View$PerformClick.run(View.java:25883)
    at android.os.Handler.handleCallback(Handler.java:873)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:193)
    at android.app.ActivityThread.main(ActivityThread.java:6642)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
 Caused by: java.lang.reflect.InvocationTargetException
    at java.lang.reflect.Method.invoke(Native Method)
    at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:385)
    at android.view.View.performClick(View.java:6597) 
    at android.view.View.performClickInternal(View.java:6574) 
    at android.view.View.access$3100(View.java:778) 
    at android.view.View$PerformClick.run(View.java:25883) 
    at android.os.Handler.handleCallback(Handler.java:873) 
    at android.os.Handler.dispatchMessage(Handler.java:99) 
    at android.os.Looper.loop(Looper.java:193) 
    at android.app.ActivityThread.main(ActivityThread.java:6642) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858) 
 Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.content.Intent.migrateExtraStreamToClipData()' on a null object reference
    at android.app.Instrumentation.execStartActivity(Instrumentation.java:1666)
    at android.app.Activity.startActivityForResult(Activity.java:4584)
    at androidx.fragment.app.FragmentActivity.startActivityForResult(FragmentActivity.java:792)
    at android.app.Activity.startActivityForResult(Activity.java:4542)
    at androidx.fragment.app.FragmentActivity.startActivityForResult(FragmentActivity.java:779)
    at android.app.Activity.startActivity(Activity.java:4903)
    at android.app.Activity.startActivity(Activity.java:4871)
    at com.example.ezplan.deleteit.MainActivity.doOnCLickButton(MainActivity.java:29)

What am I doing wrong?

Or, just give me a sample how to do it correctly

Feel free to ask

EDIT1

1)my filter in the app that I need to open

<intent-filter>
            <action android:name="android.intent.action.VIEW"/>

            <category android:name="android.intent.category.DEFAULT"/>
            <category android:name="android.intent.category.BROWSABLE"/>
            <!-- Accepts URIs that begin with "mobileapp://applink” -->
            <data
                android:host="applink"
                android:scheme="mobileapp"/>
        </intent-filter>

2) My code in the app that try invoke external app

public void testit(View view)
{
    Intent LaunchIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("mobileapp://applink"))
            .setPackage("package.name.of.destination.app");

    startActivity(LaunchIntent);
}

Exeption

Caused by: android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW dat=mobileapp://applink pkg=package.name.of.destination.app }


Solution

  • The documentation for PackageManager.getLaunchIntentForPackage(String) states:

    Returns a "good" intent to launch a front-door activity in a package. This is used, for example, to implement an "open" button when browsing through packages. The current implementation looks first for a main activity in the category Intent.CATEGORY_INFO, and next for a main activity in the category Intent.CATEGORY_LAUNCHER. Returns null if neither are found.

    If you don't comply to this contract, LaunchIntent is null and thus you crash.

    Usually you have a main launcher intent filter defined in your manifest:

    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
    

    This would be found by getLaunchIntentForPackage(). Without changing or adding the intent filters, you've defined, you could also create the appropriate intent to match it manually:

    Intent LaunchIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("mobileapp://applink"))
                                .setPackage("package.name.of.destination.app");