在我的应用程序中,我试图通过LAN连接将照片上传到我的服务器。我从本教程开始:Sending Image to Server,但发现它使用了弃用的方法 - HttpParams& HttpClient具体。在搜索时,我找到了HttpUrlConnection,我正在尝试修复应用程序以上传照片。
这是我的Android代码:
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private static final int RESULT_LOAD_IMAGE = 1;
private static final String SERVER_ADDRESS = "http://my__LAN_IP_address/SavePicture.php";
HttpURLConnection urlConnection = null;
ImageView imageToUpload, downloadedImage;
Button bUploadImage, bDownloadImage;
EditText uploadImageName, downLoadImageName;
InputStream is;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageToUpload = (ImageView) findViewById(R.id.imageToUpload);
downloadedImage = (ImageView) findViewById(R.id.downloadedImage);
bUploadImage = (Button) findViewById(R.id.bUploadImage);
bDownloadImage = (Button) findViewById(R.id.bDownloadImage);
uploadImageName = (EditText) findViewById(R.id.etUploadImage);
downLoadImageName = (EditText) findViewById(R.id.etDownloadName);
imageToUpload.setOnClickListener(this);
bUploadImage.setOnClickListener(this);
bDownloadImage.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.imageToUpload:
Intent galleryIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(galleryIntent, RESULT_LOAD_IMAGE);
break;
case R.id.bUploadImage:
Bitmap image = ((BitmapDrawable) imageToUpload.getDrawable()).getBitmap();
new UploadImage(image, uploadImageName.getText().toString()).execute();
break;
case R.id.bDownloadImage:
break;
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && data != null){
Uri selectedImage = data.getData();
imageToUpload.setImageURI(selectedImage);
}
}
private class UploadImage extends AsyncTask<Void, Void, Void>{
Bitmap image;
String name;
public UploadImage(Bitmap image, String name){
this.image = image;
this.name = name;
}
@Override
protected Void doInBackground(Void... params) {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream);
String encodedImage = Base64.encodeToString(byteArrayOutputStream.toByteArray(), Base64.DEFAULT);
ContentValues dataToSend = new ContentValues();
dataToSend.put("image", encodedImage);
dataToSend.put("name", name);
try{
URL url = new URL(SERVER_ADDRESS);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setReadTimeout(3000);
connection.setConnectTimeout(3000);
connection.setRequestMethod("POST");
connection.setDoInput(true);
connection.setDoOutput(true);
os = connection.getOutputStream();
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(os, "UTF-8"));
writer.write(String.valueOf(dataToSend));
writer.flush();
writer.close();
os.close();
connection.connect();
is = connection.getInputStream();
}catch (Exception e){
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
Toast.makeText(getApplicationContext(), "Image Uploaded", Toast.LENGTH_SHORT).show();
}
}
}
这是我的PHP代码:
<?php
$name = isset($_POST["name"]) ? $_POST["name"] : '';
$image = isset($_POST["image"]) ? $_POST["image"] : '';
$decodedImage = base64_decode("$image");
file_put_contents("pictures/" + $name + ".JPG", $decodedImage);
?>
运行应用程序并选择照片时,没有任何错误,它似乎工作,但在服务器端,没有照片上传。任何帮助将不胜感激。
答案 0 :(得分:0)
使用此
//File path
String filepath = ""
@Override
protected String doInBackground(Void... params) {
String responseString = null;
HttpURLConnection conn = null;
DataOutputStream dos = null;
DataInputStream inStream = null;
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
int bytesRead;
long sentData = 0;
//URL
String urlString = ""
try {
UUID uniqueKey = UUID.randomUUID();
String fname = uniqueKey.toString();
FileInputStream fileInputStream = new FileInputStream(new File(filePath));
int length = fileInputStream.available();
URL url = new URL(urlString);
conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setRequestMethod("POST");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("Content-Type",
"multipart/form-data;boundary=" + boundary);
conn.setChunkedStreamingMode(1024);
dos = new DataOutputStream(conn.getOutputStream());
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"file\"; filename=\""+ (new File(filePath)).getName()+"\"" + lineEnd);
dos.writeBytes(lineEnd);
int maxBufferSize = 1024;
int bufferSize = Math.min(length, maxBufferSize);
byte[ ] buffer = new byte[bufferSize];
bytesRead = 0;
int latestPercentDone;
int percentDone = -1;
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
while (bytesRead > 0) {
dos.write(buffer, 0, bytesRead);
sentData += bytesRead;
latestPercentDone = (int) ((sentData / (float) length) * 100);
if (percentDone != latestPercentDone) {
percentDone = latestPercentDone;
publishProgress(percentDone);
}
int bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable,maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
}
dos.writeBytes(lineEnd);
dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
fileInputStream.close();
dos.flush();
dos.close();
} catch (MalformedURLException ex) {
} catch (IOException ioe) {
}
try {
statusCode = conn.getResponseCode();
if (statusCode == 200) {
responseString = "File Uploaded";
} else {
responseString = "Error occurred! Http Status Code: "
+ statusCode;
}
} catch (IOException ioex) {
responseString = ioex.getMessage();
}
return responseString;
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
System.out.println(result)
}
另外,尝试在上传前将文件写入某处。如果上传失败并且您想稍后重试,这将非常有用。
答案 1 :(得分:0)
昨天我遇到了类似的问题。我发送图像和文字。在尝试了不同的方法后,我结束了使用okhttp3:Microsoft documentation。在我看来,这是最简单的方式。
首先,在Android工作室中,您必须将okhttp添加到项目中。在build.gradle文件中的依赖项下添加它:
dependencies {
compile 'com.squareup.okhttp3:okhttp:3.2.0
}
我在android项目中的java文件看起来类似于以下内容。它是片段类的一部分。因此,如果您在活动中使用它,则可以使用此更改 getActivity()以获取上下文。 我将路径存储到我想要在ArrayList中发送的文件(变量 imageList )。响应只需要函数 backgroundThreadAlert 。如果你不需要知道上传是否成功,你可以忽略这个功能。
public class UploadClient extends AsyncTask<String, String, JSONObject> {
private ProgressDialog progressBar;
String status = "";
String formname = "mytext";
@Override
protected void onPreExecute() {
super.onPreExecute();
progressBar = new ProgressDialog(getActivity());
progressBar.setMessage("Send files. Please wait...");
progressBar.setIndeterminate(false);
progressBar.setCancelable(false);
progressBar.show();
}
@Override
protected JSONObject doInBackground(String... params) {
try {
int picindex = 0;
String url = "https://<urltouploadphp>/upload.php";
MultipartBody.Builder buildernew = new MultipartBody.Builder();
buildernew.setType(MultipartBody.FORM);
buildernew.addFormDataPart("formname", formname);
for(int j = 0; j < imageList.size(); j++) { // imageList is a ArrayList<String> of local paths of the images i want to upload
String imagepath = imageList.get(j);
File imgfile = new File(imagepath);
if(imgfile.exists()) {
buildernew.addFormDataPart("file" + picindex, imagepath, RequestBody.create(MediaType.parse("image/*"), imgfile));
picindex++;
}
}
MultipartBody requestBody = buildernew.build();
Request request = new Request.Builder()
.url(url)
.post(requestBody)
.build();
OkHttpClient client = new OkHttpClient();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException throwable) {
throwable.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
try {
String jsonData = response.body().string();
JSONObject Jobject = new JSONObject(jsonData);
status = Jobject.getString("status");
} catch (JSONException e) {
// Error in json
}
backgroundThreadAlert(getActivity());
}
});
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(JSONObject json) {
if (progressBar.isShowing()) {
progressBar.dismiss();
}
}
// Looper function to call from background thread "onResponse" - in this case a AlertDialog
public void backgroundThreadAlert(final Context context) {
if (context != null) {
new Handler(Looper.getMainLooper()).post(new Runnable() {
AlertDialog.Builder warnSend = new AlertDialog.Builder(getActivity());
@Override
public void run() {
if (status.equals("FAILED")) {
warnSend.setTitle("Upload failed");
warnSend.setMessage("upload to server failed");
} else if (status.equals("SUCCESS")) {
warnSend.setTitle("Upload completed");
warnSend.setMessage("upload completed, images sent.");
} else {
// error - no connection to server ?
}
warnSend.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
});
warnSend.show();
}
});
}
}
}
用这个来调用任务:
new UploadClient().execute();
服务器上的upload.php文件与此类似:
<?php
$name = $_POST['formname'];
for($i = 0; $i < count($_FILES); $i++) {
$fileName = $_FILES['file'.$i]['name'];
$fileType = $_FILES['file'.$i]['type'];
$rootName = explode(".", $fileName)[0];
$extension = explode(".", $fileName)[1];
$newName = $rootName.".".$extension;
$moved = move_uploaded_file($_FILES["file".$i]["tmp_name"], $newName );
if ($moved) $path = $newName;
}
// JSON-Response
$time = time();
if ($moved) {
$arrayToSend = array('status'=>'SUCCESS','time'=>$time, 'name'=>$name, 'countPics'=>count($_FILES));
} else {
$arrayToSend = array('status'=>'FAILED','time'=>$time);
}
header('Content-Type:application/json');
echo json_encode($arrayToSend);
?>
希望,这有帮助。