Sharing Application Data Between Two Android Apps – Part I

In this blog post, i’ll show you How to share one Application data with one or many Application you need, the data’s can be SharedPreferences data, InternalStorage files and Local Database too.

Why one need to Share its Application data for another? – Some times when your developing Application for both free and paid application, then sharing data between apps will be more useful and for games, this will be used by many developers.

To achieve this, one should know What is Appication UserID?

At install time, Android gives each package a distinct Linux user ID. The name of a Linux user ID that will be shared with other applications. By default, Android assigns each application its own unique user ID. However, if this attribute is set to the same value for two or more applications, they will all share the same ID — provided that they are also signed by the same certificate. Application with the same user ID can access each other’s data and, if desired, run in the same process. for more details read here.

so, when developing applications, use same userId , in the app manifest.


android:sharedUserId="string"

android:sharedUserLabel="string resource"

sharedUserLabel is a user-readable label for the shared user ID. The label must be set as a reference to a string resource; it cannot be a raw string.

 

To Demonstrate this, we need to develop two Application for each. So this gonna be a massive tutorial and lets get started.

To make this simple, i have made 3 blog post including this.

My Other blog post on Sharing Application Data Between Apps.

  1. Part I – Sharing SharedPreferences data
  2. Part II – Sharing InternalStorage File’s
  3. Part III – Sharing Local DataBase (unofficial or undocumented method)
  4. Part IV – using ContentProvider (recommended by Android Developers)

 

1st Application :

Step 1: Create a new project File -> Android Project. While creating a new project give activity name as MainActivity and copy paste this code.

package com.skholingua.android.sharedpreferences_allow_sharing;

import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends Activity {

public static final String MyPREFERENCES = "MyPrefs";
public static final String STRING_VALUE = "stringKey";
public static final String INT_VALUE = "intKey";
public static final String LONG_VALUE = "longKey";
public static final String FLOAT_VALUE = "floatKey";
public static final String BOOLEAN_VALUE = "booleanKey";

EditText edt_string, edt_int, edt_long, edt_float;
CheckBox cbk;

SharedPreferences sharedPreferences;

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

sharedPreferences = getSharedPreferences(MyPREFERENCES,
Context.MODE_PRIVATE); // available only to this activity
edt_string = (EditText) findViewById(R.id.editTextString);
edt_int = (EditText) findViewById(R.id.editTextInt);
edt_long = (EditText) findViewById(R.id.editTextLong);
edt_float = (EditText) findViewById(R.id.editTextFloat);
cbk = (CheckBox) findViewById(R.id.checkBox1);

loadSavedPreferences();
}

private void loadSavedPreferences() {
// TODO Auto-generated method stub

boolean checkBoxValue = sharedPreferences.getBoolean(BOOLEAN_VALUE,
false);
String stringValue = sharedPreferences.getString(STRING_VALUE, "");
int intValue = sharedPreferences.getInt(INT_VALUE, 0);
long longValue = sharedPreferences.getLong(LONG_VALUE, 0);
float floatValue = sharedPreferences.getFloat(FLOAT_VALUE, 0);

if (checkBoxValue) {
cbk.setChecked(true);
cbk.setText("true");
} else {
cbk.setChecked(false);
cbk.setText("false");
}

if (sharedPreferences.contains(STRING_VALUE)) {
edt_string.setText(stringValue);
}
if (sharedPreferences.contains(INT_VALUE)) {
edt_int.setText(String.valueOf(intValue));
}
if (sharedPreferences.contains(LONG_VALUE)) {
edt_long.setText(String.valueOf(longValue));
}
if (sharedPreferences.contains(FLOAT_VALUE)) {
edt_float.setText(String.valueOf(floatValue));
}

}

public void clear(View view) {
Editor editor = sharedPreferences.edit();
// editor.remove(STRING_VALUE); // use this for removing certain key
// only
editor.clear();
editor.commit();
Toast.makeText(MainActivity.this, "All Values Removed",
Toast.LENGTH_SHORT).show();
}

public void save(View view) {

String stringValue = edt_string.getText().toString();
String intValue = edt_int.getText().toString();
String floatValue = edt_float.getText().toString();
String longValue = edt_long.getText().toString();

Editor editor = sharedPreferences.edit();
editor.putString(STRING_VALUE, stringValue);
if (intValue.isEmpty()) {
edt_int.setError("Cant be empty");
} else {
editor.putInt(INT_VALUE, Integer.valueOf(intValue));
}
if (longValue.isEmpty()) {
edt_long.setError("Cant be empty");
} else {
editor.putLong(LONG_VALUE, Long.valueOf(longValue));
}
if (floatValue.isEmpty()) {
edt_float.setError("Cant be empty");
} else {
editor.putFloat(FLOAT_VALUE, Float.valueOf(floatValue));
}

editor.putBoolean(BOOLEAN_VALUE, cbk.isChecked());

editor.commit();

Toast.makeText(MainActivity.this, "All Values Saved",
Toast.LENGTH_SHORT).show();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}

Step 2: Open your activity_main.xml and copy paste this code:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.skholingua.android.sharedpreferences_allow_sharing.MainActivity" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" >

        <TextView
            android:id="@+id/textView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="String Value :"
            android:textAppearance="?android:attr/textAppearanceMedium" />

        <EditText
            android:id="@+id/editTextString"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="5dp"
            android:ems="10"
            android:inputType="text" />

        <TextView
            android:id="@+id/textView5"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="int Value :"
            android:textAppearance="?android:attr/textAppearanceMedium" />

        <EditText
            android:id="@+id/editTextInt"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:ems="10"
            android:inputType="number" />

        <TextView
            android:id="@+id/textView4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Long Value :"
            android:textAppearance="?android:attr/textAppearanceMedium" />

        <EditText
            android:id="@+id/editTextLong"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:ems="10"
            android:inputType="numberSigned" />

        <TextView
            android:id="@+id/textView2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Float Value :"
            android:textAppearance="?android:attr/textAppearanceMedium" />

        <EditText
            android:id="@+id/editTextFloat"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:ems="10"
            android:inputType="numberDecimal" />

        <TextView
            android:id="@+id/textView3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Boolean Value :"
            android:textAppearance="?android:attr/textAppearanceMedium" />

        <CheckBox
            android:id="@+id/checkBox1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:checked="true"
            android:text="true" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:weightSum="2" >

            <Button
                android:id="@+id/button1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:onClick="save"
                android:text="Save" />

            <Button
                android:id="@+id/button3"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:onClick="clear"
                android:text="Clear" />
        </LinearLayout>
    </LinearLayout>

</RelativeLayout>

 

Step 3: Open your AndroidManifest.xml and copy paste this code.


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.skholingua.android.sharedpreferences_allow_sharing"
android:versionCode="1"
android:versionName="1.0"
android:sharedUserId="skholingua" >

<uses-sdk
android:minSdkVersion="16"
android:targetSdkVersion="19" />

<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

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

</manifest>

2nd Application :

Step 1: Create a new project File -> Android Project. While creating a new project give activity name as MainActivity and copy paste this code.


package com.skholingua.android.sharedpreferences_reader_shared;

import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends Activity {

public static final String MyPREFERENCES = "MyPrefs";
public static final String STRING_VALUE = "stringKey";
public static final String INT_VALUE = "intKey";
public static final String LONG_VALUE = "longKey";
public static final String FLOAT_VALUE = "floatKey";
public static final String BOOLEAN_VALUE = "booleanKey";

EditText edt_string, edt_int, edt_long, edt_float;
CheckBox cbk;

SharedPreferences sharedPreferences;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Context sharedContext = null;
try {
sharedContext = this.createPackageContext(
"com.skholingua.android.sharedpreferences_allow_sharing",
Context.MODE_PRIVATE);
if (sharedContext == null) {
return;
}
} catch (Exception e) {
String error = e.getMessage();
System.out.println("DB error : " + error);
return;
}

sharedPreferences = sharedContext.getSharedPreferences(MyPREFERENCES,
Activity.MODE_PRIVATE);

edt_string = (EditText) findViewById(R.id.editTextString);
edt_int = (EditText) findViewById(R.id.editTextInt);
edt_long = (EditText) findViewById(R.id.editTextLong);
edt_float = (EditText) findViewById(R.id.editTextFloat);
cbk = (CheckBox) findViewById(R.id.checkBox1);

loadSavedPreferences();
}

public void loadSavedPreferences() {
// TODO Auto-generated method stub

boolean checkBoxValue = sharedPreferences.getBoolean(BOOLEAN_VALUE,
false);
String stringValue = sharedPreferences.getString(STRING_VALUE, "");
int intValue = sharedPreferences.getInt(INT_VALUE, 0);
long longValue = sharedPreferences.getLong(LONG_VALUE, 0);
float floatValue = sharedPreferences.getFloat(FLOAT_VALUE, 0);

if (checkBoxValue) {
cbk.setChecked(true);
cbk.setText("true");
} else {
cbk.setChecked(false);
cbk.setText("false");
}

if (sharedPreferences.contains(STRING_VALUE)) {
edt_string.setText(stringValue);
}
if (sharedPreferences.contains(INT_VALUE)) {
edt_int.setText(String.valueOf(intValue));
}
if (sharedPreferences.contains(LONG_VALUE)) {
edt_long.setText(String.valueOf(longValue));
}
if (sharedPreferences.contains(FLOAT_VALUE)) {
edt_float.setText(String.valueOf(floatValue));
}

}

public void save(View view) {

String stringValue = edt_string.getText().toString();
String intValue = edt_int.getText().toString();
String floatValue = edt_float.getText().toString();
String longValue = edt_long.getText().toString();

Editor editor = sharedPreferences.edit();
editor.putString(STRING_VALUE, stringValue);
if (intValue.isEmpty()) {
edt_int.setError("Cant be empty");
} else {
editor.putInt(INT_VALUE, Integer.valueOf(intValue));
}
if (longValue.isEmpty()) {
edt_long.setError("Cant be empty");
} else {
editor.putLong(LONG_VALUE, Long.valueOf(longValue));
}
if (floatValue.isEmpty()) {
edt_float.setError("Cant be empty");
} else {
editor.putFloat(FLOAT_VALUE, Float.valueOf(floatValue));
}

editor.putBoolean(BOOLEAN_VALUE, cbk.isChecked());

editor.commit();
Toast.makeText(MainActivity.this, "All Values Saved",
Toast.LENGTH_SHORT).show();
}

public void clear(View view) {
Editor editor = sharedPreferences.edit();
// editor.remove(STRING_VALUE); // use this for removing certain key
// only
editor.clear();
editor.commit();
Toast.makeText(MainActivity.this, "All Values Removed",
Toast.LENGTH_SHORT).show();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}

Step 2: Open your activity_main.xml and copy paste this code:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.skholingua.android.sharedpreferences_reader_shared.MainActivity" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" >

        <TextView
            android:id="@+id/textView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="String Value :"
            android:textAppearance="?android:attr/textAppearanceMedium" />

        <EditText
            android:id="@+id/editTextString"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="5dp"
            android:ems="10"
            android:inputType="text" />

        <TextView
            android:id="@+id/textView5"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="int Value :"
            android:textAppearance="?android:attr/textAppearanceMedium" />

        <EditText
            android:id="@+id/editTextInt"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:ems="10"
            android:inputType="number" />

        <TextView
            android:id="@+id/textView4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Long Value :"
            android:textAppearance="?android:attr/textAppearanceMedium" />

        <EditText
            android:id="@+id/editTextLong"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:ems="10"
            android:inputType="numberSigned" />

        <TextView
            android:id="@+id/textView2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Float Value :"
            android:textAppearance="?android:attr/textAppearanceMedium" />

        <EditText
            android:id="@+id/editTextFloat"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:ems="10"
            android:inputType="numberDecimal" />

        <TextView
            android:id="@+id/textView3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Boolean Value :"
            android:textAppearance="?android:attr/textAppearanceMedium" />

        <CheckBox
            android:id="@+id/checkBox1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:checked="true"
            android:text="true" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:weightSum="2" >

            <Button
                android:id="@+id/button1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:onClick="save"
                android:text="Save" />

            <Button
                android:id="@+id/button3"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:onClick="clear"
                android:text="Clear" />
        </LinearLayout>
    </LinearLayout>

</RelativeLayout>

Step 3: Open your AndroidManifest.xml and copy paste this code.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.skholingua.android.sharedpreferences_reader_shared"
    android:versionCode="1"
    android:versionName="1.0"
    android:sharedUserId="skholingua" >

    <uses-sdk
        android:minSdkVersion="16"
        android:targetSdkVersion="19" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

</manifest>

 


ScreenShot:

Screenshot_2015-04-06-19-56-47 Screenshot_2015-04-06-19-57-36 Screenshot_2015-04-06-19-57-27


Tips to Remember always:

1. The String the sharedUserId is not the actual AppUserID and AppUserID is actually be in numbers, so this is just references to the AppUserID.
2. To make this actually work, we also need one more thing along with sharedUserId is both the application should be in same certificate i.e., both apps must compile with the same keystore
3. Last but not the least, we need context of that application to use. So, i’m using createPackageContext) to get the context of that application.
4. Remember if you using this many application sharing data, then this slow down the application process and chances to corrupt data, if you not handling it.

 


Hope this helpful. Your valuable comments are always welcomed. It will help to improve my post and understanding.

Download Source Code from here.

durga chiranjeevi

durga chiranjeevi

I'm currently working as Android developer at Energy Alternatives India. Interested in Application and Game development.
durga chiranjeevi

Leave a Reply

Your email address will not be published. Required fields are marked *