Repository: NativeScript/NativeScript
File: packages/core/utils/index.android.ts (TypeScript)

Code before:
export { ad, dataDeserialize, dataSerialize, iOSNativeHelper } from './native-helper';
export * from './layout-helper';
export * from './common';
export { Source } from './debug';

const MIN_URI_SHARE_RESTRICTED_APK_VERSION = 24;

export function GC() {
	gc();
}

export function releaseNativeObject(object: java.lang.Object) {
	__releaseNativeCounterpart(object);
}

export function openUrl(location: string): boolean {
	const context = ad.getApplicationContext();
	try {
		const intent = new android.content.Intent(android.content.Intent.ACTION_VIEW, android.net.Uri.parse(location.trim()));
		const packageManager =  context.getPackageManager();

		intent.addFlags(android.content.Intent.FLAG_ACTIVITY_NEW_TASK);

		// Handle schemes like mailto, tel, etc
		if (intent.resolveActivity(packageManager) == null) {
			Trace.write('Unable to open ' + location + '. Make sure to added android.permission.QUERY_ALL_PACKAGES permission or queries(https://developer.android.com/guide/topics/manifest/queries-element) to the AndroidManifest.xml file.', Trace.categories.Error, Trace.messageType.error);
			return false;
		}

		context.startActivity(intent);
	} catch (e) {
		// We Don't do anything with an error.  We just output it
		Trace.write('Error in OpenURL', Trace.categories.Error, Trace.messageType.error);

		return false;
	}

	return true;
}

/**
 * Check whether external storage is read only
 *
 * @returns {boolean} whether the external storage is read only
 */
function isExternalStorageReadOnly(): boolean {
	const extStorageState = android.os.Environment.getExternalStorageState();
	if (android.os.Environment.MEDIA_MOUNTED_READ_ONLY === extStorageState) {
		return true;
	}


Review comment (bug):
I'd rather we avoided references to using `QUERY_ALL_PACKAGES`. Have you confirmed this is really necessary for apps like mailto, tel, etc?
Here is a bit of content regarding this permission: https://support.google.com/googleplay/android-developer/answer/10158779?hl=en

The norm is that apps that handle those intents contain queries so that there is no need for permissions on the user side. See: https://stackoverflow.com/a/69490217

Code after:
export { ad, dataDeserialize, dataSerialize, iOSNativeHelper } from './native-helper';
export * from './layout-helper';
export * from './common';
export { Source } from './debug';

const MIN_URI_SHARE_RESTRICTED_APK_VERSION = 24;

export function GC() {
	gc();
}

export function releaseNativeObject(object: java.lang.Object) {
	__releaseNativeCounterpart(object);
}

export function openUrl(location: string): boolean {
	const context = ad.getApplicationContext();
	try {
		const intent = new android.content.Intent(android.content.Intent.ACTION_VIEW, android.net.Uri.parse(location.trim()));
		const packageManager =  context.getPackageManager();

		intent.addFlags(android.content.Intent.FLAG_ACTIVITY_NEW_TASK);

		// Handle schemes like mailto, tel, etc
		if (intent.resolveActivity(packageManager) == null) {
			Trace.write('Unable to open ' + location + '. Make sure to add queries element(https://developer.android.com/guide/topics/manifest/queries-element) matching the scheme to the AndroidManifest.xml file.', Trace.categories.Error, Trace.messageType.error);
			return false;
		}

		context.startActivity(intent);
	} catch (e) {
		// We Don't do anything with an error.  We just output it
		Trace.write('Error in OpenURL', Trace.categories.Error, Trace.messageType.error);

		return false;
	}

	return true;
}

/**
 * Check whether external storage is read only
 *
 * @returns {boolean} whether the external storage is read only
 */
function isExternalStorageReadOnly(): boolean {
	const extStorageState = android.os.Environment.getExternalStorageState();
	if (android.os.Environment.MEDIA_MOUNTED_READ_ONLY === extStorageState) {
		return true;
	}