在Android中通过HTTP Post请求发送Base64编码的图片

3

我完全迷失了,我正在尝试通过安卓应用程序将照片发送到一个PHP网页。

理论上一切都应该没问题,但目标数据似乎已经损坏或者出现了其他问题,我不知道怎么回事...

我可以获取到POST数据,我尝试使用一个简单的字符串,结果运行良好,但是使用一个大文件时,数据似乎就损坏了。

public class EncodingAndSending extends Thread{
    ShareOnMyWebSiteActivity mycontext;
    ContentResolver cr;
    Uri uri;
    public Handler mainHandler,sHandler;

    public EncodingAndSending(ShareOnMyWebSiteActivity myctxt,Handler mainone,Uri URI,ContentResolver crr){
         mycontext=myctxt;
         cr=crr;
         uri=URI;
         mainHandler=mainone;
         this.start();
    }

        return buffer.toString().toUpperCase();    
      }

    public void run(){

        InputStream is=null;
        byte[] data=null;
        try {
            is = cr.openInputStream(uri);
             // Get binary bytes for encode
            data = getFileBytes(is);
        } catch (Exception e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }

        String data_string=Base64.encodeToString(data,Base64.URL_SAFE);


        if(data_string!=""){
            SendRequest(data_string);
        }
        else{

        }

    }

public byte[] getFileBytes(InputStream ios) throws IOException {
            ByteArrayOutputStream ous = null;
            //InputStream ios = null;
            try {
                byte[] buffer = new byte[4096];
                ous = new ByteArrayOutputStream();
                //ios = new FileInputStream(file);
                int read = 0;
                while ((read = ios.read(buffer)) != -1)
                    ous.write(buffer, 0, read);
            } finally {
                try {
                    if (ous != null)
                        ous.close();
                } catch (IOException e) {
                    // swallow, since not that important
                }
                try {
                    if (ios != null)
                        ios.close();
                } catch (IOException e) {
                    // swallow, since not that important
                }
            }
            return ous.toByteArray();
        }


    private void SendRequest(String data_string){

        HttpClient httpclient = new DefaultHttpClient();
        HttpPost httppost = new HttpPost("xxxxx.php");

        try {

            List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
            nameValuePairs.add(new BasicNameValuePair("image", data_string));

            httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

            // Execute HTTP Post Request
            HttpResponse response = httpclient.execute(httppost);
            ResponseHandler<String> responseHandler=new BasicResponseHandler();
            String responseBody = httpclient.execute(httppost, responseHandler);


        } catch (Exception e) {
            // TODO Auto-generated catch block
        }       
    }

}

编辑:

这个方法可行。我可以对图像进行编码、解码和预览。我没有使用getBytes()函数,我不知道问题是否来自那里。

我会让你知道的。

    super.onCreate(savedInstanceState);
    setContentView(R.layout.test_image);
    ImageView image = (ImageView) findViewById(R.id.imageView1);
    FileInputStream in;
    BufferedInputStream buf;

    Intent intent = getIntent();
    Bundle extras = intent.getExtras();

    Uri uri = (Uri) extras.getParcelable(Intent.EXTRA_STREAM);
    ContentResolver cr = getContentResolver();
    Bitmap bMap=null;
    try {
        InputStream is = cr.openInputStream(uri);

        bMap = BitmapFactory.decodeStream(is);

        if (is != null) {
        is.close();
        }
    } catch (Exception e) {
        Log.e("Error reading file", e.toString());
    }

    ByteArrayOutputStream baos = new ByteArrayOutputStream();  
    bMap.compress(Bitmap.CompressFormat.JPEG, 100, baos);   
    byte[] b = baos.toByteArray();
    String data_string=Base64.encodeToString(b,Base64.DEFAULT);

    b=null;bMap=null;
    b=Base64.decode(data_string, Base64.DEFAULT);
    bMap=BitmapFactory.decodeByteArray(b, 0, b.length);
    image.setImageBitmap(bMap);

你能否包含 getFileBytes 方法的代码?也许它是罪魁祸首? - The Nail
抱歉,找不到任何明显的错误...您可以通过打印“data_string”并对其进行Base64解码并检查结果来进行调试。这样,您就可以看到问题是出在读取/编码还是HTTP POST上。 - The Nail
顺便提一下,if (data_string!="") 不是检查字符串是否为空的正确方法。!= 永远不应该用于比较两个 String,而应该使用 .equals(...)。此外,将 ArrayList 的初始容量设置为 2 是不必要的,因为它可以很好地处理自己的容量。 - The Nail
是的,您说得完全正确,这个检查方式只是为了调试而已。您是否知道这种情况只会在特殊情况下出现呢? - flo360
也许问题只是在使用 Base64.URL_SAFE 上? - The Nail
显示剩余5条评论
2个回答

2
我写了一个小应用程序,可以将使用手机相机拍摄的图像发送到数据库。以下是我解决问题的方法...
public void writeCommentForRestaurant(int id, String comment, String author,
        Bitmap image) {

    if (image != null) {
        /* Get the image as string */
        // Normal
        ByteArrayOutputStream full_stream = new ByteArrayOutputStream();
        image.compress(Bitmap.CompressFormat.PNG, 100, full_stream);
        byte[] full_bytes = full_stream.toByteArray();
        String img_full = Base64.encodeToString(full_bytes, Base64.DEFAULT);
        // Thumbnail
        ByteArrayOutputStream thumb_stream = new ByteArrayOutputStream();
                    // The getScaledBitmap method only minimizes the Bitmap to a small icon!
        getScaledBitmap(image, 72).compress(Bitmap.CompressFormat.JPEG, 75,
                thumb_stream);
        byte[] thumb_bytes = thumb_stream.toByteArray();
        String img_thumbnail = Base64.encodeToString(thumb_bytes, Base64.DEFAULT);

        // new HTTPWorker(ctx, mHandler, HTTPWorker.WRITE_COMMENT, true).execute(
        // Integer.toString(id), comment, author, img_thumbnail, img_full);
    } else {
        // new HTTPWorker(ctx, mHandler, HTTPWorker.WRITE_COMMENT, true).execute(
        // Integer.toString(id), comment, author, null, null);
    }
}

HTTPWorker只是一个异步任务,它构造HTTP方法。
...
/* Add arguments */
arguments.add(new BasicNameValuePair("idrestaurant", params[0]));
arguments.add(new BasicNameValuePair("comment", params[1]));
arguments.add(new BasicNameValuePair("author", params[2]));
if (params.length > 3) {
  arguments.add(new BasicNameValuePair("image", params[3]));
  arguments.add(new BasicNameValuePair("bigimage", params[4]));
}
...

然后我像这样将其发送到服务器。

/**
* Executes a httppost to a server instance with the given POST arguments
* and returns a String response from the server.
*/
private String httppost(String url, ArrayList<NameValuePair> args) {
  /* Create the channel for communicaton */
  InputStream is = null;

  /* Send request to server */
  try {
    /* Create the POST */
    HttpClient httpclient = new DefaultHttpClient();
    HttpPost httppost = new HttpPost(url);

    /* Add the login information "POST" variables in the php */
    httppost.setEntity(new UrlEncodedFormEntity(args));

    /* Execute the http POST and get the response */
    HttpResponse response = httpclient.execute(httppost);
    HttpEntity entity = response.getEntity();
    is = entity.getContent();
  } catch (Exception e) {
    Log.e(TAG, "Error in http connection " + e.toString());
    return null;
  }

  /* Read response from server */
  try {
    /* Read the response stream */
    BufferedReader reader = new BufferedReader(new InputStreamReader(
    is, "iso-8859-1"), 8);

    /* Copy the response to StringBuilder */
    StringBuilder sb = new StringBuilder();
    String line = null;
    while ((line = reader.readLine()) != null) {
      sb.append(line + "\n");
    }
    is.close();

    /* Return the response as string */
    return sb.toString();
  } catch (Exception e) {
    Log.e(TAG, "Error converting result " + e.toString());
    return null;
  }
}

2

非常感谢。实际上,问题出在服务器上。Base64被发送到一个php脚本,该脚本将字符串存储到一个字段中...该字段是长文本类型(mysql)。问题是它会损坏数据,我将其更改为blob,然后它就正常工作了。典型的吧?

非常感谢您的帮助。

这是我的第一个主题,在这里有一个伟大的社区,太好了。

再见。


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