如何使用PRDownloader库下载文件及配置dirPath参数
Hey there! Let's break down your PRDownloader questions and fix up your code to get that download working properly.
First, let's address a couple of issues in your current code, then walk through the proper workflow:
- Don't initialize PRDownloader twice: Your code calls
PRDownloader.initialize(this)and then immediately calls it again with a config. You only need one initialization, and it's best to do this once (like in yourApplicationclass) instead of in an Activity. If you're doing it in an Activity, use the config version directly. - Don't pause/cancel immediately after starting: Right now you start the download and then instantly pause and cancel it—this will prevent the download from ever running. Instead, trigger these actions from user interactions (like button clicks).
Here's the proper step-by-step workflow:
- Initialize PRDownloader with your desired config (once at app startup).
- Build your download request with the URL, directory path, and filename.
- Attach listeners to track progress, completion, errors, and state changes.
- Start the download when needed (e.g., when a user taps a button).
- Pause/cancel the download in response to user actions or app lifecycle events.
dirPath Parameter The dirPath defines where the downloaded file will be stored on the device. You have a few options depending on your needs:
Option 1: Private Internal Storage (No Permissions Needed)
This storage is only accessible by your app, and files are deleted when your app is uninstalled. Use this for files that don't need to be visible to other apps:
String dirPath = getFilesDir().getPath();
Or organize into a subfolder (make sure to create it first):
File downloadDir = new File(getFilesDir(), "MyAppDownloads"); downloadDir.mkdirs(); String dirPath = downloadDir.getPath();
Option 2: Private External Storage (No Permissions Needed for Android 10+)
This is external storage but still private to your app. Files are deleted when your app is uninstalled:
String dirPath = getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).getPath();
Option 3: Public External Storage (Requires Permissions)
This makes files visible to other apps and the user's file manager. For Android 6.0+, you need to request the WRITE_EXTERNAL_STORAGE permission (skip for Android 13+ if targeting media files):
// First check if permission is granted if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { String dirPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath(); }
Let's adjust your MainActivity to include button triggers for download, pause, and cancel, and fix the initialization issues:
public class MainActivity extends AppCompatActivity { private int downloadId = -1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Initialize PRDownloader ONCE with config PRDownloaderConfig config = PRDownloaderConfig.newBuilder() .setDatabaseEnabled(true) .build(); PRDownloader.initialize(getApplicationContext(), config); // Assume you have these buttons in your layout Button btnStart = findViewById(R.id.btn_start_download); Button btnPause = findViewById(R.id.btn_pause_download); Button btnCancel = findViewById(R.id.btn_cancel_download); String url = "https://firebasestorage.googleapis.com/v0/b/mohammed-1f35b.appspot.com/o/fear-storynory-jana.mp3?alt=media&token=4d0fc7a3-2b95-4ddd-8ecc-c792a09ab539"; String fileName = "fear-storynory-jana.mp3"; // Use matching file extension // Use private external storage for this example File downloadDir = getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS); assert downloadDir != null; downloadDir.mkdirs(); String dirPath = downloadDir.getPath(); btnStart.setOnClickListener(v -> { if (downloadId == -1) { // Start a new download downloadId = PRDownloader.download(url, dirPath, fileName) .build() .setOnStartOrResumeListener(() -> { btnStart.setEnabled(false); btnPause.setEnabled(true); }) .setOnPauseListener(() -> { btnPause.setEnabled(false); btnStart.setEnabled(true); }) .setOnCancelListener(() -> { downloadId = -1; btnStart.setEnabled(true); btnPause.setEnabled(false); }) .setOnProgressListener(progress -> { // Update progress (e.g., progress bar) long percent = (progress.currentBytes * 100) / progress.totalBytes; Log.d("Download", "Progress: " + percent + "%"); }) .start(new OnDownloadListener() { @Override public void onDownloadComplete() { Toast.makeText(MainActivity.this, "Download done!", Toast.LENGTH_SHORT).show(); downloadId = -1; btnStart.setEnabled(true); btnPause.setEnabled(false); } @Override public void onError(Error error) { Toast.makeText(MainActivity.this, "Download failed: " + error.getMessage(), Toast.LENGTH_SHORT).show(); downloadId = -1; btnStart.setEnabled(true); btnPause.setEnabled(false); } }); } else { // Resume paused download PRDownloader.resume(downloadId); } }); btnPause.setOnClickListener(v -> { if (downloadId != -1) { PRDownloader.pause(downloadId); } }); btnCancel.setOnClickListener(v -> { if (downloadId != -1) { PRDownloader.cancel(downloadId); } }); } }
内容的提问来源于stack exchange,提问作者Abdullah Khudher

