Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Android

Cách truy cập SharedPreferences của ứng dụng khác trong Android

Giới thiệu

Bài viết này minh họa cách đọc/ghi SharedPreferences của một ứng dụng khác thông qua cơ chế sharedUserId (cần cùng chữ ký ký ứng dụng). Lưu ý: Từ Android 10 (API 29), cơ chế này bị hạn chế nghiêm ngặt.

Yêu cầu tiên quyết

  • Hai ứng dụng phải có cùng android:sharedUserId trong Manifest
  • Hai ứng dụng phải được ký bằng cùng một keystore (cùng chữ ký)
  • Ứng dụng đích phải dùng Context.MODE_WORLD_READABLE hoặc MODE_WORLD_WRITEABLE (deprecated từ API 17)

Các bước thực hiện (Demo trong cùng 1 app)

Bước 1: Tạo dự án mới

Bước 2: Layout (res/layout/activity_main.xml)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/etEmail"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:ems="10"
        android:hint="Email"
        android:inputType="textEmailAddress" />

    <EditText
        android:id="@+id/etName"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:hint="Name"
        android:inputType="text" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="50dp"
        android:onClick="Save"
        android:text="Save" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="Clear"
        android:text="Clear Data" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="Retrieve"
        android:text="Retrieve Data" />

</LinearLayout>

Bước 3: Code Java (src/MainActivity.java)

package app.com.sample;

import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

    EditText etName, etEmail;
    SharedPreferences sharedPreferences;

    public static final String MY_PREFERENCE = "myPref";
    public static final String KEY_NAME = "nameKey";
    public static final String KEY_EMAIL = "emailKey";

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

        etName = findViewById(R.id.etName);
        etEmail = findViewById(R.id.etEmail);

        // MODE_PRIVATE: Chỉ app này truy cập được (mặc định, an toàn)
        // MODE_WORLD_READABLE/WRITEABLE: ĐÃ DEPRECATED, KHÔNG NÊN DÙNG
        sharedPreferences = getSharedPreferences(MY_PREFERENCE, Context.MODE_PRIVATE);

        loadSavedData();
    }

    private void loadSavedData() {
        if (sharedPreferences.contains(KEY_NAME)) {
            etName.setText(sharedPreferences.getString(KEY_NAME, ""));
        }
        if (sharedPreferences.contains(KEY_EMAIL)) {
            etEmail.setText(sharedPreferences.getString(KEY_EMAIL, ""));
        }
    }

    public void Clear(View view) {
        etName.setText("");
        etEmail.setText("");
        Toast.makeText(this, "Cleared", Toast.LENGTH_LONG).show();
    }

    public void Retrieve(View view) {
        loadSavedData();
        Toast.makeText(this, "Retrieved", Toast.LENGTH_LONG).show();
    }

    public void Save(View view) {
        String name = etName.getText().toString();
        String email = etEmail.getText().toString();

        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putString(KEY_NAME, name);
        editor.putString(KEY_EMAIL, email);
        editor.apply(); // apply() async, commit() sync

        Toast.makeText(this, "Saved", Toast.LENGTH_LONG).show();
    }
}

Bước 4: Manifest (cần sharedUserId nếu muốn chia sẻ thực sự)

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
    package="app.com.sample"
    android:sharedUserId="com.mycompany.shareduid"> <!-- Quan trọng -->

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        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>

Cách truy cập SharedPreferences của app khác (nếu đủ điều kiện)

// Trong app B, muốn đọc SharedPreferences của app A
try {
    Context otherAppContext = createPackageContext("com.app.a.package", Context.CONTEXT_IGNORE_SECURITY);
    SharedPreferences sharedPref = otherAppContext.getSharedPreferences("pref_name", Context.MODE_PRIVATE);
    String value = sharedPref.getString("key", "default");
} catch (PackageManager.NameNotFoundException e) {
    e.printStackTrace();
}

Giải pháp hiện đại thay thế

Do hạn chế bảo mật, Google khuyến nghị các phương án thay thế:

  • ContentProvider: Chia sẻ dữ liệu có kiểm soát quyền truy cập
  • DataStore (Jetpack): Thay thế SharedPreferences, hỗ trợ coroutine, type-safe
  • File trong external storage: Chia sẻ qua file (cần quyền storage)
  • WorkManager + BroadcastReceiver: Đồng bộ dữ liệu giữa apps

Chạy demo

Chạy app, nhập tên/email, nhấn Save. Thoát app và mở lại - dữ liệu vẫn còn (Retrieve). Nhấn Clear để xóa.

Cách truy cập SharedPreferences của ứng dụng khác trong Android Cách truy cập SharedPreferences của ứng dụng khác trong Android