【问题标题】:disable the intent filter from android manifest programmatically以编程方式从android清单中禁用意图过滤器
【发布时间】:2017-03-23 04:02:09
【问题描述】:

在我的活动中,我有一个 web 视图,在 manifest.xml 中我声明了这样的意图过滤器

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

这不是启动器活动。 此处使用的意图过滤器用于 Web 视图长按上的复制粘贴工具栏。这工作正常。 除此之外,我想使用 Webview.setOnLongClickListener() 来获取其他选项,并且我是这样实现的。

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

我的问题是

  1. 如果我在没有 webview.setOnLongClickListener() 的情况下单独使用意图过滤器,我可以将文本复制粘贴到 webview 中

  2. 如果我单独使用 webview.setOnLongClickListener(),我可以执行其他选项并且它工作正常。

  3. 如果我同时实现了意图过滤器和 webview.setOnLongClickListener(),我无法从 webview 复制粘贴文本。 webview.setOnLongClickListener() 可以正常工作。在这里,我了解到这两个功能都依赖于 longPress,但我希望两者一起工作。

我搜索了 TextType 的 Webview.HitResult 选项,但它没有这样的选项。 https://developer.android.com/reference/android/webkit/WebView.HitTestResult.html

【问题讨论】:

  • 使用 touchlistener 和手势监听器,如果你想复制粘贴返回 false,如果你想做自定义任务返回 true

标签: android android-intent webview copy-paste long-press


【解决方案1】:

您可以使用活动别名来执行此操作(以编程方式从 android 清单中禁用意图过滤器):

1) 将 AndroidManifest.xml 中的(例如 AliasMySocialNetworkActivity)添加到您的 MySocialNetworkActivity 并将您的意图过滤器移至它们。它看起来像这样:

         <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) 添加此代码以在需要时抑制别名活动中的意图过滤器

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

3) 在需要时恢复意图过滤器:

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

更多详情见thisthat答案。

更新

其实你不需要别名,只要使用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);

直接针对您的活动。谢谢@pskink。

【讨论】:

  • activity-alias 是否需要setComponentEnabledSetting 才能工作?
  • 是否有必要创建另一个活动来编写第二点,或者我必须在 MySocialNetworkActivity 活动中编写
  • 您不需要创建任何其他活动。即使是别名,@pskink - 对。请查看更新的答案。
  • @pskink Ik ben onder de indruk )))
  • @pskink ) 实际上我使用的是其他 - 我的谷歌翻译中没有 de Nederlandse taal
【解决方案2】:

就我而言,

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>

禁用别名的代码

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

当我尝试时

getPackageName() + ".alias.Shortcut"

我得到 java.lang.IllegalArgumentException: 组件类 com.myexample.shortcutexample.alias.Shortcut 在 com.myexample.shortcutexample 中不存在

所以我把代码改成了

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

它就像魅力一样。

【讨论】:

  • 此策略是否也适用于启用/禁用清单中的 meta-data 标记?例如,一个实现WebView 的网络浏览器应用程序为用户提供opt-in/out of Google metrics collection 的功能。
【解决方案3】:

我实现了这一点,但在将我的应用升级到 Marshmallow 支持时遇到了问题。

您不能动态地从清单组件中删除 IntentFilter。

如果您正在使用 C & C++(NDK) 等 Marmalade/Native 语言,您可以禁用 IntentFilter 组件,但在平台升级后(如 Kitkat 到 LollyPop)会出现问题。

android 社​​区不建议在任何 developer.android.com 页面中进行此更改。

一个解决方案可能是,

  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();
    }

使用代码“别名”中的别名

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

【讨论】:

  • 你能根据我的代码建议我在哪里写这段代码吗?
  • 我是新手,如果您将其集成到我的代码中,将会很有帮助。我对 componentName 属性感到困惑。我是否有必要在 manifest.xml 文件中创建活动别名。
  • 能否详细说明。
【解决方案4】:

@Andrii Omelchenko 的回答是正确的,但我想补充一点,如果您在 build.gradle 中使用 applicationIdSuffix 参数作为您的构建类型(例如,调试变体的“.debug”后缀)或构建风格,它不会工作,因为它不会在代码中找到您的组件。

问题是当你指定时:

<activity-alias
    android:targetActivity=".MySocialNetworkActivity"
    android:name=".AliasMySocialNetworkActivity" />

见点“。”在名称的开头 - Android 将在它前面加上您应用的包名称,不带 applicationIdSuffix,因此您将获得例如com.example.packagename但在代码中,context.getPackageName() 将返回包名applicationIdSuffix所以在这种情况下它不会找到组件。

有两种解决方案:

  • 指定完整的 android:name,不带“.”在开始时。例如。 “我的社交网络活动”。
  • 使用变量"${applicationId} 指定包名前缀,其中包含应用的applicationIdSuffix(它在清单文件中自动可用):

    <activity-alias
        android:targetActivity=".MySocialNetworkActivity"
        android:name="${applicationId}.AliasMySocialNetworkActivity" />
    

【讨论】:

    猜你喜欢
    • 2020-02-03
    • 2012-12-18
    • 2011-09-18
    • 1970-01-01
    • 1970-01-01
    • 2013-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多