首页 > 解决方案 > 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;
}

}

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

标签: android

解决方案


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

AsyncTask 允许正确和轻松地使用 UI 线程。此类允许您执行后台操作并在 UI 线程上发布结果,而无需操作线程和/或处理程序

我真的建议您在开始开发 Android 应用程序之前阅读一些 Android 教程,因为并非所有标准 Java 模式都适用于 Android。我推荐门课程,因为它是免费的,它会教你标准的 Android 设计模式。这也是谷歌员工的想法,所以我可以向你保证,他们知道他们在说什么。


推荐阅读