Change summary
build.gradle | 1
src/cheogram/java/com/cheogram/android/BrowserHelper.java | 88 ++++
src/main/java/eu/siacs/conversations/ui/text/FixedURLSpan.java | 16
3 files changed, 101 insertions(+), 4 deletions(-)
Detailed changes
@@ -107,6 +107,7 @@ dependencies {
implementation 'io.github.nishkarsh:android-permissions:2.1.6'
implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation 'androidx.documentfile:documentfile:1.0.1'
+ implementation 'androidx.browser:browser:1.8.0'
implementation 'com.github.martin-stone:hsv-alpha-color-picker-android:3.1.0'
implementation 'com.github.ipld:java-cid:v1.3.1'
//implementation 'com.splitwise:tokenautocomplete:3.0.2'
@@ -0,0 +1,88 @@
+package com.cheogram.android;
+
+import android.content.Intent;
+import android.Manifest;
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Build;
+import android.content.ActivityNotFoundException;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import androidx.browser.customtabs.CustomTabsIntent;
+
+import eu.siacs.conversations.ui.XmppActivity;
+
+public class BrowserHelper {
+ static boolean launchNativeApi30(Context context, Uri uri) {
+ Intent nativeAppIntent = new Intent(Intent.ACTION_VIEW, uri)
+ .addCategory(Intent.CATEGORY_BROWSABLE)
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
+ Intent.FLAG_ACTIVITY_REQUIRE_NON_BROWSER);
+ try {
+ context.startActivity(nativeAppIntent);
+ return true;
+ } catch (ActivityNotFoundException ex) {
+ return false;
+ }
+ }
+
+ private static Set<String> extractPackageNames(List<ResolveInfo> infos) {
+ Set<String> names = new HashSet<>();
+ for (ResolveInfo resolveInfo : infos) {
+ String packageName = resolveInfo.activityInfo.packageName;
+ names.add(packageName);
+ }
+ return names;
+ }
+
+ private static boolean launchNativeBeforeApi30(Context context, Uri uri) {
+ PackageManager pm = context.getPackageManager();
+
+ // Get all Apps that resolve a generic url
+ Intent browserActivityIntent = new Intent()
+ .setAction(Intent.ACTION_VIEW)
+ .addCategory(Intent.CATEGORY_BROWSABLE)
+ .setData(Uri.fromParts("http", "", null));
+ Set<String> genericResolvedList = extractPackageNames(
+ pm.queryIntentActivities(browserActivityIntent, 0));
+
+ // Get all apps that resolve the specific Url
+ Intent specializedActivityIntent = new Intent(Intent.ACTION_VIEW, uri)
+ .addCategory(Intent.CATEGORY_BROWSABLE);
+ Set<String> resolvedSpecializedList = extractPackageNames(
+ pm.queryIntentActivities(specializedActivityIntent, 0));
+
+ // Keep only the Urls that resolve the specific, but not the generic
+ // urls.
+ resolvedSpecializedList.removeAll(genericResolvedList);
+
+ // If the list is empty, no native app handlers were found.
+ if (resolvedSpecializedList.isEmpty()) {
+ return false;
+ }
+
+ // We found native handlers. Launch the Intent.
+ specializedActivityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(specializedActivityIntent);
+ return true;
+ }
+
+ public static void launchUri(Context context, Uri uri) {
+ boolean launched = Build.VERSION.SDK_INT >= 30 ?
+ launchNativeApi30(context, uri) :
+ launchNativeBeforeApi30(context, uri);
+
+ if (!launched) {
+ var builder = new CustomTabsIntent.Builder().setShowTitle(true);
+ if (context instanceof XmppActivity) {
+ builder = builder.setColorScheme(((XmppActivity) context).isDark() ? CustomTabsIntent.COLOR_SCHEME_DARK : CustomTabsIntent.COLOR_SCHEME_LIGHT);
+ }
+ builder.build().launchUrl(context, uri);
+ }
+ }
+}
@@ -42,6 +42,8 @@ import android.view.SoundEffectConstants;
import android.view.View;
import android.widget.Toast;
+import com.cheogram.android.BrowserHelper;
+
import java.util.Arrays;
import eu.siacs.conversations.R;
@@ -95,11 +97,17 @@ public class FixedURLSpan extends URLSpan {
}
}
+ if (uri.getScheme().equals("http") || uri.getScheme().equals("https")) {
+ widget.playSoundEffect(SoundEffectConstants.CLICK);
+ BrowserHelper.launchUri(context, uri);
+ return;
+ }
+
final Intent intent = new Intent(Intent.ACTION_VIEW, uri);
- if ("geo".equalsIgnoreCase(uri.getScheme())) {
- intent.setClass(context, ShowLocationActivity.class);
- } else {
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
+ if ("geo".equalsIgnoreCase(uri.getScheme())) {
+ intent.setClass(context, ShowLocationActivity.class);
+ } else {
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
}
try {
context.startActivity(intent);