我有一个应用程序,用户可以在单击按钮时拍照。点击后相机预览打开没有任何问题。但是在拍完照片并点击“#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上,它就像一个魅力。
答案 0 :(得分:1)
我问你LogCat是否有来自相机应用程序的任何消息崩溃。如果你发现这些消息是什么,他们可能会给你一些线索。
如果您向addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
ACTION_IMAGE_CAPTURE
致电Intent
,则可以提高兼容性。
但是,总体而言,并非每个相机应用都支持Uri
content
方案作为图像的目的地。谷歌自己的相机应用程序直到去年这个时候都不支持。仅在Android 7.0+设备上使用FileProvider
并在旧版设备上使用Uri.fromFile()
可以更好地提供服务。