18

I have implemented two activity-alias that the user should be able to enable or disable in runtime.

<activity-alias
    android:name=".ui.alias.open_location"
    android:targetActivity=".ui.activity.location"
    android:enabled="false">

    <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
        <category android:name="android.intent.category.LAUNCHER"/>
    </intent-filter>
</activity-alias>

I do not want them to be enabled in the beginning, to not clutter up the app-screen of the users device. But in runtime, the user should be able to enable the alias. I do this via the PackageManager:

PackageManager pm  = getApplicationContext().getPackageManager();
ComponentName componentName = new ComponentName(context, ".ui.alias.open_location");
pm.setComponentEnabledSetting(componentName,
                              PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
                              PackageManager.DONT_KILL_APP);

This works like charm in the beginning, but the alias gets disabled again, when an update of my app is installed. How can I prevent the system from overwriting the enabled state by the manifest? I don't want the user to floot with Launcher in the beginning and I don't want the user to recreate all alias shortcuts after an update.

I think I would need something similar to PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER, but only for enabled state.

Thanks!

Mattia Maestrini
  • 32,270
  • 15
  • 87
  • 94
JacksOnF1re
  • 3,336
  • 24
  • 55

2 Answers2

8

All the configurations of the enabled or disabled components are saved in this path of the device (0 is for the first user of the device):

/data/system/user/0/package-restrictions.xml

The format of the XML is something like this (you can pull the file only from a rooted device):

<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<package-restrictions>
    <pkg name="com.example.myapplication">
        <enabled-components>
            <item name="com.example.myapplication.ActivityAlias" />
        </enabled-components>
    </pkg>
    <preferred-activities />
    <persistent-preferred-activities />
    <crossProfile-intent-filters />
</package-restrictions>

When you update the app the enabled or disabled components remain the same, even if you clear the data of the app.

The only case in which this setting is lost is when the package name or the name of the component change.

I think your problem is due to the changing of the component name (maybe some strange configuration of ProGuard/DexGuard), since you can't upload on the play store an update with a different package name.

You can try to decompile the APK and verify if the name of the component is the same in both the app.

Mattia Maestrini
  • 32,270
  • 15
  • 87
  • 94
  • "maybe some strange configuration of ProGuard/DexGuard" well, this could actually be the case. I will check this at the weekend. thank you so far, I will comment everything I find out. – JacksOnF1re Nov 06 '15 at 17:29
  • So I ended up with creating a new test project. Installed it on a device, enabled some in the manifest as disabled declared alias. Afterwards I deployed a new version of the testproject and installed "the update". Actually the alias persists. And I don't know why, at my other project, they where gone multiple times. I will try to find the problem but I think your answer should the accepted. – JacksOnF1re Nov 09 '15 at 09:15
1

Save the options your user selects in SharedPreferences and re-apply them after the update. For this you can also save in preferences the version number, so you can know when this needs to be applied.

As you can see in this answer, it is safe to say that these preferences are kept on app update, thus maybe providing a solution for your issue.

Community
  • 1
  • 1
Mikel
  • 1,581
  • 17
  • 35
  • That does not work for me, because the update will remove the shortcuts, created by the user. And setting them back manually will clutter up the homescreen, because you can't get nor set the order where your shortcut should be placed to. Thanks nevertheless. – JacksOnF1re Nov 06 '15 at 15:02
  • Ok, I see what you mean. Would it work if you did it the other way? set it to true by default and remove them after app starts if they are not enabled by the user? Not the ideal experience though... – Mikel Nov 06 '15 at 15:07
  • Unfortunately not, because first installs will see all the aliases until they start the application and will get confused. – JacksOnF1re Nov 06 '15 at 15:08