2016-07-10 4 views
1

I storage app mit Feuerbasis Speicherbeispielanwendung zu bauen versucht, und wenn ich ein Bild nehme ich bekommen RESUL_CANCELED immer in onActivityResult (..). Hier ist der Code:Taking Foto immer wieder RESULT_CANCELED (0) in onActivityResult (..)

@AfterPermissionGranted(RC_STORAGE_PERMS) 
private void launchCamera() { 
    Log.d(LOG_TAG, "launchCamera"); 

    // Check that we have permission to read images from external storage. 
    String perm = Manifest.permission.WRITE_EXTERNAL_STORAGE; 
    if (!EasyPermissions.hasPermissions(this, perm)) { 
     EasyPermissions.requestPermissions(this, getString(R.string.rationale_storage), 
       RC_STORAGE_PERMS, perm); 
     return; 
    } 

    // Choose file storage location, must be listed in res/xml/file_paths.xml 
    File externalDir = Environment.getExternalStorageDirectory(); 
    File file = new File(externalDir, "photos/" + UUID.randomUUID().toString() + ".jpg"); 

    // Create content:// URI for file, required since Android N 
    // See: https://developer.android.com/reference/android/support/v4/content/FileProvider.html 
    mFileUri = FileProvider.getUriForFile(this, 
      "com.google.firebase.quickstart.firebasestorage.fileprovider", file); 

    // Create and launch the intent 
    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
    takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, mFileUri); 

    startActivityForResult(takePictureIntent, RC_TAKE_PICTURE); 
} 

@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    Log.d(LOG_TAG, "onActivityResult:" + requestCode + ":" + resultCode + ":" + data); 
    if (requestCode == RC_TAKE_PICTURE) { 
     if (resultCode == RESULT_OK) { 
      if (mFileUri != null) { 
       uploadFromUri(mFileUri); 
      } else { 
       Log.w(LOG_TAG, "File URI is null"); 
      } 
     } else { 
      Toast.makeText(this, "Taking picture failed.", Toast.LENGTH_SHORT).show(); 
     } 
    } 
} 

Protokolle: onActivityResult: 101: 0: Intent {}

+0

Versuchen Sie eine andere Kamera-App. "ACTION_IMAGE_CAPTURE" -Implementierungen haben [eine Fehlerhistorie] (https://commonsware.com/blog/2015/06/08/action-image-capture-fallacy.html). Vergessen Sie auch nicht, 'mFileUri' in Ihren gespeicherten Instanzzustand' Bundle' zu ​​setzen, da Ihr Prozess möglicherweise beendet wird, während sich die Kamera-App im Vordergrund befindet. – CommonsWare

+0

@CommonsWare Danke, das war das Problem.Also kommt es auf die Android-Version an? – madim

Antwort

6

So hängt es von der Version des Android?

Das hängt davon ab, was Sie damit meinen und was der Fehler ist.

Wie ich in meinem Kommentar notierte, ACTION_IMAGE_CAPTURE Implementierungen haben a history of bugs. Es gibt eine große Auswahl an solchen Fehlern, die nicht unbedingt mit der Android-Version verknüpft sind.

Ihr Code nimmt jedoch einen interessanten Ansatz zu EXTRA_OUTPUT: Verwenden FileProvider mit einem Speicherort auf externen Speicher. Langfristig, FileProvider ist eine feine Antwort, wie Android N is starting to ban file:Uri values. Allerdings gibt es viele Kamera-Apps, die Probleme mit content:Uri Werten haben, weil die Entwickler dieser Kamera-Apps solche Werte nicht erwarten. Zum Beispiel schlägt die eigene Kamera-App von Google für ACTION_VIDEO_CAPTURE auf content:Uri Werte, mindestens wie vor ein paar Monaten, obwohl es für ACTION_IMAGE_CAPTURE in Ordnung ist.

Schlimmer noch, es gibt keine Möglichkeit für eine App, welche Schemata es für ein Extra unterstützt. Mit der Facette "Daten" einer Intent kann die <intent-filter> unterstützte Schemata ankündigen, aber das funktioniert nicht für Extras. Wenn Sie also ACTION_IMAGE_CAPTURE mit einem content:Uri in EXTRA_OUTPUT aufrufen, sind Sie nicht auf Kamera-Apps beschränkt, die content:Uri Werte unterstützen.

Sie könnten in Betracht ziehen, Ihre targetSdkVersion unter 24, dann Uri.fromFile(file) anstelle von FileProvider.getUriForFile(...) vorübergehend fallen zu lassen und zu sehen, was passiert. Wenn Ihre ursprüngliche Kamera-App einwandfrei funktioniert, unterstützt diese App content:Uri Werte nicht korrekt, und das hat Ihr ursprüngliches Problem verursacht.

Insgesamt empfehle ich, dass Entwickler, die mit ACTION_IMAGE_CAPTURE ihr halten targetSdkVersion unter 24 und file:Uri Werte für ein paar Jahre verwenden, so lange, bis ein höherer Prozentsatz der Benutzer eine Kamera-App installiert haben, dass content:Uri Werte unterstützt. Oder bieten Sie Ihren Nutzern eine Auswahl zwischen ihren bestehenden Kamera-Apps (über ACTION_IMAGE_CAPTURE) und einigen Kamerafunktionen, die Sie in Ihre eigene App einbauen (z. B. mit my library), um die Wahrscheinlichkeit zu erhöhen, dass etwas funktioniert.

0

Fügen Sie einfach einen Code hinzu, der eine sanfte Umgehungslösung zum Hinzufügen zu @CommonsWare aufruft. Checking API und die Handhabung hat gut funktioniert.

private void startCamera() { 
    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 

    if (takePictureIntent.resolveActivity(getPackageManager()) != null) { 
     File photoFile = null; 
     try { 
      photoFile = ImgUtils.createTempImageFile(this); 
     } catch (IOException ex) { 
      ex.printStackTrace(); 
     } 
     if (photoFile != null) { 
      mTempPhotoPath = photoFile.getAbsolutePath(); 
      if(Build.VERSION.SDK_INT < 24) { 

      //create Uri with 'file://' prefix 
       tempImgUri = Uri.fromFile(photoFile); 
      }else{ 

      //create Uri with 'content://' prefix 
       tempImgUri = FileProvider.getUriForFile(this, 
         FILE_PROVIDER_AUTHORITY, 
         photoFile); 
      } 
      mImgUriString = tempImgUri.toString(); 

      // Add the URI so the camera can store the image 
      takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, tempImgUri); 
      startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE); 
     } 
    }