diff --git a/app-launcher/README.md b/app-launcher/README.md index 24a2ef302..da5154051 100644 --- a/app-launcher/README.md +++ b/app-launcher/README.md @@ -6,12 +6,18 @@ On iOS you can only open apps if you know their url scheme. On Android you can open apps if you know their url scheme or use their public package name. -**Note:** On [Android 11](https://developer.android.com/about/versions/11/privacy/package-visibility) and newer you have to add the app package names you want to query in the `AndroidManifest.xml` inside the `queries` tag. +**Note:** On [Android 11](https://developer.android.com/about/versions/11/privacy/package-visibility) and newer you have to add the app package names or url schemes you want to query in the `AndroidManifest.xml` inside the `queries` tag. Example: ```xml - + + + + + + + ``` @@ -27,14 +33,26 @@ npx cap sync ```typescript import { AppLauncher } from '@capacitor/app-launcher'; -const checkCanOpenUrl = async () => { - const { value } = await AppLauncher.canOpenUrl({ url: 'com.getcapacitor.myapp' }); - +const checkCanOpenTwitterUrl = async () => { + const { value } = await AppLauncher.canOpenUrl({ url: 'twitter://timeline' }); console.log('Can open url: ', value); }; -const openPortfolioPage = async () => { - await AppLauncher.openUrl({ url: 'com.getcapacitor.myapp://page?id=portfolio' }); +const openTwitterUrl = async () => { + const { completed } = await AppLauncher.openUrl({ url: 'twitter://timeline' }); + console.log('openUrl completed: ', completed); +}; + +// Android only +const checkCanOpenTwitterPackage = async () => { + const { value } = await AppLauncher.canOpenUrl({ url: 'com.twitter.android' }); + console.log('Can open package: ', value); +}; + +// Android only +const openTwitterPackage = async () => { + const { completed } = await AppLauncher.openUrl({ url: 'com.twitter.android' }); + console.log('openUrl package completed: ', completed); }; ``` @@ -68,6 +86,12 @@ This method always returns false for undeclared schemes, whether or not an appropriate app is installed. To learn more about the key, see [LSApplicationQueriesSchemes](https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/LaunchServicesKeys.html#//apple_ref/doc/plist/info/LSApplicationQueriesSchemes). +On Android the URL can be a known URLScheme or an app package name. + +On [Android 11](https://developer.android.com/about/versions/11/privacy/package-visibility) +and newer you have to add the app package names or url schemes you want to query in the `AndroidManifest.xml` +inside the `queries` tag. + | Param | Type | | ------------- | --------------------------------------------------------------- | | **`options`** | CanOpenURLOptions | diff --git a/app-launcher/android/src/main/java/com/capacitorjs/plugins/applauncher/AppLauncherPlugin.java b/app-launcher/android/src/main/java/com/capacitorjs/plugins/applauncher/AppLauncherPlugin.java index 9f2f6d404..95cf2ea49 100644 --- a/app-launcher/android/src/main/java/com/capacitorjs/plugins/applauncher/AppLauncherPlugin.java +++ b/app-launcher/android/src/main/java/com/capacitorjs/plugins/applauncher/AppLauncherPlugin.java @@ -3,6 +3,7 @@ import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; import android.net.Uri; import com.getcapacitor.JSObject; import com.getcapacitor.Logger; @@ -35,11 +36,19 @@ public void canOpenUrl(PluginCall call) { } catch (PackageManager.NameNotFoundException e) { Logger.error(getLogTag(), "Package name '" + url + "' not found!", null); } - - ret.put("value", false); + if (!canResolve(pm, new Intent(Intent.ACTION_VIEW, Uri.parse(url)))) { + ret.put("value", canResolve(pm, new Intent(url))); + } else { + ret.put("value", true); + } call.resolve(ret); } + private boolean canResolve(PackageManager pm, Intent intent) { + ResolveInfo resolve = pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY); + return resolve != null; + } + @PluginMethod public void openUrl(PluginCall call) { String url = call.getString("url"); @@ -47,24 +56,28 @@ public void openUrl(PluginCall call) { call.reject("Must provide a url to open"); return; } - JSObject ret = new JSObject(); final PackageManager manager = getContext().getPackageManager(); Intent launchIntent = new Intent(Intent.ACTION_VIEW); launchIntent.setData(Uri.parse(url)); - - try { - getActivity().startActivity(launchIntent); - ret.put("completed", true); - } catch (Exception ex) { - launchIntent = manager.getLaunchIntentForPackage(url); - try { - getActivity().startActivity(launchIntent); + if (!canLaunchIntent(launchIntent)) { + if (!canLaunchIntent(manager.getLaunchIntentForPackage(url))) { + ret.put("completed", canLaunchIntent(new Intent(url))); + } else { ret.put("completed", true); - } catch (Exception expgk) { - ret.put("completed", false); } + } else { + ret.put("completed", true); } call.resolve(ret); } + + private boolean canLaunchIntent(Intent intent) { + try { + getActivity().startActivity(intent); + return true; + } catch (Exception ex) { + return false; + } + } } diff --git a/app-launcher/src/definitions.ts b/app-launcher/src/definitions.ts index 2c567366c..b06866f6f 100644 --- a/app-launcher/src/definitions.ts +++ b/app-launcher/src/definitions.ts @@ -11,6 +11,12 @@ export interface AppLauncherPlugin { * appropriate app is installed. To learn more about the key, see * [LSApplicationQueriesSchemes](https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/LaunchServicesKeys.html#//apple_ref/doc/plist/info/LSApplicationQueriesSchemes). * + * On Android the URL can be a known URLScheme or an app package name. + * + * On [Android 11](https://developer.android.com/about/versions/11/privacy/package-visibility) + * and newer you have to add the app package names or url schemes you want to query in the `AndroidManifest.xml` + * inside the `queries` tag. + * * @since 1.0.0 */ canOpenUrl(options: CanOpenURLOptions): Promise;