2016-11-03 2 views
1

Я получаю изображение из галереи и отправляю на свой удаленный сервер. Затем я сохраняю путь изображения в своих общих настройках. Это хорошо работает. Через некоторое время, когда я пытаюсь восстановить изображение из сохраненного пути и показать, на мой взгляд изображения я получаю это исключение в строке:SecurityException читает картинку из галереи Android

bitmap = MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(), fileUri); 

несколько раз, код работает, но через некоторое время я получаю это исключение ,

Мое исключение:

E/AndroidRuntime: FATAL EXCEPTION: main 
        Process: net.techabout.medappointment, PID: 4160 
        java.lang.SecurityException: Permission Denial: opening provider com.android.externalstorage.ExternalStorageProvider from ProcessRecord{9922e7c 4160:net.techabout.medappointment/u0a105} (pid=4160, uid=10105) requires android.permission.MANAGE_DOCUMENTS or 
android.permission.MANAGE_DOCUMENTS 
         at android.os.Parcel.readException(Parcel.java:1599) 
         at android.os.Parcel.readException(Parcel.java:1552) 
         at android.app.ActivityManagerProxy.getContentProvider(ActivityManagerNative.java:3550) 
         at android.app.ActivityThread.acquireProvider(ActivityThread.java:4778) 
         at android.app.ContextImpl$ApplicationContentResolver.acquireUnstableProvider(ContextImpl.java:2018) 
         at android.content.ContentResolver.acquireUnstableProvider(ContentResolver.java:1468) 
         at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1088) 
         at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:942) 
         at android.content.ContentResolver.openInputStream(ContentResolver.java:662) 
         at android.provider.MediaStore$Images$Media.getBitmap(MediaStore.java:866) 
         at net.techabout.medappointment.ConfigurationFragment.onCreateView(ConfigurationFragment.java:115) 

Вот мой манифест:

<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" /> 

Вот мой код:

private Uri fileUri; 
String pathimg; 
Bitmap bitmap = null; 
ImageView imageView; 
private static int RESULT_LOAD_IMG = 1; 
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 
     View view = inflater.inflate(R.layout.configuationfrag, container, false); 
     imageView = (ImageView) view.findViewById(R.id.imageView); 
     SharedPreferences pref = getActivity().getSharedPreferences(Common.SHARED_PREF_NAME, Context.MODE_PRIVATE); 
     pathimg = pref.getString("imagepath", ""); 
     fileUri = Uri.parse(pathimg); 

     try { 
      bitmap = MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(), fileUri); 
      imageView.setImageBitmap(bitmap); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     Button buttonChoose = (Button) view.findViewById(R.id.buttonChooseImage); 
     buttonChoose.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       showFileChooser(); 
      } 
     }); 

     Button buttonupload = (Button) view.findViewById(R.id.buttonUpload); 
     buttonupload.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       if (bitmap != null) new UploadImage().execute(); 
      } 
     }); 
     return view; 
    } 
    private void showFileChooser() { 
     Intent intent; 

     if (Build.VERSION.SDK_INT < 19) { 
      intent = new Intent(); 
      intent.setAction(Intent.ACTION_GET_CONTENT); 
      intent.setType("image/*"); 
      startActivityForResult(intent, RESULT_LOAD_IMG); 
     } else { 
      intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); 
      intent.addCategory(Intent.CATEGORY_OPENABLE); 
      intent.setType("image/*"); 
      startActivityForResult(intent, RESULT_LOAD_IMG); 
     } 

    } 
@Override 
    public void onActivityResult(int requestCode, int resultCode, Intent data) { 
     super.onActivityResult(requestCode, resultCode, data); 
     if (requestCode == RESULT_LOAD_IMG && resultCode == RESULT_OK && data != null && data.getData() != null) { 
      Uri filePath = data.getData(); 
      try { 
       bitmap = MediaStore.Images.Media.getBitmap(getActivity().getApplicationContext().getContentResolver(), filePath); 
       imageView.setImageBitmap(bitmap); 
       pathimg=filePath.toString(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

ответ

3

Проблема заключается в том, что структура только предоставляет временный доступ к URI изображения. Если вы хотите продолжать использовать URI вы должны запросить постоянное разрешение, выполните следующие действия перед сохранением URI для общих предпочтений:

final int takeFlags = intent.getFlags() 
     & (Intent.FLAG_GRANT_READ_URI_PERMISSION 
     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 
// Check for the freshest data. 
getContentResolver().takePersistableUriPermission(uri, takeFlags); 

Для получения более подробной информации посмотрите на documentation.

+0

takePersistableUriPermission требует api 19. Есть ли какое-то решение для api 15? –

+0

Структура доступа к хранилищу, вызывающая это измерение безопасности, была введена с уровнем API 19. На более ранних уровнях API структура предоставляет постоянный доступ к URI, открытым по замыслу. Вы испытываете проблему с уровнями API ниже 19? – dthulke

+0

Я не тестировал в api <19. Я только видел предупреждение. Другой вопрос: может ли это намерение быть возвращено в onActivityResult (int requestCode, int resultCode, Intent data) или у меня есть первоначальное намерение, требующее изображения? –

Смежные вопросы