Question

I am inheriting a code base that needs to be kept fairly in sync with the previous version to make updating to new versions as painless as possible when they push the changes via git. The changes I am making are related to re-styling and adding new features.

In the latest release, I was trying to install both the original version of the app alongside this custom version and got this error:

Failure [INSTALL_FAILED_CONFLICTING_PROVIDER]

I looked through my source control and found that in previous versions I was using the same authorities and name as the parent app, but I don't recall having this problem, but maybe I just never tested the case where both apps were installed at the same time?

In the original version of the manifest, this is the provider element:

<provider
    android:name="com.foo.mobile.android.provider.Provider"
    android:authorities="com.foo.android.mobile.contentprovider"
    android:exported="false" />

I tried changing the authority to this:

<provider
    android:name="com.foo.mobile.android.provider.Provider"
    android:authorities="com.bar.android.mobile.contentprovider"
    android:exported="false" />

But now the app crashes shortly after launch with SecurityException:

java.lang.SecurityException: Permission Denial: opening provider com.foo.mobile.android.provider.Provider from ProcessRecord{42cbc998 2462:com.bar/u0a191} (pid=2462, uid=10191) that is not exported from uid 10189

I've looked on SO and saw a couple of questions regarding this topic and also looked at the documentation and it all says I need this authorities to be different, but how can I keep this different while keeping synergy with the base code?

Was it helpful?

Solution

maybe I just never tested the case where both apps were installed at the same time?

I would presume this is the case. You cannot have two apps with providers supporting the same authority installed at the same time.

But now the app crashes shortly after launch with SecurityException:

My guess is that you changed your manifest, but you did not change the Uri that you are using to access the provider. Hence, your com.bar app is still trying to talk to the com.foo provider, and that provider is not exported.

how can I keep this different while keeping synergy with the base code?

Either this is the same app, or it is not.

If it is the same app, your first step is to switch back to the original package name. The only way you could have gotten Failure [INSTALL_FAILED_CONFLICTING_PROVIDER] is because you changed the package name and did not change the provider's authority. Changing the package name means that, from the standpoint of everyone outside of you and your team, it is a completely different app. Once you have switched back to the original package name (and rolled back to the original provider authority), everything should be fine, except that you won't be able to have the release version and the development version on the same device at the same time.

If you do indeed plan to have this app have a separate package name (so existing users of the existing app cannot upgrade to this new app), you will need to change the authority string in all relevant places. I presume that you can do this using a string resource, where you have different versions of the string resource. Or, if this is a free-vs.-paid app scenario, move to doing your builds using Gradle for Android, and set up separate free and paid product flavors, which can patch up your package name and authority data as part of the builds, without having to tweak the source code.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top