目次
shareUserId の概要
shareUserId を学習する前に、Android アプリ サンドボックス (android サンドボックスのメカニズム) を見てみましょう。Linux のサンドボックスは、主に分離作業を行い、異なるタスクまたはユーザー間の結合を最小限に抑えます。Android アプリケーションも Linux サンドボックス テクノロジを利用して、さまざまなアプリをゲストとして分離します. 主なパフォーマンスは、リソースとアクセス許可の分離です. 各 Android アプリは独自の Linux スレッドで (異なる UID で) 実行され、各アプリケーションは互いに独立しており、デフォルトでは他のアプリケーション リソースにアクセスできません。APP許可メカニズムは、アプリケーション間のリソースへの相互アクセスの可能性を提供します.APPは許可を申請し、ユーザーがAndroidシステムAPIまたは他のサービスにアクセスすることを承認する必要があります.
共有ユーザー ID を使用すると、同じユーザー ID を持つ複数の APK を同じプロセスで実行するように構成できます。したがって、デフォルトでは、相互に任意のデータにアクセスできます。また、別のプロセスとして実行するように構成することもできます。同時に、このプログラムのデータにアクセスするのと同じように、他の APK のデータ ディレクトリ内のデータベースやファイルにアクセスすることもできます。
shareUserId 設定方法
リソースを共有する必要があるプロジェクトの各 AndroidMainfest.xml に shareuserId タグを追加します。
android:sharedUserId= "com.example.XX"
ID 名は自由に設定できますが、各プロジェクトが同じ sharedUserId を使用するようにする必要があります。メインフェストは、Shareuserid タグを 1 つだけ持つことができます。
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.shareusertesta"
android:versionCode="1"
android:versionName="1.0"
android:sharedUserId="com.example">
shareUserId の役割は、システム権限を取得することです
step1. AndroidManifest.xml に android:sharedUserId = "android.uid.system" を追加
step2. Android.mk ファイルに LOCAL_CERTIFICATE := platfrom を追加 (システム署名を使用)
step3. ソースコードの下でmmコンパイルを実行
この方法で生成された apk は、システム権限を取得し、任意のシステム権限ディレクトリにディレクトリまたはファイルを作成し、他の apk リソースにアクセスできます。一般的なシナリオは次のとおりです。
- Setting.apk マニフェスト ノードに android:sharedUserId = "android.uid.system" を追加し、Android.mk に LOCAL_CERTIFICATE:= platfrom を追加します。
- Launcher.apk はマニフェスト ノードに android:sharedUserId = "android.uid.shared" を追加し、Android.mk に LOCAL_CERTIFICATE:= shared を追加します。
- Gallery.apk はマニフェスト ノードに android:sharedUserId="android.media" を追加し、Android.mk に LOCAL_CERTIFICATE := media を追加します。
shareUserId の役割は、apk 間のデータにアクセスすることです。
場合によっては、複数の APK を開発し、リソースを相互に共有する必要があるため、これを実現するために shareUserId を設定する必要があります。2 つのアプリケーション A と B がデータ アクセスを実行する方法を見てみましょう。
step1. 2 つの APP manifest.xml ファイルに属性 android:sharedUserId を追加し、同じ値または名前に設定します (実際、これらは同じ UID に設定されています)。
step2. 両方のアプリが同じ秘密鍵で署名されている必要があります
//A应用的代码,保存数据
private void writeData(Context context, String data) {
FileOutputStream fileOutputStream = null;
OutputStreamWriter outputStreamWriter = null;
try {
//文件保存在/data/data/com.example.test/setting.dat
//MODE_PRIVATE限制数据类型为私有
fileOutputStream = openFileOutput("setting.dat",MODE_PRIVATE);
outputStreamWriter = new OutputStreamWriter(fileOutputStream);
outputStreamWriter.write(data);
outputStreamWriter.flush();
Toast.makeText(context, "Settings saved", Toast.LENGTH_SHORT).show();
}catch (Exception e){
Toast.makeText(context, "Settings not saved", Toast.LENGTH_SHORT).show();
}finally {
try {
outputStreamWriter.close();
fileOutputStream.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
}
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.test"
android:sharedUserId="com.example.testID"
>
アプリケーション B は A のデータを読み取ります。
private void getData() {
try {
//获取com.example.test/A应用的context
Context context = this.createPackageContext("com.example.test",Context.CONTEXT_IGNORE_SECURITY);
String msg = readData(context);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
}
private String readData(Context context) {
FileInputStream fileInputStream = null;
InputStreamReader inputStreamReader = null;
char[] inputBuffer = new char[255];
String data = null;
try {
//通过文件名settings.dat找到数据
fileInputStream = context.openFileInput("settings.dat");
inputStreamReader = new InputStreamReader(fileInputStream);
inputStreamReader.read(inputBuffer);
data = new String(inputBuffer);
Toast.makeText(context, "Settings read", Toast.LENGTH_SHORT).show();
}catch (Exception e){
Toast.makeText(context, "Settings not read", Toast.LENGTH_SHORT).show();
}finally {
try {
inputStreamReader.close();
fileInputStream.close();
}catch (IOException e){
e.printStackTrace();
}
}
return data;
}
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.appb"
android:sharedUserId="com.example.testID"
>
B書き込みデータ
private void writeData(String s,Context context){
FileOutputStream fileOutputStream = null;
OutputStreamWriter outputStreamWriter = null;
try {
//context还是从程序A里面获取的
fileOutputStream = context.openFileOutput("strrings.bat",MODE_PRIVATE);
outputStreamWriter = new OutputStreamWriter(fileOutputStream);
outputStreamWriter.write(s);
outputStreamWriter.flush();
Toast.makeText(context,"Settings saved",Toast.LENGTH_SHORT).show();
}catch (Exception e){
e.printStackTrace();
Toast.makeText(context,"Settings not saved",Toast.LENGTH_SHORT).show();
}finally {
try {
outputStreamWriter.close();
fileOutputStream.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
参考リンク:
android:sharedUserId を使用してシステム権限を取得する - 見てみる