diff --git a/twidere/src/main/java/org/mariotaku/twidere/activity/BaseActivity.java b/twidere/src/main/java/org/mariotaku/twidere/activity/BaseActivity.java index 0419df401..26de04ed4 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/activity/BaseActivity.java +++ b/twidere/src/main/java/org/mariotaku/twidere/activity/BaseActivity.java @@ -60,6 +60,7 @@ import org.mariotaku.twidere.activity.iface.IThemedActivity; import org.mariotaku.twidere.fragment.iface.IBaseFragment.SystemWindowsInsetsCallback; import org.mariotaku.twidere.preference.iface.IDialogPreference; import org.mariotaku.twidere.util.AsyncTwitterWrapper; +import org.mariotaku.twidere.util.IntentUtils; import org.mariotaku.twidere.util.KeyboardShortcutsHandler; import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutCallback; import org.mariotaku.twidere.util.MediaLoaderWrapper; @@ -197,19 +198,25 @@ public class BaseActivity extends ATEActivity implements Constants, IExtendedAct super.onResume(); final NfcAdapter adapter = NfcAdapter.getDefaultAdapter(this); if (adapter != null && adapter.isEnabled()) { - final Intent linkIntent = new Intent(this, WebLinkHandlerActivity.class); - final PendingIntent intent = PendingIntent.getActivity(this, 0, linkIntent, 0); - final IntentFilter intentFilter = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED); - intentFilter.addDataScheme("http"); - intentFilter.addDataScheme("https"); - intentFilter.addDataAuthority("twitter.com", null); - intentFilter.addDataAuthority("www.twitter.com", null); - intentFilter.addDataAuthority("mobile.twitter.com", null); - intentFilter.addDataAuthority("fanfou.com", null); - try { - adapter.enableForegroundDispatch(this, intent, new IntentFilter[]{intentFilter}, null); - } catch (Exception e) { - // Ignore if blocked by modified roms + + final IntentFilter handlerFilter = IntentUtils.getWebLinkIntentFilter(this); + if (handlerFilter != null) { + final Intent linkIntent = new Intent(this, WebLinkHandlerActivity.class); + final PendingIntent intent = PendingIntent.getActivity(this, 0, linkIntent, 0); + final IntentFilter intentFilter = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED); + for (int i = 0, j = handlerFilter.countDataSchemes(); i < j; i++) { + intentFilter.addDataScheme(handlerFilter.getDataScheme(i)); + } + for (int i = 0, j = handlerFilter.countDataAuthorities(); i < j; i++) { + final IntentFilter.AuthorityEntry authorityEntry = handlerFilter.getDataAuthority(i); + final int port = authorityEntry.getPort(); + intentFilter.addDataAuthority(authorityEntry.getHost(), port < 0 ? null : Integer.toString(port)); + } + try { + adapter.enableForegroundDispatch(this, intent, new IntentFilter[]{intentFilter}, null); + } catch (Exception e) { + // Ignore if blocked by modified roms + } } } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/activity/MediaViewerActivity.java b/twidere/src/main/java/org/mariotaku/twidere/activity/MediaViewerActivity.java index 523963ed6..d8562f87a 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/activity/MediaViewerActivity.java +++ b/twidere/src/main/java/org/mariotaku/twidere/activity/MediaViewerActivity.java @@ -218,9 +218,10 @@ public final class MediaViewerActivity extends BaseActivity implements Constants case R.id.open_in_browser: { final ParcelableMedia media = getMedia()[currentItem]; try { - final Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(media.url)); + final Uri uri = Uri.parse(media.url); + final Intent intent = new Intent(Intent.ACTION_VIEW, uri); intent.addCategory(Intent.CATEGORY_BROWSABLE); - intent.setPackage(IntentUtils.getDefaultBrowserPackage(this)); + intent.setPackage(IntentUtils.getDefaultBrowserPackage(this, uri)); startActivity(intent); } catch (ActivityNotFoundException e) { // TODO show error, or improve app url diff --git a/twidere/src/main/java/org/mariotaku/twidere/activity/WebLinkHandlerActivity.java b/twidere/src/main/java/org/mariotaku/twidere/activity/WebLinkHandlerActivity.java index 3d2790a2f..c6a14e04a 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/activity/WebLinkHandlerActivity.java +++ b/twidere/src/main/java/org/mariotaku/twidere/activity/WebLinkHandlerActivity.java @@ -93,7 +93,7 @@ public class WebLinkHandlerActivity extends Activity implements Constants { } final Intent fallbackIntent = new Intent(Intent.ACTION_VIEW, uri); fallbackIntent.addCategory(Intent.CATEGORY_BROWSABLE); - fallbackIntent.setPackage(IntentUtils.getDefaultBrowserPackage(this)); + fallbackIntent.setPackage(IntentUtils.getDefaultBrowserPackage(this, uri)); final ComponentName componentName = fallbackIntent.resolveActivity(packageManager); if (componentName == null) { final Intent targetIntent = new Intent(Intent.ACTION_VIEW, uri); diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/UserFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/UserFragment.java index 71d06f7e0..7c1906425 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/UserFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/UserFragment.java @@ -1102,7 +1102,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener final Uri uri = LinkCreator.getUserWebLink(user); final Intent intent = new Intent(Intent.ACTION_VIEW, uri); intent.addCategory(Intent.CATEGORY_BROWSABLE); - intent.setPackage(IntentUtils.getDefaultBrowserPackage(getContext())); + intent.setPackage(IntentUtils.getDefaultBrowserPackage(getContext(), uri)); startActivity(intent); return true; } @@ -1355,8 +1355,8 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener @Override public boolean onLinkClick(final String link, final String orig, final UserKey accountKey, - final long extraId, final int type, final boolean sensitive, - int start, int end) { + final long extraId, final int type, final boolean sensitive, + int start, int end) { final ParcelableUser user = getUser(); if (user == null) return false; switch (type) { diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/IntentUtils.java b/twidere/src/main/java/org/mariotaku/twidere/util/IntentUtils.java index 276835d6c..1719f83bc 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/IntentUtils.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/IntentUtils.java @@ -1,9 +1,12 @@ package org.mariotaku.twidere.util; import android.app.Activity; +import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; import android.content.SharedPreferences; +import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.net.Uri; import android.os.Build; @@ -35,6 +38,7 @@ import org.mariotaku.twidere.model.util.ParcelableLocationUtils; import org.mariotaku.twidere.model.util.ParcelableMediaUtils; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Random; @@ -192,9 +196,14 @@ public class IntentUtils implements Constants { options, newDocument); } - public static String getDefaultBrowserPackage(Context context) { - Uri.Builder builder = new Uri.Builder(); - builder.scheme(SCHEME_HTTP); + public static String getDefaultBrowserPackage(Context context, Uri uri) { + if (!isWebLinkHandled(context, uri)) { + return null; + } + final Intent intent = new Intent(Intent.ACTION_VIEW); + intent.addCategory(Intent.CATEGORY_BROWSABLE); + Uri.Builder testBuilder = new Uri.Builder(); + testBuilder.scheme(SCHEME_HTTP); StringBuilder sb = new StringBuilder(); Random random = new Random(); int range = 'z' - 'a'; @@ -202,15 +211,29 @@ public class IntentUtils implements Constants { sb.append((char) ('a' + (Math.abs(random.nextInt()) % range))); } sb.append(".com"); - builder.authority(sb.toString()); - final Intent intent = new Intent(Intent.ACTION_VIEW, builder.build()); - intent.addCategory(Intent.CATEGORY_BROWSABLE); - List info = context.getPackageManager().queryIntentActivities(intent, 0); - if (info.isEmpty()) return null; - for (ResolveInfo item : info) { - if (item.isDefault) return item.activityInfo.packageName; - } - return info.get(0).activityInfo.packageName; + testBuilder.authority(sb.toString()); + intent.setData(testBuilder.build()); + + final ComponentName componentName = intent.resolveActivity(context.getPackageManager()); + if (componentName == null) return null; + return componentName.getPackageName(); + } + + public static boolean isWebLinkHandled(Context context, Uri uri) { + final IntentFilter filter = getWebLinkIntentFilter(context); + if (filter == null) return false; + return filter.match(Intent.ACTION_VIEW, null, uri.getScheme(), uri, + Collections.singleton(Intent.CATEGORY_BROWSABLE), LOGTAG) >= 0; + } + + @Nullable + public static IntentFilter getWebLinkIntentFilter(Context context) { + Intent testIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://twitter.com/user_name")); + testIntent.addCategory(Intent.CATEGORY_BROWSABLE); + testIntent.setPackage(context.getPackageName()); + final ResolveInfo resolveInfo = context.getPackageManager().resolveActivity(testIntent, + PackageManager.GET_RESOLVED_FILTER); + return resolveInfo != null ? resolveInfo.filter : null; } public static void openMediaDirectly(@NonNull final Context context, diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/MenuUtils.java b/twidere/src/main/java/org/mariotaku/twidere/util/MenuUtils.java index 3385f7277..f277e5ec7 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/MenuUtils.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/MenuUtils.java @@ -27,6 +27,7 @@ import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.res.Resources; import android.graphics.drawable.Drawable; +import android.net.Uri; import android.support.annotation.DrawableRes; import android.support.annotation.NonNull; import android.support.annotation.Nullable; @@ -54,8 +55,8 @@ import org.mariotaku.twidere.fragment.DestroyStatusDialogFragment; import org.mariotaku.twidere.fragment.SetUserNicknameDialogFragment; import org.mariotaku.twidere.graphic.ActionIconDrawable; import org.mariotaku.twidere.graphic.PaddingDrawable; -import org.mariotaku.twidere.menu.SupportStatusShareProvider; import org.mariotaku.twidere.menu.FavoriteItemProvider; +import org.mariotaku.twidere.menu.SupportStatusShareProvider; import org.mariotaku.twidere.model.ParcelableCredentials; import org.mariotaku.twidere.model.ParcelableStatus; import org.mariotaku.twidere.model.util.ParcelableCredentialsUtils; @@ -343,9 +344,10 @@ public class MenuUtils implements Constants { break; } case R.id.open_in_browser: { - final Intent intent = new Intent(Intent.ACTION_VIEW, LinkCreator.getStatusWebLink(status)); + final Uri uri = LinkCreator.getStatusWebLink(status); + final Intent intent = new Intent(Intent.ACTION_VIEW, uri); intent.addCategory(Intent.CATEGORY_BROWSABLE); - intent.setPackage(IntentUtils.getDefaultBrowserPackage(context)); + intent.setPackage(IntentUtils.getDefaultBrowserPackage(context, uri)); // IntentSupport.setSelector(intent, new Intent(Intent.ACTION_VIEW).addCategory(IntentSupport.CATEGORY_APP_BROWSER)); context.startActivity(intent); break; diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/OnLinkClickHandler.java b/twidere/src/main/java/org/mariotaku/twidere/util/OnLinkClickHandler.java index 73c2b07aa..1eac6cee0 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/OnLinkClickHandler.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/OnLinkClickHandler.java @@ -123,9 +123,12 @@ public class OnLinkClickHandler implements OnLinkClickListener, Constants { } break; } - case "twitter.com": { - openTwitterLink(link, accountKey); - return true; + default: { + if (IntentUtils.isWebLinkHandled(context, Uri.parse(link))) { + openTwitterLink(link, accountKey); + return true; + } + break; } } openLink(link); @@ -171,9 +174,10 @@ public class OnLinkClickHandler implements OnLinkClickListener, Constants { protected void openLink(final String link) { if (manager != null && manager.isActive()) return; - final Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(link)); + final Uri uri = Uri.parse(link); + final Intent intent = new Intent(Intent.ACTION_VIEW, uri); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - intent.setPackage(IntentUtils.getDefaultBrowserPackage(context)); + intent.setPackage(IntentUtils.getDefaultBrowserPackage(context, uri)); try { context.startActivity(intent); } catch (final ActivityNotFoundException e) {