Failed to find provider info for com.android.gallery3d.provider
Et pour cause, ceci est un bug de la galerie, le provider com.android.gallery3d.provider n'existe pas! c'est une erreur de la part de Google, car la galerie répond plutôt à com.google.android.gallery3d.provider. Voici comment j'ai procédé pour arriver à ce résultat:
Je vous épargne le XML, rien de plus classique ici.
Au niveau Java on appelle les applications susceptibles de nous renvoyer une image:
Intent takePictureIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(takePictureIntent, actionCode);
Ensuite on réceptionne le résultat:
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case ACTIVITY_SELECT_IMAGE: { if (resultCode == Activity.RESULT_OK) { Uri selectedImage = data.getData(); final String[] columns = { MediaColumns.DATA, MediaColumns.DISPLAY_NAME }; Cursor cursor = getContentResolver().query(selectedImage, columns, null, null, null); if (cursor != null) { cursor.moveToFirst(); int columnIndex = cursor.getColumnIndex(MediaColumns.DATA); if (columnIndex != -1) { // regular processing for gallery files String fileName = cursor.getString(columnIndex); setPic(fileName); } } else { // Ce n'est pas une image stockée dans la gallerie { try { if (selectedImage.toString().startsWith("content://com.android.gallery3d.provider")) { // utiliser le provider com.google, pas // com.android provider. selectedImage = Uri.parse(selectedImage.toString().replace("com.android.gallery3d", "com.google.android.gallery3d")); } final InputStream inputStream = getContentResolver().openInputStream(selectedImage); // On lit l'image dans un InputStream // qu'on enregistre dans un FileOutputStream File f = createImageFile(); OutputStream out = new FileOutputStream(f); int read = 0; byte[] bytes = new byte[1024]; while ((read = inputStream.read(bytes)) != -1) { out.write(bytes, 0, read); } inputStream.close(); out.flush(); out.close(); setPic(f.getAbsolutePath()); } catch (IOException e) { Log.e("PhotoIntentActivity", "io", e); } } } } break; } // ACTIVITY_SELECT_IMAGE } // switch }
Et pour la forme voici la méthode setPic() qui me permet d'afficher l'image:
private void setPic(String filePath) { mCurrentPhotoPath = filePath; // There isn't enough memory to open up more than a couple camera photos // So pre-scale the target bitmap into which the file is decoded // Get the size of the ImageView int targetW = mImageView.getWidth(); int targetH = mImageView.getHeight(); // Get the size of the image BitmapFactory.Options bmOptions = new BitmapFactory.Options(); bmOptions.inJustDecodeBounds = true; BitmapFactory.decodeFile(filePath, bmOptions); int photoW = bmOptions.outWidth; int photoH = bmOptions.outHeight; // Figure out which way needs to be reduced less int scaleFactor = 1; if ((targetW > 0) || (targetH > 0)) { scaleFactor = Math.min(photoW / targetW, photoH / targetH); } // Set bitmap options to scale the image decode target bmOptions.inJustDecodeBounds = false; bmOptions.inSampleSize = scaleFactor; bmOptions.inPurgeable = true; isFormReady = true; // Decode the JPEG file into a Bitmap Bitmap bitmap = BitmapFactory.decodeFile(filePath, bmOptions); // Associate the Bitmap to the ImageView mImageView.setImageBitmap(bitmap); mImageView.setVisibility(View.VISIBLE); mButtonSend.setEnabled(canSend()); }
Il faut bien garder à l'esprit que la méthode donnée ici ne prend pas tous les cas de figure en compte, mais palie au bug de la galerie Android. Ceci n'est qu'un hack qui je l'espère sera provisoire. Si l'équipe d'Android change com.google.android.gallery3d.provider en com.android.gallery3d.provider alors cette méthode restera valide pour les futures versions, si c'est le contraire, alors il faudra mettre à jour vos appli avec de grosses verrues spécialement pour HoneyComb et IceScream Sandwich.
Le code montré ci-dessus est disponible dans les sources de mon appli: My Figure Collection