improved link handler

This commit is contained in:
Mariotaku Lee 2016-04-19 08:55:04 +08:00
parent caccdca1a2
commit 6c1623cecb
7 changed files with 76 additions and 39 deletions

View File

@ -60,6 +60,7 @@ import org.mariotaku.twidere.activity.iface.IThemedActivity;
import org.mariotaku.twidere.fragment.iface.IBaseFragment.SystemWindowsInsetsCallback; import org.mariotaku.twidere.fragment.iface.IBaseFragment.SystemWindowsInsetsCallback;
import org.mariotaku.twidere.preference.iface.IDialogPreference; import org.mariotaku.twidere.preference.iface.IDialogPreference;
import org.mariotaku.twidere.util.AsyncTwitterWrapper; import org.mariotaku.twidere.util.AsyncTwitterWrapper;
import org.mariotaku.twidere.util.IntentUtils;
import org.mariotaku.twidere.util.KeyboardShortcutsHandler; import org.mariotaku.twidere.util.KeyboardShortcutsHandler;
import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutCallback; import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutCallback;
import org.mariotaku.twidere.util.MediaLoaderWrapper; import org.mariotaku.twidere.util.MediaLoaderWrapper;
@ -197,19 +198,25 @@ public class BaseActivity extends ATEActivity implements Constants, IExtendedAct
super.onResume(); super.onResume();
final NfcAdapter adapter = NfcAdapter.getDefaultAdapter(this); final NfcAdapter adapter = NfcAdapter.getDefaultAdapter(this);
if (adapter != null && adapter.isEnabled()) { if (adapter != null && adapter.isEnabled()) {
final Intent linkIntent = new Intent(this, WebLinkHandlerActivity.class);
final PendingIntent intent = PendingIntent.getActivity(this, 0, linkIntent, 0); final IntentFilter handlerFilter = IntentUtils.getWebLinkIntentFilter(this);
final IntentFilter intentFilter = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED); if (handlerFilter != null) {
intentFilter.addDataScheme("http"); final Intent linkIntent = new Intent(this, WebLinkHandlerActivity.class);
intentFilter.addDataScheme("https"); final PendingIntent intent = PendingIntent.getActivity(this, 0, linkIntent, 0);
intentFilter.addDataAuthority("twitter.com", null); final IntentFilter intentFilter = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
intentFilter.addDataAuthority("www.twitter.com", null); for (int i = 0, j = handlerFilter.countDataSchemes(); i < j; i++) {
intentFilter.addDataAuthority("mobile.twitter.com", null); intentFilter.addDataScheme(handlerFilter.getDataScheme(i));
intentFilter.addDataAuthority("fanfou.com", null); }
try { for (int i = 0, j = handlerFilter.countDataAuthorities(); i < j; i++) {
adapter.enableForegroundDispatch(this, intent, new IntentFilter[]{intentFilter}, null); final IntentFilter.AuthorityEntry authorityEntry = handlerFilter.getDataAuthority(i);
} catch (Exception e) { final int port = authorityEntry.getPort();
// Ignore if blocked by modified roms 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
}
} }
} }
} }

View File

@ -218,9 +218,10 @@ public final class MediaViewerActivity extends BaseActivity implements Constants
case R.id.open_in_browser: { case R.id.open_in_browser: {
final ParcelableMedia media = getMedia()[currentItem]; final ParcelableMedia media = getMedia()[currentItem];
try { 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.addCategory(Intent.CATEGORY_BROWSABLE);
intent.setPackage(IntentUtils.getDefaultBrowserPackage(this)); intent.setPackage(IntentUtils.getDefaultBrowserPackage(this, uri));
startActivity(intent); startActivity(intent);
} catch (ActivityNotFoundException e) { } catch (ActivityNotFoundException e) {
// TODO show error, or improve app url // TODO show error, or improve app url

View File

@ -93,7 +93,7 @@ public class WebLinkHandlerActivity extends Activity implements Constants {
} }
final Intent fallbackIntent = new Intent(Intent.ACTION_VIEW, uri); final Intent fallbackIntent = new Intent(Intent.ACTION_VIEW, uri);
fallbackIntent.addCategory(Intent.CATEGORY_BROWSABLE); fallbackIntent.addCategory(Intent.CATEGORY_BROWSABLE);
fallbackIntent.setPackage(IntentUtils.getDefaultBrowserPackage(this)); fallbackIntent.setPackage(IntentUtils.getDefaultBrowserPackage(this, uri));
final ComponentName componentName = fallbackIntent.resolveActivity(packageManager); final ComponentName componentName = fallbackIntent.resolveActivity(packageManager);
if (componentName == null) { if (componentName == null) {
final Intent targetIntent = new Intent(Intent.ACTION_VIEW, uri); final Intent targetIntent = new Intent(Intent.ACTION_VIEW, uri);

View File

@ -1102,7 +1102,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
final Uri uri = LinkCreator.getUserWebLink(user); final Uri uri = LinkCreator.getUserWebLink(user);
final Intent intent = new Intent(Intent.ACTION_VIEW, uri); final Intent intent = new Intent(Intent.ACTION_VIEW, uri);
intent.addCategory(Intent.CATEGORY_BROWSABLE); intent.addCategory(Intent.CATEGORY_BROWSABLE);
intent.setPackage(IntentUtils.getDefaultBrowserPackage(getContext())); intent.setPackage(IntentUtils.getDefaultBrowserPackage(getContext(), uri));
startActivity(intent); startActivity(intent);
return true; return true;
} }
@ -1355,8 +1355,8 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
@Override @Override
public boolean onLinkClick(final String link, final String orig, final UserKey accountKey, public boolean onLinkClick(final String link, final String orig, final UserKey accountKey,
final long extraId, final int type, final boolean sensitive, final long extraId, final int type, final boolean sensitive,
int start, int end) { int start, int end) {
final ParcelableUser user = getUser(); final ParcelableUser user = getUser();
if (user == null) return false; if (user == null) return false;
switch (type) { switch (type) {

View File

@ -1,9 +1,12 @@
package org.mariotaku.twidere.util; package org.mariotaku.twidere.util;
import android.app.Activity; import android.app.Activity;
import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo; import android.content.pm.ResolveInfo;
import android.net.Uri; import android.net.Uri;
import android.os.Build; import android.os.Build;
@ -35,6 +38,7 @@ import org.mariotaku.twidere.model.util.ParcelableLocationUtils;
import org.mariotaku.twidere.model.util.ParcelableMediaUtils; import org.mariotaku.twidere.model.util.ParcelableMediaUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
@ -192,9 +196,14 @@ public class IntentUtils implements Constants {
options, newDocument); options, newDocument);
} }
public static String getDefaultBrowserPackage(Context context) { public static String getDefaultBrowserPackage(Context context, Uri uri) {
Uri.Builder builder = new Uri.Builder(); if (!isWebLinkHandled(context, uri)) {
builder.scheme(SCHEME_HTTP); 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(); StringBuilder sb = new StringBuilder();
Random random = new Random(); Random random = new Random();
int range = 'z' - 'a'; int range = 'z' - 'a';
@ -202,15 +211,29 @@ public class IntentUtils implements Constants {
sb.append((char) ('a' + (Math.abs(random.nextInt()) % range))); sb.append((char) ('a' + (Math.abs(random.nextInt()) % range)));
} }
sb.append(".com"); sb.append(".com");
builder.authority(sb.toString()); testBuilder.authority(sb.toString());
final Intent intent = new Intent(Intent.ACTION_VIEW, builder.build()); intent.setData(testBuilder.build());
intent.addCategory(Intent.CATEGORY_BROWSABLE);
List<ResolveInfo> info = context.getPackageManager().queryIntentActivities(intent, 0); final ComponentName componentName = intent.resolveActivity(context.getPackageManager());
if (info.isEmpty()) return null; if (componentName == null) return null;
for (ResolveInfo item : info) { return componentName.getPackageName();
if (item.isDefault) return item.activityInfo.packageName; }
}
return info.get(0).activityInfo.packageName; 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, public static void openMediaDirectly(@NonNull final Context context,

View File

@ -27,6 +27,7 @@ import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo; import android.content.pm.ResolveInfo;
import android.content.res.Resources; import android.content.res.Resources;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.support.annotation.DrawableRes; import android.support.annotation.DrawableRes;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.annotation.Nullable; 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.fragment.SetUserNicknameDialogFragment;
import org.mariotaku.twidere.graphic.ActionIconDrawable; import org.mariotaku.twidere.graphic.ActionIconDrawable;
import org.mariotaku.twidere.graphic.PaddingDrawable; import org.mariotaku.twidere.graphic.PaddingDrawable;
import org.mariotaku.twidere.menu.SupportStatusShareProvider;
import org.mariotaku.twidere.menu.FavoriteItemProvider; import org.mariotaku.twidere.menu.FavoriteItemProvider;
import org.mariotaku.twidere.menu.SupportStatusShareProvider;
import org.mariotaku.twidere.model.ParcelableCredentials; import org.mariotaku.twidere.model.ParcelableCredentials;
import org.mariotaku.twidere.model.ParcelableStatus; import org.mariotaku.twidere.model.ParcelableStatus;
import org.mariotaku.twidere.model.util.ParcelableCredentialsUtils; import org.mariotaku.twidere.model.util.ParcelableCredentialsUtils;
@ -343,9 +344,10 @@ public class MenuUtils implements Constants {
break; break;
} }
case R.id.open_in_browser: { 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.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)); // IntentSupport.setSelector(intent, new Intent(Intent.ACTION_VIEW).addCategory(IntentSupport.CATEGORY_APP_BROWSER));
context.startActivity(intent); context.startActivity(intent);
break; break;

View File

@ -123,9 +123,12 @@ public class OnLinkClickHandler implements OnLinkClickListener, Constants {
} }
break; break;
} }
case "twitter.com": { default: {
openTwitterLink(link, accountKey); if (IntentUtils.isWebLinkHandled(context, Uri.parse(link))) {
return true; openTwitterLink(link, accountKey);
return true;
}
break;
} }
} }
openLink(link); openLink(link);
@ -171,9 +174,10 @@ public class OnLinkClickHandler implements OnLinkClickListener, Constants {
protected void openLink(final String link) { protected void openLink(final String link) {
if (manager != null && manager.isActive()) return; 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.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setPackage(IntentUtils.getDefaultBrowserPackage(context)); intent.setPackage(IntentUtils.getDefaultBrowserPackage(context, uri));
try { try {
context.startActivity(intent); context.startActivity(intent);
} catch (final ActivityNotFoundException e) { } catch (final ActivityNotFoundException e) {