当前位置:首页 > 行业动态 > 正文

安卓上传图片到php服务器

安卓用MultipartEntity上传图片,PHP服务器端通过$_FILES接收,move_uploaded_file保存至指定目录,需配置服务器写入权限并校验文件

安卓端实现图片上传

权限配置

AndroidManifest.xml 中添加存储和网络权限:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>

选择图片

通过 Intent 调用系统相册或相机:

Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, REQUEST_CODE_SELECT_IMAGE);

处理选中的图片

onActivityResult 中获取图片路径并转换为 File

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REQUEST_CODE_SELECT_IMAGE && resultCode == RESULT_OK) {
        Uri imageUri = data.getData();
        File file = new File(getPathFromUri(imageUri)); // 需实现 getPathFromUri 方法
        uploadImage(file);
    }
}

上传图片到服务器

使用 RetrofitOkHttp 发送 Multipart 请求:

// 示例:使用 Retrofit 上传
public interface ApiService {
    @Multipart
    @POST("upload.php")
    Call<ResponseBody> uploadImage(@Part MultipartBody.Part image);
}
private void uploadImage(File file) {
    Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("http://yourserver.com/") // 替换为你的服务器地址
        .build();
    ApiService apiService = retrofit.create(ApiService.class);
    MultipartBody.Part imagePart = MultipartBody.Part.createFormData("image", file.getName(), RequestBody.create(file, MediaType.parse("image/")));
    apiService.uploadImage(imagePart).enqueue(new Callback<ResponseBody>() {
        @Override
        public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
            if (response.isSuccessful()) {
                // 上传成功
            } else {
                // 处理错误(如服务器返回错误码)
            }
        }
        @Override
        public void onFailure(Call<ResponseBody> call, Throwable t) {
            // 网络错误处理
        }
    });
}

PHP服务器端接收图片

创建上传脚本 upload.php

<?php
$targetDir = "uploads/"; // 保存目录
$targetFile = $targetDir . basename($_FILES["image"]["name"]);
$imageFileType = strtolower(pathinfo($targetFile, PATHINFO_EXTENSION));
// 检查文件类型是否合法
$allowedTypes = array("jpg", "jpeg", "png", "gif");
if (!in_array($imageFileType, $allowedTypes)) {
    echo json_encode(["status" => "error", "message" => "Invalid file type"]);
    exit;
}
// 检查文件大小(例如限制为 5MB)
if ($_FILES["image"]["size"] > 5  1024  1024) {
    echo json_encode(["status" => "error", "message" => "File too large"]);
    exit;
}
// 移动文件到目标目录
if (!move_uploaded_file($_FILES["image"]["tmp_name"], $targetFile)) {
    echo json_encode(["status" => "error", "message" => "Upload failed"]);
    exit;
}
echo json_encode(["status" => "success", "url" => $targetFile]);
?>

关键步骤与代码对照表

步骤 安卓端实现 PHP服务器端实现
选择图片 使用 Intent.ACTION_PICK 调用系统相册 无需处理
权限配置 AndroidManifest.xml 中声明 READ_EXTERNAL_STORAGEINTERNET 无需配置(PHP默认有文件读写权限)
图片转换为文件 通过 Uri 获取文件路径并创建 File 对象 无需处理
发送网络请求 使用 RetrofitOkHttp 发送 Multipart 请求 通过 $_FILES 接收文件
服务器端保存文件 无需处理 使用 move_uploaded_file 将临时文件移动到目标目录
错误处理 检查响应码、捕获异常 检查文件类型、大小,返回 JSON 格式的错误信息

常见问题与解决方法

问题 解决方法
安卓端崩溃:未获取存储权限 在运行时动态申请权限(Android 6.0+):
ActivityCompat.requestPermissions
服务器端无法保存文件 检查 uploads/ 目录是否存在且有写入权限
上传大文件失败 修改 PHP 配置文件 php.ini 中的 upload_max_filesizepost_max_size
图片显示为空白 确保服务器返回的路径正确,且图片 URL 可访问(如使用绝对路径)

相关问题与解答

问题1:如何实现多张图片批量上传?

解答
在安卓端,可以通过循环遍历选中的图片列表,逐个添加到 MultipartBody 中。

List<File> files = ...; // 获取多张图片的File对象
for (File file : files) {
    MultipartBody.Part part = MultipartBody.Part.createFormData("images[]", file.getName(), RequestBody.create(file, MediaType.parse("image/")));
    parts.add(part); // 将每个文件添加到请求体中
}

服务器端需修改 upload.php,通过 $_FILES["images"][name] 循环处理多个文件。


问题2:如何限制上传图片的分辨率?

解答
在安卓端上传前,可以使用 Bitmap 压缩图片:

Bitmap bitmap = BitmapFactory.decodeFile(filePath);
Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, 800, 800, true); // 限制最大宽高为800px
File scaledFile = saveBitmapToFile(scaledBitmap); // 自定义方法,将Bitmap保存为File

或在服务器端使用 PHP 的 imagecopyresampled 函数调整图片

0