2017-10-17 62 views
0

在我的應用程序中,通過相機拍攝照片並將其發送給作物,但是當相機應用程序打開時發送圖像和用戶作物並單擊確定,即會顯示一個烤麪包由相機應用,發送作物到相機的圖像

「無法保存裁剪圖像」

下面是我爲它編寫的代碼:

public static void sendImageForCrop(final Activity activity, final Uri mImageCaptureUri){ 

     final ArrayList<CropOption> cropOptions = new ArrayList<>(); 

     Intent intent = new Intent("com.android.camera.action.CROP"); 
     intent.setType("image/*"); 

     List<ResolveInfo> list = activity.getPackageManager().queryIntentActivities(
       intent, 0); 

     int size = list.size(); 

     if (size == 0) { 
      Toast.makeText(activity, "Can not find image crop app", 
        Toast.LENGTH_SHORT).show(); 
     } else { 
      //intent.setData(mImageCaptureUri); 
      intent.setDataAndType(mImageCaptureUri, "image/*"); 

      intent.putExtra("crop", "true"); 
      intent.putExtra("outputX", 150); 
      intent.putExtra("outputY", 150); 
      intent.putExtra("aspectX", 1); 
      intent.putExtra("aspectY", 1); 
      intent.putExtra("scale", true); 
      intent.putExtra("return-data", true); 

      intent.setFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 
      try{ 
       intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(File.createTempFile("temp", null, activity.getCacheDir()))); 

      }catch(IOException ioe){ 
       // It is unfortunate that the Photo can't be cropped. 
       // Show a Toast for this. 
       Toast.makeText(activity, "The photo couldn't be saved :(. Try clearing the App data.", Toast.LENGTH_SHORT).show(); 
       return; 
      } 

      activity.startActivityForResult(i, CROP_FROM_CAMERA); 
     } 
    } 

這裏是意圖對象的toString()

Intent { act=com.android.camera.action.CROP dat=file:///storage/emulated/0/Snap_1508218098533.jpg typ=image/* flg=0x2 (has extras) } 

這裏有什麼問題?


編輯:按照要求,這裏是清單文件:

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    package="com.example.example" 
    android:versionCode="156" 
    android:versionName="1.2.54"> 

    <uses-permission android:name="android.permission.INTERNET" /> 
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> 
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> 
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> 
    <uses-permission android:name="android.permission.CAMERA" /> 
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 
    <uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" /> 
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> 
    <uses-permission android:name="android.permission.VIBRATE" /> 
    <uses-permission android:name="android.permission.WAKE_LOCK" /> 
    <uses-permission android:name="android.permission.RECORD_AUDIO" /> 
    <uses-permission android:name="android.permission.READ_CONTACTS" /> 
    <uses-permission android:name="android.permission.READ_PHONE_STATE" /> 

    <uses-permission android:name="com.google.android.apps.photos.permission.GOOGLE_PHOTOS"/> 

    <uses-sdk tools:overrideLibrary="com.braintreepayments.api.core,com.android.volley,com.paypal.android.sdk.onetouch.core,com.braintreepayments.api" /> 

    <uses-feature 
     android:name="android.hardware.camera" 
     android:required="false" /> 
    <uses-feature 
     android:name="android.hardware.camera.autofocus" 
     android:required="false" /> 
    <uses-feature 
     android:name="android.hardware.location.network" 
     android:required="false" /> 
    <uses-feature 
     android:name="android.hardware.location" 
     android:required="false" /> 
    <uses-feature 
     android:name="android.hardware.location.gps" 
     android:required="false" /> 
    <uses-feature 
     android:name="android.hardware.microphone" 
     android:required="false" /> 


    <!-- Tell the system this app requires OpenGL ES 2.0. --> 
    <uses-feature 
     android:glEsVersion="0x00015000" 
     android:required="true" /> 
    <uses-feature 
     android:name="android.hardware.touchscreen" 
     android:required="false" /> 


    <application 
     android:name="com.example.example.UILApplication" 
     android:allowBackup="true" 
     android:hardwareAccelerated="true" 
     android:icon="@drawable/applicationlogo" 
     android:label="@string/app_name" 
     android:largeHeap="true" 
     android:theme="@style/Theme.MyTheme"> 

      <!-- List of Activities here --> 


     <provider 
      android:name=".provider.GenericFileProvider" 
      android:authorities="${applicationId}.provider" 
      android:exported="false" 
      android:grantUriPermissions="true"> 
      <meta-data 
       android:name="android.support.FILE_PROVIDER_PATHS" 
       android:resource="@xml/provider_paths" /> 
     </provider> 


    </application> 

</manifest> 
+0

你也可以顯示你的清單文件嗎? –

+0

@AngelKoh已發佈! –

+0

@pulp_fiction你可以在活動結果上加上你的問題 – UltimateDevil

回答

0

我有,但我固定,通過改變如下保存的圖像目錄的路徑相同的問題 - :

File croppedImageDirectory = new File(Environment.getExternalStorageDirectory()+"/croppedImage"); 

或者,看到此答案可能會對您有所幫助 - :stackoverflow.com/a/1976115

可以幫你

+0

此解決方案的問題是'Environment.getExternalStorageDirectory()'不能保證可用。 https://stackoverflow.com/questions/11463695/fallback-solutions-when-getexternalstoragedirectory-is-not-available –

+0

你的問題解決了嗎 – UltimateDevil

0

我認爲這個問題是可能是在您試圖保存路徑,

嘗試使用如下

public void choosePhoto(View view) {   
    Intent intent = new Intent(Intent.ACTION_PICK, null); 
    intent.setType("image/*"); 
    intent.putExtra("crop", "true"); 
    intent.putExtra("aspectX", 1); 
    intent.putExtra("aspectY", 1); 
    intent.putExtra("outputX", int_Width_crop); 
    intent.putExtra("outputY", int_Height_crop); 
    intent.putExtra("scale", false); 
    intent.putExtra("return-data", true); 
    File photo = new File(Environment.getExternalStorageDirectory(), "cropped_image.jpg");   
    intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photo)); 
    imageUri = Uri.fromFile(photo); 
    intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString()); 
    startActivityForResult(intent, CHOOSE_PICTURE);   
} 
+0

這個解決方案的問題是Environment.getExternalStorageDirectory()不能保證可用。 https://stackoverflow.com/questions/11463695/fallback-solutions-when-getexternalstoragedirectory-is-not-available –

+0

外部存儲總是可用的。不要相信你閱讀的每一篇文章。 – greenapps

+0

@greenapps:那麼,文檔說'getExternalStorageDirectory()':*返回主共享/外部存儲目錄。 **如果用戶在他們的計算機上安裝了該目錄,或者已經從設備上刪除了該目錄,或者發生了其他問題,則該目錄可能無法訪問。**您可以使用* –

0

我知道這將是一個被認爲是破解方法通過你們許多人,但它的作品!

intent.putExtra(MediaStore.EXTRA_OUTPUT, (String)null); 

推理

好了,我擡頭一看畫廊應用在棉花糖的source(作物是失敗的地方之一;另一個是照片應用),並發現這種方法處理農作物請求:

private void saveOutput(Bitmap croppedImage) { 
     if (mSaveUri != null) { 
      OutputStream outputStream = null; 
      try { 
       outputStream = mContentResolver.openOutputStream(mSaveUri); 
       if (outputStream != null) { 
        croppedImage.compress(mOutputFormat, 75, outputStream); 
       } 
      } catch (IOException ex) { 
       // TODO: report error to caller 
       Log.e(TAG, "Cannot open file: " + mSaveUri, ex); 
      } finally { 
       Util.closeSilently(outputStream); 
      } 
      Bundle extras = new Bundle(); 
      setResult(RESULT_OK, new Intent(mSaveUri.toString()) 
        .putExtras(extras)); 
     } else if (mSetWallpaper) { 
      try { 
       WallpaperManager.getInstance(this).setBitmap(croppedImage); 
       setResult(RESULT_OK); 
      } catch (IOException e) { 
       Log.e(TAG, "Failed to set wallpaper.", e); 
       setResult(RESULT_CANCELED); 
      } 
     } else { 
      Bundle extras = new Bundle(); 
      extras.putString("rect", mCrop.getCropRect().toString()); 
      File oldPath = new File(mImage.getDataPath()); 
      File directory = new File(oldPath.getParent()); 
      int x = 0; 
      String fileName = oldPath.getName(); 
      fileName = fileName.substring(0, fileName.lastIndexOf(".")); 
      // Try file-1.jpg, file-2.jpg, ... until we find a filename which 
      // does not exist yet. 
      while (true) { 
       x += 1; 
       String candidate = directory.toString() 
         + "/" + fileName + "-" + x + ".jpg"; 
       boolean exists = (new File(candidate)).exists(); 
       if (!exists) { 
        break; 
       } 
      } 
      try { 
       int[] degree = new int[1]; 
       Uri newUri = ImageManager.addImage(
         mContentResolver, 
         mImage.getTitle(), 
         mImage.getDateTaken(), 
         null, // TODO this null is going to cause us to lose 
           // the location (gps). 
         directory.toString(), fileName + "-" + x + ".jpg", 
         croppedImage, null, 
         degree); 
       setResult(RESULT_OK, new Intent() 
         .setAction(newUri.toString()) 
         .putExtras(extras)); 
      } catch (Exception ex) { 
       // basically ignore this or put up 
       // some ui saying we failed 
       Log.e(TAG, "store image fail, continue anyway", ex); 
      } 
     } 
     final Bitmap b = croppedImage; 
     mHandler.post(new Runnable() { 
      public void run() { 
       mImageView.clear(); 
       b.recycle(); 
      } 
     }); 
     finish(); 
    } 

您看到聲明if (mSaveUri != null) {。它處理我們提供空Uri的情況。假設是第三方應用程序可能會處理我們提供空Uri的情況。

現在,我測試了它與幾個應用程序,它的工作。但絕不是,這個解決方案是一個理想的解決方案。