Android : how to create componentName in code usin

2020-07-25 03:10发布

问题:

I have a feature that I only want to be available only when certain conditions are met so I have this activity alias:

<activity-alias android:name="share-files-text"
                    android:targetActivity=".MyActivity"
                    android:exported="true"
                    android:enabled="false">
        <intent-filter android:label="@string/open_with">
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data android:mimeType="application/pdf" />
            <data android:mimeType="image/*" />
            <data android:mimeType="text/plain" />
        </intent-filter>
    </activity-alias>

Once in activity I have this code to enable the component

        String packageName = getPackageName();
        ComponentName componentWithTextFiles = new ComponentName(packageName, "share-files-text");
        ComponentName componentWithoutTextFiles = new ComponentName(packageName, "share-files");
        if(DebugAndTestSettings.ENABLE_TEXT_SLIDE){
            getPackageManager().setComponentEnabledSetting(componentWithTextFiles, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0);
            getPackageManager().setComponentEnabledSetting(componentWithoutTextFiles, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 0);
        } else {
            getPackageManager().setComponentEnabledSetting(componentWithTextFiles, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 0);
            getPackageManager().setComponentEnabledSetting(componentWithoutTextFiles, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0);
        }

The problem is it crashes saying the package blabla doesn't contain an activity named share-files-text, how can disable/enable this element suing the alias name? Thanks

EDIT: I got the idea from this post: Android: Can I enable/disable an activity's intent filter programmatically?

回答1:

I have found the solution using this code

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

if your alias is "alias"

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


回答2:

Solution given by @vallllll worked fine, i tried to upvote or to comment , but i'm not able to do as still needs reputation points.

I tried a lot of other solutions in other questions and didn't work. Solution given here was the only one worked for me

Problem i was facing that after migrating code from sdk 18 to sdk 26, i was getting this error Component class x does not exist in Y , while calling setComponentEnabledSetting when switching from Activity to Alias-Activity Old code

      getPackageManager().setComponentEnabledSetting(
   new ComponentName(pkg name, alias name),
   PackageManager.COMPONENT_ENABLED_STATE_ENABLED,    PackageManager.DONT_KILL_APP);

New code

getPackageManager().setComponentEnabledSetting(
        new ComponentName(this, pkg name + alias name,
        PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);

Two changes were made, 1- change ComponentName constructor to use version that accepts context and class name instead of the constructor version using pkg name , class name 2- use fully qualified alias name + To get fully qualified alias name, i used the following code

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