#android
Вопрос:
После ограничений, введенных в Android 10 и 11, мне трудно извлечь видео из внутреннего / внешнего хранилища и скопировать его в каталог конкретного приложения, а затем использовать(возникает ошибка «Отказано в разрешении»). Для изображения я реализовал следующее:
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
Bitmap bm = testObj.getScaledBitmap(bitmap);//used own method
Uri uriimg = testObj.storeImage(internalPath imageName, bm);//used own method
Я не могу сделать то же самое для видео.
Не могли бы вы предоставить код для извлечения видео с помощью api Mediastore и сохранить его в каталоге конкретного приложения или предоставить пример извлечения видео из api mediastore?
Я также очень признателен, если я смогу получить пример использования scopedstorage с использованием JAVA, потому что большинство примеров, которые я нашел, используют только Kotlin.
Код: После того, как файл будет выбран в результате действия, затем проверьте, есть ли его видео, затем
File file = new File(getPath(ProductFlipperActivity.this,uri));
Метод getPath:
public static String getPath(final Context context, final Uri uri) {
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
Log.i("URI", uri "");
String result = uri "";
// DocumentProvider
// if (isKitKat amp;amp; DocumentsContract.isDocumentUri(context, uri)) {
if (isKitKat amp;amp; (result.contains("media.documents"))) {
String[] ary = result.split("/");
int length = ary.length;
String imgary = ary[length - 1];
final String[] dat = imgary.split(":");
final String docId = dat[1];
final String type = dat[0];
Uri contentUri = null;
if ("image".equals(type)) {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else if ("video".equals(type)) {
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
} else if ("audio".equals(type)) {
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
}
final String selection = "_id=?";
final String[] selectionArgs = new String[]{
dat[1]
};
return getDataColumn(context, contentUri, selection, selectionArgs);
} else if ("content".equalsIgnoreCase(uri.getScheme())) {
return getDataColumn(context, uri, null, null);
}
// File
else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
return null;
}
Метод getDataColumn():
public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
Cursor cursor = null;
final String column = "_data";
final String[] projection = {
column
};
try {
if (checkPermissionREAD_EXTERNAL_STORAGE(context)) {
// do your stuff..
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
if (cursor != null amp;amp; cursor.moveToFirst()) {
final int column_index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(column_index);
}
}
} finally {
if (cursor != null)
cursor.close();
}
return null;
}
Get the file name and use storepdf method
String videoName = file.getName();
testObj.storePDF(internalPath videoName, file);
storepdf method to save file in app specific directory:
//store pdf to sdcard
public Uri storePDF(String path, File file) {
Uri uri = null;
FileInputStream in = null;
FileOutputStream out = null;
try {
in = new FileInputStream(file);
String newFileName = path;
out = new FileOutputStream(newFileName);
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
in.close();
out.flush();
out.close();
} catch (Exception e) {
Log.e("tag", e.getMessage());
}
return Uri.fromFile(file);
}
После использования uri для сохранения файла и когда я открываю inputstream по реальному пути к файлу или uri, оба выдают ошибку:
File file = new File(String.valueOf(uri));
//File file = new File(getPath(ProductFlipperActivity.this,uri));
String videoName = file.getName();
InputStream in = new FileInputStream(file);
OutputStream out = new FileOutputStream(new File(internalPath videoName));
// Copy the bits from instream to outstream
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
Ошибка устранена с помощью следующего кода, предложенного @blackapps:
File file = new File(getPath(ProductFlipperActivity.this,uri));
String videoName = file.getName();
InputStream in = this.getContentResolver().openInputStream(uri);
OutputStream out = this.getContentResolver().openOutputStream((Uri.fromFile(new File(internalPath videoName))));
// Copy the bits from instream to outstream
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
in.close();
out.flush();
out.close();
Комментарии:
1.
(Video is in Internal/External Storage)
Ну … тогда зачем вам делать копию, если видео уже есть на вашем устройстве?2. пользователь выбирает видео из своего внутреннего/внешнего хранилища, и его необходимо скопировать в каталог конкретного приложения для дальнейшего использования.. т. е. внутри данных/данных/com. myapp/папка/ … но это приводит к отказу в разрешении в Android 10 и 11 @blackapps
3. Я не вижу никакого кода. Так почему бы вам для начала не опубликовать свой код? И мы понятия не имеем, за что или когда вы увидите отказ в разрешении. Начните публиковать код для «выбора пользователя».
4. да @blackapps.. я опубликую сейчас.. спасибо
5. @blackapps Я обновил код.. он отлично работает до Android 9..