androidshared-data

Two Application's using sharedUserID - createPackageContext issue


I have two separate applications. I would like appB to have access to the database within appA's code. I do not want to use a content provider in this instance.

I have read the post on SO regarding this and followed the instructions (Share SQLite database between 2 android apps?).

What I have done:

The Android Manifest of the AppA:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.micode.primaryapplication">

    <application
        android:sharedUserId="com.micode.sharedid"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:screenOrientation="portrait"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

The Android Manifest of AppB:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.micode.secondaryapplication">

    <application
        android:sharedUserId="com.micode.sharedid"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:screenOrientation="portrait"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

AppA creates a database, AppB needs to access the database.

The following code is used in AppB:

package com.micode.secondaryapplication;

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    Button btnExit;
    TextView txtViewDisplay;
    Context sharedContext;

    SQLiteDatabase db = null;
    private static String DBNAME = "Contacts.db";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        setupContext();
    }

    private void setupContext()
    {
        try {
            sharedContext = this.createPackageContext("com.micode.primaryapplication", Context.CONTEXT_INCLUDE_CODE);
            if (sharedContext == null) {
                return;
            }
        } catch (Exception e) {
            String error = e.getMessage();
            System.out.println(error);
            return;
        }
    }

I have tried building both applications with the exact same signing key, i.e. Build/Generate Signed APK and uninstalled any previous instances prior to installation.

I am also trying to run this in debug mode, i.e. install AppA in debug mode, then install AppB in debug mode.

In the latter case I see the following error:

Requesting code from com.micode.primaryapplication (with uid 10226) to be run in process com.micode.secondaryapplication (with uid 10227)

This error is hit when the following line is executed.

this.createPackageContext("com.micode.primaryapplication", Context.CONTEXT_INCLUDE_CODE);

It leads me to believe that the problem is with the installation, i.e. it seems to me that the shareduserid has been ignored and thus the two applications are not sharing the same UID, instead having unique UIDs.

To be clear, I only have two applications that are using these shared user ids.

Any help is greatly appreciated...


Solution

  • First, I really do not recommend this technique. sharedUserId is mostly for pre-installed apps. In particular, once you publish an app, you can never change the sharedUserId (including defining one where you did not have one before). If you change sharedUserId, and the user upgrades from the old sharedUserId to the new one, your app no longer has access to your app's own files, as they are owned by the old sharedUserId.

    That being said, android:sharedUserId is an attribute on <manifest>, not <application>.