如何在Android Studio中通过Volley与PHP实现图片及两个TextView数据上传
Android Studio中Volley+PHP上传图片与文本数据实现指南
嘿,我来帮你搞定Android Studio里用Volley搭配PHP上传图片和两个TextView数据的事儿!先看看你提供的PHP代码,再一步步梳理清楚怎么实现~
一、先完善你的PHP后端代码
你写的upload.php有几个小问题需要修正,比如$item = $_POST['item']后面缺了分号,还有random_word函数没定义,另外也没处理数据库插入和图片保存的逻辑。我帮你补全后的代码如下:
include_once "koneksi.php"; class emp{} // 定义生成随机文件名的函数,避免重名 function random_word($length = 20) { $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; $word = ''; for ($i = 0; $i < $length; $i++) { $word .= $chars[rand(0, strlen($chars) - 1)]; } return $word; } $image = $_POST['image']; $name = $_POST['name']; $item = $_POST['item']; // 补上缺失的分号 // 检查两个文本字段是否为空 if (empty($name) || empty($item)) { $response = new emp(); $response->success = 0; $response->message = "请不要留空名称或项目字段。"; die(json_encode($response)); } else { $random = random_word(20); $path = "images/" . $random . ".png"; // 确保images目录存在并拥有写入权限 if (!file_exists('images')) { mkdir('images', 0777, true); } // 解码Base64格式的图片并保存到指定路径 if (file_put_contents($path, base64_decode($image))) { // 这里添加数据库插入逻辑(假设你的表名为uploads,字段为name、item、image_path) // 注意:实际项目中建议用预处理语句防止SQL注入! $sql = "INSERT INTO uploads (name, item, image_path) VALUES ('$name', '$item', '$path')"; // 假设koneksi.php中的数据库连接变量为$conn if (mysqli_query($conn, $sql)) { $response = new emp(); $response->success = 1; $response->message = "上传成功!"; echo json_encode($response); } else { $response = new emp(); $response->success = 0; $response->message = "数据库插入失败:" . mysqli_error($conn); die(json_encode($response)); } } else { $response = new emp(); $response->success = 0; $response->message = "图片保存失败,请检查images目录权限。"; die(json_encode($response)); } }
PHP端注意事项:
- 确保
koneksi.php中的数据库连接配置正确,且连接变量和代码里的$conn一致 - 给
images目录设置777权限(测试环境可用,生产环境建议调整为更安全的权限配置) - 替换接口地址为你电脑/服务器的实际IP,比如本地测试的话,地址可能是
http://192.168.1.105/upload.php
二、Android Studio端Volley上传实现
1. 添加Volley依赖
在app模块的build.gradle文件中添加Volley依赖:
dependencies { implementation 'com.android.volley:volley:1.2.1' }
2. 配置权限
在AndroidManifest.xml中添加必要的权限:
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <!-- Android 10及以上可使用这个权限替代外部存储读写 --> <uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION" />
如果是Android 13及以上版本,还需要动态申请读取媒体文件的权限。
3. 图片转Base64工具类
写一个工具方法把Bitmap转换成Base64字符串,方便上传:
public class ImageUtil { public static String imageToBase64(Bitmap bitmap) { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream); byte[] byteArray = byteArrayOutputStream.toByteArray(); return Base64.encodeToString(byteArray, Base64.DEFAULT); } }
4. 核心上传逻辑
假设你有两个TextView(tvName和tvItem)用于输入文本,还有一个选择图片的按钮,选择图片后调用以下上传方法:
private void uploadData(String name, String item, Bitmap imageBitmap) { // 替换成你的PHP接口实际地址 String uploadUrl = "http://你的服务器IP/upload.php"; StringRequest stringRequest = new StringRequest(Request.Method.POST, uploadUrl, response -> { try { JSONObject jsonObject = new JSONObject(response); int success = jsonObject.getInt("success"); String message = jsonObject.getString("message"); Toast.makeText(MainActivity.this, message, Toast.LENGTH_SHORT).show(); if (success == 1) { // 上传成功后可以清空输入框等操作 tvName.setText(""); tvItem.setText(""); } } catch (JSONException e) { e.printStackTrace(); Toast.makeText(MainActivity.this, "响应解析失败", Toast.LENGTH_SHORT).show(); } }, error -> { Toast.makeText(MainActivity.this, "网络请求失败:" + error.getMessage(), Toast.LENGTH_SHORT).show(); }) { @Override protected Map<String, String> getParams() throws AuthFailureError { Map<String, String> params = new HashMap<>(); params.put("name", name); params.put("item", item); params.put("image", ImageUtil.imageToBase64(imageBitmap)); return params; } }; // 将请求加入Volley请求队列 Volley.newRequestQueue(this).add(stringRequest); }
5. 选择图片的逻辑示例
用系统相册选择图片,然后调用上传方法:
private static final int PICK_IMAGE_REQUEST = 1; // 触发选择图片的方法,比如绑定到按钮点击事件 private void pickImage() { Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(intent, PICK_IMAGE_REQUEST); } @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null) { Uri imageUri = data.getData(); try { Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imageUri); // 获取两个TextView的文本内容 String name = tvName.getText().toString().trim(); String item = tvItem.getText().toString().trim(); // 调用上传方法 uploadData(name, item, bitmap); } catch (IOException e) { e.printStackTrace(); Toast.makeText(this, "获取图片失败", Toast.LENGTH_SHORT).show(); } } }
内容的提问来源于stack exchange,提问作者laura
相关产品推荐
相关产品推荐

