2015-11-09 44 views
9

在我的應用程序中我試圖從廚房中挑選圖像,以便將該圖像傳遞給服務器。圖片來自Android 6中的圖庫(棉花糖)

代碼在Android 5及更低版本上正常工作,但對於Nexus 5上的Android 6,我無法獲取圖像信息。 日誌跟蹤我了

注意:代碼是在Android 5及以下版本

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

很好的解釋http://inthecheesefactory.com/blog/things-you-need-to- android-m-permission-developer-edition/en – AEMLoviji

+0

我想你應該嘗試在相同的上下文中解碼圖像,而不將uri傳遞給另一個上下文並解碼那裏的圖像(如startActivity)。 – yugy

回答

5

我相信你會需要請求的權限給用戶在運行時工作正常(這是從22日至23日最顯着的變化之一)。

你可以試試這個片段中,從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. 
     } 
    } 
    } 

提取讓我知道,如果它幫助。

2

爲了從棉花糖廊中獲取圖像,您需要在運行時授予READ_EXTERNAL_STORAGE權限。 Android版本M改變了授予應用程序權限的方式。

棉花糖之前,所有必需的權限一次性授予,並在安裝時。但是在棉花糖中,只有在需要該權限時,用戶才被要求獲得許可,並且用戶必須允許或拒絕該權限。

下面兩個鏈接會幫助你更多。鏈接1來自Android的官方文檔,鏈接2是一個博客,通過一個工作示例解釋了這個問題。

鏈接1:http://developer.android.com/training/permissions/requesting.html

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

19

做這種方式... 上按鈕單擊檢查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); 
        } 

在覆蓋方法onRequestPermissionsResult寫這樣的代碼:

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; 
      } 

@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和我初始化它? –

+0

它是一個靜態int值賦予它任何int值,但該值不應該用於任何其他請求。例如,如果對於使用值1的相機,則可以使用除1之外的任何整數值。 – Ashwani

0

後試試這個

這是我與其他實例創建

  1. 呼叫CHECKGALLERYPERMISSION)要在其中粘貼內方法的代碼的簡單方法(方法

    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(); 
        } 
    } 
        } 
    

注意

  1. in fragement使用getactivity()而不是活動。在所有地方本
  2. 如果android.Manifest.permission.READ_EXTERNAL_STORAGE工作不改變這Manifest.permission.READ_EXTERNAL_STORAGE