【问题标题】:Get file size using URI in android在android中使用URI获取文件大小
【发布时间】:2018-08-31 02:02:49
【问题描述】:

我正在开发 android 视频应用程序,我正在使用 Camera Intent 录制视频并从图库中获取视频。录制视频或从图库中选择视频后,我想知道我拍摄的视频的大小。如果选择的视频大小大于 5MB,我想制定一个逻辑来向用户显示敬酒消息。 我制作了不起作用的底部逻辑,并在尝试从 URI 中获取大小时给了我 0 值。

提前致谢。

我的逻辑不起作用

java.net.URI juri = new java.net.URI(uri.toString());
        File mediaFile = new File(juri.getPath());
        long fileSizeInBytes = mediaFile.length();
        long fileSizeInKB = fileSizeInBytes / 1024;
        long fileSizeInMB = fileSizeInKB / 1024;

        if (fileSizeInMB > 5) {
            Toast.makeText(this,"Video files lesser than 5MB are allowed",Toast.LENGTH_LONG).show();
            return;
        }

这是我用来从图库中获取视频并录制视频的代码。

public void takeVideoFromCamera(){

        File mediaFile =new File(Environment.getExternalStorageDirectory().getAbsolutePath()+ "/myvideo.mp4");

        Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
        Uri videoUri;

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
//            videoUri = FileProvider.getUriForFile(this, this.getApplicationContext().getPackageName() + ".provider", mediaFile);
            videoUri = FileProvider.getUriForFile(this, "i.am.ce.by.ncy.provider", mediaFile);
        } else {
            videoUri  = Uri.fromFile(mediaFile);
        }
        intent.putExtra(MediaStore.EXTRA_OUTPUT, videoUri);
        intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
        intent.putExtra(MediaStore.EXTRA_SIZE_LIMIT, 5491520L);//5*1048*1048=5MB
        intent.putExtra(MediaStore.EXTRA_DURATION_LIMIT,45);
        startActivityForResult(intent, VIDEO_CAPTURE);
    }

    public void takeVideoFromGallery(){
        Intent intent = new Intent();
        intent.setType("video/*");
        intent.setAction(Intent.ACTION_GET_CONTENT);
        long maxVideoSize = 5 * 1024 * 1024; // 10 MB
        intent.putExtra(MediaStore.EXTRA_SIZE_LIMIT, maxVideoSize);
        startActivityForResult(Intent.createChooser(intent,"Select Video"),REQUEST_TAKE_GALLERY_VIDEO);

    }

onActivityResult 代码

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == this.RESULT_OK) {

            switch (requestCode) {
                case VIDEO_CAPTURE:
                        if (resultCode == RESULT_OK) {
                            showVideoImage(data.getData());
// Here I want to know what is the size of my Video File
                        } 
                    break;
                case REQUEST_TAKE_GALLERY_VIDEO:
                    if (resultCode == RESULT_OK) {
                        showVideoGallery(data);
// Here I want to know what is the size of my Video File
                    } 
                    break;
          }

【问题讨论】:

    标签: android file video uri


    【解决方案1】:
    1. 检查AssetFileDescriptor.length
    2. 如果未找到,则检查 ParcelFileDescriptor.getStatSize 隐含在 AssetFileDescriptor.length
    3. 如果没有找到,检查MediaStore/ContentResolver,如果URI有content://方案

    应该适用于file://content:// 方案。如果找不到则返回-1L

    fun Uri.length(contentResolver: ContentResolver)
            : Long {
    
        val assetFileDescriptor = try {
            contentResolver.openAssetFileDescriptor(this, "r")
        } catch (e: FileNotFoundException) {
            null
        }
        // uses ParcelFileDescriptor#getStatSize underneath if failed
        val length = assetFileDescriptor?.use { it.length } ?: -1L
        if (length != -1L) {
            return length
        }
    
        // if "content://" uri scheme, try contentResolver table
        if (scheme.equals(ContentResolver.SCHEME_CONTENT)) {
            return contentResolver.query(this, arrayOf(OpenableColumns.SIZE), null, null, null)
                    ?.use { cursor ->
                        // maybe shouldn't trust ContentResolver for size: https://stackoverflow.com/questions/48302972/content-resolver-returns-wrong-size
                        val sizeIndex = cursor.getColumnIndex(OpenableColumns.SIZE)
                        if (sizeIndex == -1) {
                            return@use -1L
                        }
                        cursor.moveToFirst()
                        return try {
                            cursor.getLong(sizeIndex)
                        } catch (_: Throwable) {
                            -1L
                        }
                    } ?: -1L
        } else {
            return -1L
        }
    }
    

    【讨论】:

      【解决方案2】:
      AssetFileDescriptor fileDescriptor = getApplicationContext().getContentResolver().openAssetFileDescriptor(uri , "r");
      long fileSize = fileDescriptor.getLength();
      

      【讨论】:

      • 我认为它从为 uri 注册的 ContentProvider 获取流并询问流它的长度。
      【解决方案3】:
      java.net.URI juri = new java.net.URI(uri.toString());
      File mediaFile = new File(juri.getPath());
      

      Uri 不是 File

      showVideoImage(data.getData());
      

      ACTION_VIDEO_CAPTURE does not return a Uri.

      此外,您已经知道文件在哪里。您在takeVideoFromCamera() 中创建一个File 对象并将其用于EXTRA_OUTPUT。按住 File 对象(并将其保存为已保存的实例状态 Bundle),然后使用它来找出生成的视频的大小。

      【讨论】:

      • 感谢您的回答和很好的解释。您能否在我上面的代码示例中给我一个代码 sn-p。这对我真的很有帮助。
      • @CommonWare 基本上我想知道两种情况下生成的视频大小,例如 takeVideoFromCamera() 和 takeVideoFromGallery()。谢谢
      • @UKhan: This sample app 演示了使用ACTION_VIDEO_CAPTUREFileProvider。我将展示如何在字段中保留FileUri。就我而言,我碰巧在onActivityResult() 中使用了Uri,而您将使用File
      【解决方案4】:
      private long getFileSize(Uri fileUri) {
          Cursor returnCursor = getContentResolver().
                  query(fileUri, null, null, null, null);
          int sizeIndex = returnCursor.getColumnIndex(OpenableColumns.SIZE);
          returnCursor.moveToFirst();
          
          return returnCursor.getLong(sizeIndex);
      }
      

      查看here了解更多详情

      【讨论】:

      • 你应该关闭光标释放资源。
      【解决方案5】:

      这对我有用:

              Uri path = data.getData();
              Cursor returnCursor = getContentResolver().
                      query(path, null, null, null, null);
              int sizeIndex = returnCursor.getColumnIndex(OpenableColumns.SIZE);
              returnCursor.moveToFirst();
      
              int size = returnCursor.getInt(sizeIndex) / 1000;
      
              tv_description.setText("size: " + size);
      

      您可以使用 getInt、getLong 等...

      【讨论】:

        【解决方案6】:

        试试这个

        文件文件 = 新文件(URI);

            if (file.exists()){
                long size = file.length();
            }
        

        当值=0时

        文件存在但包含零字节。 该文件不存在,或 该文件是一些特定于操作系统的特殊文件。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-09
          • 2011-10-31
          • 1970-01-01
          • 1970-01-01
          • 2015-10-15
          • 1970-01-01
          相关资源
          最近更新 更多