上一篇
安卓上传图片 php服务器
- 行业动态
- 2025-04-24
- 4784
安卓通过MultipartEntity构建POST请求上传图片,PHP服务器使用$_FILES接收并调用move_uploaded_file保存至服务器目录,需配置安卓存储权限及服务器文件写入
安卓上传图片至PHP服务器实现方案
客户端(Android)实现
权限配置
在AndroidManifest.xml
中声明存储和网络权限:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.INTERNET"/>
图片选择与处理
使用PhotoPicker选择图片
val intent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI) startActivityForResult(intent, REQUEST_CODE_SELECT_IMAGE)
图片压缩处理(可选)
fun compressImage(filePath: String): File { val options = BitmapFactory.Options().apply { inSampleSize = 4 } val bitmap = BitmapFactory.decodeFile(filePath, options) val outputFile = File(cacheDir, "compressed_${System.currentTimeMillis()}.jpg") bitmap.compress(Bitmap.CompressFormat.JPEG, 80, outputFile.outputStream()) return outputFile }
上传实现方式
方法 | 特点 | 适用场景 |
---|---|---|
Base64编码 | 简单易实现 | 小文件快速传输 |
Multipart | 支持大文件 | 常规图片上传 |
Retrofit+OkHttp | 高效管理 | 复杂网络请求 |
使用OkHttp实现Multipart上传
fun uploadImage(file: File) { val client = OkHttpClient.Builder().build() val requestBody = MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart("image", file.name, file.asRequestBody()) .build() val request = Request.Builder() .url("https://yourserver.com/upload.php") .post(requestBody) .build() client.newCall(request).enqueue(object : Callback { override fun onFailure(call: Call, e: IOException) { // 处理失败 } override fun onResponse(call: Call, response: Response) { // 处理响应 } }) }
服务器端(PHP)实现
接收处理脚本
<?php // upload.php $uploadDir = 'uploads/'; $response = []; if ($_SERVER['REQUEST_METHOD'] === 'POST') { if (isset($_FILES['image'])) { $file = $_FILES['image']; // 安全校验 $allowedTypes = ['image/jpeg', 'image/png', 'image/gif']; if (!in_array($file['type'], $allowedTypes)) { $response['status'] = 'error'; $response['message'] = '不支持的文件类型'; } elseif ($file['size'] > 5 1024 1024) { // 5MB限制 $response['status'] = 'error'; $response['message'] = '文件过大'; } else { // 生成唯一文件名 $newName = uniqid() . '.' . pathinfo($file['name'], PATHINFO_EXTENSION); $destination = $uploadDir . $newName; if (move_uploaded_file($file['tmp_name'], $destination)) { $response['status'] = 'success'; $response['url'] = $uploadDir . $newName; } else { $response['status'] = 'error'; $response['message'] = '上传失败'; } } } else { $response['status'] = 'error'; $response['message'] = '未收到文件'; } } else { $response['status'] = 'error'; $response['message'] = '无效请求方式'; } header('Content-Type: application/json'); echo json_encode($response); ?>
服务器配置要点
配置项 | 说明 | 推荐值 |
---|---|---|
upload_max_filesize | 单文件最大大小 | 10M |
post_max_size | POST数据最大值 | 15M |
max_execution_time | 脚本执行时间 | 300秒 |
file_uploads | 是否启用文件上传 | On |
常见问题解决方案
问题现象 | 解决方案 |
---|---|
安卓7.0+权限崩溃 | 添加动态权限申请java<br>ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, REQUEST_CODE);<br> |
大文件上传失败 | 修改服务器php.ini配置 客户端启用分片上传 |
图片变形问题 | 在PHP处理时保持原始比例php<br>list($width, $height) = getimagesize($file['tmp_name']);<br>imagecopyresampled(...);<br> |
HTTP 500错误 | 检查服务器error_log,常见原因: 文件夹权限不足 php配置错误 |
相关问题解答
Q1:如何实现多图批量上传?
A1:可通过以下两种方式实现:
- 客户端打包多个文件:使用
MultipartBody.Builder
添加多个addFormDataPart
- 服务器端处理数组:修改PHP脚本遍历
$_FILES
数组
Q2:如何优化大文件上传体验?
A2:建议采用分片上传方案:
- 客户端将文件分割为多个小块(如2MB/片)
- 逐片上传并记录已上传片段
- 服务器端合并片段并校验完整性
- 优势:支持断点续传、进度显示、失败重