2017-07-07 3 views
0

Dieser Code funktioniert nicht auf allen Android-VersionenWie bekomme ich das uri von gefangenem Bitmap korrekt?

Auf Android 4.x funktioniert gut, aber auf 7.0 funktioniert dieser Code nicht. Der Code kann das Bild erfassen und speichern, aber letzten Schritt über Crop Image: Ich bekomme balck Bildschirm, bedeutet, dass die URI verloren ist. Überprüfen Sie den Screenshot nach dem Code unten.

Hier ist meine Demo:

import android.content.ActivityNotFoundException; 
import android.content.Intent; 
import android.graphics.Bitmap; 
import android.net.Uri; 
import android.provider.MediaStore; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.view.View; 
import android.widget.ImageView; 
import android.widget.Toast; 

import java.io.IOException; 

public class CameraCrop1 extends AppCompatActivity { 
    Uri picUri; 
    Bitmap bitmap, bitmap2; 
    ImageView img, img_original; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_camera_crop1); 

     img=(ImageView)findViewById(R.id.imageView); 
     img_original=(ImageView)findViewById(R.id.imageView_original); 
    } 

    public void Capture(View view) { 
     Capture_Cam(); 
    } 

    private void Capture_Cam() { 
     Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); 
     startActivityForResult(cameraIntent, 1); 

    } 

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


     if (requestCode == 1 && resultCode == RESULT_OK && data != null) { 

      picUri = data.getData(); 
      try { 
       // bitmap2 = MediaStore.Images.Media.getBitmap(this.getContentResolver(), picUri); // bitmap2 = original before cur 
       bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), Uri.parse("file://"+picUri)); 
       img_original.setImageBitmap(bitmap); 

      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
      performCrop(); 

     } else if (requestCode == 2) { 

      bitmap2=(Bitmap) data.getExtras().get("data"); 
      img.setImageBitmap(bitmap2); 

     }else{ 
      super.onActivityResult(requestCode, resultCode, data); 
     } 

    } 

    private void performCrop(){ 
     try { 

      Intent cropIntent = new Intent("com.android.camera.action.CROP"); 
      //indicate image type and Uri 
      cropIntent.setDataAndType(picUri, "image/*"); 
      cropIntent.putExtra("crop", "true"); 
      cropIntent.putExtra("aspectX", 1); 
      cropIntent.putExtra("aspectY", 1); 
      cropIntent.putExtra("outputX", 100); 
      cropIntent.putExtra("outputY", 100); 
      cropIntent.putExtra("scale", true); 
      cropIntent.putExtra("return-data", true); 
      startActivityForResult(cropIntent, 2); 
      Toast toast = Toast.makeText(this, "Done", Toast.LENGTH_SHORT); 
     } 
     catch(ActivityNotFoundException anfe){ 
      //display an error message 
      String errorMessage = "Whoops - your device doesn't support the crop action!"; 
      Toast toast = Toast.makeText(this, errorMessage, Toast.LENGTH_SHORT); 
      toast.show(); 
     } 

    } 

} 

Hier ist xml:

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:id="@+id/activity_camera_crop1" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:paddingBottom="@dimen/activity_vertical_margin" 
    android:paddingLeft="@dimen/activity_horizontal_margin" 
    android:paddingRight="@dimen/activity_horizontal_margin" 
    android:paddingTop="@dimen/activity_vertical_margin" 
    tools:context="Test.testing.CameraCrop1"> 

    <ImageView 
     android:layout_width="400px" 
     android:layout_height="400px" 
     app:srcCompat="@color/colorAccent" 
     android:id="@+id/imageView" 
     android:layout_alignParentTop="true" 
     android:layout_centerHorizontal="true" /> 

    <Button 
     android:text="Capture Camera" 
     android:onClick="Capture" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:id="@+id/button4" 
     android:layout_alignParentBottom="true" 
     android:layout_centerHorizontal="true" /> 

    <ImageView 
     android:layout_width="400px" 
     android:layout_height="400px" 
     app:srcCompat="@color/wallet_highlighted_text_holo_dark" 
     android:id="@+id/imageView_original" 
     android:layout_below="@+id/imageView" 
     android:layout_alignLeft="@+id/imageView" 
     android:layout_alignStart="@+id/imageView" /> 
</RelativeLayout> 

Screenshot

Antwort

0

Sie haben mit FileProvider.getUriForFile(Context, String, File) den URI des Bildes zu erhalten, eine URI wie content://

zu erhalten

Für neuere Apps, die auf Android 7.0 (API-Level 24) und höher abzielen, übergibt eine Datei: // URI über eine Paketgrenze hinweg eine FileUriExposedException.

Werfen Sie einen Blick here beschreibt, wie dies zu erreichen ist.

+0

ich jetzt diesen Fehler des Pfades: 'konnte nicht konfiguriert Wurzel finden, die/Speicher enthält// 0/Android/data/Test emuliert. Testen/Dateien/Bilder/JPEG_20170708_191838_1889413611.jpg' – Biblio

+0

@Biblio haben Sie den Dateianbieter erstellt und zu Ihrem Manifest hinzugefügt, wie im Tutorial angezeigt? Stellen Sie sicher, dass Sie das Paket aus dem Beispiel durch den tatsächlichen Paketnamen Ihrer App ersetzen. – pablobu

0

@pablobu, Wenn ich die Methode von dort verwenden, bekomme ich diesen Fehler:

java.lang.NullPointerException: Der Versuch, virtuelle Methode ‚android.content.res.XmlResourceParser android.content.pm.ProviderInfo aufzurufen .loadXmlMetaData (android.content.pm.PackageManager, java.lang.String)‘auf einem null-Objekt durch diese Linie

Fehler Referenz:

Uri photoURI = FileProvider.getUriForFile(this, // error is here 

private void Capture_Cam() { 
    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
    // Ensure that there's a camera activity to handle the intent 
    if (takePictureIntent.resolveActivity(getPackageManager()) != null) { 
     // Create the File where the photo should go 
     File photoFile = null; 
     try { 
      photoFile = createImageFile(); 
     } catch (IOException ex) { 
      // Error occurred while creating the File 

     } 
     // Continue only if the File was successfully created 
     if (photoFile != null) { 
      Uri photoURI = FileProvider.getUriForFile(this, // error is here 
        "com.example.android.fileprovider", 
        photoFile); 
      takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI); 
      startActivityForResult(takePictureIntent, 1000); 
     } 
    } 
} 


private File createImageFile() throws IOException { 
    // Create an image file name 
    String timeStamp = null; 
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) { 
     timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); 
    } 
    String imageFileName = "JPEG_" + timeStamp + "_"; 
    File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES); 
    File image = File.createTempFile(
      imageFileName, /* prefix */ 
      ".jpg",   /* suffix */ 
      storageDir  /* directory */ 
    ); 

Ich habe den Fehler behoben. Neue SDK-Versionen unterstützen keine URI-Form von: "file: //" Ich meine TargetVersion. Til 23 Version Unterstützung "file: //" Quelle: Found here

+0

Sie sollten Ihre Frage aktualisieren oder Kommentare hinzufügen, anstatt eine weitere Frage als Antwort hinzuzufügen. – pablobu

+0

Ich habe den Fehler behoben. Das Problem war die ** TargetVersion **. Die neuen Versionen unterstützen nicht die URI-Form von ** "file: //" ** more. Ich habe die Version von 25 auf 23 geändert, dann funktioniert es. – Biblio

+0

das klingt nicht wie eine langfristige Lösung – pablobu

Verwandte Themen