2016-03-01 39 views
1

我有這個代碼,它允許用戶訪問相機拍照並從圖庫中選擇圖像,它適用於運行Android 5.1.1的我的索尼Xperia Z3。訪問相機並存儲圖像棉花糖

我現在已經升級到運行Android 6.0的Nexus 5X,但是當我嘗試使用相機或保存圖像時,我得到的錯誤有任何幫助?

我的代碼使用相機

Intent CameraImage = new Intent("android.media.action.IMAGE_CAPTURE"); 
Intent SelectedCameraImage = Intent.createChooser(CameraImage, "Take A Photo With"); 
startActivityForResult(SelectedCameraImage, SELECTED); 

我的結果處理

public void onActivityResult(int RequestCode, int ResultCode, Intent Data) { 
    if (ResultCode == RESULT_OK) { 
     if (RequestCode == SELECTED) { 
      Uri SelectedImageUri = Data.getData(); 
      SelectedImagePath = getPath(SelectedImageUri); 
      Log.d("DatabaseOperations", "Image Path : " + SelectedImagePath); 
      Img.setImageURI(SelectedImageUri); 

      try { 
       FileInputStream FileInpStream = new FileInputStream(SelectedImagePath); 
       BufferedInputStream BufInputStream = new BufferedInputStream(FileInpStream); 
       DBByte = new byte[BufInputStream.available()]; 
       BufInputStream.read(DBByte); 
       Log.d("DatabaseOperations", "Image Size : " + DBByte.length + " KB"); 
      } 

      catch (IOException e) { 
       Log.d("DatabaseOperations", "Error : " + SelectedImagePath); 
       Log.d("DatabaseOperations", e.getMessage(), e); 
      } 
     } 
    } 
} 

public String getPath(Uri Uris) { 
    String[] projection = { MediaStore.Images.Media.DATA }; 
    Cursor Cursor = managedQuery(Uris, projection, null, null, null); 
    int ColumnIndex = Cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); 
    Cursor.moveToFirst(); 
    return Cursor.getString(ColumnIndex); 
} 

我的清單權限

<uses-permission android:name="android.permission.CAMERA" /> 
<uses-feature android:name="android.hardware.camera" /> 
<uses-feature android:name="android.hardware.camera.autofocus" /> 
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> 
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 

<uses-permission-sdk-23 android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 
<uses-permission-sdk-23 android:name="android.permission.READ_EXTERNAL_STORAGE" /> 
<uses-permission-sdk-23 android:name="android.permission.CAMERA" /> 

的錯誤(logcat的)

FATAL EXCEPTION: main 
03-01 22:12:44.071 3768-3768/rajancorporations.database E/AndroidRuntime: Process: rajancorporations.database, PID: 3768 
03-01 22:12:44.071 3768-3768/rajancorporations.database E/AndroidRuntime: java.lang.SecurityException: Permission Denial: starting Intent { act=android.media.action.IMAGE_CAPTURE cmp=com.google.android.GoogleCamera/com.android.camera.CaptureActivity } from ProcessRecord{c9f94d7 3768:rajancorporations.database/u0a80} (pid=3768, uid=10080) with revoked permission android.permission.CAMERA 
03-01 22:12:44.071 3768-3768/rajancorporations.database E/AndroidRuntime:  at android.os.Parcel.readException(Parcel.java:1620) 
03-01 22:12:44.071 3768-3768/rajancorporations.database E/AndroidRuntime:  at android.os.Parcel.readException(Parcel.java:1573) 
03-01 22:12:44.071 3768-3768/rajancorporations.database E/AndroidRuntime:  at android.app.ActivityManagerProxy.startActivity(ActivityManagerNative.java:2658) 
03-01 22:12:44.071 3768-3768/rajancorporations.database E/AndroidRuntime:  at android.app.Instrumentation.execStartActivity(Instrumentation.java:1507) 
03-01 22:12:44.071 3768-3768/rajancorporations.database E/AndroidRuntime:  at android.app.Activity.startActivityForResult(Activity.java:3930) 
03-01 22:12:44.071 3768-3768/rajancorporations.database E/AndroidRuntime:  at android.app.Activity.startActivityForResult(Activity.java:3890) 
03-01 22:12:44.071 3768-3768/rajancorporations.database E/AndroidRuntime:  at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:784) 
03-01 22:12:44.071 3768-3768/rajancorporations.database E/AndroidRuntime:  at rajancorporations.database.Reg$2.onClick(Reg.java:75) 
03-01 22:12:44.071 3768-3768/rajancorporations.database E/AndroidRuntime:  at android.view.View.performClick(View.java:5204) 
03-01 22:12:44.071 3768-3768/rajancorporations.database E/AndroidRuntime:  at android.view.View$PerformClick.run(View.java:21153) 
03-01 22:12:44.071 3768-3768/rajancorporations.database E/AndroidRuntime:  at android.os.Handler.handleCallback(Handler.java:739) 
03-01 22:12:44.071 3768-3768/rajancorporations.database E/AndroidRuntime:  at android.os.Handler.dispatchMessage(Handler.java:95) 
03-01 22:12:44.071 3768-3768/rajancorporations.database E/AndroidRuntime:  at android.os.Looper.loop(Looper.java:148) 
03-01 22:12:44.071 3768-3768/rajancorporations.database E/AndroidRuntime:  at android.app.ActivityThread.main(ActivityThread.java:5417) 
03-01 22:12:44.071 3768-3768/rajancorporations.database E/AndroidRuntime:  at java.lang.reflect.Method.invoke(Native Method) 
03-01 22:12:44.071 3768-3768/rajancorporations.database E/AndroidRuntime:  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
03-01 22:12:44.071 3768-3768/rajancorporations.database E/AndroidRuntime:  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
+1

始終顯示錯誤。 –

+0

它只是說圖像存儲/storage/emulated/0/Pictures/RajanDP.jpg:打開失敗:EACCES(權限被拒絕) – RexDough

+0

和相機java.lang.SecurityException:權限拒絕:啓動Intent {act = android.media .action.IMAGE_CAPTURE cmp = com.google.android.GoogleCamera/com.android.camera.CaptureActivity} from ProcessRecord {c9f94d7 3768:rajancorporations.database/u0a80}(pid = 3768,uid = 10080),具有撤銷權限android.permission。攝像機 – RexDough

回答

1

首先,您認爲Data.getData()在這裏有意義。 There is no Uri returned by ACTION_IMAGE_CAPTURE, according to the specification。您的選項要麼提供EXTRA_OUTPUT(在這種情況下,圖像應該是您在其中指出的位置),或從Data.getExtra("data")獲取縮略圖。可能有幾個相機應用程序返回Uri。但有超過8,000 Android設備型號,有數百個(如果不是數千)不同的默認相機應用程序。用戶可能也會讓您的請求由第三方相機應用處理。大多數相機應用會爲您提供Data.getData()null值。

其次,即使如果你得到一個Uri,你假設Uri是已知的MediaStore。這不是必需的。

第三,即使如果你得到一個Uri,這是已知MediaStore,你假設DATA欄是可以訪問本地文件的路徑。這不是必需的。例如,它可能是移動存儲的路徑,您無法在Android 4.4+上訪問它。

爲了解決這些三個問題,使用EXTRA_OUTPUT指定您希望相機存儲圖片,並擺脫getPath()和你於Uri依賴。

第四,外部存儲在Android 6.0+工作時,如果你的targetSdkVersion爲23或更高,則需要請求READ_EXTERNAL_STORAGEWRITE_EXTERNAL_STORAGEfrom the user at runtime。這同樣適用於CAMERA權限。

五,沒有<uses-permission><uses-permission-sdk-23>爲相同的權限。在你的情況下,使用<uses-permission>

+0

它更容易將圖像路徑存儲到數據庫,這是我所選擇的圖像,我會嘗試運行時權限,我將如何在活動代碼中執行此操作,我可以看到示例 – RexDough

+0

@RexDough: 「更容易將圖像路徑存儲到數據庫,這是我對選定圖像的處理」 - 什麼是「更容易」並不重要。如果你依賴'Uri',**你可能沒有圖像路徑**,因爲**你可能不會得到'Uri' **。 「我將如何在活動代碼中執行此操作」 - https://github.com/commonsguy/cw-omnibus/tree/master/Permissions/tutorial/finish/RuntimePermTutorial – CommonsWare

3

這裏是我從攝像頭或圖庫拍攝圖像的完整代碼,它與其他人一起在棉花糖中工作正常。

這裏我聲明Varriables

protected static final int CAMERA_REQUEST = 0; 
protected static final int GALLERY_REQUEST = 1; 
private static final int REQUEST_ACESS_STORAGE=3; 
private static final int REQUEST_ACESS_CAMERA=2; 
private Uri uri; 

在這裏,我有棉花糖許可一些方法

public static boolean checkPermission(String permission, Context context) { 
    int statusCode = ContextCompat.checkSelfPermission(context, permission); 
    return statusCode == PackageManager.PERMISSION_GRANTED; 
} 

public static void requestPermission(AppCompatActivity activity, String[] permission, int requestCode) { 
    if (ActivityCompat.shouldShowRequestPermissionRationale(activity, permission[0])) { 
     Toast.makeText(activity, "Application need permission", Toast.LENGTH_SHORT).show(); 
    } 
    ActivityCompat.requestPermissions(activity, permission, requestCode); 
} 

public static void requestPermission(Fragment fragment, String[] permission, int requestCode) { 
    fragment.requestPermissions(permission, requestCode); 
} 

我的onclick方法處理的相機的方法

if (v.getId()==R.id.idOfPhoto){ 
      handleCamera(); 
     } 

詳細

private void handleCamera(){ 
     if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.M) { 
      if (checkPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE, this)) { 
       startDilog(); 
      }else{ 
       requestPermission(this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},REQUEST_ACESS_STORAGE); 
      } 
     }else{ 
      startDilog(); 
     } 
    } 

startdilog方法

private void startDilog() { 
    AlertDialog.Builder myAlertDilog = new AlertDialog.Builder(YourActivity.this); 
    myAlertDilog.setTitle("Upload picture option.."); 
    myAlertDilog.setMessage("Where to upload picture????"); 
    myAlertDilog.setPositiveButton("Gallery", new DialogInterface.OnClickListener() { 
     @Override 
     public void onClick(DialogInterface dialog, int which) { 
      Intent picIntent = new Intent(Intent.ACTION_GET_CONTENT,null); 
      picIntent.setType("image/*"); 
      picIntent.putExtra("return_data",true); 
      startActivityForResult(picIntent,GALLERY_REQUEST); 
     } 
    }); 
    myAlertDilog.setNegativeButton("Camera", new DialogInterface.OnClickListener() { 
     @Override 
     public void onClick(DialogInterface dialog, int which) { 
      if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.M){ 
       if(checkPermission(Manifest.permission.CAMERA,YourActivity.this)){ 
        openCameraApplication(); 
       }else{ 
        requestPermission(YourActivity.this,new String[]{Manifest.permission.CAMERA},REQUEST_ACESS_CAMERA); 
       } 
      }else{ 
       openCameraApplication(); 
      } 
     } 
    }); 
    myAlertDilog.show(); 
} 

openCameraApplication方法

private void openCameraApp() { 
    Intent picIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
    if (picIntent.resolveActivity(getPackageManager())!= null){ 
     startActivityForResult(picIntent, CAMERA_REQUEST); 
    } 
} 

休息的代碼

@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    super.onActivityResult(requestCode, resultCode, data); 
    if (requestCode == GALLERY_REQUEST) { 
     if (resultCode == RESULT_OK) { 
      if (data != null) { 
       uri = data.getData(); 
       BitmapFactory.Options options = new BitmapFactory.Options(); 
       options.inJustDecodeBounds = true; 
       try { 
        BitmapFactory.decodeStream(getContentResolver().openInputStream(uri), null, options); 
        options.inSampleSize =calculateInSampleSize(options, 100, 100); 
        options.inJustDecodeBounds = false; 
        Bitmap image = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri), null, options); 
        imageview.setImageBitmap(image); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } else { 
       Toast.makeText(getApplicationContext(), "Cancelled", 
         Toast.LENGTH_SHORT).show(); 
      } 
     } else if (resultCode == RESULT_CANCELED) { 
      Toast.makeText(getApplicationContext(), "Cancelled", 
        Toast.LENGTH_SHORT).show(); 
     } 
    } else if (requestCode == CAMERA_REQUEST) { 
     if (resultCode == RESULT_OK) { 
      if (data.hasExtra("data")) { 
       Bitmap bitmap = (Bitmap) data.getExtras().get("data"); 
       uri = getImageUri(YourActivity.this, bitmap); 
       File finalFile = new File(getRealPathFromUri(uri)); 
       imageview.setImageBitmap(bitmap); 
      } else if (data.getExtras() == null) { 

       Toast.makeText(getApplicationContext(), 
         "No extras to retrieve!", Toast.LENGTH_SHORT) 
         .show(); 

       BitmapDrawable thumbnail = new BitmapDrawable(
         getResources(), data.getData().getPath()); 
       owner_pic.setImageDrawable(thumbnail); 

      } 

     } else if (resultCode == RESULT_CANCELED) { 
      Toast.makeText(getApplicationContext(), "Cancelled", 
        Toast.LENGTH_SHORT).show(); 
     } 
    } 
} 

private String getRealPathFromUri(Uri tempUri) { 
    Cursor cursor = null; 
    try { 
     String[] proj = {MediaStore.Images.Media.DATA}; 
     cursor = this.getContentResolver().query(tempUri, proj, null, null, null); 
     int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); 
     cursor.moveToFirst(); 
     return cursor.getString(column_index); 
    } finally { 
     if (cursor != null) { 
      cursor.close(); 
     } 
    } 
} 
private Uri getImageUri(YourActivity youractivity, Bitmap bitmap) { 
    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); 
    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream); 
    String path = MediaStore.Images.Media.insertImage(youractivity.getContentResolver(), bitmap, "Title", null); 
    return Uri.parse(path); 

public static int calculateInSampleSize(
      BitmapFactory.Options options, int reqWidth, int reqHeight) { 
     // Raw height and width of image 
     final int height = options.outHeight; 
     final int width = options.outWidth; 
     int inSampleSize = 1; 

     if (height > reqHeight || width > reqWidth) { 

      final int halfHeight = height/2; 
      final int halfWidth = width/2; 

      // Calculate the largest inSampleSize value that is a power of 2 and keeps both 
      // height and width larger than the requested height and width. 
      while ((halfHeight/inSampleSize) > reqHeight 
        && (halfWidth/inSampleSize) > reqWidth) { 
       inSampleSize *= 2; 
      } 
     } 
     return inSampleSize; 
    } 



@Override 
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { 
    super.onRequestPermissionsResult(requestCode, permissions, grantResults); 
    if(requestCode==REQUEST_ACESS_STORAGE && grantResults[0]== PackageManager.PERMISSION_GRANTED){ 
     startDilog(); 
    } 
    if(requestCode==REQUEST_ACESS_CAMERA && grantResults[0]==PackageManager.PERMISSION_GRANTED){ 
     openCameraApp(); 
    } 
} 

它的工作在witth所有設備都很好..

+0

謝謝,它在棉花糖設備中工作。 –

+0

非常好的解決方案,但在打電話功能時有一些錯誤。 –