別のアプリ(アプリB)からカスタムコンテンツプロバイダー(アプリA)をクエリしようとしています。
コンテンツプロバイダーの権限保護がない場合にそれを行うことができます。具体的には、アプリAでカスタムコンテンツプロバイダーを構築し、URIを含むインテントをアプリBに送信しました。これがアプリAのインテント送信部分です。
class InsertOnClickListener implements OnClickListener{
public void onClick(View v) {
ContentValues values = new ContentValues();
values.put(DataBaseConfiguation.TableConfiguation.USER_NAME, "Jack");
Uri uri = getContentResolver().insert(DataBaseConfiguation.TableConfiguation.CONTENT_URI, values);
System.out.println("uri------------------->" + uri);
// the uri above should be like "content://com.catking.contentprovider.MyContentProvider/user"
Uri uri2 = Uri.parse("content://com.catking.contentprovider.MyContentProvider/user");
Cursor c = managedQuery(uri2, null, null, null, null);
String sendvalue = null;
if (c.moveToFirst()) {
do{
System.out.println("User name:"+c.getString(c.getColumnIndex(DataBaseConfiguation.TableConfiguation.USER_NAME)).toString());
sendvalue = c.getString(c.getColumnIndex(DataBaseConfiguation.TableConfiguation.USER_NAME)).toString();
} while (c.moveToNext());
}
Intent sendIntent = new Intent();
sendIntent.setClassName("com.android.web", "com.android.web.Provid");
sendIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
sendIntent.putExtra("name", uri2.toString());
sendIntent.setType("text/plain");
startActivity(sendIntent);
}
}
続いてアプリAのマニフェストファイル。
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:name=".ContentProviderTestActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider android:authorities="com.catking.contentprovider.MyContentProvider"
android:exported="true"
android:grantUriPermissions="true"
android:name="com.catking.contentprovider.MyContentProvider"
android:readPermission="android.permission.permRead"
android:writePermission="android.permission.permWrite" >
</provider>
</application>
次に、アプリB(クラスProvid)がURIを取得し、コンテンツプロバイダーで対応するデータをクエリします(次のコードを使用)。
public class Provid extends Activity {
public void onCreate(Bundle savedInstanceState) {
Bundle extras = getIntent().getExtras();
String userNameuri;
if (extras != null) {
userNameuri = extras.getString("name");
Uri allTitles = Uri.parse(userNameuri);
Cursor c = managedQuery(allTitles, null, null, null, null);
if (c.moveToFirst()) {
do{
System.out.println("Name is"+c.getString(c.getColumnIndex(DataBaseConfiguation.TableConfiguation.USER_NAME)).toString());
} while (c.moveToNext());
}
}
}
}
これがアプリBのマニフェストファイルです。
<uses-permission android:name="android.permission.INTERNET" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:name="._GetWebResoureActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND" >
</action>
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="*/*" />
</intent-filter>
</activity>
<receiver android:name="StaticReceiver11" >
<intent-filter>
<action android:name="android.intent.action.MYSEND" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<activity
android:name="Provid"
android:label="@string/title_activity_provid" >
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="*/*" />
</intent-filter>
</activity>
</application>
ただし、アプリBからコンテンツプロバイダーにクエリを実行すると、エラーが発生します。
java.lang.RuntimeException: Unable to start activity ComponentInfo {com.android.web/com.android.web.Provid}: java.lang.SecurityException: Permission Denial: opening provider com.ck.contentprovider.MyContentProvider from ProcessRecord{426c6ea8 17032:com.android.web/u0a95} (pid=17032, uid=10095) requires android.permission.permRead or android.permission.permWrite
アプリBは一時的なアクセス許可を利用していなかったようです。言い換えれば、アプリBからFLAG_GRANT_READ_URI_PERMISSIONを利用するにはどうすればよいですか?
また、Uri.toString()(putExtra()を使用)の代わりに、(setData()を使用して)intentにUriを直接追加しようとしました。
sendIntent.setData(uri2);
と
Uri userNameuri = getIntent().getData();
ただし、アプリBで取得した「userNameuri」はnullです。
私は完全に混乱しています...
更新しました
以前の投稿によると、「grantUriPermission( "com.android.getCPaccess"、uri2、Intent.FLAG_GRANT_READ_URI_PERMISSION)」を試しました。
機密性の高いアプリデータをメールの添付ファイルとして送信する場合の正しい権限処理は何ですか?
そしてそれは確かに機能します。FLAG_GRANT_READ_URI_PERMISSIONを使用しなくても機能します。しかし、許可は「一時的」ではありません。revokeUriPermission()を使用して手動で終了する必要があります。
それで、FLAG_GRANT_READ_URI_PERMISSIONで導入されたような一時的な許可を与える方法があるのか、それともバグなのか疑問に思います。