select 如何将特定的视频文件上传到图库 Android Q?
How to select specific video files to upload to gallery in Android Q?
使用 mediaRecorder 和 Camera 录制视频后 API,我正在尝试将视频保存到用户的画廊(通过保存到他们的外部电影、DCIM 目录或其他目录)。
不幸的是,我从文档或 Whosebug 中找到的代码似乎创建了它们各自的 URI,但没有引用录制的视频或其保存的文件。具体来说,我尝试使用的代码是:
String videoFileName = "video_" + System.currentTimeMillis() + ".mp4";
ContentValues valuesvideos;
valuesvideos = new ContentValues();
valuesvideos.put(MediaStore.Video.Media.RELATIVE_PATH, "Movies/" + "Folder");
valuesvideos.put(MediaStore.Video.Media.TITLE, videoFileName);
valuesvideos.put(MediaStore.Video.Media.DISPLAY_NAME, videoFileName);
valuesvideos.put(MediaStore.Video.Media.MIME_TYPE, "video/mp4");
valuesvideos.put(MediaStore.Video.Media.DATE_ADDED, System.currentTimeMillis() / 1000);
valuesvideos.put(MediaStore.Video.Media.DATE_TAKEN, System.currentTimeMillis());
valuesvideos.put(MediaStore.Video.Media.IS_PENDING, 1);
ContentResolver resolver = context.getContentResolver();
Uri collection = MediaStore.Video.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY);
Uri uriSavedVideo = resolver.insert(collection, valuesvideos);
ParcelFileDescriptor pfd;
try {
pfd = context.getContentResolver().openFileDescriptor(uriSavedVideo,"w");
assert pfd != null;
FileOutputStream out = new FileOutputStream(pfd.getFileDescriptor());
// Get the already saved video as fileinputstream from here
File storageDir = new File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "Folder");
File imageFile = new File(storageDir, "testStorage");
FileInputStream in = new FileInputStream(imageFile);
byte[] buf = new byte[8192];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
out.close();
in.close();
pfd.close();
} catch (Exception e) {
e.printStackTrace();
}
它周围的代码和答案似乎暗示通过访问 MediaStore.VOLUME_EXTERNAL_PRIMARY 解析器可以访问保存的视频文件,但我看不到对它的明确引用。在录制视频之前,我定义了分配给 mediaRecorder 的文件:
static File getMediaFile(Context c) {
File mediaStorageDir = c.getExternalFilesDir(null);
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
return new File(mediaStorageDir.getPath() + File.separator + "VID_" + timeStamp + ".mp4");
}
停止视频后出现此错误(引用此行:Uri uriSavedVideo = resolver.insert(collection, valuesvideos);
):
java.lang.UnsupportedOperationException: Unknown URI: content://media/external_primary/video/media at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java.167) ...
如何参考保存的视频正确创建 URI?用文件 Uri.fromFile(f);
中的 URI 代替 uriSavedVideo 也不起作用。
为了将特定视频文件保存到图库,我将该文件作为参数传递给 new FileInputStream
。
其次,作为Android docs状态:
Only your app can view the file until your app changes the value of IS_PENDING back to 0.
因此,根据用户@blackapps 的建议,我手动更改了该状态。更改后的代码如下:
private static void addToApi29Gallery(File file, Context context) {
String videoFileName = "video_" + System.currentTimeMillis() + ".mp4";
ContentValues valuesvideos = new ContentValues();
valuesvideos.put(MediaStore.Video.Media.RELATIVE_PATH, "Movies/" + "Trickshott");
valuesvideos.put(MediaStore.Video.Media.TITLE, videoFileName);
valuesvideos.put(MediaStore.Video.Media.DISPLAY_NAME, videoFileName);
valuesvideos.put(MediaStore.Video.Media.MIME_TYPE, "video/mp4");
valuesvideos.put(MediaStore.Video.Media.DATE_ADDED, System.currentTimeMillis() / 1000);
valuesvideos.put(MediaStore.Video.Media.DATE_TAKEN, System.currentTimeMillis());
valuesvideos.put(MediaStore.Video.Media.IS_PENDING, 1);
ContentResolver resolver = context.getContentResolver();
Uri collection = MediaStore.Video.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY); //all video files on primary external storage
Uri uriSavedVideo = resolver.insert(collection, valuesvideos);
ParcelFileDescriptor pfd;
try {
pfd = context.getContentResolver().openFileDescriptor(uriSavedVideo,"w");
assert pfd != null;
FileOutputStream out = new FileOutputStream(pfd.getFileDescriptor());
// Get the already saved video as fileinputstream from here.
FileInputStream in = new FileInputStream(file);
byte[] buf = new byte[8192];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
out.close();
in.close();
pfd.close();
valuesvideos.clear();
valuesvideos.put(MediaStore.Video.Media.IS_PENDING, 0); // Only your app can see the files until pending is turned into 0.
context.getContentResolver().update(uriSavedVideo, valuesvideos, null, null);
} catch (Exception e) {
e.printStackTrace();
}
}
使用 mediaRecorder 和 Camera 录制视频后 API,我正在尝试将视频保存到用户的画廊(通过保存到他们的外部电影、DCIM 目录或其他目录)。
不幸的是,我从文档或 Whosebug 中找到的代码似乎创建了它们各自的 URI,但没有引用录制的视频或其保存的文件。具体来说,我尝试使用的代码是:
String videoFileName = "video_" + System.currentTimeMillis() + ".mp4";
ContentValues valuesvideos;
valuesvideos = new ContentValues();
valuesvideos.put(MediaStore.Video.Media.RELATIVE_PATH, "Movies/" + "Folder");
valuesvideos.put(MediaStore.Video.Media.TITLE, videoFileName);
valuesvideos.put(MediaStore.Video.Media.DISPLAY_NAME, videoFileName);
valuesvideos.put(MediaStore.Video.Media.MIME_TYPE, "video/mp4");
valuesvideos.put(MediaStore.Video.Media.DATE_ADDED, System.currentTimeMillis() / 1000);
valuesvideos.put(MediaStore.Video.Media.DATE_TAKEN, System.currentTimeMillis());
valuesvideos.put(MediaStore.Video.Media.IS_PENDING, 1);
ContentResolver resolver = context.getContentResolver();
Uri collection = MediaStore.Video.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY);
Uri uriSavedVideo = resolver.insert(collection, valuesvideos);
ParcelFileDescriptor pfd;
try {
pfd = context.getContentResolver().openFileDescriptor(uriSavedVideo,"w");
assert pfd != null;
FileOutputStream out = new FileOutputStream(pfd.getFileDescriptor());
// Get the already saved video as fileinputstream from here
File storageDir = new File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "Folder");
File imageFile = new File(storageDir, "testStorage");
FileInputStream in = new FileInputStream(imageFile);
byte[] buf = new byte[8192];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
out.close();
in.close();
pfd.close();
} catch (Exception e) {
e.printStackTrace();
}
它周围的代码和答案似乎暗示通过访问 MediaStore.VOLUME_EXTERNAL_PRIMARY 解析器可以访问保存的视频文件,但我看不到对它的明确引用。在录制视频之前,我定义了分配给 mediaRecorder 的文件:
static File getMediaFile(Context c) {
File mediaStorageDir = c.getExternalFilesDir(null);
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
return new File(mediaStorageDir.getPath() + File.separator + "VID_" + timeStamp + ".mp4");
}
停止视频后出现此错误(引用此行:Uri uriSavedVideo = resolver.insert(collection, valuesvideos);
):
java.lang.UnsupportedOperationException: Unknown URI: content://media/external_primary/video/media at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java.167) ...
如何参考保存的视频正确创建 URI?用文件 Uri.fromFile(f);
中的 URI 代替 uriSavedVideo 也不起作用。
为了将特定视频文件保存到图库,我将该文件作为参数传递给 new FileInputStream
。
其次,作为Android docs状态:
Only your app can view the file until your app changes the value of IS_PENDING back to 0.
因此,根据用户@blackapps 的建议,我手动更改了该状态。更改后的代码如下:
private static void addToApi29Gallery(File file, Context context) {
String videoFileName = "video_" + System.currentTimeMillis() + ".mp4";
ContentValues valuesvideos = new ContentValues();
valuesvideos.put(MediaStore.Video.Media.RELATIVE_PATH, "Movies/" + "Trickshott");
valuesvideos.put(MediaStore.Video.Media.TITLE, videoFileName);
valuesvideos.put(MediaStore.Video.Media.DISPLAY_NAME, videoFileName);
valuesvideos.put(MediaStore.Video.Media.MIME_TYPE, "video/mp4");
valuesvideos.put(MediaStore.Video.Media.DATE_ADDED, System.currentTimeMillis() / 1000);
valuesvideos.put(MediaStore.Video.Media.DATE_TAKEN, System.currentTimeMillis());
valuesvideos.put(MediaStore.Video.Media.IS_PENDING, 1);
ContentResolver resolver = context.getContentResolver();
Uri collection = MediaStore.Video.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY); //all video files on primary external storage
Uri uriSavedVideo = resolver.insert(collection, valuesvideos);
ParcelFileDescriptor pfd;
try {
pfd = context.getContentResolver().openFileDescriptor(uriSavedVideo,"w");
assert pfd != null;
FileOutputStream out = new FileOutputStream(pfd.getFileDescriptor());
// Get the already saved video as fileinputstream from here.
FileInputStream in = new FileInputStream(file);
byte[] buf = new byte[8192];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
out.close();
in.close();
pfd.close();
valuesvideos.clear();
valuesvideos.put(MediaStore.Video.Media.IS_PENDING, 0); // Only your app can see the files until pending is turned into 0.
context.getContentResolver().update(uriSavedVideo, valuesvideos, null, null);
} catch (Exception e) {
e.printStackTrace();
}
}