Last active
August 29, 2015 13:58
Revisions
-
robUx4 revised this gist
Apr 14, 2014 . 1 changed file with 31 additions and 29 deletions.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,7 +1,9 @@ package com.levelup.touiteur; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import android.annotation.SuppressLint; import android.app.Activity; @@ -47,60 +49,47 @@ public abstract class ActivityWith_Ads extends Activity { */ private static boolean adClicked; static { List<IntentFilter> badFilters = new ArrayList<IntentFilter>(12); // intents from the Play Store manifest IntentFilter playStoreAssetBrowser = new IntentFilter(); playStoreAssetBrowser.addAction(Intent.ACTION_MAIN); playStoreAssetBrowser.addAction(Intent.ACTION_SEARCH); playStoreAssetBrowser.addCategory(Intent.CATEGORY_LAUNCHER); playStoreAssetBrowser.addCategory("android.intent.category.APP_MARKET"); // Intent.CATEGORY_APP_MARKET playStoreAssetBrowser.addCategory(Intent.CATEGORY_DEFAULT); badFilters.add(playStoreAssetBrowser); IntentFilter playStoreMarket = new IntentFilter(); playStoreMarket.addAction(Intent.ACTION_VIEW); playStoreMarket.addAction("android.nfc.action.NDEF_DISCOVERED"); playStoreMarket.addAction("com.google.android.finsky.NAVIGATIONAL_SUGGESTION"); playStoreMarket.addCategory(Intent.CATEGORY_BROWSABLE); playStoreMarket.addCategory(Intent.CATEGORY_DEFAULT); badFilters.add(filterWithData(playStoreMarket, "market", "search")); badFilters.add(filterWithData(playStoreMarket, "market", "details")); badFilters.add(filterWithData(playStoreMarket, "http", "market.android.com", "/", PatternMatcher.PATTERN_LITERAL)); badFilters.add(filterWithData(playStoreMarket, "http", "market.android.com", "/", PatternMatcher.PATTERN_PREFIX)); badFilters.add(filterWithData(playStoreMarket, "https", "market.android.com", "/", PatternMatcher.PATTERN_LITERAL)); badFilters.add(filterWithData(playStoreMarket, "https", "market.android.com", "/", PatternMatcher.PATTERN_PREFIX)); IntentFilter playStoreStore = new IntentFilter(); playStoreStore.addAction(Intent.ACTION_VIEW); playStoreStore.addAction("android.nfc.action.NDEF_DISCOVERED"); playStoreStore.addCategory(Intent.CATEGORY_BROWSABLE); playStoreStore.addCategory(Intent.CATEGORY_DEFAULT); badFilters.add(filterWithData(playStoreStore, "http", "play.google.com", "/store", PatternMatcher.PATTERN_PREFIX)); badFilters.add(filterWithData(playStoreStore, "https", "play.google.com", "/store", PatternMatcher.PATTERN_PREFIX)); badFilters.add(filterWithData(playStoreStore, "http", "play.google.com", "/redeem", PatternMatcher.PATTERN_PREFIX)); badFilters.add(filterWithData(playStoreStore, "https", "play.google.com", "/redeem", PatternMatcher.PATTERN_PREFIX)); IntentFilter playStorePurchase = new IntentFilter(); playStorePurchase.addAction("com.android.vending.billing.PURCHASE"); playStorePurchase.addCategory(Intent.CATEGORY_DEFAULT); badFilters.add(playStorePurchase); badIntentFilters = badFilters.toArray(new IntentFilter[]{}); } private static boolean isBadIntent(Context context, Intent intent) { @@ -252,6 +241,19 @@ protected void onStart() { super.onStart(); } private static IntentFilter filterWithData(IntentFilter baseFilter, String scheme, String authority) { IntentFilter result = new IntentFilter(baseFilter); result.addDataScheme(scheme); result.addDataAuthority(authority, null); return result; } private static IntentFilter filterWithData(IntentFilter baseFilter, String scheme, String authority, String path, int type) { IntentFilter result = filterWithData(baseFilter, scheme, authority); result.addDataPath(path, type); return result; } @Override public void setIntent(Intent newIntent) { if (null == newIntent) { -
robUx4 created this gist
Apr 2, 2014 .There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,263 @@ package com.levelup.touiteur; import java.lang.reflect.Field; import java.util.HashMap; import android.annotation.SuppressLint; import android.app.Activity; import android.app.Instrumentation; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.PatternMatcher; import android.text.TextUtils; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; import android.view.ViewGroup; public abstract class ActivityWith_Ads extends Activity { private final static String TAG = "AdSafe"; private final static boolean HAS_ADS = true; /** * Extra field you should put on your external browser Intents to make sure they're not blocked */ public static final String EXTRA_BYPASS_BLOCK = "com.levelup.touiteur.extra.urlbypass"; private static final IntentFilter badIntentFilters[]; /** * The {@link android.app.Instrumentation Instrumentation} of the process where filters are added */ private static Instrumentation mInstrumentation; /** * The list of {@link android.app.Instrumentation.ActivityMonitor ActivityMonitor} currently registered to block some intents * for the whole process */ private static Instrumentation.ActivityMonitor registeredMonitors[]; /** * Flag to indicate an ad was clicked so the resulting Intent launched is OK */ private static boolean adClicked; static { // intents from the Play Store manifest IntentFilter playStoreAssetBrowser = new IntentFilter(); playStoreAssetBrowser.addAction(Intent.ACTION_MAIN); playStoreAssetBrowser.addAction(Intent.ACTION_SEARCH); playStoreAssetBrowser.addCategory(Intent.CATEGORY_LAUNCHER); playStoreAssetBrowser.addCategory("android.intent.category.APP_MARKET"); // Intent.CATEGORY_APP_MARKET playStoreAssetBrowser.addCategory(Intent.CATEGORY_DEFAULT); IntentFilter playStoreMarket = new IntentFilter(); playStoreMarket.addAction(Intent.ACTION_VIEW); playStoreMarket.addAction("android.nfc.action.NDEF_DISCOVERED"); playStoreMarket.addAction("com.google.android.finsky.NAVIGATIONAL_SUGGESTION"); playStoreMarket.addCategory(Intent.CATEGORY_BROWSABLE); playStoreMarket.addCategory(Intent.CATEGORY_DEFAULT); playStoreMarket.addDataScheme("market"); playStoreMarket.addDataAuthority("search", null); playStoreMarket.addDataPath("/", PatternMatcher.PATTERN_LITERAL); playStoreMarket.addDataScheme("http"); playStoreMarket.addDataAuthority("market.android.com", null); playStoreMarket.addDataPath("/", PatternMatcher.PATTERN_LITERAL); playStoreMarket.addDataScheme("http"); playStoreMarket.addDataAuthority("market.android.com", null); playStoreMarket.addDataPath("/", PatternMatcher.PATTERN_PREFIX); playStoreMarket.addDataScheme("https"); playStoreMarket.addDataAuthority("market.android.com", null); playStoreMarket.addDataPath("/", PatternMatcher.PATTERN_LITERAL); playStoreMarket.addDataScheme("https"); playStoreMarket.addDataAuthority("market.android.com", null); playStoreMarket.addDataPath("/", PatternMatcher.PATTERN_PREFIX); IntentFilter playStoreStore = new IntentFilter(); playStoreStore.addAction(Intent.ACTION_VIEW); playStoreStore.addAction("android.nfc.action.NDEF_DISCOVERED"); playStoreStore.addCategory(Intent.CATEGORY_BROWSABLE); playStoreStore.addCategory(Intent.CATEGORY_DEFAULT); playStoreStore.addDataScheme("http"); playStoreStore.addDataAuthority("play.google.com", null); playStoreStore.addDataPath("/store", PatternMatcher.PATTERN_PREFIX); playStoreStore.addDataScheme("https"); playStoreStore.addDataAuthority("play.google.com", null); playStoreStore.addDataPath("/store", PatternMatcher.PATTERN_PREFIX); playStoreStore.addDataScheme("http"); playStoreStore.addDataAuthority("play.google.com", null); playStoreStore.addDataPath("/redeem", PatternMatcher.PATTERN_PREFIX); playStoreStore.addDataScheme("https"); playStoreStore.addDataAuthority("play.google.com", null); playStoreStore.addDataPath("/redeem", PatternMatcher.PATTERN_PREFIX); IntentFilter playStorePurchase = new IntentFilter(); playStorePurchase.addAction("com.android.vending.billing.PURCHASE"); playStorePurchase.addCategory(Intent.CATEGORY_DEFAULT); badIntentFilters = new IntentFilter[] { playStoreAssetBrowser, playStoreMarket, playStoreStore, playStorePurchase, }; } private static boolean isBadIntent(Context context, Intent intent) { if (null != intent.getComponent() && TextUtils.equals(intent.getComponent().getPackageName(), context.getPackageName())) { // this intent is launching some of our activities if (TextUtils.equals(intent.getComponent().getClassName(), "com.admarvel.android.ads.AdMarvelActivity")) { Intent testIntent = new Intent(Intent.ACTION_VIEW); testIntent.addCategory(Intent.CATEGORY_BROWSABLE); testIntent.setData(Uri.parse(intent.getStringExtra("url"))); intent = testIntent; // fall through to test the target that wasn't clicked } else if (TextUtils.equals(intent.getComponent().getClassName(), "com.admarvel.android.ads.AdMarvelVideoActivity")) { // this Intent was launched without the user clicking in the ad area Log.e(TAG, "AdMarvelVideoActivity launched without click intent:" + intent + " extras:" + intent.getExtras()); } else if (TextUtils.equals(intent.getComponent().getClassName(), "com.google.ads.AdActivity")) { Bundle adData = intent.getBundleExtra("com.google.ads.AdOpener"); if ("intent".equals(adData.get("action"))) { Object params = adData.get("params"); if (params instanceof HashMap) { Intent testIntent = new Intent(Intent.ACTION_VIEW); testIntent.addCategory(Intent.CATEGORY_BROWSABLE); testIntent.setData(Uri.parse(((HashMap<String, String>) params).get("u"))); intent = testIntent; // fall through to test the target that wasn't clicked } } } else if (TextUtils.equals(intent.getComponent().getClassName(), "com.millennialmedia.android.MMActivity")) { // this Intent was launched without the user clicking in the ad area Log.e(TAG, "MMActivity launched without click intent:" + intent + " extras:" + intent.getExtras()); } else if (TextUtils.equals(intent.getComponent().getClassName(), "com.millennialmedia.android.VideoPlayer")) { // this Intent was launched without the user clicking in the ad area Log.e(TAG, "VideoPlayer launched without click intent:" + intent + " extras:" + intent.getExtras()); } else { return false; // all other activities we know about should not be blocked } } ContentResolver resolver = context.getContentResolver(); for (IntentFilter monitor : badIntentFilters) { if (monitor.match(resolver, intent, true, "IntentBlock") >= 0) { Log.d(TAG, "bad intent detected intent:" + intent + " extras:" + intent.getExtras()); return true; } } return false; } public static boolean isIntentLegal(Context context, Intent intent) { if (adClicked || intent.hasExtra(EXTRA_BYPASS_BLOCK)) return true; return !isBadIntent(context, intent); } @Override public void startActivityForResult(Intent intent, int requestCode) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { // it will be done in the other version otherwise if (isIntentLegal(this, intent)) { unregisterIntentBlockers(); } } super.startActivityForResult(intent, requestCode); } @SuppressLint("NewApi") @Override public void startActivityForResult(Intent intent, int requestCode, Bundle options) { if (isIntentLegal(this, intent)) { unregisterIntentBlockers(); } super.startActivityForResult(intent, requestCode, options); } public static void registerIntentBlockers() { if (null != mInstrumentation && null == registeredMonitors) { Log.v(TAG, "register intent blockers in " + mInstrumentation); registeredMonitors = new Instrumentation.ActivityMonitor[badIntentFilters.length]; for (int i = 0; i < badIntentFilters.length; ++i) { registeredMonitors[i] = new Instrumentation.ActivityMonitor(badIntentFilters[i], null, true); mInstrumentation.addMonitor(registeredMonitors[i]); } } } public static void unregisterIntentBlockers() { if (null != mInstrumentation && null != registeredMonitors) { Log.v(TAG, "unregister intent blockers in " + mInstrumentation); for (int i = 0; i < registeredMonitors.length; ++i) { mInstrumentation.removeMonitor(registeredMonitors[i]); } registeredMonitors = null; } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.id.MainLayout); ViewGroup mAdGroup = (ViewGroup) findViewById(R.id.AdItem); if (!HAS_ADS) {// || !InvisiblePreferences.getInstance().getBoolean(InvisiblePreferences.Show_Ads)) { ((ViewGroup) mAdGroup.getParent()).removeView(mAdGroup); mAdGroup = null; } else { mAdGroup.setVisibility(View.GONE); View adClick = mAdGroup.findViewById(R.id.adClick); adClick.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { // ad touched adClicked = true; return false; } }); } } @Override protected void onStart() { adClicked = false; if (HAS_ADS) { try { Field instrumentationField = Activity.class.getDeclaredField("mInstrumentation"); instrumentationField.setAccessible(true); Instrumentation instrumentation = (Instrumentation) instrumentationField.get(this); Log.v(TAG, this + " Found instrumentation:" + instrumentation); if (null == mInstrumentation) { mInstrumentation = instrumentation; } else if (mInstrumentation != instrumentation) { Log.d(TAG, this + " different instrumentation:" + instrumentation + " was:" + mInstrumentation); unregisterIntentBlockers(); mInstrumentation = instrumentation; } registerIntentBlockers(); if (null == mInstrumentation) { Log.d(TAG, "Could not find instrumentation in " + this); } } catch (NoSuchFieldException e) { Log.d(TAG, "Failed to get the activity instrumentation in " + this, e); } catch (IllegalAccessException e) { Log.d(TAG, "Failed to get the activity instrumentation in " + this, e); } catch (IllegalArgumentException e) { Log.d(TAG, "Failed to get the activity instrumentation in " + this, e); } } super.onStart(); } @Override public void setIntent(Intent newIntent) { if (null == newIntent) { Log.e(TAG, "Intent blockers are not compatible with an Activity that has no intent set"); newIntent = new Intent(); } super.setIntent(newIntent); } } This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,7 @@ Intent launchIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); launchIntent.putExtra(ActivityWithAds.EXTRA_BYPASS_BLOCK, true); // make sure we're not blocked launchIntent.addCategory(Intent.CATEGORY_BROWSABLE); if (null!=referrer) launchIntent.putExtra("android.intent.extra.REFERRER", referrer); launchIntent.putExtra(Browser.EXTRA_APPLICATION_ID, activity.getPackageName()); activity.startActivity(launchIntent); This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,17 @@ <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="150dip" > <com.admarvel.android.ads.AdMarvelView android:id="@+id/adMarcel" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" /> <View android:id="@+id/adClick" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </FrameLayout> This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,26 @@ package com.levelup.touiteur; import android.annotation.SuppressLint; import android.app.Application; import android.content.Intent; import android.os.Bundle; public class MyApp extends Application { @Override public void startActivity(Intent intent) { if (ActivityWithAds.isIntentLegal(this, intent)) { ActivityWithAds.unregisterIntentBlockers(); super.startActivity(intent); } } @SuppressLint("NewApi") @Override public void startActivity(Intent intent, Bundle options) { if (ActivityWithAds.isIntentLegal(this, intent)) { ActivityWithAds.unregisterIntentBlockers(); super.startActivity(intent, options); } } }