使图像文件在 Lollipop 上的 Android 个图库中可见

Make image File visible in Android Gallery on Lollipop

我正在尝试使在应用程序中拍摄的一些照片在图库中可见(这样它们就可以在应用程序之外共享和查看),但我想将图像本身保存在数据目录中应用程序,因此当应用程序被删除时,它们将被删除(因此它们存储在 "{sdcard}/Android/data/{appID}/Pictures/{subfolder}/" 中)。

我看了很多答案,对于 Android 的旧版本,以下两种解决方案都有效,但它们似乎在 Lollipop 中不起作用:

MediaScannerConnection.scanFile(this,
    new String[]{file.toString()}, new String[] { "image/jpeg" },
    new MediaScannerConnection.OnScanCompletedListener() {
        public void onScanCompleted(String path, Uri uri) {
            Log.i("ExternalStorage", "Scanned " + path + ":");
            Log.i("ExternalStorage", "-> uri=" + uri);
        }
    });

Uri contentUri = Uri.fromFile(file);
Intent mediaScanIntent = new 
    Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,contentUri);
sendBroadcast(mediaScanIntent);

我已经在 Nexus 4 (Android 5.0.1) 和 Nexus 6 (Android 5.1) 上测试过它,但它不起作用。在 Nexus 7 (Android 4.2.2) 中它确实有效。所有 3 台设备在 {sdcard}/Android/data/ 文件夹中都有一个“.onmedia”文件,因此正常的媒体扫描应该不会拾取它们...

有没有人知道解决方法可以让它在所有 devices/Android 版本上工作?这应该是因为 noMedia 文件首先不起作用,而 Lollipop 是唯一正确执行此操作的版本吗?

编辑:请注意,即使 phone 重新启动(也应该触发文件重新扫描)也不起作用。并且有充分的理由,因为文件位于“.nomedia”目录的子文件夹中......所以我认为任何包含 MEDIA_MOUNTED 广播的解决方案都是无用的。

我建议你看看my answer here。它总结了我所做的关于 MediaScanner 的所有发现。

旁注:所有 KitKat 问题似乎也都存在于 Lollipop 上。

我不确定媒体内容提供商是否会获得对包含图像的本地数据目录的读取权限。没有权限,您的图库方法将无法工作。

要了解是否可行,您可以尝试通过

自己将对本地图像的引用放入 android 媒体数据库中
    mMediaProvider = mContext.getContentResolver().acquireProvider("media");
    mImagesUri = Images.Media.getContentUri(volumeName);
    result = mMediaProvider.insert(mImagesUri, values);

这是一个媒体扫描器的源代码,它应该包含所有必要的代码片段如何从 jpg 中填充值

图片保存后调用scan方法扫描图库,会显示图库中的图片。

  scanFile(Environment.getExternalStorageDirectory().getAbsolutePath() + "/appfolder/imgname"+imagenumber+".png");


 private void scanFile(String file) {


      MediaScannerConnection.scanFile(this,
                new String[] { file.toString() }, null,
                new MediaScannerConnection.OnScanCompletedListener() {
                    public void onScanCompleted(String path, Uri uri) {
                        Log.i("ExternalStorage", "Scanned " + path + ":");
                        Log.i("ExternalStorage", "-> uri=" + uri);
                    }
                });


    }

正如您所说 {sdcard}/Android/data/ 文件夹包含一个 .nomedia 文件,那么我们可以将 MediaScanner 的广播发送到通过使用波纹管代码指定子文件夹路径,扫描包含 .nomedia 文件的文件夹的子文件夹。

sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file:// "+"Directory path")));

试试下面的代码。它在 Lollipop 对我有用,希望对你也有用

ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DATA,"file path");
values.put(MediaStore.Images.Media.MIME_TYPE,"image/jpeg");
mContext.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,values);

编辑:不要忘记将它添加到您的清单中(尽管在 Lollipop 中不再需要它):

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />