Android中使用AsyncTask上传视频至服务器的问题解决及脚本编写
Hey there, let's work through this video upload issue together! The problem you're facing with Multipart entity.addPart() is almost certainly due to using deprecated Apache HttpClient libraries (which Android dropped support for in API 23+). Let's replace that with a modern, reliable approach using OkHttp, and fix both the Android and PHP code.
1. Fix Android Dependencies
First, update your module-level build.gradle to use OkHttp—the current standard for HTTP requests in Android:
dependencies { // Remove any old Apache HttpClient dependencies if present implementation 'com.squareup.okhttp3:okhttp:4.12.0' }
Sync your project after adding this dependency.
2. Rewrite Android Upload Code (Using OkHttp with ArrayList)
Replace your existing upload logic with this code, which handles an ArrayList of video files properly:
import android.os.Bundle; import android.widget.Toast; import androidx.appcompat.app.AppCompatActivity; import java.io.File; import java.io.IOException; import java.util.List; import okhttp3.Call; import okhttp3.Callback; import okhttp3.MediaType; import okhttp3.MultipartBody; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Example: Populate your ArrayList of video files here // List<File> videoFiles = getSelectedVideoFiles(); // uploadVideos(videoFiles); } private void uploadVideos(List<File> videoFiles) { if (videoFiles == null || videoFiles.isEmpty()) { Toast.makeText(this, "No video files to upload", Toast.LENGTH_SHORT).show(); return; } OkHttpClient client = new OkHttpClient(); MultipartBody.Builder requestBodyBuilder = new MultipartBody.Builder() .setType(MultipartBody.FORM); // Add every video from your ArrayList to the multipart request for (int i = 0; i < videoFiles.size(); i++) { File video = videoFiles.get(i); if (!video.exists() || !video.isFile()) { Toast.makeText(this, "Skipping invalid file: " + video.getName(), Toast.LENGTH_SHORT).show(); continue; } RequestBody videoBody = RequestBody.create(video, MediaType.parse("video/*")); // Use "videos[]" so PHP can recognize multiple files requestBodyBuilder.addFormDataPart("videos[]", video.getName(), videoBody); } // Optional: Add extra form fields (like user ID, upload metadata) requestBodyBuilder.addFormDataPart("upload_source", "android_app"); Request request = new Request.Builder() .url("http://your-server-ip/videoUp.php") // Replace with your actual server URL .post(requestBodyBuilder.build()) .build(); // Execute request asynchronously (avoids freezing the UI) client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { runOnUiThread(() -> { Toast.makeText(MainActivity.this, "Upload failed: " + e.getMessage(), Toast.LENGTH_LONG).show(); }); } @Override public void onResponse(Call call, Response response) throws IOException { runOnUiThread(() -> { if (response.isSuccessful()) { try { String responseData = response.body().string(); Toast.makeText(MainActivity.this, "Upload success! Response: " + responseData, Toast.LENGTH_LONG).show(); } catch (IOException e) { e.printStackTrace(); } } else { Toast.makeText(MainActivity.this, "Upload failed. Server code: " + response.code(), Toast.LENGTH_SHORT).show(); } }); } }); } }
Key Notes:
- We use OkHttp's
MultipartBodywhich is fully supported on all modern Android versions. - The loop adds each video from your ArrayList to the request without compatibility issues.
- The request runs asynchronously to keep your app responsive.
3. Fix the PHP Server Script (videoUp.php)
Update your PHP script to handle multiple video files, validate uploads, and return clear JSON responses:
<?php // Define directory to store uploaded videos $uploadDirectory = 'uploads/'; // Create directory if it doesn't exist if (!file_exists($uploadDirectory)) { mkdir($uploadDirectory, 0777, true); } $uploadResults = []; // Check if multiple videos were uploaded if (isset($_FILES['videos'])) { $videos = $_FILES['videos']; // Loop through each uploaded video for ($i = 0; $i < count($videos['name']); $i++) { $fileName = $videos['name'][$i]; $tempFilePath = $videos['tmp_name'][$i]; $fileSize = $videos['size'][$i]; $uploadError = $videos['error'][$i]; $fileType = $videos['type'][$i]; // Allow only common video formats $allowedVideoTypes = ['video/mp4', 'video/mov', 'video/avi', 'video/webm', 'video/3gp']; if (!in_array($fileType, $allowedVideoTypes)) { $uploadResults[] = [ 'status' => 'error', 'file_name' => $fileName, 'message' => 'Invalid video format. Allowed types: MP4, MOV, AVI, WEBM, 3GP' ]; continue; } if ($uploadError !== UPLOAD_ERR_OK) { $uploadResults[] = [ 'status' => 'error', 'file_name' => $fileName, 'message' => 'Upload error code: ' . $uploadError ]; continue; } // Generate unique filename to avoid overwriting $uniqueFileName = uniqid('video_', true) . '_' . $fileName; $finalFilePath = $uploadDirectory . $uniqueFileName; if (move_uploaded_file($tempFilePath, $finalFilePath)) { $uploadResults[] = [ 'status' => 'success', 'file_name' => $uniqueFileName, 'original_name' => $fileName, 'message' => 'Video uploaded successfully' ]; } else { $uploadResults[] = [ 'status' => 'error', 'file_name' => $fileName, 'message' => 'Failed to save video to server' ]; } } } else { $uploadResults[] = [ 'status' => 'error', 'message' => 'No video files were received' ]; } // Return JSON response to Android app header('Content-Type: application/json'); echo json_encode($uploadResults); ?>
PHP Script Checks:
- Automatically creates an
uploadsdirectory if missing. - Validates video file types to block malicious uploads.
- Generates unique filenames to prevent overwriting existing videos.
- Returns a detailed status for each uploaded video.
4. Critical Permissions (AndroidManifest.xml)
Add these permissions to your manifest to access videos and the internet:
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" /> <!-- For Android 13+ --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <!-- For Android <13 -->
For Android 10+, use scoped storage or request MANAGE_EXTERNAL_STORAGE if accessing non-media files.
5. Test the Setup
- Ensure your server's
uploadsdirectory has write permissions (usechmod 777 uploads/or adjust for your server config). - Replace
http://your-server-ip/videoUp.phpin the Android code with your actual server URL. - Populate your
ArrayList<File>with valid videos (use a file picker to let users select files). - Run the app and test the upload—you'll get toast messages with the upload status.
内容的提问来源于stack exchange,提问作者Balwant Chandel

