尝试使用getExternalStorageDir()方法将PDF文件存储在用户的Android设备上

3

所以我正在尝试创建一个文件夹并将PDF文件存储在用户的安卓设备上。我使用了getExternalStorageDir()函数,但这个函数在API29及以上版本已经被弃用。问题是,安卓指南中说要退出作用域存储,我必须将此放入Manifest文件中。

<manifest xmlns:android="http://schemas.android.com/apk/res/android
....
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />  
<application  
    android:requestLegacyExternalStorage="true"
....
</application>

这个已经不起作用了。我可以在安卓 M 的设备上下载,但是在最近的 9/10 设备上却无法下载。

public class FinalActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks {

    private static final int WRITE_REQUEST_CODE = 300;
    private static final String TAG = MainActivity.class.getSimpleName();
    private String url;
    SessionManagement sessionManagement;
    String userID;

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

        sessionManagement = new SessionManagement(this);
        HashMap<String, String> user = sessionManagement.getUserDetail();
        userID = user.get(sessionManagement.ID);

        TextView submit = findViewById(R.id.download);

        submit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (EasyPermissions.hasPermissions(FinalActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                    //Get the URL entered
                    url = F.url1 + userID + "/FPO.pdf";
                    new DownloadFile().execute(url.replaceAll(" ", "%20"));

                } else {
                    //If permission is not present request for the same.
                    EasyPermissions.requestPermissions(FinalActivity.this, "This app needs access to your file storage so that it can write files.", WRITE_REQUEST_CODE, Manifest.permission.READ_EXTERNAL_STORAGE);
                }
            }
        });
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, FinalActivity.this);
    }

    @Override
    public void onPermissionsGranted(int requestCode, List<String> perms) {
        //Download the file once permission is granted
        url = F.url1 + userID + "/FPO.pdf";
        new DownloadFile().execute(url.replaceAll(" ", "%20"));
    }

    @Override
    public void onPermissionsDenied(int requestCode, List<String> perms) {
        Log.d(TAG, "Permission has been denied");
    }

    private class DownloadFile extends AsyncTask<String, String, String> {
        private ProgressDialog progressDialog;
        private String fileName;
        private String folder;
        private boolean isDownloaded;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            this.progressDialog = new ProgressDialog(FinalActivity.this);
            this.progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
            this.progressDialog.setCancelable(false);
            this.progressDialog.show();
        }

        @Override
        protected String doInBackground(String... f_url) {
            int count;
            try {
                URL url = new URL(f_url[0]);
                URLConnection connection = url.openConnection();
                connection.connect();
                // getting file length
                int lengthOfFile = connection.getContentLength();


                // input stream to read file - with 8k buffer
                InputStream input = new BufferedInputStream(url.openStream(), 8192);

                String timestamp = new SimpleDateFormat("yyyy.MM.dd.HH.mm.ss").format(new Date());

                //Extract file name from URL
                fileName = f_url[0].substring(f_url[0].lastIndexOf('/') + 1, f_url[0].length());

                //External directory path to save fileb n
                folder = Environment.getExternalStorageDirectory() + File.separator + "FPO/";

                //Create LSK folder if it does not exist
                File directory = new File(folder);

                if (!directory.exists()) {
                    directory.mkdirs();
                }

                // Output stream to write file
                OutputStream output = new FileOutputStream(folder + fileName.replaceAll("%20", " "));

                byte data[] = new byte[1024];

                long total = 0;

                while ((count = input.read(data)) != -1) {
                    total += count;
                    // publishing the progress....
                    // After this onProgressUpdate will be called
                    publishProgress("" + (int) ((total * 100) / lengthOfFile));
                    Log.d(TAG, "Progress: " + (int) ((total * 100) / lengthOfFile));

                    // writing data to file
                    output.write(data, 0, count);
                }

                // flushing output
                output.flush();

                // closing streams
                output.close();
                input.close();
                return "Downloaded at: " + folder + fileName.replaceAll("%20", " ");

            } catch (Exception e) {
                Log.e("Error: ", e.getMessage());
                Log.i("error123", e.getMessage());
                return e.getMessage();

            }
            
            //           return "Something went wrong";
        }

        protected void onProgressUpdate(String... progress) {
            // setting progress percentage
            progressDialog.setProgress(Integer.parseInt(progress[0]));
        }

        @Override
        protected void onPostExecute(String message) {
            // dismiss the dialog after the file was downloaded
            this.progressDialog.dismiss();
            Intent intent = new Intent(FinalActivity.this, Welcome_screen1.class);
            startActivity(intent);
            // Display File path after downloading
            Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show();
        }
    }
}
2个回答

0

我尝试使用getExternalFilesDir()方法,但文件存储在应用程序的内部文件夹中。我希望文件可以下载到用户设备的“下载”文件夹中,或者不管文件位置如何,都可以在文件下载后立即打开文档。 - Neel Patel
你试过这个吗?Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); - Recep_dagli
不要忘记在AndroidManifest.xml中添加此内容; <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> - Recep_dagli
请查看这个链接:https://stackoverflow.com/a/61560931/5924743 - Recep_dagli
无法工作。我在清单文件和Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)中都有用户权限,但问题是Android立即给我一个拒绝访问的权限,即使用户已经授予了权限。 - Neel Patel

0
在进行一些分析后,这是我的建议。
        //External directory path to save fileb n
        folder = Environment.getExternalStoragePublicDirectory("FPO")+File.separator;// Deprecated I know but it works 


        //Create LSK folder if it does not exist
        File file = new File(folder + fileName.replaceAll("%20"," "));// create file in particular path with name and extension

        if (!file.exists()) {
            file.createNewFile(); //creates file for writing
        }



        // Output stream to write file
        OutputStream output = new FileOutputStream(file);

在使用OutputStream开始写入之前,首先创建一个文件。不要只创建目录。

希望有所帮助!


由于getExternalStoragePublicDirectory已被弃用,所以无法工作。 - Neel Patel
@NeelPatel 你真的尝试过了吗?它会出现任何错误吗?我正在使用这种方法将视频下载到 Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)+"/"+videoName+".mp4" 中,它在 Samsung M21(API 29) 中运行良好。顺便问一下,你指定文件类型了吗? - Udhaya
是的,我能够在运行Andriod M的设备上下载文件,但在运行android Q和P的设备上会出现EONOET或EACCESS(权限被拒绝或文件夹不存在)的错误。 - Neel Patel
@NeelPatel,因为它说文件不存在,所以我再次引用一下:在创建带有路径+文件名+文件扩展名的文件对象时,您是否使用了file.createNewFile() - Udhaya
尝试了您编辑后的答案。响应是“E/Error:: 没有这样的文件或目录”。 - Neel Patel
@NeelPatel 嘿,伙计抱歉!我在编辑后的答案中两次使用了 folder,如 new File(folder + folder + fileName.replaceAll("%20"," "));。在执行之前你有更改过吗?如果没有,请现在检查一下,我已经调试过了。请再次尝试使用正确的目录,同时记录 folder + fileName.replaceAll("%20"," ") 并在评论中发布。 - Udhaya

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接