Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 31 additions & 7 deletions app-launcher/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
<queries>
<package android:name="com.getcapacitor.myapp" />
<!-- Query by package name -->
<package android:name="com.twitter.android" />
<!-- Query by url scheme -->
<intent>
<action android:name="android.intent.action.VIEW"/>
<data android:scheme="twitter"/>
</intent>
</queries>
```

Expand All @@ -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);
};
```

Expand Down Expand Up @@ -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`** | <code><a href="#canopenurloptions">CanOpenURLOptions</a></code> |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -35,36 +36,48 @@ 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");
if (url == null) {
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;
}
}
}
6 changes: 6 additions & 0 deletions app-launcher/src/definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<CanOpenURLResult>;
Expand Down
Loading