Comment accorder un accès temporaire à un fournisseur de contenu personnalisé à l'aide de FLAG_GRANT_READ_URI_PERMISSION
Je suis en train de requête personnalisés fournisseur de contenu(App) à partir d'une autre application(App B).
Je peux le faire quand il n'y a pas d'autorisation de la protection de fournisseur de contenu. Plus précisément, je build fournisseur de contenu sur App Un et envoyé une intention contenant l'URI d'Application B.
Ici est l'intention-en envoyant une partie en Application 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);
}
}
suivie par fichier manifeste de l'Application 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>
Puis l'Application B(classe prévue à cet effet) obtenir l'URI de requête et les données correspondantes dans le fournisseur de contenu(à l'aide de code suivant).
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());
}
}
}
}
Ici de l'Application du B du fichier manifest.
<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>
Cependant, lorsque j'ai une requête fournisseur de contenu à partir de l'App B, les erreurs se produisent:
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
Il semble que l'Application B n'a pas fait usage de la temporaire de l'autorisation d'accès. En d'autres mots, comment utiliser FLAG_GRANT_READ_URI_PERMISSION à partir de l'App B?
J'ai aussi essayé d'ajouter directement des Uri de l'intention(à l'aide de setData()), au lieu d'Uri.toString()(à l'aide de putExtra()).
sendIntent.setData(uri2);
et
Uri userNameuri = getIntent().getData();
Mais le "userNameuri" a obtenu dans l'Application B est null.
Je suis totalement confus...
mis à jour
J'ai essayé le "grantUriPermission("com.android.getCPaccess", uri2, l'Intention.FLAG_GRANT_READ_URI_PERMISSION)", selon un précédent post
Est-ce la bonne gestion des permissions lors de l'envoi de sensibles les données de l'application en tant que pièce jointe à un courriel?
Et il fonctionne en effet. Il peut fonctionner sans l'aide de FLAG_GRANT_READ_URI_PERMISSION. Mais l'autorisation n'est pas "temporaire". Il faut être terminés manuellement par revokeUriPermission().
Donc, je me demandais si il existe un moyen d'accorder une autorisation temporaire introduite dans FLAG_GRANT_READ_URI_PERMISSION, ou c'est un bug?
Salut, Jens. J'ai également essayé. Lorsque les deux applications ont <uses-permission android:name="android.la permission.permRead" /> dans le fichier de manifeste, il fonctionne très bien. Mais c'est le genre d'autorisation permanente. Je veux de travail temporaire d'autorisation d'accès avec FLAG_GRANT_READ_URI_PERMISSION(comme décrit par google android developer). Ainsi, l'Application B de ne pas avoir de android.la permission.permRead, au lieu de cela, il reçoit l'intention avec FLAG_GRANT_READ_URI_PERMISSION drapeau "vrai" à partir de l'App A. Mais cela échoue.
Vous devriez seulement besoin d'une
uses-permission
, a déclaré dans l'application qui déclare que le sélecteur d'activité qui appelle #addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
. Vous devriez probablement inclure plus de votre manifeste, & code en question.Assurez-vous. J'ai édité la question. Oui, Une Application n'a pas besoin uses-permission. Mais l'Application B ne devrait pas avoir <uses-permission android:name="android.la permission.permRead" />soit, parce que si elle a, il n'y a pas besoin de addFlags(Intention.FLAG_GRANT_READ_URI_PERMISSION).
Non - application, qui définit le fournisseur, doit également définir l'autorisation(s) que vous utilisez pour lire/écrire. aussi déclarer un utilise-l'autorisation pour le lire (& écrire, si vous souhaitez accorder l'autorisation d'écriture aussi) - vous ne pouvez pas accorder une autorisation que vous avez vous-même ne tiennent pas.
OriginalL'auteur Jin | 2012-11-17
Vous devez vous connecter pour publier un commentaire.
Il semble que
FLAG_GRANT_READ_URI_PERMISSION
affecte uniquementUri Intent.mData
mais pas les uri dans les extras.J'ai trouvé des problèmes similaires lors de la lecture avec
ACTION_SEND
, qui prend un uri dansEXTRA_STREAM
. En offrant la même uri danssetData()
de fonctionner, mais ne sont pas conformes aux règles et conduit à un comportement inattendu (par exemple, Gmail destinataire).De Jelly Bean intentions peuvent contenir ClipData, qui devrait résoudre le problème. Pour
ACTION_SEND
il est généré automatiquement à partir d'extras.grantUriPermission
fonctionne, mais nécessiterevokeUriPermission
. Pour faire le même travail questartActivity(Intent.createChooser(intent, title))
vous aurez à choisir la cible (ACTION_PICK_ACTIVITY
), d'accorder des autorisations à son paquet et de les révoquer lorsqu'il n'est pas plus nécessaire (onActivityResult?).Voici un code:
Récepteur app:
ActivityView.java:
Expéditeur application:
ActivitySend.java:
OriginalL'auteur marx