尝试捕捉照片时相机停止(Android 4.1.1)

时间:2017-04-20 19:31:39

标签: android camera spinner

我有一个应用程序,用户可以在单击按钮时拍照。点击后相机预览打开没有任何问题。但是在拍完照片并点击“#34; OK"相机停止并显示一条消息"相机已停止"。 (在使用4.1.1的Galaxy S3上使用应用程序时出现错误)

在Log中说:

04-20 19:24:50.481 1048-1048/ibas.orosol I/dalvikvm: Could not find 

method android.widget.PopupWindow.showAsDropDown, referenced from method android.support.v7.widget.AppCompatPopupWindow.showAsDropDown
04-20 19:24:50.481 1048-1048/ibas.orosol W/dalvikvm: VFY: unable to resolve virtual method 18089: Landroid/widget/PopupWindow;.showAsDropDown (Landroid/view/View;III)V
04-20 19:24:50.533 1048-1048/ibas.orosol I/dalvikvm-heap: Grow heap (frag case) to 47.112MB for 640012-byte allocation
04-20 19:24:50.549 1048-1048/ibas.orosol E/dalvikvm: Could not find class 'android.widget.ThemedSpinnerAdapter', referenced from method android.support.v7.widget.AppCompatSpinner$DropDownAdapter.<init>
04-20 19:24:50.549 1048-1048/ibas.orosol W/dalvikvm: VFY: unable to resolve instanceof 2214 (Landroid/widget/ThemedSpinnerAdapter;) in Landroid/support/v7/widget/AppCompatSpinner$DropDownAdapter;

活动

public class BildActivity extends AppCompatActivity {

final private int REQUEST_CODE_ASK_PERMISSION = 123; //kann jegliche Zahl sein. Wir benutzens halt später
final private int REQUEST_IMAGE_CAPTURE = 555; //kann jegliche Zahl sein. Wir benutzens halt später

private ImageView mImageView;
private Uri mUri;
private String mCurrentPhotoPath = "";
private Bitmap mBitmap;

Spinner spinner;

Boolean tokenImage;

RequestQueue queue;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_bild);
    getSupportActionBar().setTitle("");
    getSupportActionBar().setBackgroundDrawable(ResourcesCompat.getDrawable(getResources(), R.drawable.kopf_app, null));
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);

    mImageView = (ImageView) findViewById(R.id.imageView);

    mBitmap = getBitmapFromDrawable(R.drawable.kamera);

    tokenImage = false;

    // wenn die Permission NICHT gegeben wurde... und was wir dann machen kommt in diesem Block
    if(ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED){

        if(ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)){

            //Hier können wir eintragen, wieso wir eigentlich die Permission brauchen/verlangen
        }else{

            //Permission anfragen
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE_ASK_PERMISSION);
        }
    }
    //---------------------------------------------------------------------------------------------
    ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE}, REQUEST_CODE_ASK_PERMISSION);


    //Drop-Down-Menü (Spinner) erstelllen:
    spinner = (Spinner) findViewById(R.id.spinner);

    //Die Werte des Menüs können in den Stringressourcen festgelegt werden und dann hier eingbunden werden (hier die String Rssource "R.array.arten"

    // Create an ArrayAdapter using the string array and a default spinner layout
    ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
            R.array.arten, R.layout.spinner_item);
    // Specify the layout to use when the list of choices appears
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); //Hier das DropDown-Design festlegen...eigenes erstellen und hier angeben geht auch
    // Apply the adapter to the spinner
    spinner.setAdapter(adapter);

    //Change DropDownIcon-Color
    spinner.getBackground().setColorFilter(Color.parseColor("#ffffff"), PorterDuff.Mode.SRC_ATOP);

    //.getSelectedItem().toString();

    queue = Volley.newRequestQueue(this);



}

public void takePicture(View view) throws IOException {

    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    try{
        File file =  createImageFile();

        mUri = FileProvider.getUriForFile(getApplication().getApplicationContext(),
                "ibas.provider", file);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, mUri);
        startActivityForResult(intent, REQUEST_IMAGE_CAPTURE);
    } catch (IOException e){
        e.printStackTrace();
    }

}

private File createImageFile() throws IOException {

    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    String imageFileName = "JPEG_" + timeStamp + "_";
    File storageDir = getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
    File image = File.createTempFile(
            imageFileName,  /* prefix */
            ".jpg",         /* suffix */
            storageDir      /* directory */
    );

    // Save a file: path for use with ACTION_VIEW intents
    mCurrentPhotoPath = "file:" + image.getAbsolutePath();
    return image;
}


@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {

    String path = "sdcard/orosol/captured_image.jpg";
    if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == Activity.RESULT_OK) {
        Log.i("uri-data", "Uri: " + mUri.toString());


        mBitmap = getBitmapFromUri(mImageView, BildActivity.this, mUri);

        mImageView.setImageBitmap(mBitmap);
        mImageView.getLayoutParams().height = 1000;
        mImageView.setScaleType(ImageView.ScaleType.CENTER_CROP);

        tokenImage = true;
    }

}

public void bildAnfrageSenden(View view){

    if(MainActivity.sharedPreferences.getInt("later", -1) == 1){
        new AlertDialog.Builder(BildActivity.this)
                .setTitle("Information")
                .setMessage("Es werden weitere Angaben benötigt, um die Anfrage senden zu können.")
                .setPositiveButton("ok", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {

                        Intent intent = new Intent(BildActivity.this, MainActivity.class);
                        intent.putExtra("von", "BildActivity");
                        startActivity(intent);

                        dialogInterface.cancel();

                    }
                }).show();
    }else if(!tokenImage){
        new AlertDialog.Builder(BildActivity.this)
                .setTitle("Information")
                .setMessage("Bitte erstellen Sie erst ein Bild.")
                .setPositiveButton("ok", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {

                        dialogInterface.cancel();
                    }
                }).show();

    }else if(spinner.getSelectedItem().toString().equals("Bitte wählen")) {
        new AlertDialog.Builder(BildActivity.this)
                .setTitle("Information")
                .setMessage("Bitte definieren Sie Ihre Anfrage.")
                .setPositiveButton("ok", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {

                        dialogInterface.cancel();
                    }
                }).show();

    } else{

            new AlertDialog.Builder(BildActivity.this)
                    .setTitle("Information")
                    .setMessage("Möchten Sie Ihre Anfrage senden?")
                    .setPositiveButton("Ja", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {

                            anfrageSenden();
                        }
                    })
                    .setNegativeButton("Nein", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {

                            dialogInterface.cancel();
                        }
                    }).show();
        }
    }




private void anfrageSenden(){

    final String bitmapString = getBase64StringFromBitmap(mBitmap);

    String url = "LINK";
    StringRequest postRequest = new StringRequest(Request.Method.POST, url,
            new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {
                    Log.i("response", response);
                    // response

                    new AlertDialog.Builder(BildActivity.this)
                            .setTitle("Information")
                            .setMessage("Ihre Anfrage wurde gesendet.")
                            .setPositiveButton("ok", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialogInterface, int i) {
                                    dialogInterface.cancel();
                                }
                            }).show();

                    //TODO: bei Anfrage ohne Daten -> wieder zurück zu Main-Activity
                }
            },
            new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    // error
                    Log.d("Error.Response", error.toString());
                }
            }
    ) {
        @Override
        protected Map<String, String> getParams() {
            Map<String, String> params = new HashMap<String, String>();
            params.put("test", "1");
            params.put("image", bitmapString);
            params.put("art", spinner.getSelectedItem().toString());

            params.put("name", MainActivity.sharedPreferences.getString("name", "-1"));
            params.put("tel", (MainActivity.sharedPreferences.getString("telefonnummer", "-1")));
            params.put("kundennummer", MainActivity.sharedPreferences.getString("kundennummer", "-1"));
            params.put("email", MainActivity.sharedPreferences.getString("email", "-1"));

            return params;
        }
    };
    queue.add(postRequest);

}




private Bitmap getBitmapFromUri(Uri uri) throws IOException {
    ParcelFileDescriptor parcelFileDescriptor = getContentResolver().openFileDescriptor(uri, "r");
    FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
    Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor);
    parcelFileDescriptor.close();
    return image;
}

public static Bitmap getBitmapFromUri(ImageView imageView, Context context, Uri uri) {

    if (uri == null) {
        return null;
    }

    int targetW = imageView.getWidth();
    int targetH = imageView.getHeight();
    ParcelFileDescriptor parcelFileDescriptor = null;
    try {

        parcelFileDescriptor =
                context.getContentResolver().openFileDescriptor(uri, "r");
        FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();

        BitmapFactory.Options opts = new BitmapFactory.Options();
        opts.inJustDecodeBounds = true;
        BitmapFactory.decodeFileDescriptor(fileDescriptor, null, opts);
        int photoW = opts.outWidth;
        int photoH = opts.outHeight;

        int scaleFactor = Math.min(photoW / targetW, photoH / targetH);

        opts.inJustDecodeBounds = false;
        opts.inSampleSize = scaleFactor;
        opts.inPurgeable = true;
        Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor, null, opts);

        if (image.getWidth() > image.getHeight()) {
            Matrix mat = new Matrix();
            int degree = 90;
            mat.postRotate(degree);
            Bitmap imageRotate = Bitmap.createBitmap(image, 0, 0, image.getWidth(), image.getHeight(), mat, true);
            return imageRotate;
        } else {
            return image;
        }
    } catch (Exception e) {
        Log.e("fail", "Failed to load image.", e);
        return null;
    } finally {
        try {
            if (parcelFileDescriptor != null) {
                parcelFileDescriptor.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
            Log.e("error", "Error closing ParcelFile Descriptor");
        }
    }
}

private String getBase64StringFromBitmap(Bitmap bitmap) {
    String base64StringOfBitmap = Base64.encodeToString(getBitmapData(bitmap), 1); // die 1 ist ein Flag
    Log.i("base64", base64StringOfBitmap);
    Log.i("length", base64StringOfBitmap.length() + "");
    return base64StringOfBitmap;
}

private Bitmap getBitmapFromBase64String(String base64String) {
    byte[] decoded = Base64.decode(base64String, 1); // die 1 ist ein Flag
    Bitmap bitmap = BitmapFactory.decodeByteArray(decoded, 0, decoded.length); //Returns the decoded Bitmap, or null if the image could not be decoded.
    return bitmap;
}

private byte[] getBitmapData(Bitmap bitmap) {
    ByteArrayOutputStream blob = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, blob);

    byte[] bitmapdata = blob.toByteArray();
    //System.out.println(blob.toByteArray());


    try {
        blob.close();
        blob = null;
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return bitmapdata; //als byte []
}

private Bitmap getBitmapFromDrawable(int drawableResId) {
    Bitmap bitmap = BitmapFactory.decodeResource(getApplicationContext().getResources(),
            drawableResId);
    return bitmap;
}

在我的Galaxy s6上,它就像一个魅力。

1 个答案:

答案 0 :(得分:1)

我问你LogCat是否有来自相机应用程序的任何消息崩溃。如果你发现这些消息是什么,他们可能会给你一些线索。

如果您向addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) ACTION_IMAGE_CAPTURE致电Intent,则可以提高兼容性。

但是,总体而言,并非每个相机应用都支持Uri content方案作为图像的目的地。谷歌自己的相机应用程序直到去年这个时候都不支持。仅在Android 7.0+设备上使用FileProvider并在旧版设备上使用Uri.fromFile()可以更好地提供服务。