Android,编写一个拍照的应用程序,然后在发布请求中发送该图片

时间:2018-05-01 11:17:49

标签: android

我已经足够远,我可以看似激活相机并获得目标图片,但是后期请求部分似乎是一个更大的问题。在不断遇到“NetworkOnMainThreadException”和上下文错误之后,我将我在这里学到的一些东西组合成了一些......仍然没有摆脱那个异常。我确信其他地方也存在问题。

编辑:这是代码。

public class MainActivity extends AppCompatActivity {
static final int REQUEST_IMAGE_CAPTURE =1;
//final IntentServiceActivity intentPost = new IntentServiceActivity();
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    final Button captureButton = findViewById(R.id.CaptureButton);
    captureButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            dispatchTakePictureIntent();
        }
    });

}
private void dispatchTakePictureIntent() {
    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
        startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
    }
}
protected  void  onActivityResult(int requestCode, int resultCode, Intent data){
    if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
        Bundle extras = data.getExtras();
        Bitmap imageBitmap = (Bitmap) extras.get("data");

        IntentServiceActivity intentPost = new IntentServiceActivity();
        intentPost.postRequest(imageBitmap);
    }
}

}

然后:

public class IntentServiceActivity extends AppCompatActivity {
private TextView result;

@Override
protected void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    result = (TextView) findViewById(R.id.resultText);

}
@Override
protected void onStop(){
    super.onStop();
}
public void postRequest(Bitmap bmp){
    HttpClient httpClient = new DefaultHttpClient();
    HttpContext localContext = new BasicHttpContext();
    HttpPost httpPost = new HttpPost("http://192.168.0.14:8000/trash/");

    try {
        File f = new File(myApp.getAppContext().getFilesDir(), "temp");
        f.createNewFile();

        //Convert bitmap to byte array
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        bmp.compress(Bitmap.CompressFormat.PNG, 0 /*ignored for PNG*/, bos);
        byte[] bitmapdata = bos.toByteArray();

        //write the bytes in file
        FileOutputStream fos = new FileOutputStream(f);
        fos.write(bitmapdata);
        fos.flush();
        fos.close();

        MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);

        entity.addPart("image", new FileBody(f));

        httpPost.setEntity(entity);

        HttpResponse response = httpClient.execute(httpPost, localContext);
        Log.d("response", EntityUtils.toString(response.getEntity()));
        result.setText(EntityUtils.toString(response.getEntity()));
        Log.d("Debug", "the end!");
    } catch (IOException e) {
        e.printStackTrace();
    }
}

最后:

public class myApp extends Application {
private static Context context;

public void onCreate() {
    super.onCreate();
    myApp.context = getApplicationContext();
}

public static Context getAppContext() {
    return myApp.context;
}

}

如果有人想知道的话,我已经添加了相机的使用功能和互联网的使用权限以及名称。

3 个答案:

答案 0 :(得分:0)

NetworkOnMainThreadException当您的应用程序在其主线程上执行网络操作(服务调用)时,抛出此异常。

使用** AsyncTask **来避免此异常。

class UploadImageTask extends AsyncTask<String, Void, Void> {

 @Override
    protected void onPreExecute() {
        super.onPreExecute();
       //here you can show progress dialog
    }

protected void doInBackground(String... data) {
    try {

         postRequest(bitmap);
    } catch (Exception e) {

    }
}

protected void onPostExecute(void res) {

}
}

然后更改IntentServiceActivity类

 @Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

result = (TextView) findViewById(R.id.resultText);
UploadImageTask task= new UploadImageTask ();
  task.execute();

}

希望这会对你有所帮助。

答案 1 :(得分:0)

如异常所示,不允许在Android主线程上触发网络调用。您需要使用的是AsyncTask

  

AsyncTask可以正确,轻松地使用UI线程。这个班   允许您执行后台操作并在上面发布结果   UI线程,而不必操纵线程和/或处理程序

我建议您在开始开发Android应用之前先完成一些Android教程,因为并非所有标准Java模式都适用于Android。我推荐this课程,因为它是免费的,它会教你标准的Android设计模式。谷歌员工也应该这样做,所以我可以向你保证他们知道他们在谈论什么。

答案 2 :(得分:0)

当您尝试在主UI线程上执行网络请求时,您可能会获得NetworkOnMainThreadException。这种行为使应用程序无响应。为了处理这种情况,您应该始终使用单独的线程来处理网络和繁重的处理代码逻辑。 AsyncTask是为繁重工作创建单独线程的最佳方法之一。

以下是根据您的要求的工作代码。只需按以下方式更改IntentServiceActivity

即可
public class IntentServiceActivity extends AppCompatActivity {
    private TextView result;
    private Bitmap bitmap;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        result = (TextView) findViewById(R.id.resultText);

    }

    @Override
    protected void onStop() {
        super.onStop();
    }

    public void postRequest(Bitmap bmp) {
        this.bitmap = bmp;
        new UploadImageTask().execute();
    }


    private class UploadImageTask extends AsyncTask<String, Integer, String> {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            Toast.makeText(IntentServiceActivity.this, "Uploading Image", Toast.LENGTH_LONG).show();
        }

        @Override
        protected String doInBackground(String... params) {
            try {
                HttpClient httpClient = new DefaultHttpClient();
                HttpContext localContext = new BasicHttpContext();
                HttpPost httpPost = new HttpPost("http://192.168.0.14:8000/trash/");

                File f = new File(myApp.getAppContext().getFilesDir(), "temp");
                f.createNewFile();

                //Convert bitmap to byte array
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                bmp.compress(Bitmap.CompressFormat.PNG, 0 /*ignored for PNG*/, bos);
                byte[] bitmapdata = bos.toByteArray();

                //write the bytes in file
                FileOutputStream fos = new FileOutputStream(f);
                fos.write(bitmapdata);
                fos.flush();
                fos.close();

                MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);

                entity.addPart("image", new FileBody(f));

                httpPost.setEntity(entity);

                HttpResponse response = httpClient.execute(httpPost, localContext);
                String responseTxt = EntityUtils.toString(response.getEntity());

                return responseTxt;
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(String resultTxt) {
            super.onPostExecute(resultTxt);
            Toast.makeText(IntentServiceActivity.this, "Image Uploaded", Toast.LENGTH_LONG).show();
            Log.d("response", resultTxt);
            if(result !== null) result.setText(resultTxt);
            Log.d("Debug", "the end!");

        }
    }