我有一个Android应用程序,允许用户为其个人资料选择照片,如下所示:
public void pickImage(View view) {
Intent getIntent = new Intent(Intent.ACTION_GET_CONTENT);
getIntent.setType("image/*");
Intent pickIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
pickIntent.setType("image/*");
Intent chooserIntent = Intent.createChooser(getIntent, "Select Image");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[] {pickIntent});
startActivityForResult(chooserIntent, 1);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Context context = getApplicationContext();
if (requestCode == 1 && resultCode == Activity.RESULT_OK) {
if (data == null) {
//Display an error
return;
}
try {
ImageView im = findViewById(R.id.circularImageView);
uri = data.getData();
im.setImageURI(uri);
String image = uri.toString();
Log.d("ImageS", image);
SqlHelper db = new SqlHelper(this);
Intent i = getIntent();
String userid = i.getStringExtra("Name");
db.updateImage(userid, image);
}catch (Exception e){
}
//Now you can do whatever you want with your inpustream, save it as file, upload to a server, decode a bitmap...
}
}
在重新启动应用之前,一切正常。在这里,我想从我的数据库中检索图像一切正常:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActionBar actionBar = getActionBar();
actionBar.hide();
setContentView(R.layout.activity_main);
String[] permissions = {Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.MANAGE_DOCUMENTS};
for(String permission: permissions){
if (ContextCompat.checkSelfPermission(this, permission)
!= PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
permission)) {
// Show an explanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
} else {
// No explanation needed; request the permission
ActivityCompat.requestPermissions(this,
permissions, 0);
// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
// app-defined int constant. The callback method gets the
// result of the request.
}
}
}
mGoogleApiClient = new GoogleApiClient.Builder(this).addApi(LocationServices.API).addConnectionCallbacks(this).addOnConnectionFailedListener(this).build();
ImageView logo = findViewById(R.id.imageView4);
logo.setImageResource(R.drawable.logo);
SqlHelper db = new SqlHelper(this);
//Add some locations for the users
a.setLatitude(Latitude[0]);
a.setLongitude(Longitude[0]);
b.setLatitude(Latitude[1]);
b.setLongitude(Longitude[1]);
Intent intentR = getIntent();
String name = intentR.getStringExtra("Name");
// Check for the freshest data.
ImageView im1 = findViewById(R.id.circularImageView2);
im1.setImageURI(null);
String iS = db.getImage(name);
Log.d("ImageR", iS);
//
// Uri uri = Uri.parse(image);
//Log.d("Equals", String.valueOf(iS.equals(String.valueOf(R.drawable.imageuser))));
if(iS.equals(String.valueOf(R.drawable.imageuser))){
im1.setImageResource(Integer.parseInt(iS));
}else{
Uri uri = Uri.parse(iS);
ContentResolver contentResolver= getContentResolver();
ParcelFileDescriptor parcelFileDescriptor = null;
try {
//HERE COMES THE PROBLEM//
parcelFileDescriptor = contentResolver.openFileDescriptor(uri, "r"); /
} catch (FileNotFoundException e) {
e.printStackTrace();
}
FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor);
try {
parcelFileDescriptor.close();
} catch (IOException e) {
e.printStackTrace();
}
im1.setImageBitmap(image);
}
ArrayList<String> notifications = db.getNotifications(name);
if(notifications.size()>0) {
ImageView im = findViewById(R.id.bell);
ImageView c = findViewById(R.id.circleN);
TextView tx = findViewById(R.id.nNot);
im.setVisibility(View.VISIBLE);
c.setVisibility(View.VISIBLE);
tx.setVisibility(View.VISIBLE);
tx.setText(String.valueOf(notifications.size()));
}
// db.addUser(new User("Babouche", "Babouche", location[1]), this);
// db.addUser(new User("Arturo", "Arturo", location[0]), this);
}`
问题是当我重新启动应用程序时,在进入用户更改图像的活动时出现以下错误:
FATAL EXCEPTION: main
Process: com.example.arturopavon.finalproject, PID: 1445
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.arturopavon.finalproject/com.example.arturopavon.finalproject.MainActivity} : java.lang.SecurityException: Permission Denial: opening provider com.android.providers.media.MediaDocumentsProvider from ProcessRecord{47cb71a 1445:com.example.arturopavon.finalproject/u0a294} (pid=1445, uid=10294) requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs
我为我的应用设置了权限以读取内部存储空间,但它在重新启动后无法正常工作。
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.arturopavon.finalproject">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission
android:name="android.permission.MANAGE_DOCUMENTS"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="BiteME"
android:roundIcon="@drawable/logo"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".LoginActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".MainActivity" />
<activity android:name=".UserActivity" />
<activity android:name=".UserPreferences" />
<activity android:name=".SignUp" />
<activity android:name=".Notifications" />
</application>
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.login);
String[] permissions = {Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.MANAGE_DOCUMENTS};
for(String permission: permissions){
if (ContextCompat.checkSelfPermission(this, permission)
!= PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
permission)) {
// Show an explanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
} else {
// No explanation needed; request the permission
ActivityCompat.requestPermissions(this,
permissions, 0);
// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
// app-defined int constant. The callback method gets the
// result of the request.
}
}
}
}
关于如何解决这个问题的任何想法?
答案 0 :(得分:2)
如SAF Storage Access Framework (SAF)中所述:
如果您希望应用简单地读取/导入数据,请使用ACTION_GET_CONTENT。通过这种方法,应用程序可以导入数据的副本,例如图像文件。
如果您希望自己的应用对文档提供商拥有的文档具有长期持久访问权限,请使用ACTION_OPEN_DOCUMENT。
似乎你有第二个用例。
所以而不是:
Intent getIntent = new Intent(Intent.ACTION_GET_CONTENT);
试
Intent getIntent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
文档提供了sample来使用它。