অন্য অ্যাপের SharedPreferences এক্সেস করা: MODE_WORLD_READABLE এবং ContentProvider পদ্ধতি
গুরুত্বপূর্ণ সতর্কতা: Android 4.2 (API 17) থেকে MODE_WORLD_READABLE এবং MODE_WORLD_WRITABLE ডিপ্রিকেইটেড এবং নিরাপত্তা কারণে ব্লক করা হয়েছে। বর্তমানে অন্য অ্যাপের শেয়ার্ড প্রিফারেন্স পড়ার সুপারিশ করা পদ্ধতি হলো ContentProvider ব্যবহার করা। এই টিউটোরিয়ালে দুটি পদ্ধতিই আলোচনা করা হলো।
প্রয়োজনীয় ধাপসমূহ
ধাপ ১: ডেটা সংরক্ষণকারী অ্যাপ (Provider App) তৈরি করুন
লেআউট (activity_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<EditText
android:id="@+id/etEmail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:hint="ইমেইল"
android:inputType="textEmailAddress" />
<EditText
android:id="@+id/etName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="নাম"
android:inputType="text" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:onClick="saveData"
android:text="সেভ করুন" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="clearData"
android:text="ডেটা মুছুন" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="retrieveData"
android:text="ডেটা পড়ুন" />
</LinearLayout>
MainActivity.java (Provider App)
package com.example.providerapp;
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_PREF = "mySharedPref";
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);
sharedPreferences = getSharedPreferences(MY_PREF, 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 saveData(View view) {
String name = etName.getText().toString().trim();
String email = etEmail.getText().toString().trim();
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(KEY_NAME, name);
editor.putString(KEY_EMAIL, email);
editor.apply();
Toast.makeText(this, "ডেটা সেভ করা হয়েছে", Toast.LENGTH_SHORT).show();
}
public void clearData(View view) {
etName.setText("");
etEmail.setText("");
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.clear().apply();
Toast.makeText(this, "ডেটা মুছে ফেলা হয়েছে", Toast.LENGTH_SHORT).show();
}
public void retrieveData(View view) {
loadSavedData();
Toast.makeText(this, "ডেটা লোড করা হয়েছে", Toast.LENGTH_SHORT).show();
}
}
ধাপ ২: ContentProvider তৈরি করুন (সুপারিশ করা পদ্ধতি)
MyContentProvider.java
package com.example.providerapp;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.net.Uri;
import android.os.Bundle;
public class MyContentProvider extends ContentProvider {
private static final String AUTHORITY = "com.example.providerapp.dataprovider";
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/sharedprefs");
private static final int SHARED_PREFS = 1;
private static final UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
static {
uriMatcher.addURI(AUTHORITY, "sharedprefs", SHARED_PREFS);
}
private SharedPreferences sharedPreferences;
@Override
public boolean onCreate() {
Context context = getContext();
if (context != null) {
sharedPreferences = context.getSharedPreferences("mySharedPref", Context.MODE_PRIVATE);
}
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
MatrixCursor cursor = new MatrixCursor(new String[]{"key", "value"});
if (sharedPreferences != null) {
// সব কী-ভ্যালু পেয়ার কーソরে যোগ করুন
for (String key : sharedPreferences.getAll().keySet()) {
String value = sharedPreferences.getString(key, "");
cursor.addRow(new Object[]{key, value});
}
}
return cursor;
}
@Override
public String getType(Uri uri) {
return "vnd.android.cursor.dir/vnd.example.sharedprefs";
}
@Override
public Uri insert(Uri uri, ContentValues values) { return null; }
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) { return 0; }
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { return 0; }
}
AndroidManifest.xml-এ প্রোভাইডার ডিক্লেয়ার করুন
<application ...>
<provider
android:name=".MyContentProvider"
android:authorities="com.example.providerapp.dataprovider"
android:exported="true"
android:readPermission="com.example.providerapp.READ_PREFS"
android:writePermission="com.example.providerapp.WRITE_PREFS">
</provider>
</application>
ধাপ ৩: ডেটা পড়া অ্যাপ (Consumer App) তৈরি করুন
Consumer App-এ MainActivity.java
package com.example.consumerapp;
import android.content.ContentResolver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
TextView tvData;
private static final Uri PROVIDER_URI = Uri.parse("content://com.example.providerapp.dataprovider/sharedprefs");
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvData = findViewById(R.id.tvData);
readSharedPreferences();
}
private void readSharedPreferences() {
ContentResolver resolver = getContentResolver();
Cursor cursor = null;
try {
cursor = resolver.query(PROVIDER_URI, null, null, null, null);
if (cursor != null && cursor.moveToFirst()) {
StringBuilder data = new StringBuilder("প্রদানকারী অ্যাপের ডেটা:\n\n");
do {
String key = cursor.getString(cursor.getColumnIndexOrThrow("key"));
String value = cursor.getString(cursor.getColumnIndexOrThrow("value"));
data.append(key).append(" = ").append(value).append("\n");
} while (cursor.moveToNext());
tvData.setText(data.toString());
} else {
tvData.setText("কোনো ডেটা পাওয়া যায়নি");
}
} catch (SecurityException e) {
tvData.setText("পারমিশন নেই: " + e.getMessage());
} catch (Exception e) {
tvData.setText("ত্রুটি: " + e.getMessage());
} finally {
if (cursor != null) cursor.close();
}
}
}
Consumer App-এর Manifest-এ পারমিশন যোগ করুন
<manifest ...>
<uses-permission android:name="com.example.providerapp.READ_PREFS" />
<application ...> ... </application>
</manifest>
পুরনো পদ্ধতি (API 17 এর নিচে) - এখন কাজ করে না
// এটি আর কাজ করে না - শুধু ঐতিহাসিক রেফারেন্স
SharedPreferences prefs = getSharedPreferences("prefName", Context.MODE_WORLD_READABLE);
// অন্য অ্যাপ থেকে:
Context otherAppContext = createPackageContext("com.other.app", Context.CONTEXT_IGNORE_SECURITY);
SharedPreferences otherPrefs = otherAppContext.getSharedPreferences("prefName", Context.MODE_WORLD_READABLE);
সেরা অনুশীলন (Best Practices)
- ContentProvider ব্যবহার করুন - এটি নিরাপদ এবং আধুনিক অ্যান্ড্রয়েডে সমর্থিত
- পারমিশন সেট করুন -
android:readPermissionএবংwritePermissionব্যবহার করুন - exported="true" সেট করুন অন্য অ্যাপ এক্সেস করার জন্য
- সেনসিটিভ ডেটা এনক্রিপ্ট করুন - শেয়ার্ড প্রিফারেন্সে পাসওয়ার্ড, টোকেন ইত্যাদি সরাসরি সংরক্ষণ করবেন না
- Jetpack DataStore বিবেচনা করুন - নতুন প্রজেক্টের জন্য DataStore বা EncryptedSharedPreferences ব্যবহার করুন
ফলাফল
প্রদানকারী অ্যাপে ডেটা সেভ করলে, কনজিউমার অ্যাপটি ContentProvider کے মাধ্যমে সেই ডেটা পড়তে পারবে।