disable the intent filter from android manifest pr

2019-02-14 08:51发布

问题:

In my activity i have a web view and in manifest.xml i have declared intent filter like this

 <activity
        android:name=".ui.socialNetwork.MySocialNetworkActivity"
        android:configChanges="orientation|screenSize"
        android:process=":fb"
        android:screenOrientation="portrait" >

    </activity>

    <activity-alias
        android:targetActivity=".ui.socialNetwork.MySocialNetworkActivity"
        android:name=".AliasMySocialNetworkActivity"
        android:label="@string/app_name">
        <intent-filter>
            <action android:name="android.intent.action.PROCESS_TEXT" />
            <category android:name="android.intent.category.DEFAULT" />
            <data android:mimeType="text/plain" />
        </intent-filter>
    </activity-alias>

This is not launcher activity. The intent filter used here is for copy paste toolbar on web view long press.This works fine. In addition to this i want to use Webview.setOnLongClickListener() for additional options, and i implemented like this.

  webView = (WebView) findViewById(R.id.webview);

PackageManager pm = getApplicationContext().getPackageManager();
    ComponentName compName =
            new ComponentName(getPackageName(), getPackageName() + ".AliasMySocialNetworkActivity");
    pm.setComponentEnabledSetting(
            compName,
            PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
            PackageManager.DONT_KILL_APP);

    webView.setOnLongClickListener(new View.OnLongClickListener() {
        public boolean onLongClick(View v) {
            WebView.HitTestResult hitResult = null;
            hitResult = webView.getHitTestResult();
            if (hitResult != null && hitResult.getExtra() != null) {
                final String hitRes = hitResult.getExtra();
                if (hitResult.getType() == WebView.HitTestResult.IMAGE_TYPE || hitResult.getType() == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE) {
                    Intent ImageSaveIntent = new Intent(getApplicationContext(), SaveImage.class);
                    ImageSaveIntent.putExtra("putImage", hitRes);
                    startActivity(ImageSaveIntent);
                }
                if (hitResult.getType() != WebView.HitTestResult.IMAGE_TYPE || hitResult.getType() != WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE) {
                    PackageManager pm = getApplicationContext().getPackageManager();
                    ComponentName compName =
                            new ComponentName(getPackageName(), getPackageName() + ".AliasMySocialNetworkActivity");
                    pm.setComponentEnabledSetting(
                            compName,
                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
                            PackageManager.DONT_KILL_APP);
                                       }
            }
            return true;
        }
    });

My Problem is that

  1. If i use intent filter alone without webview.setOnLongClickListener(), i can copy paste the text in webview

  2. If i use webview.setOnLongClickListener() alone, i can do my additional options and it is working fine.

  3. If i implement both intent filter and webview.setOnLongClickListener(), i cannot copy paste the text from webview. webview.setOnLongClickListener() will work fine. Here i understood that both functionalities depends on longPress, But i want both to work together.

I searched Webview.HitResult options for TextType, but it is not having such option. https://developer.android.com/reference/android/webkit/WebView.HitTestResult.html

Please help me in solving this.

回答1:

You can do this (disable the intent filter from android manifest programatically) by using Activity Alias:

1) add (e.g. AliasMySocialNetworkActivity) in AndroidManifest.xml to your MySocialNetworkActivity and move your intent-filter to them. It will be looks like that:

         <activity-alias
            android:targetActivity=".MySocialNetworkActivity"
            android:name=".AliasMySocialNetworkActivity"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.PROCESS_TEXT" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="text/plain" />
             </intent-filter>
        </activity-alias>

2) add this code to suppress intent-filter in alias activity when You need that

PackageManager pm = getApplicationContext().getPackageManager();
        ComponentName compName =
                new ComponentName(getPackageName(), getPackageName() + ".AliasMySocialNetworkActivity");
        pm.setComponentEnabledSetting(
                compName,
                PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
                PackageManager.DONT_KILL_APP);

3) restore intent-filter, when You need it:

PackageManager pm = getApplicationContext().getPackageManager();
    ComponentName compName =
            new ComponentName(getPackageName(), getPackageName() + ".AliasMySocialNetworkActivity");
    pm.setComponentEnabledSetting(
            compName,
            PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
            PackageManager.DONT_KILL_APP);

For more details see this or that answer.

Update

Actually You don't need Alias, just use PackageManager.COMPONENT_ENABLED_STATE_DISABLED/PackageManager.COMPONENT_ENABLED_STATE_ENABLED

PackageManager pm = getApplicationContext().getPackageManager();
        ComponentName compName =
                new ComponentName(getPackageName(), getPackageName() + ".MySocialNetworkActivity");
        pm.setComponentEnabledSetting(
                compName,
                PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
                PackageManager.DONT_KILL_APP);

directly on your activity. Thanks @pskink.



回答2:

This i achieved but faced issues when upgraded my app to Marshmallow support.

Dynamically you can't remove the IntentFilter from the Manifest Components.

If you are working on Marmalade/Native languages like C & C++(NDK), You can achieve disable the IntentFilter components but after platform upgrade(like Kitkat to LollyPop) it gives problem.

This changes is not recommended by android community in any of the developer.android.com pages.

One Solution could be,

  String packageName = getPackageName();
    try {
        PackageInfo p = getApplicationContext().getPackageManager().getPackageInfo(packageName, PackageManager.GET_ACTIVITIES);
        for (ActivityInfo activityInfo : p.activities) {
            if(log.d()) log.d("ACT " + activityInfo.name+" "+activityInfo.packageName);
        }
    } catch (PackageManager.NameNotFoundException e) {
        e.printStackTrace();
    }

Go with alias from the code "alias"

ComponentName componentWithoutTextFiles = new ComponentName(packageName, packageName".alias");



回答3:

In my case,

Code in AndroidManifest.xml

<activity-alias
        android:name="alias.Shortcut"
        android:icon="@drawable/shortcut_icon"
        android:label="@string/shortcut_text"
        android:targetActivity="com.myexample.shortcutexample.ShortcutActivity">
        <intent-filter>
            <action android:name="android.intent.action.CREATE_SHORTCUT" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </activity-alias>

Code to disable alias

PackageManager pm = getApplicationContext().getPackageManager();
        ComponentName compName =
                new ComponentName(getPackageName(), getPackageName() + ".alias.Shortcut");
        pm.setComponentEnabledSetting(
                compName,
                PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
                PackageManager.DONT_KILL_APP);

when I tried

getPackageName() + ".alias.Shortcut"

I got java.lang.IllegalArgumentException: Component class com.myexample.shortcutexample.alias.Shortcut does not exist in com.myexample.shortcutexample

So I changed my code to

ComponentName compName =
                new ComponentName(getPackageName(), "alias.Shortcut");

and it worked like charm.