在android中存储其他应用程序可公开访问的视频文件

在android中存储其他应用程序可公开访问的视频文件,android,android-contentprovider,android-gallery,Android,Android Contentprovider,Android Gallery,这是我必须将应用程序生成的视频存储在磁盘上的当前代码。我希望这段视频可以被其他应用程序访问,比如TikTok、WhatsApp和谷歌照片。我还想在我的应用程序中创建自己的图库。但是,通过以下方法保存的文件不会显示在TikTok上。它们显示在Google photos Library\Movies文件夹下,用户必须深入挖掘才能找到 如何使所有应用都可以访问这些文件?我如何编写自己的视频库来显示应用程序创建的文件 private void addVideoToGallery(File videoFi

这是我必须将应用程序生成的视频存储在磁盘上的当前代码。我希望这段视频可以被其他应用程序访问,比如TikTok、WhatsApp和谷歌照片。我还想在我的应用程序中创建自己的图库。但是,通过以下方法保存的文件不会显示在TikTok上。它们显示在Google photos Library\Movies文件夹下,用户必须深入挖掘才能找到

如何使所有应用都可以访问这些文件?我如何编写自己的视频库来显示应用程序创建的文件

private void addVideoToGallery(File videoFile) {
        Uri uriSavedVideo;
        File createdvideo = null;
        ContentResolver resolver = activity.getContentResolver();

        String path = videoFile.getAbsolutePath();
        String videoFileName = path.substring(path.lastIndexOf("/") + 1);
        ContentValues valuesvideos;
        valuesvideos = new ContentValues();

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            valuesvideos.put(MediaStore.Video.Media.RELATIVE_PATH, Environment.DIRECTORY_MOVIES + File.pathSeparator + activity.getString(R.string.app_name));
            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);
            Uri collection = MediaStore.Video.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY);
            uriSavedVideo = resolver.insert(collection, valuesvideos);
        } else {
            String directory = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + Environment.DIRECTORY_MOVIES;
            createdvideo = new File(directory, videoFileName);
            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.DATA, createdvideo.getAbsolutePath());
            uriSavedVideo = resolver.insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, valuesvideos);
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            valuesvideos.put(MediaStore.Video.Media.DATE_TAKEN, System.currentTimeMillis());
            valuesvideos.put(MediaStore.Video.Media.IS_PENDING, 1);
        }

        ParcelFileDescriptor pfd;
        try {
            pfd = resolver.openFileDescriptor(uriSavedVideo, "w");
            FileOutputStream out = new FileOutputStream(pfd.getFileDescriptor());
            FileInputStream in = new FileInputStream(videoFile);
            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();
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            valuesvideos.clear();
            valuesvideos.put(MediaStore.Video.Media.IS_PENDING, 0);
            resolver.update(uriSavedVideo, valuesvideos, null, null);
        }
    }
此代码无法使用下面的代码从我的应用程序访问相同的文件

    private void getVids(){
    List<Video> videoList = new ArrayList<Video>();

    Uri collection;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        collection = MediaStore.Video.Media.getContentUri(MediaStore.VOLUME_EXTERNAL);
    } else {
        collection = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
    }

    String[] projection = new String[] {
            MediaStore.Video.Media._ID,
            MediaStore.Video.Media.DISPLAY_NAME,
            MediaStore.Video.Media.DURATION,
            MediaStore.Video.Media.SIZE
    };
    String selection = MediaStore.Video.Media.DURATION +
            " >= ?";
    String[] selectionArgs = new String[] {
            String.valueOf(TimeUnit.MILLISECONDS.convert(5, TimeUnit.MINUTES))};
    String sortOrder = MediaStore.Video.Media.DISPLAY_NAME + " ASC";

    try (Cursor cursor = activity.getContentResolver().query(
            collection,
            projection,
            selection,
            selectionArgs,
            sortOrder
    )) {
        // Cache column indices.
        int idColumn = cursor.getColumnIndexOrThrow(MediaStore.Video.Media._ID);
        int nameColumn =
                cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DISPLAY_NAME);
        int durationColumn =
                cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATION);
        int sizeColumn = cursor.getColumnIndexOrThrow(MediaStore.Video.Media.SIZE);

        while (cursor.moveToNext()) {
            // Get values of columns for a given video.
            long id = cursor.getLong(idColumn);
            String name = cursor.getString(nameColumn);
            int duration = cursor.getInt(durationColumn);
            int size = cursor.getInt(sizeColumn);

            Uri contentUri = ContentUris.withAppendedId(
                    MediaStore.Video.Media.EXTERNAL_CONTENT_URI, id);

            // Stores column values and the contentUri in a local object
            // that represents the media file.
            videoList.add(new Video(contentUri, name, duration, size));
        }
    }
}
private void getVids(){
List videoList=new ArrayList();
Uri集合;
if(Build.VERSION.SDK\u INT>=Build.VERSION\u code.Q){
collection=MediaStore.Video.Media.getContentUri(MediaStore.VOLUME\u外部);
}否则{
collection=MediaStore.Video.Media.EXTERNAL\u CONTENT\u URI;
}
字符串[]投影=新字符串[]{
MediaStore.Video.Media.\u ID,
MediaStore.Video.Media.DISPLAY\u名称,
MediaStore.Video.Media.DURATION,
MediaStore.Video.Media.SIZE
};
字符串选择=MediaStore.Video.Media.DURATION+
" >= ?";
字符串[]selectionArgs=新字符串[]{
valueOf(TimeUnit.millides.convert(5,TimeUnit.MINUTES))};
字符串sortOrder=MediaStore.Video.Media.DISPLAY_NAME+“ASC”;
try(Cursor=activity.getContentResolver().query(
收集
投影,
选择,
精选,
排序器
)) {
//缓存列索引。
int-idColumn=cursor.getColumnIndexOrThrow(MediaStore.Video.Media.\u-ID);
整数名称列=
cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DISPLAY\u NAME);
int-durationColumn=
cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATION);
int-sizeColumn=cursor.getColumnIndexOrThrow(MediaStore.Video.Media.SIZE);
while(cursor.moveToNext()){
//获取给定视频的列值。
long id=cursor.getLong(idColumn);
字符串名称=cursor.getString(nameColumn);
int duration=cursor.getInt(durationColumn);
int size=cursor.getInt(sizeColumn);
Uri contentUri=ContentUris.withAppendedId(
MediaStore.Video.Media.EXTERNAL_CONTENT_URI,id);
//在本地对象中存储列值和contentUri
//表示媒体文件的。
添加(新视频(contentUri、名称、持续时间、大小));
}
}
}

对于Android版本的旧设备,您应该单独指定问题。你的代码线程不同的Android版本,这是好的。如果你只在Q+上有问题,那么只发布该代码。你的应用程序可以通过选择相对路径查询其所有文件,该路径等于Environment.DIRECTORY\u MOVIES+File.pathSeparator+activity.getString(R.string.app\u name)。还可以编写一个查询该相对路径的小应用程序。尤其是在Android 11上,因为Android 11对文件所有者非常挑剔。如果你的testapp可以列出它们,那么其他应用没有理由不能列出。谢谢,我的手机是28版。为什么提克托克拿不到文件?嗯…谁说提克托克不能?蒂克托克没有;T谁知道为什么?而且。。。你的测试应用程序能做到吗?