Android:将图片上传到PHP服务器

6
我已经编写了一个脚本,用于将从相机拍摄的图像上传到我的服务器。我收到了200OK响应,但是在uploads/文件夹中没有看到我的图片:

enter image description here

也许我的脚本存在错误。你能帮我吗?
这是我的示例链接:http://androidexample.com/Upload_File_To_Server_-_Android_Example/index.php?view=article_discription&aid=83&aaid=106 以下是完整的Android类:
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;

import android.app.ActionBar;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

public class New_annonce_act_step3 extends Activity {

    private static final int REQUEST_IMAGE = 100;   

    TextView tvPath;
    TextView txtHaut;
    ImageView preview;
    File destination;
    String imagePath;
    ImageButton takePhoto;
    Button btnCreate;

    int serverResponseCode = 0;
    ProgressDialog dialog = null;

    String upLoadServerUri = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);

        setContentView(R.layout.nouvelle_annonce_step3);

        // Change color of action bar
        ActionBar bar = getActionBar();
        bar.setBackgroundDrawable(new ColorDrawable(Color.parseColor("#0099CC")));

        preview = (ImageView) findViewById(R.id.nouvelle_annonce_step3_phototaken_preview);
        btnCreate = (Button) findViewById(R.id.nouvelle_annonce_step3_btn) ;
        txtHaut = (TextView) findViewById(R.id.nouvelle_annonce_step3_texteHaut);
        takePhoto = (ImageButton) findViewById(R.id.nouvelle_annonce_choose_image);
        preview.setVisibility(View.GONE);

        upLoadServerUri = "http://mywebsite.com/database/PDO/uploadFile.php";

        String name = dateToString(new Date(),"yyyy-MM-dd-hh-mm-ss");
        destination = new File(Environment.getExternalStorageDirectory(), name + ".jpg");

        takePhoto.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(destination));
                startActivityForResult(intent, REQUEST_IMAGE);
            }
        });

        btnCreate.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                dialog = ProgressDialog.show(New_annonce_act_step3.this, "", "Uploading file...", true);

                new Thread(new Runnable() {
                    public void run() {              
                        uploadFile(imagePath);
                    }
                }).start();        
            }

        });





    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if( requestCode == REQUEST_IMAGE && resultCode == Activity.RESULT_OK ){
            try {
                preview.setVisibility(View.VISIBLE);
                takePhoto.setVisibility(View.GONE);
                txtHaut.setText("Cette image est parfaite !");
                FileInputStream in = new FileInputStream(destination);
                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inSampleSize = 10;
                imagePath = destination.getAbsolutePath();
                Log.d("INFO", "PATH === " +imagePath);
                //tvPath.setText(imagePath);
                Bitmap bmp = BitmapFactory.decodeStream(in, null, options);
                preview.setImageBitmap(bmp);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }

        }
        else{
            tvPath.setText("Request cancelled");
        }
    }

    public String dateToString(Date date, String format) {
        SimpleDateFormat df = new SimpleDateFormat(format);
        return df.format(date);
    }

    public int uploadFile(String sourceFileUri) {

        String fileName = sourceFileUri;

        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()) {
            dialog.dismiss(); 
            Log.e("uploadFile", "Source File not exist :" +imagePath);
            return 0;
        }
        else
        {
            try { 

                // 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("uploaded_file", fileName); 

                dos = new DataOutputStream(conn.getOutputStream());

                dos.writeBytes(twoHyphens + boundary + lineEnd); 
                dos.writeBytes("Content-Disposition: form-data; name=\"uploaded_file\";filename="+ fileName + "" + 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();

                Log.i("uploadFile", "HTTP Response is : "+ serverResponseMessage + ": " + serverResponseCode);

                if(serverResponseCode == 200){

                    runOnUiThread(new Runnable() {
                        public void run() {

                            Toast.makeText(New_annonce_act_step3.this, "File Upload Complete.", 
                                    Toast.LENGTH_SHORT).show();
                        }
                    });                
                }    

                //close the streams //
                fileInputStream.close();
                dos.flush();
                dos.close();

            } catch (MalformedURLException ex) {

                dialog.dismiss();  
                ex.printStackTrace();

                runOnUiThread(new Runnable() {
                    public void run() {

                        Toast.makeText(New_annonce_act_step3.this, "MalformedURLException", 
                                Toast.LENGTH_SHORT).show();
                    }
                });

                Log.e("Upload file to server", "error: " + ex.getMessage(), ex);  
            } catch (Exception e) {

                dialog.dismiss();  
                e.printStackTrace();

                runOnUiThread(new Runnable() {
                    public void run() {

                        Toast.makeText(New_annonce_act_step3.this, "Got Exception : see logcat ", 
                                Toast.LENGTH_SHORT).show();
                    }
                });
                Log.e("Upload file to server Exception", "Exception : "
                        + e.getMessage(), e);  
            }
            dialog.dismiss();       
            return serverResponseCode; 

        } // End else block 
    } 

}

以下是PHP脚本:

<?php
    $file_path = "uploads/";

    $file_path = $file_path . basename( $_FILES['uploaded_file']['name']);
    if(move_uploaded_file($_FILES['uploaded_file']['tmp_name'], $file_path)) {
        echo "success";
    } else{
        echo "fail";
    }
 ?>

你需要从 PHP 脚本中捕获错误。 - dcclassics
你认为在PHP中会出现错误吗?即使我收到了200 OK的响应? - wawanopoulos
嗨@wawanopoulos,我正在使用相同的代码,目前卡在了200 OK响应上。我已经给了文件夹权限,并且Alan C添加的脚本也可以工作并写入数据。但是,我的图像没有被写入。它显示文件已上传并且给出http 200 ok,我转到服务器并运行php文件,然后输出为“失败”。您能提供任何帮助吗?谢谢 - Polynomial Proton
另外,您有从Web服务器下载图像到Android的参考资料吗?谢谢。 - Polynomial Proton
我把它弄好了。写字节时出现了错误 :) 虽然感谢你的帖子,但这确实帮了我很大的忙。 - Polynomial Proton
你的类中声明了一个名为imagePath的变量,在uploadFile()方法中声明了一个名为sourceFileUri的变量,在uploadFile()方法的实现中又声明了一个名为fileName的变量。看起来这些变量都具有相同的值,并且在代码中可以互换使用。你应该只使用一个变量,可能是在类顶部声明的那个变量。 - tschwab
1个回答

8

您是否已经验证了用户apache(或者php运行的任何其他用户)是否有权限写入$file_path指定的目录?

将下面的代码放在与您的PHP脚本相同的目录中,然后在Web浏览器中访问它。

<?php

$file_path = 'uploads/';

$success = file_put_contents($file_path . "afile", "This is a test");

if($success === false) {
    echo "Couldn't write file";
} else {
    echo "Wrote $success bytes";
}

?>

这会显示成功消息还是错误消息?

如果它显示错误消息,则尝试更改uploads目录的所有权。


3
问题已解决!我忘记为uploads/目录设置777权限。 - wawanopoulos

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接