如何使用 asynctask 将图像从 android 上传到 php
Posted
技术标签:
【中文标题】如何使用 asynctask 将图像从 android 上传到 php【英文标题】:How to upload an image from android to php using asynctask 【发布时间】:2017-03-08 16:47:27 【问题描述】:每个人。我被困在我正在从事的这个项目上。我希望能够从 android 库上传图像,将该图像编码为 base64 字符串并作为 get 变量发送到 php Web 服务,然后从另一端解码图像并按照我的意愿进行处理。
到目前为止,我能够从图库中选择图像,甚至可以编码为 base64 字符串并存储在 android 首选项中。
问题是,我认为并非所有字符串都被发送到 PHP 服务(有些被截断)。
我为什么这么认为?我的 Log.d 在转储到不同位置时向我显示了不同的字符串。
获取图像并编码的代码是:-
private void galleryIntent()
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Please select a file"),1);
private String onSelectFromGalleryResult (Intent data)
if (data != null)
try
bitmap = MediaStore.Images.Media.getBitmap(getContext().getContentResolver() , data.getData()) ;
catch (IOException e)
e.printStackTrace();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream() ;
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream) ;
byte[] imageBytes = byteArrayOutputStream.toByteArray() ;
Log.d ("Selected Image Gallery" , Base64.encodeToString(imageBytes, Base64.DEFAULT)) ;
return Base64.encodeToString (imageBytes, Base64.DEFAULT) ;
else
return null ;
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
super.onActivityResult(requestCode, resultCode, data);
SharedPreferences sharedPreferences = getContext().getSharedPreferences("MyOnActivityResultPref" , Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit() ;
if (resultCode == Activity.RESULT_OK)
if (requestCode == 1)
/*Here we handle the image gotten from the gallery*/
String encodedGalleryImage = onSelectFromGalleryResult(data);
editor.putString("userEncodedGalleryImage" , encodedGalleryImage);
else if (requestCode == 0)
/*Here we handle the image that was take using the camera*/
editor.apply();
这里我们称之为 asynctask 类
private void callAsynctask ()
SharedPreferences sp = getContext().getSharedPreferences("MyOnActivityResultPref" , Context.MODE_PRIVATE);
String userQuestionAttachement = sp.getString("userEncodedGalleryImage" , "") ;
Log.d("callingEncodedImage" , userQuestionAttachement) ;
我遇到的问题是来自 Log.d ("Selected Image Gallery" , Base64.encodeToString(imageBytes, Base64.DEFAULT)) 的日志;与 Log.d("callingEncodedImage" , userQuestionAttachement) 不同;
两者的开头相同,但结尾不同。我希望看到相同的字符。
有人可以帮我解决吗?
【问题讨论】:
base64 字符串有时可能太大而无法一次性发送。更好的选择是使用多部分上传图像文件。 你好@VivekMishra 你会怎么做?我想这就是我需要的!... 【参考方案1】:在 Android 中,
new UploadFileAsync().execute("");
private class UploadFileAsync extends AsyncTask<String, Void, String>
@Override
protected String doInBackground(String... params)
try
String sourceFileUri = "/mnt/sdcard/abc.png";
HttpURLConnection conn = null;
DataOutputStream dos = null;
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
int bytesRead, bytesAvailable, bufferSize;
byte[] buffer;
int maxBufferSize = 1 * 1024 * 1024;
File sourceFile = new File(sourceFileUri);
if (sourceFile.isFile())
try
String upLoadServerUri = "http://website.com/abc.php?";
// open a URL connection to the Servlet
FileInputStream fileInputStream = new FileInputStream(
sourceFile);
URL url = new URL(upLoadServerUri);
// Open a HTTP connection to the URL
conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true); // Allow Inputs
conn.setDoOutput(true); // Allow Outputs
conn.setUseCaches(false); // Don't use a Cached Copy
conn.setRequestMethod("POST");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("ENCTYPE",
"multipart/form-data");
conn.setRequestProperty("Content-Type",
"multipart/form-data;boundary=" + boundary);
conn.setRequestProperty("bill", sourceFileUri);
dos = new DataOutputStream(conn.getOutputStream());
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"bill\";filename=\""
+ sourceFileUri + "\"" + lineEnd);
dos.writeBytes(lineEnd);
// create a buffer of maximum size
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
// read file and write it into form...
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
while (bytesRead > 0)
dos.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math
.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0,
bufferSize);
// send multipart form data necesssary after file
// data...
dos.writeBytes(lineEnd);
dos.writeBytes(twoHyphens + boundary + twoHyphens
+ lineEnd);
// Responses from the server (code and message)
serverResponseCode = conn.getResponseCode();
String serverResponseMessage = conn
.getResponseMessage();
if (serverResponseCode == 200)
// messageText.setText(msg);
//Toast.makeText(ctx, "File Upload Complete.",
// Toast.LENGTH_SHORT).show();
// recursiveDelete(mDirectory1);
// close the streams //
fileInputStream.close();
dos.flush();
dos.close();
catch (Exception e)
// dialog.dismiss();
e.printStackTrace();
// dialog.dismiss();
// End else block
catch (Exception ex)
// dialog.dismiss();
ex.printStackTrace();
return "Executed";
@Override
protected void onPostExecute(String result)
@Override
protected void onPreExecute()
@Override
protected void onProgressUpdate(Void... values)
在 PHP 中,
<?php
if (is_uploaded_file($_FILES['bill']['tmp_name']))
$uploads_dir = './';
$tmp_name = $_FILES['bill']['tmp_name'];
$pic_name = $_FILES['bill']['name'];
move_uploaded_file($tmp_name, $uploads_dir.$pic_name);
else
echo "File not uploaded successfully.";
?>
【讨论】:
你好@Magash。我已经有一个 Asynctask 代码和一个 PHP 服务,我的问题介于两者之间,编码的字符串被截断。我不知道为什么... 感谢您提供 PHP 代码!这对我有用。我确实向扩展的 AsyncTask 类添加了一个构造函数,它将输入文件路径和 IP 地址作为参数。通过这个微小的更改,代码按预期工作。【参考方案2】:要使用 Multipart 上传图片,请按以下步骤操作:
下载 httpmime.jar 文件并将其添加到您的 libs 文件夹中。
下载 http client.jar 文件并将其添加到您的 libs 文件夹中。
从后台线程或 AsyncTask 调用以下方法。
public void executeMultipartPost() throws Exception
try
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bm.compress(CompressFormat.JPEG, 75, bos);
byte[] data = bos.toByteArray();
HttpClient httpClient = new DefaultHttpClient();
HttpPost postRequest = new HttpPost(
"YOUR SERVER URL");
ByteArrayBody bab = new ByteArrayBody(data, "YOUR IMAGE.JPG");
MultipartEntity reqEntity = new MultipartEntity(
HttpMultipartMode.BROWSER_COMPATIBLE);
reqEntity.addPart("IMAGE", bab);
postRequest.setEntity(reqEntity);
HttpResponse response = httpClient.execute(postRequest);
BufferedReader reader = new BufferedReader(new InputStreamReader(
response.getEntity().getContent(), "UTF-8"));
String sResponse;
StringBuilder s = new StringBuilder();
while ((sResponse = reader.readLine()) != null)
s = s.append(sResponse);
System.out.println("Response: " + s);
catch (Exception e)
// handle exception here
Log.e(e.getClass().getName(), e.getMessage());
【讨论】:
以上是关于如何使用 asynctask 将图像从 android 上传到 php的主要内容,如果未能解决你的问题,请参考以下文章
如果使用 Asynctask 将 URL 存储在 ArrayList 中,如何从服务器下载图像?
如何从服务器下载图像如果使用Asynctask存储在ArrayList中的URL?
Android:使用 Asynctask 从 Web 加载图像