2017-04-20 4 views
0

Ich habe eine Anwendung, wo der Benutzer ein Foto aufnehmen kann, wenn er auf eine Schaltfläche klickt. Nach dem Klick öffnet sich die Kameravorschau ohne Probleme. Aber nachdem Sie das Foto gemacht und auf "OK" geklickt haben, stoppt die Kamera und zeigt die Meldung "Kamera hat aufgehört". (Fehler wird angezeigt, wenn der App auf einem Galaxy S3 mit mit 4.1.1)Kamera stoppt, wenn versucht wird, Foto zu erfassen (Android 4.1.1)

Im Log sagt es:

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; 

Aktivität

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; 
} 

Auf meinem Galaxy s6 es klappt wunderbar.

+0

Es gibt nichts im Code in Ihrer Frage, das etwas mit einer Kamera zu tun hat. – CommonsWare

+0

Bearbeitet. Bitte werfen Sie einen Blick auf – skm

+0

Vermutlich stammt diese Nachricht von jeder Kamera-App, die Sie verwenden. Hat LogCat irgendwelche Nachrichten von * dieser * App? – CommonsWare

Antwort

1

Ich fragte Sie, ob LogCat irgendwelche Nachrichten von der Kamera-App hat, die abstürzt. Wenn Sie herausfinden, was diese Nachrichten sind, können sie Ihnen einige Hinweise geben.

Sie verbessern die Kompatibilität, wenn Sie addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) zu Ihrem ACTION_IMAGE_CAPTUREIntent anrufen.

Insgesamt wird jedoch nicht jede Kamera-App eine Uri mit einem content Schema als Ziel für das Bild unterstützen. Die eigene Kamera-App von Google hat das bis zu dieser Zeit im letzten Jahr nicht unterstützt. Sie können besser mit FileProvider nur auf Android 7.0 + Geräte und mit Uri.fromFile() für die älteren Geräte bedient werden.

+0

könnte es dieser Fehler sein. Wie ändere ich den Code so, dass er sowohl (über 7,0 als auch unter 7,0-Geräte) passt? – skm

+0

@skm: Überprüfen Sie 'Build.VERSION.SDK_INT', um zu sehen, auf welcher Version von Android Sie laufen, und wählen Sie entsprechend Ihren' Uri'. Verwenden Sie auf 'Build.VERSION_CODES.N' oder höheren Geräten den' FileProvider' 'Uri'. Verwenden Sie auf älteren Geräten 'Uri.fromFile()'. In beiden Fällen sollte das Bild an die gleiche Stelle geschrieben werden - was unterscheidet ist die "Uri", die Sie verwenden. – CommonsWare

+0

Das war es !!! Vielen Dank! – skm

Verwandte Themen