Android环境下HTTP上传手机Download目录文件至服务器指定目录问题求助
Hey there! No worries about your English at all—we’re all here to help you work through this file upload issue. Let’s break this down step by step.
1. First, sort out permissions for the Download directory
Accessing the Download folder varies a bit depending on your Android version, thanks to scoped storage introduced in Android 10 (API 29):
- For API ≤28: Add the
READ_EXTERNAL_STORAGEpermission to yourAndroidManifest.xml, and remember to request it dynamically at runtime (users have to grant it). - For API ≥29: Scoped storage limits direct file access, so you can either use the
MediaStoreAPI to query files in Downloads, or request theMANAGE_EXTERNAL_STORAGEpermission (but this is a sensitive permission that requires users to enable it manually in settings, so only use it if absolutely necessary).
Here’s a quick snippet for dynamic permission request (for API ≤28):
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 1001); }
2. Locate and read your target file in Downloads
Once permissions are sorted, you can get the Download directory path and find your file. For older Android versions, you can directly access the directory:
// Get the Download directory File downloadDir = Environment.getExternalPublicDirectory(Environment.DIRECTORY_DOWNLOADS); // Replace "your_file_name.ext" with the actual file you need to upload File targetFile = new File(downloadDir, "your_file_name.ext"); // Check if the file exists and is readable if (targetFile.exists() && targetFile.canRead()) { // Ready to upload! } else { Log.e("UploadIssue", "File not found or cannot be read"); }
For Android 10+, using MediaStore is the more compliant way to get the file:
// Query for the target file in Downloads String[] projection = { MediaStore.Files.FileColumns._ID, MediaStore.Files.FileColumns.DISPLAY_NAME }; String selection = MediaStore.Files.FileColumns.DISPLAY_NAME + " = ?"; String[] selectionArgs = new String[]{"your_file_name.ext"}; Cursor cursor = getContentResolver().query( MediaStore.Downloads.EXTERNAL_CONTENT_URI, projection, selection, selectionArgs, null ); if (cursor != null && cursor.moveToFirst()) { Uri fileUri = ContentUris.withAppendedId( MediaStore.Downloads.EXTERNAL_CONTENT_URI, cursor.getLong(cursor.getColumnIndex(MediaStore.Files.FileColumns._ID)) ); // Open an input stream to read the file content InputStream inputStream = getContentResolver().openInputStream(fileUri); // Use this stream for upload later cursor.close(); }
3. Implement HTTP file upload to your server
We’ll use OkHttp (a popular, easy-to-use HTTP library) for this. First, add the dependency to your module-level build.gradle file:
implementation 'com.squareup.okhttp3:okhttp:4.11.0'
Then write the upload code—important: network operations can’t run on the main thread, so we’ll use OkHttp’s async callback:
private void uploadFile(File file) { OkHttpClient client = new OkHttpClient(); // Build the multipart request body (most servers expect this for file uploads) RequestBody requestBody = new MultipartBody.Builder() .setType(MultipartBody.FORM) // Add the file itself .addFormDataPart("file", file.getName(), RequestBody.create(MediaType.parse("application/octet-stream"), file)) // If your server needs to know the target directory, add it as a parameter .addFormDataPart("target_directory", "/your/server/target/path") .build(); Request request = new Request.Builder() .url("http://your-server-ip-or-domain.com/upload-endpoint") // Replace with your server's upload URL .post(requestBody) .build(); // Execute the request asynchronously client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { e.printStackTrace(); // Update UI back on the main thread runOnUiThread(() -> { TextView resultView = findViewById(R.id.your_result_text_view); resultView.setText("Upload failed: " + e.getMessage()); }); } @Override public void onResponse(Call call, Response response) throws IOException { if (response.isSuccessful()) { String serverResponse = response.body().string(); runOnUiThread(() -> { TextView resultView = findViewById(R.id.your_result_text_view); resultView.setText("Upload successful! Server said: " + serverResponse); }); } else { runOnUiThread(() -> { TextView resultView = findViewById(R.id.your_result_text_view); resultView.setText("Upload failed: Server returned error code " + response.code()); }); } } }); }
Quick reminders:
- Don’t forget to add the
INTERNETpermission to yourAndroidManifest.xml:<uses-permission android:name="android.permission.INTERNET" /> - If you’re using the
MediaStoreinput stream approach, you can adapt the upload code to use the stream instead of aFileobject (OkHttp supports uploading from input streams too).
内容的提问来源于stack exchange,提问作者Matteo Cicchinelli

