2017-04-10 180 views
1

由於我已經使用FileProvider將我的應用程序遷移到了Android N,因此我無法在手機的圖庫中看到我的圖片(即使是低於Android N的版本)。所以我創建了一個小測試應用程序來調試,沒有成功。使用FileProvider拍攝照片後無法保存在圖庫中

在我的清單

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

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

<application 
    ...> 
    ... 


    <provider 
     android:name="android.support.v4.content.FileProvider" 
     android:authorities="${applicationId}.fileprovider" 
     android:exported="false" 
     android:grantUriPermissions="true"> 
     <meta-data 
      android:name="android.support.FILE_PROVIDER_PATHS" 
      android:resource="@xml/file_paths"></meta-data> 
    </provider> 
</application> 

在file_paths.xml

<paths> 
<external-files-path 
    name="test_images" 
    path="Pictures/TestPictures"/> 
</paths> 

而且我做了一個小活動,顯示最後拍攝的照片,以確保URI是正確的:

private final static int REQUEST_CAMERA = 1102; 
public static final String CAMERA_IMAGES_DIR = "TestPictures"; 
String mOutputFilePath; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    findViewById(R.id.button).setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      onCamera(); 
     } 
    }); 
} 

public void onCamera() { 
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
    if (intent.resolveActivity(getPackageManager()) != null) { 
     File photoFile = createImageFile(); 
     Uri photoURI = FileProvider.getUriForFile(this, 
       getPackageName() + ".fileprovider", 
       photoFile); 
     mOutputFilePath = photoFile.getAbsolutePath(); 
     intent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI); 
     startActivityForResult(intent, REQUEST_CAMERA); 
    } 
} 

@Override 
public void onActivityResult(int requestCode, int resultCode, Intent data) { 
    super.onActivityResult(requestCode, resultCode, data); 
    if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_CAMERA) 
     onCaptureImageResult(); 
} 

private void onCaptureImageResult() { 
    if (mOutputFilePath != null) { 
     File f = new File(mOutputFilePath); 
     Uri finalUri = Uri.fromFile(f); 
     galleryAddPic(finalUri); 
     ((ImageView) findViewById(R.id.imageView)).setImageURI(finalUri); 
    } 
} 

public File createImageFile() { 
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); 
    String imageFileName = "JPEG_" + timeStamp + "_"; 
    File storageDir = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), CAMERA_IMAGES_DIR + "/"); 
    if (!storageDir.exists()) 
     storageDir.mkdir(); 
    return new File(storageDir, imageFileName + ".jpg"); 
} 

private void galleryAddPic(Uri contentUri) { 
    Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, contentUri); 
    sendBroadcast(mediaScanIntent); 
} 

我的照片是在我的應用程序和我的文件瀏覽器像預期的,但我不能在照片庫中看到它。 我試圖使用FileProvider Uri,這不起作用。

+1

https://stackoverflow.com/questions/32789157/how-to-write-files-to-external-public-storage-in-android-so-這是他們是可見的 – CommonsWare

+0

在畫廊中添加我的照片的方式不是問題,但我注意到您分享的線程中使用的目錄,它幫助我找到解決方案,thx。 – Silwek

回答

2

問題似乎是要添加到圖庫的文件的位置,而不是添加它的方式。

getExternalFilesDir(Environment.DIRECTORY_PICTURES)沒有爲介質掃描,但Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)做工作。但是,我們不能使用FileProvider中的最後一個,所以我需要在公共目錄中創建拍攝照片的副本。

更新我的代碼,如:

private void onCaptureImageResult() { 
    if (mOutputFilePath != null) { 
     File f = new File(mOutputFilePath); 
     try { 
      File publicFile = copyImageFile(f); 
      Uri finalUri = Uri.fromFile(publicFile); 
      galleryAddPic(finalUri); 
      ((ImageView) findViewById(R.id.imageView)).setImageURI(finalUri); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

public File copyImageFile(File fileToCopy) throws IOException { 
    File storageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), CAMERA_IMAGES_DIR + "/"); 
    if (!storageDir.exists()) 
     storageDir.mkdir(); 
    File copyFile = new File(storageDir, fileToCopy.getName()); 
    copyFile.createNewFile(); 
    copy(fileToCopy, copyFile); 
    return copyFile; 
} 

public static void copy(File src, File dst) throws IOException { 
    InputStream in = new FileInputStream(src); 
    OutputStream out = new FileOutputStream(dst); 
    byte[] buf = new byte[1024]; 
    int len; 
    while ((len = in.read(buf)) > 0) { 
     out.write(buf, 0, len); 
    } 
    in.close(); 
    out.close(); 
} 
+0

查看https://stackoverflow.com/a/33031091/966789 (Android爲Android 6.0 Marshmallow添加了新的權限模型) –

相關問題