java - 图片(base64)上传不正确

标签 java android android-asynctask base64

不幸的是,当我尝试将一些图像从 Android 设备上传到数据库时遇到了一些问题。 图像在一个文件夹中。该文件夹包含图像以及其他内容。我不知道图片的名称,我只需要上传图片(jpg)。在上传图像之前,我需要使用 base64 对其进行编码。

首先,我从文件夹中获取 jpg 文件。然后我从图像名称中获取 ID。之后,我通过 base64 对其进行编码:

Button upload = (Button) findViewById(R.id.upload);
upload.setOnClickListener(new View.OnClickListener() {
    public void onClick(View arg0) {
        String path = Environment.getExternalStorageDirectory().getPath();
        File dir = new File(path);
        File[] files = dir.listFiles();

        for (int i = 0; i < files.length; ++i) {
            if (files[i].getName().endsWith(".jpg")) {
                pics = new File(String.valueOf(files[i]));
                id = String.valueOf(files[i]);
                String sub = id.substring(id.lastIndexOf("/") + 1);
                int index = sub.indexOf("_");
                String book;
                if (index >= 0) {
                    book = sub.substring(0, index);
                    ID = book;
                    Log.e("ID", ID);
                }
                Bitmap imagex = BitmapFactory.decodeFile(pics.getAbsolutePath());
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                imagex.compress(Bitmap.CompressFormat.JPEG, 70, baos);
                byte[] b = baos.toByteArray();
                Image = Base64.encodeToString(b, Base64.DEFAULT);

                try {
                    new HttpAsyncTask(ID,Image,Nummer).execute("https://....");
                } catch (Exception e) {
                    Log.e("InputStream", e.getMessage());
                }

                Log.e("PICS", id);
            }
        }
    }
});

public String POST(String url) {
    InputStream inputStream;
    try {

        HttpClient httpclient = classxy.getNewHttpClient();

        HttpPost httpPost = new HttpPost(url);
        String json = "";

        JSONObject jsonObject = new JSONObject();

        jsonObject.put("bookId", ID);
        jsonObject.put("imageString", Image);
        jsonObject.put("imageNumber", Nummer);

        json = jsonObject.toString();

        StringEntity se = new StringEntity(json);

        httpPost.setEntity(se);

        httpPost.setHeader("Apikey", data);
        httpPost.setHeader("Modul", "upload_image");

        HttpResponse httpResponse = httpclient.execute(httpPost);
        inputStream = httpResponse.getEntity().getContent();


        if (inputStream != null)
            result = classxy.convertInputStreamToString(inputStream);
        else
            result = "Fehler!";
    } catch (Exception e) {
        Log.e("InputStream", e.getLocalizedMessage());
    }
    int num = Integer.parseInt(Nummer);
    num++;
    Nummer = Integer.toString(num);
    return result;
}

public class HttpAsyncTask extends AsyncTask<String, Void, String> {
    private final Object ID, Image, Nummer;

    public HttpAsyncTask(Object ID, Object Image, Object Nummer) {
        this.ID = ID;
        this.Image = Image;
        this.Nummer = Nummer;
    }

    protected String doInBackground(String... urls) {
        return POST(urls[0]);
    }

    protected void onPostExecute(String result) {
        if (result.matches("(.*)false(.*)")) {
            Toast.makeText(getApplicationContext(), "....", Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(getApplicationContext(), "...", Toast.LENGTH_SHORT).show();
        }
        Log.e("RESPONSE", result);
    }
}

它确实通过 base64 对图像进行了编码,并且确实上传了一些图像。不幸的是,它只上传第一张图片或多次上传一张图片。它永远不会以正确的顺序上传正确数量的图像。我已经在这个问题上坐了一段时间了,不知道我做错了什么。

你能告诉我哪里做错了吗?

最佳答案

您的程序似乎根本不是线程安全的。

您的字段 IDImageNummer 会随着 for 循环的每次迭代而更新。很可能在 POST 第一次运行之前循环已经完成。您的观察会支持这个假设:

Unfortunately it uploads only the first image or one image multiple times.

您可以通过记录对这些字段的每次访问来观察这一点。您会发现,它并不像您期望的那样交替出现。

因此,您应该完全不使用这些字段来实现所有内容。而是使用局部变量并传递它们。如果您想将它用于多个上传,使用 Nummer 字段可能很有用。但直接使用 int 可能会更好:

upload.setOnClickListener(new View.OnClickListener() {
    public void onClick(View arg0) {
        String ID = "", Image;
        int Nummer = 0;
        [...]

        for (int i = 0; i < files.length; ++i) {
            if (files[i].getName().endsWith(".jpg")) {
                [...]

                try {
                    new HttpAsyncTask(ID,Image,Integer.toString(Nummer++)).execute("https://....");
                } catch (Exception e) {
                    Log.e("InputStream", e.getMessage());
                }

                Log.e("PICS", id);
            }
        }
    }
});

public String POST(String url, String ID, String Image, String Nummer) {
    InputStream inputStream;
    try {
        [...]
    } catch (Exception e) {
        Log.e("InputStream", e.getLocalizedMessage());
    }
    //int num = Integer.parseInt(Nummer);
    //num++;
    //Nummer = Integer.toString(num);
    return result;
}

public class HttpAsyncTask extends AsyncTask<String, Void, String> {
    private final String ID, Image, Nummer;

    public HttpAsyncTask(String ID, String Image, String Nummer) {
        this.ID = ID;
        this.Image = Image;
        this.Nummer = Nummer;
    }

    protected String doInBackground(String... urls) {
        return POST(urls[0], ID, Image, Nummer);
    }

    protected void onPostExecute(String result) {
        [...]
    }
}

关于java - 图片(base64)上传不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31262768/

相关文章:

android - 如何在 Android 模拟器中隐藏应用程序图标?

android - 在 AsyncTask 中动态地将项目添加到微调器

java - SurfaceView滚动时闪烁

java - Android - 将 View 从 Activity 传递到 AsyncTask 类

java - 从数据库中解密 unicode 文本

java - 不兼容的操作数类型

java - InvalidUseOfMatchersException 在使用 mockito 强制在正在接受 junit 测试的 Copy() 方法中出现 CloneNotSupportedException 时

java - 在java中将秒数转换为日期和时间组合的代码

java - 简化多个旨在调用相同操作的 onclicklistener

android - 在 Android 中创建一个空的 Drawable