2015-11-09 46 views
9

Trong ứng dụng của tôi Tôi đang cố gắng Chọn hình ảnh từ galley, để chuyển hình ảnh đó đến máy chủ.Hình ảnh từ Bộ sưu tập trong Android 6 (Marshmallow)

Mã hoạt động tốt trên Android 5 trở xuống, nhưng đối với Android 6 trên Nexus 5, tôi không thể nhận thông tin hình ảnh. Log dấu vết mà tôi nhận

Note: Mã đang làm việc tốt trên Android 5 và dưới các phiên bản

11-06 12:27:43.736: W/System.err(31678): java.lang.SecurityException: Permission Denial: reading com.google.android.apps.photos.contentprovider.MediaContentProvider uri content://com.google.android.apps.photos.contentprovider/0/1/content%3A//media/external/images/media/19138/ACTUAL/94710853 from pid=31678, uid=10111 requires the provider be exported, or grantUriPermission() 
11-06 12:27:43.757: W/System.err(31678): 
at android.os.Parcel.readException(Parcel.java:1599) 
11-06 12:27:43.757: W/System.err(31678): 
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:183) 
11-06 12:27:43.757: W/System.err(31678): 
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:135) 
11-06 12:27:43.757: W/System.err(31678): 
at android.content.ContentProviderProxy.query(ContentProviderNative.java:421) 
11-06 12:27:43.757: W/System.err(31678): 
at android.content.ContentResolver.query(ContentResolver.java:491) 
11-06 12:27:43.757: W/System.err(31678): 
at android.content.ContentResolver.query(ContentResolver.java:434) 
11-06 12:27:43.758: W/System.err(31678): 
at org.apache.cordova.file.ContentFilesystem.openCursorForURL(ContentFilesystem.java:258) 
11-06 12:27:43.758: W/System.err(31678): 
at org.apache.cordova.file.ContentFilesystem.getFileMetadataForLocalURL(ContentFilesystem.java:169) 
11-06 12:27:43.758: W/System.err(31678): 
at org.apache.cordova.file.FileUtils.getFileMetadata(FileUtils.java:822) 
11-06 12:27:43.758: W/System.err(31678): 
at org.apache.cordova.file.FileUtils.access$500(FileUtils.java:52) 
11-06 12:27:43.758: W/System.err(31678): 
at org.apache.cordova.file.FileUtils$15.run(FileUtils.java:394) 
11-06 12:27:43.758: W/System.err(31678): 
at org.apache.cordova.file.FileUtils$25.run(FileUtils.java:551) 
11-06 12:27:43.758: W/System.err(31678): 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) 
11-06 12:27:43.758: W/System.err(31678): 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) 
11-06 12:27:43.758: W/System.err(31678): 
at java.lang.Thread.run(Thread.java:818) 
+0

đẹp giải thích http://inthecheesefactory.com/blog/things-you-need-to- know-about-android-m-permission-developer-edition/vi – AEMLoviji

+0

Tôi đoán bạn nên cố gắng giải mã hình ảnh trong cùng một bối cảnh mà không chuyển uri sang ngữ cảnh khác và giải mã hình ảnh ở đó (như startActivity). – yugy

Trả lời

5

Tôi tin rằng bạn sẽ cần phải yêu cầu các điều khoản cho người sử dụng trong thời gian chạy (đây là một trong những thay đổi đáng chú ý nhất từ ​​api 22 đến 23).

Bạn có thể thử đoạn này, được chiết xuất từ ​​các Android Developers permission page

if (Build.VERSION.SDK_INT >= 23){  
// Here, thisActivity is the current activity 
    if (ContextCompat.checkSelfPermission(thisActivity, 
        Manifest.permission.READ_EXTERNAL_STORAGE) 
      != PackageManager.PERMISSION_GRANTED) { 

     // Should we show an explanation? 
     if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity, 
       Manifest.permission.READ_EXTERNAL_STORAGE)) { 

      // Show an expanation 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, we can request the permission. 

      ActivityCompat.requestPermissions(thisActivity, 
        new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 
        MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE); 

      // MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE is an 
      // app-defined int constant. The callback method gets the 
      // result of the request. 
     } 
    } 
    } 

Hãy cho tôi biết nếu nó giúp.

2

Để tải hình ảnh từ Thư viện trong Marshmallow, Bạn được yêu cầu cấp quyền cho phép READ_EXTERNAL_STORAGE vào thời gian chạy. Phiên bản Android M đã thay đổi cách cấp quyền cho các ứng dụng.

Trước Marshmallow, tất cả các quyền bắt buộc được cấp cùng một lúc và đó là tại thời điểm cài đặt. Nhưng trong Marshmallow, Người dùng chỉ được yêu cầu quyền khi có quyền đó là bắt buộc và Người dùng phải Cho phép hoặc Từ chối quyền đó.

Dưới hai liên kết sẽ giúp bạn nhiều hơn. Liên kết 1 là từ tài liệu chính thức của Android và Link 2 là một blog đã giải thích vấn đề này với một ví dụ làm việc.

link1: http://developer.android.com/training/permissions/requesting.html

Link2: http://inthecheesefactory.com/blog/things-you-need-to-know-about-android-m-permission-developer-edition/en

19

DO nó theo cách này ... trên nhấp chuột lên nút kiểm tra Phiên bản SDK

if (Build.VERSION.SDK_INT >= 23){ 
    // Here, thisActivity is the current activity 
         if (ContextCompat.checkSelfPermission(MainActivity.this, 
           Manifest.permission.READ_EXTERNAL_STORAGE) 
           != PackageManager.PERMISSION_GRANTED) { 

          // Should we show an explanation? 
          if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, 
            Manifest.permission.READ_EXTERNAL_STORAGE)) { 

           // Show an expanation 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, we can request the permission. 

           ActivityCompat.requestPermissions(MainActivity.this, 
             new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 
             MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE); 

           // MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE is an 
           // app-defined int constant. The callback method gets the 
           // result of the request. 
          } 
         }else{ 
          ActivityCompat.requestPermissions(MainActivity.this, 
            new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 
            MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE); 
         } 
        }else { 

         Intent photoPickerIntent = new Intent(Intent.ACTION_PICK); 
         photoPickerIntent.setType("image/*"); 
         startActivityForResult(photoPickerIntent, SELECT_PHOTO); 
        } 

sau đó trong phương pháp ghi đè onRequestPermissionsResult viết mã này:

case MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE: { 
       // If request is cancelled, the result arrays are empty. 
       if (grantResults.length > 0 
         && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 

        // permission was granted, yay! Do the 
        // contacts-related task you need to do. 
        Intent photoPickerIntent = new Intent(Intent.ACTION_PICK); 
        photoPickerIntent.setType("image/*"); 
        startActivityForResult(photoPickerIntent, SELECT_PHOTO); 
       } else { 

        // permission denied, boo! Disable the 
        // functionality that depends on this permission. 
       } 
       return; 
      } 

Sau đó

@Override 
    protected void onActivityResult(int reqCode, int resultCode, Intent data) { 
     super.onActivityResult(reqCode, resultCode, data); 

     switch (reqCode) { 
case SELECT_PHOTO: 
       if (resultCode == RESULT_OK) { 
        try { 
         final Uri imageUri = data.getData(); 
         final InputStream imageStream = getContentResolver().openInputStream(imageUri); 
         final Bitmap selectedImage = BitmapFactory.decodeStream(imageStream); 
         contactimage.setImageBitmap(selectedImage); 
        } catch (FileNotFoundException e) { 
         e.printStackTrace(); 
        } 

       } 
+1

MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE là gì và tôi khởi tạo nó ở đâu ?? –

+0

nó là một giá trị int tĩnh asign nó bất kỳ giá trị int nhưng giá trị đó không nên được sử dụng cho bất kỳ yêu cầu nào khác. ví dụ: nếu đối với máy ảnh bạn đang sử dụng giá trị 1 thì bạn có thể sử dụng bất kỳ giá trị nguyên nào trừ 1 .. – Ashwani

0

Hãy thử điều này

Đây là phương pháp đơn giản mà tôi đã tạo ra với các ví dụ khác

  1. gọi CHECKGALLERYPERMISSION() phương pháp mà bạn muốn và dán đoạn mã bên trong phương pháp

    private void CHECKGALLERYPERMISSION() 
    { 
        int MY_READ_PERMISSION_REQUEST_CODE =1 ; 
        int PICK_IMAGE_REQUEST = 2; 
        if (ContextCompat.checkSelfPermission(YourActivity.this, android.Manifest.permission.READ_EXTERNAL_STORAGE)== PackageManager.PERMISSION_GRANTED) 
        { 
         Intent intent = new Intent(); 
         intent.setType("image/*"); 
         intent.setAction(Intent.ACTION_GET_CONTENT); 
         startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE_REQUEST); 
        } 
        else 
        { 
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) 
         { 
          requestPermissions(
            new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE}, 
            MY_READ_PERMISSION_REQUEST_CODE); 
         } 
         else 
         { 
         } 
        } 
        } 
        @Override 
        public void onRequestPermissionsResult(int requestCode, String[] 
        permissions, int[] grantResults) { 
        if (requestCode == MY_READ_PERMISSION_REQUEST_CODE 
         && grantResults[0] == PackageManager.PERMISSION_GRANTED) 
        { 
        Intent intent = new Intent(); 
        intent.setType("image/*"); 
        intent.setAction(Intent.ACTION_GET_CONTENT); 
        startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE_REQUEST); 
    } 
        } 
        @Override 
        public void onActivityResult(int requestCode, int resultCode, Intent data) 
        { 
    super.onActivityResult(requestCode, resultCode, data); 
    if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null) 
    { 
        Uri uri = data.getData(); 
        try 
        { 
         Bitmap bitmap = MediaStore.Images.Media.getBitmap(YourActivity.this.getContentResolver(), uri); 
         imageview.setImageBitmap(bitmap); 
        } 
        catch (IOException e) 
        { 
         e.printStackTrace(); 
        } 
    } 
        } 
    

Lưu ý

  1. trong sử dụng phân đoạn getactivity() thay vì hoạt động.này thay đổi
  2. nếu android.Manifest.permission.READ_EXTERNAL_STORAGE không làm việc này để Manifest.permission.READ_EXTERNAL_STORAGE ở mọi nơi
Các vấn đề liên quan