从库中复制文件时显示 ProgressDialog

Posted

技术标签:

【中文标题】从库中复制文件时显示 ProgressDialog【英文标题】:Show ProgressDialog when copying a file from gallery 【发布时间】:2017-12-20 23:43:08 【问题描述】:

目前

我用Intent 打开图库,然后用户可以从图库中选择一个视频,然后将文件复制到指定的文件夹。这一切都很好。

我想在用户选择视频(在图库中)后立即显示ProgressBar,然后在文件完成复制后显示progresbar.dismiss

这里有类似的问题,但没有答案(没有任何效果):

How to display a dialog over gallery screen in android? Progress Bar Circle after user selects image from gallery in android?

这就是我对画廊的称呼:

public void selectVideoFromGallery()


    Intent intent;
    if(android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
    
        intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Video.Media.EXTERNAL_CONTENT_URI);
    
    else
    
        intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Video.Media.INTERNAL_CONTENT_URI);
    

    intent.setType("video/*");
    intent.setAction(Intent.ACTION_GET_CONTENT);
    intent.putExtra("return-data", true);
    startActivityForResult(intent,SELECT_VIDEO_REQUEST);

我在这里(上图)尝试过progressbar.show();,但显然它会在选择视频之前开始显示。

这是我的OnActivityResult

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)

    if(requestCode == SELECT_VIDEO_REQUEST && resultCode == RESULT_OK)
    
        if(data.getData()!=null)
        


            //copy file to new folder
            Uri selectedImageUri = data.getData();
            String sourcePath = getRealPathFromURI(selectedImageUri);

            File source = new File(sourcePath);

            String filename = sourcePath.substring(sourcePath.lastIndexOf("/")+1);

            File destination = new File(Environment.getExternalStorageDirectory(), "MyAppFolder/CopiedVids/"+filename);
            try
            
                FileUtils.copyFile(source, destination);
            
            catch (IOException e)
            
                e.printStackTrace();
            


            sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(destination)));


            Toast.makeText(getApplicationContext(),"Stored at:  "+"---"+sourcePath+"----"+"with name:   "+filename, Toast.LENGTH_LONG).show();



        
        else
        
            Toast.makeText(getApplicationContext(), "Failed to select video" , Toast.LENGTH_LONG).show();
        
    

我在此处(上图)尝试过progressbar.show();,但对话框从未显示。

我的猜测是用AsyncTask 来做这件事,然后在哪里打电话给AsyncTask

这是我的 ProgressDialog:

ProgressDialog progress;

 @Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    progress = new ProgressDialog(this);
    progress.setMessage("Copying Video....");
    progress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
    progress.setIndeterminate(true);


我的问题

我需要澄清如何实现这一点,如果没有AsyncTask,我是否能够做到这一点,如果不能,应该从哪里调用AsyncTask

【问题讨论】:

where should AsyncTask be called from? 内部 onActivityResult 方法内部 if (data.getData() != null) @FirozMemon 你能解释一下这将如何工作吗?我能否在画廊意图上显示progressDialog?如何将所选视频Uri 传递给AsyncTask 【参考方案1】:

应该从哪里调用 AsyncTask?

onActivityResult 内部方法if (data.getData() != null) 块内部

if(data.getData()!=null)

    new MyCopyTask().execute(data.getData());

--

 private class MyCopyTask extends AsyncTask<Uri, Integer, File> 
    ProgressDialog progressDialog;
    @Override
    protected String doInBackground(Uri... params) 
        //copy file to new folder
        Uri selectedImageUri = params[0];
        String sourcePath = getRealPathFromURI(selectedImageUri);

        File source = new File(sourcePath);

        String filename = sourcePath.substring(sourcePath.lastIndexOf("/")+1);

        File destination = new File(Environment.getExternalStorageDirectory(), "MyAppFolder/CopiedVids/"+filename);

        // call onProgressUpdate method to update progress on UI
        publishProgress(50);    // update progress to 50%

        try
        
            FileUtils.copyFile(source, destination);
        
        catch (IOException e)
        
            e.printStackTrace();
        
        return destination;
    

    @Override
    protected void onPostExecute(File result) 
        if(result.exists()) 
            sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(result)));

            Toast.makeText(getApplicationContext(),"Stored at:  "+"---"+result.getParent()+"----"+"with name:   "+result.getName(), Toast.LENGTH_LONG).show();

         else 
            Toast.makeText(getApplicationContext(),"File could not be copied", Toast.LENGTH_LONG).show();
        

        // Hide ProgressDialog here
        progressDialog.dismiss();
    

    @Override
    protected void onPreExecute() 
        // Show ProgressDialog here

        progressDialog = new ProgressDialog(YourActivity.this);
        progressDialog.setCancelable(false);
        progressDialog.setIndeterminate(false);
        progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        progressDialog.setMax(100);
        progressDialog.show();
    

    @Override
    protected void onProgressUpdate(Integer... values)
        super.onProgressUpdate(values);
        progressDialog.setProgress(values[0]);
    


希望对你有帮助!

【讨论】:

我知道这不是问题的一部分,但请您更新您的代码并告诉我如何在复制文件时显示进度百分比? 感谢您的回复,但我有 2 个错误,publishProgress(50); - Void cannot be applied to intsuper.onProgressUpdate(values); values - Void cannot be applied to Integers。我也不能在 onProgressUpdate 之前使用@Overright 我在这里问了一个新问题---***.com/questions/45137748/…【参考方案2】:

首先创建这个 asynctask 类:

private class FileCopyProcess extends AsyncTask<Uri, Void, Boolean> 

    @Override
    protected String doInBackground(Uri... params) 
        Uri selectedImageUri = params[0];
        String sourcePath = getRealPathFromURI(selectedImageUri);

        File source = new File(sourcePath);

        String filename = sourcePath.substring(sourcePath.lastIndexOf("/")+1);

        File destination = new File(Environment.getExternalStorageDirectory(), "MyAppFolder/CopiedVids/"+filename);
        try
        
            FileUtils.copyFile(source, destination);
            sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(destination)));
            Toast.makeText(getApplicationContext(),"Stored at:  "+"---"+sourcePath+"----"+"with name:   "+filename, Toast.LENGTH_LONG).show();
            return true;
        
        catch (IOException e)
        
            e.printStackTrace();
            return false;
        

    

    @Override
    protected void onPostExecute(Boolean result) 
        if (result) 
             // PROCESS DONE
        
    

    @Override
    protected void onPreExecute() 

    @Override
    protected void onProgressUpdate(Void... values) 

并像下面这样执行它:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)

if(requestCode == SELECT_VIDEO_REQUEST && resultCode == RESULT_OK)

    if(data.getData()!=null)
    

         // SHOW PROGRESS

         new FileCopyProcess().execute(data.getData());

    
    else
    
        Toast.makeText(getApplicationContext(), "Failed to select video" , Toast.LENGTH_LONG).show();
    


【讨论】:

我尝试复制大文件,然后 UI 冻结,直到文件完成复制,仍然没有显示进度。 正如我所想的那样,UI 会冻结,直到文件被复制然后显示进度,因为您延迟了时间。我希望在用户选择文件时开始显示进度。 @NewUser 然后你需要使用 AsyncTask 我说你的复制过程但没有处理程序 好的,您能否更新您的代码,向我展示如何在 AsyncTask 中获取选定的视频 uri?

以上是关于从库中复制文件时显示 ProgressDialog的主要内容,如果未能解决你的问题,请参考以下文章

打开新的 Fragment 和 AsyncTask 时显示 ProgressDialog

复制文件时显示文件过大,怎么回事?

在将文件从捆绑包复制到文档路径时显示进度条[重复]

如何在 Swift 中使用 URL 从库中获取图像? [复制]

Android 强制关闭 ProgressDialog

Matlab 变量在复制并传递到 mex 文件时显示“类似引用”的行为