You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin+Volley相机拍照上传Web服务器失败问题求助

问题解决:Android拍照上传服务器失败+相册不立即显示照片

问题分析

  1. 相册无法立即显示照片:拍摄的照片保存后,未通知系统媒体扫描器更新媒体库,导致相册无法实时识别新文件。
  2. 上传服务器失败:
    • PHP代码接收参数时,$_POST[namaFile]与Android端传递的namafile(小写f)大小写不匹配,导致无法获取文件名。
    • MainActivity中请求URL存在空格:"http:// 192.168.45.240/htdocs/upload.php",会直接导致请求失败。
    • MediaHelper类的getBitmapToString方法存在无效代码,第二个return ""永远不会执行。
    • 旧版Uri.fromFile在Android 7.0+会触发FileUriExposedException,当前用StrictMode禁用不是最佳方案。

解决方案及代码修改

1. 修复相册不立即显示问题

在拍照完成后发送广播,通知媒体扫描器扫描新文件,修改MainActivity的onActivityResult方法:

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    if (resultCode == Activity.RESULT_OK && requestCode == mediaHelper.getRcCamera()) {
        imstr = mediaHelper.getBitmapToString(imv)
        namafile = mediaHelper.getMyFileName()
        
        // 通知媒体扫描器更新相册
        val mediaScanIntent = Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE)
        mediaScanIntent.data = mediaHelper.fileUri
        sendBroadcast(mediaScanIntent)
    }
}

2. 修复上传参数匹配与URL错误

修正Android端请求URL

// 去掉URL中的空格
val url = "http://192.168.45.240/htdocs/upload.php"

修正PHP参数名匹配

<?php
    $imstr = $_POST['imstr'];
    // 改为与Android端一致的小写namafile
    $namaFile = $_POST['namafile'];
    $path = "images/";
    
    // 确保images目录存在,避免写入失败
    if (!is_dir($path)) {
        mkdir($path, 0777, true);
    }
    
    $respon = array();
    $respon['kode'] = '000';
    if(file_put_contents($path.$namaFile, base64_decode($imstr)) == false){
        $respon['kode'] = '111';
        echo json_encode($respon);
    }else{
        echo json_encode($respon);
    }   
?>

3. 清理MediaHelper无效代码

移除getBitmapToString方法中永远不会执行的return语句:

fun getBitmapToString(imV: ImageView):String{
    var bmp:Bitmap = Bitmap.createBitmap(100,100,Bitmap.Config.ARGB_8888)
    bmp = BitmapFactory.decodeFile(this.fileUri.path)
    val dim = 720
    if (bmp.height>bmp.width){
        bmp = Bitmap.createScaledBitmap(bmp,(bmp.width*dim).div(bmp.height),dim, true)
    }else{
        bmp  = Bitmap.createScaledBitmap(bmp, dim, (bmp.height*dim).div(bmp.width), true)
    }
    imV.setImageBitmap(bmp)
    return bitmapToString(bmp)
    // 移除无效的return语句
    // return ""
}

4. 适配Android 7.0+的FileProvider(推荐)

步骤1:在AndroidManifest.xml添加FileProvider配置

<application ...>
    <provider
        android:name="androidx.core.content.FileProvider"
        android:authorities="${applicationId}.fileprovider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths" />
    </provider>
</application>

步骤2:创建res/xml/file_paths.xml文件

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-files-path
        name="my_images"
        path="DCIM/upload8/" />
</paths>

步骤3:修改MediaHelper的Uri生成方法

fun getOutputMediaFileUri(context: Context): Uri{
    val timeStamp = SimpleDateFormat("yyyyMMddHHmmss", Locale.getDefault()).format(Date())
    this.namaFile = "DC_${timeStamp}.jpg"
    val mediaFile = getOutputMediaFile()
    // 使用FileProvider生成安全Uri
    return FileProvider.getUriForFile(
        context,
        "${context.packageName}.fileprovider",
        mediaFile!!
    )
}

步骤4:修改MainActivity中相机启动代码

fun requestPermissions() = runWithPermissions(Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.CAMERA){
    fileUri = mediaHelper.getOutputMediaFileUri(this)
    val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
    // 授予临时写入权限
    intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
    intent.putExtra(MediaStore.EXTRA_OUTPUT,fileUri)
    startActivityForResult(intent,mediaHelper.getRcCamera())
}

额外注意事项

  • 确保服务器端images目录存在且具备写入权限,否则file_put_contents会执行失败。
  • Android 10及以上版本,建议改用MediaStoreAPI保存照片,规避存储权限限制。

内容的提问来源于stack exchange,提问作者Kretos Kim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 01:03:26