2014-02-19 6 views
11

Da KitKat die URIs von Pflücker Größen wieNew KitKat URIs reagieren nicht auf Intent.ACTION_VIEW

content://com.android.providers.media.documents/document/image:3951 

dann keiner meiner ACTION_VIEW Absichten arbeiten mehr geändert hat. Wenn zum Beispiel Benutzer ein Bild aufnimmt, verwende ich

public static void openImage(Fragment f, Uri uri) { 
     Intent intent = new Intent(Intent.ACTION_VIEW); 
     intent.setDataAndType(uri, "image/*"); 

     f.startActivity(intent); 
    } 

und Android Gallery und Google+ Fotos kommen, aber wenn sie ausgewählt wird, die Galerie zeigt nur leere Bildschirme, sagt Fotos

Das „Medium nicht gefunden“ gleiche mit Sounds, ich bin

public static void playSound(Fragment f, Uri uri) { 
    Intent intent = new Intent(Intent.ACTION_VIEW); 
    intent.setDataAndType(uri, "audio/*"); 

    f.startActivity(intent); 
} 

, die mit dem kleinen weißen spielen Dialog UI zeigen Google, die in früheren Versionen Play Music verwendet zu verwenden, verwendet. Mit den neuen URIs bekomme ich die Ausnahme, dass keine App diese Absicht verarbeiten kann.

// Mit Fotos, die lustige Sache ist, dass, wenn Sie Galerie anstelle der Bilder in der neuen KK Picker UI wählen, gibt es die alten URIs, die funktionieren.

Irgendwelche Ideen? Sind die System-Apps gerade nicht bereit für die neuen Uris? Soll ich die neuen Uris irgendwie zu alten hacken, damit Absichten funktionieren? Oder fehlt mir etwas?

Danke!

+0

Google hat das wegen des neuen StorageProviders geändert. Ich denke, du kannst einen Blick hier werfen: http://s.stefma.ws/62ad44 – StefMa

+0

Nun, okay, ich verstehe, warum sie es getan haben. Aber inzwischen haben sie ACTION_VIEW Absicht gebrochen. Alles, was ich dort sehe, ist, wie man über inputStream oder packetFileDescriptor importiert, was ich in meinem Anwendungsfall nicht will. Ich möchte nur Uris in meiner Datenbank speichern und sie wie vorher in externen Anwendungen onClick anzeigen. – urSus

+0

Es scheint, dass die empfangenden Apps in diesem Fall das URI nicht korrekt handhaben, z. Sie versuchen, sie zu analysieren, nicht "openInputStream()" auf ihnen. – botteaap

Antwort

5

Die Lösung ist die Flagge FLAG_GRANT_READ_URI_PERMISSION auf die Absicht passieren (auf KitKat und höher):

intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 

auch sicher, dass dieser Inhalt Uri von einer ACTION_OPEN_DOCUMENT Absicht abgerufen wurde, wie hier beschrieben: https://stackoverflow.com/a/19874645/334209

+0

Funktioniert wie erwartet, vielen Dank –

0

Sie können folgende Absicht verwenden, um ein Bild aus der Galerie

Intent i = new Intent (Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); 
startActivityForResult(i, 2); 

und erhalten die ausgewählten ima zu holen ge in onActivityResult like,

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

    super.onActivityResult(requestCode, resultCode, data); 

    if(data==null)return; 

    try { 
     Bitmap bit = scaleImage(this, data.getData()); 
     img.setImageBitmap(bit); 
    } catch (FileNotFoundException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
} 

public static Bitmap scaleImage(Context context, Uri photoUri) throws IOException { 
     InputStream is = context.getContentResolver().openInputStream(photoUri); 

     BitmapFactory.Options dbo = new BitmapFactory.Options(); 

     dbo.inJustDecodeBounds = true; 

     BitmapFactory.decodeStream(is, null, dbo); 

     is.close(); 

     int rotatedWidth, rotatedHeight; 
     int orientation = getOrientation(context, photoUri); 

     if (orientation == 90 || orientation == 270) { 
      rotatedWidth = dbo.outHeight; 
      rotatedHeight = dbo.outWidth; 
     } else { 
      rotatedWidth = dbo.outWidth; 
      rotatedHeight = dbo.outHeight; 
     } 

     Bitmap srcBitmap; 
     is = context.getContentResolver().openInputStream(photoUri); 
     if (rotatedWidth > 100 || rotatedHeight > 100) { 
      float widthRatio = ((float) rotatedWidth)/((float) 100); 
      float heightRatio = ((float) rotatedHeight)/((float) 100); 
      float maxRatio = Math.max(widthRatio, heightRatio); 

      // Create the bitmap from file 
      BitmapFactory.Options options = new BitmapFactory.Options(); 
      options.inSampleSize = (int) maxRatio; 
      srcBitmap = BitmapFactory.decodeStream(is, null, options); 
     } else { 
      srcBitmap = BitmapFactory.decodeStream(is); 
     } 
     is.close(); 

     /* 
     * if the orientation is not 0 (or -1, which means we don't know), we 
     * have to do a rotation. 
     */ 
     if (orientation > 0) { 
      Matrix matrix = new Matrix(); 
      matrix.postRotate(orientation); 

      srcBitmap = Bitmap.createBitmap(srcBitmap, 0, 0, srcBitmap.getWidth(), 
        srcBitmap.getHeight(), matrix, true); 
     } 

     String type = context.getContentResolver().getType(photoUri); 
     ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
     if (type.equals("image/png")) { 
      srcBitmap.compress(Bitmap.CompressFormat.PNG, 100, baos); 
     } else if (type.equals("image/jpg") || type.equals("image/jpeg")) { 
      srcBitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos); 
     } 
     byte[] bMapArray = baos.toByteArray(); 
     baos.close(); 
     return BitmapFactory.decodeByteArray(bMapArray, 0, bMapArray.length); 
    } 

    public static int getOrientation(Context context, Uri photoUri) { 
     /* it's on the external media. */ 
     Cursor cursor = context.getContentResolver().query(photoUri, 
       new String[] { MediaStore.Images.ImageColumns.ORIENTATION }, null, null, null); 

     if (cursor.getCount() != 1) { 
      return -1; 
     } 

     cursor.moveToFirst(); 
     return cursor.getInt(0); 
    }