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.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
}
}
}
}

View File

@ -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

View File

@ -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);

View File

@ -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) {

View File

@ -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<ResolveInfo> 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,

View File

@ -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;

View File

@ -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) {