2017-04-20 1 views
0

J'ai une application où l'utilisateur peut prendre une photo en cliquant sur un bouton. Après avoir cliqué, l'aperçu de la caméra s'ouvre sans problème. Mais après avoir pris la photo et cliqué sur "OK", la caméra s'arrête et affiche un message "la caméra est arrêtée". (Erreur apparaît lorsque vous utilisez l'application sur un Galaxy S3 avec 4.1.1)L'appareil photo s'arrête en essayant de capturer Photo (Android 4.1.1)

Dans le journal, il dit:

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; 

Activité

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

Sur mon Galaxy s6 il fonctionne comme un charme.

+0

Il n'y a rien dans le code dans votre question qui a quelque chose à voir avec un appareil photo. – CommonsWare

+0

Modifié. S'il vous plaît jeter un oeil – skm

+0

Vraisemblablement, ce message provient de n'importe quelle application de la caméra que vous utilisez. Est-ce que LogCat a des messages de * cette * application? – CommonsWare

Répondre

1

Je vous ai demandé si LogCat avait des messages de l'application de caméra qui plante. Si vous découvrez ce que sont ces messages, ils peuvent vous donner des indices.

Vous améliorerez la compatibilité si vous appelez addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) à votre ACTION_IMAGE_CAPTUREIntent.

Toutefois, dans l'ensemble, toutes les applications de caméra ne prennent pas en charge un Uri avec un schéma content comme destination de l'image. La propre application pour appareil photo de Google ne l'a pas supportée avant l'année dernière. Vous pouvez être mieux servi en utilisant FileProvider uniquement sur les appareils Android 7.0 ou version ultérieure et en utilisant Uri.fromFile() pour les appareils plus anciens.

+0

il pourrait être cet échec. Comment changer le code pour s'adapter à la fois (ci-dessus 7.0 et ci-dessous 7.0 appareils)? – skm

+0

@skm: Cochez 'Build.VERSION.SDK_INT' pour voir quelle version d'Android vous utilisez, et choisissez votre' Uri' en conséquence. Sur 'Build.VERSION_CODES.N' ou des périphériques plus élevés, utilisez le' FileProvider' 'Uri'. Sur les appareils plus anciens, utilisez 'Uri.fromFile()'. Dans les deux cas, l'image doit être écrite au même endroit - ce qui diffère est le 'Uri' que vous utilisez. – CommonsWare

+0

C'était tout !!! Merci! – skm