2017-04-10 138 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添加了新的权限模型) –

相关问题