通过 apache 中的 php 文件将图像上传到服务器,使用 Android 上的 HttpUrlConnection


Uploading an image to a server via a php file in apache, using HttpUrlConnection on Android

在我的应用程序中,我试图通过LAN连接将照片上传到我的服务器。我从本教程开始:将图像发送到服务器,但发现它使用了不推荐使用的方法 - HttpParams和HttpClient。搜索后,我找到了HttpUrlConnection,并正在尝试修复该应用程序以上传照片。

这是我的安卓代码:

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);
?>

运行应用程序并选择照片后,没有任何错误,它似乎可以工作,但是从服务器端看,没有上传照片。任何帮助将不胜感激。

使用这个

//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)
}

另外,请尝试在上传之前将文件写入某个位置。如果上传失败并且您想稍后重试,这将非常有用。

我昨天遇到了类似的问题。我讨厌发送图像和文本。在尝试了不同的方法后,我最终使用了okhttp3:https://github.com/square/okhttp。在我看来,这是最简单的方法。

在 Android 工作室中,首先您必须将 okhttp 添加到您的项目中。在 build.gradle 文件中的依赖项下添加它:

dependencies {
    compile 'com.squareup.okhttp3:okhttp:3.2.0
}

我在安卓项目中的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();

我在服务器上上传.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);
?>

希望,它有帮助。