我想方设法如何在不使用AlertDialog的情况下从相机或图库为ImageView设置图像,或者处理两个按钮以实现过于意图。
所以,我从https://gist.github.com/Mariovc/f06e70ebe8ca52fbbbe2或Allow user to select camera or gallery for image
找到了Intent.createChooser当我从Gallery中选择图像时,一切都很完美,但是从Camera,总是RunExceptionError。
以下是我的课程: MainActivity.class
public class MainActivity extends AppCompatActivity {
private static final int PICK_IMAGE_ID = 234;
ImageView image;
Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
image = (ImageView) findViewById(R.id.imageView);
button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
onPickImage(v);
}catch (IOException e){e.printStackTrace();}
}
});
}
public void onPickImage(View view) throws IOException{
Intent chooseIntent = ImagePicker.getPickImageIntent(this);
startActivityForResult(chooseIntent,PICK_IMAGE_ID);
}
@Override
protected void onActivityResult(int requestCode, int resultCode,Intent data) {
switch (requestCode){
case PICK_IMAGE_ID:
Bitmap bitmap = ImagePicker.getImageFromResult(this, resultCode, data);
image.setImageBitmap(bitmap);
}
}
}
ImagePicker.java
public class ImagePicker {
private static final int DEFAULT_MIN_WIDTH_QUALITY = 400; // min pixels
private static final String TAG = "ImagePicker";
private static final String TEMP_IMAGE_NAME = "tempImage";
public static int minWidthQuality = DEFAULT_MIN_WIDTH_QUALITY;
public static Intent getPickImageIntent(Context context) {
Intent chooserIntent = null;
List<Intent> intentList = new ArrayList<>();
Intent pickIntent = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
takePhotoIntent.putExtra("return-data", true);
takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(getTempFile(context)));
intentList = addIntentsToList(context, intentList, pickIntent);
intentList = addIntentsToList(context, intentList, takePhotoIntent);
if (intentList.size() > 0) {
chooserIntent = Intent.createChooser(intentList.remove(intentList.size() - 1),
context.getString(R.string.pick_image_intent_text));
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentList.toArray(new Parcelable[]{}));
}
return chooserIntent;
}
private static List<Intent> addIntentsToList(Context context, List<Intent> list, Intent intent) {
List<ResolveInfo> resInfo = context.getPackageManager().queryIntentActivities(intent, 0);
for (ResolveInfo resolveInfo : resInfo) {
String packageName = resolveInfo.activityInfo.packageName;
Intent targetedIntent = new Intent(intent);
targetedIntent.setPackage(packageName);
list.add(targetedIntent);
Log.d(TAG, "Intent: " + intent.getAction() + " package: " + packageName);
}
return list;
}
public static Bitmap getImageFromResult(Context context, int resultCode,
Intent imageReturnedIntent) {
Log.d(TAG, "getImageFromResult, resultCode: " + resultCode);
Bitmap bm = null;
File imageFile = getTempFile(context);
if (resultCode == Activity.RESULT_OK) {
Uri selectedImage;
boolean isCamera = imageReturnedIntent == null;
if (isCamera) { /** CAMERA **/
selectedImage = Uri.fromFile(imageFile);
} else { /** ALBUM **/
selectedImage = imageReturnedIntent.getData();
}
Log.d(TAG, "selectedImage: " + selectedImage);
bm = getImageResized(context, selectedImage);
int rotation = getRotation(context, selectedImage, isCamera);
bm = rotate(bm, rotation);
}
return bm;
}
private static File getTempFile(Context context) {
File imageFile = new File(context.getExternalCacheDir(), TEMP_IMAGE_NAME);
imageFile.getParentFile().mkdirs();
return imageFile;
}
private static Bitmap decodeBitmap(Context context, Uri theUri, int sampleSize) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = sampleSize;
AssetFileDescriptor fileDescriptor = null;
try {
fileDescriptor = context.getContentResolver().openAssetFileDescriptor(theUri, "r");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
Bitmap actuallyUsableBitmap = BitmapFactory.decodeFileDescriptor(
fileDescriptor.getFileDescriptor(), null, options);
Log.d(TAG, options.inSampleSize + " sample method bitmap ... " +
actuallyUsableBitmap.getWidth() + " " + actuallyUsableBitmap.getHeight());
return actuallyUsableBitmap;
}
/**
* Resize to avoid using too much memory loading big images (e.g.: 2560*1920)
**/
private static Bitmap getImageResized(Context context, Uri selectedImage) {
Bitmap bm = null;
int[] sampleSizes = new int[]{5, 3, 2, 1};
int i = -1;
do {
i++;
bm = decodeBitmap(context, selectedImage, sampleSizes[i]);
Log.d(TAG, "resizer: new bitmap width = " + bm.getWidth());
} while (bm.getWidth() < minWidthQuality && i < sampleSizes.length);
return bm;
}
private static int getRotation(Context context, Uri imageUri, boolean isCamera) {
int rotation;
if (isCamera) {
rotation = getRotationFromCamera(context, imageUri);
} else {
rotation = getRotationFromGallery(context, imageUri);
}
Log.d(TAG, "Image rotation: " + rotation);
return rotation;
}
private static int getRotationFromCamera(Context context, Uri imageFile) {
int rotate = 0;
try {
context.getContentResolver().notifyChange(imageFile, null);
ExifInterface exif = new ExifInterface(imageFile.getPath());
int orientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
}
} catch (Exception e) {
e.printStackTrace();
}
return rotate;
}
public static int getRotationFromGallery(Context context, Uri imageUri) {
String[] columns = {MediaStore.Images.Media.ORIENTATION};
Cursor cursor = context.getContentResolver().query(imageUri, columns, null, null, null);
if (cursor == null) return 0;
cursor.moveToFirst();
int orientationColumnIndex = cursor.getColumnIndex(columns[0]);
return cursor.getInt(orientationColumnIndex);
}
private static Bitmap rotate(Bitmap bm, int rotation) {
if (rotation != 0) {
Matrix matrix = new Matrix();
matrix.postRotate(rotation);
Bitmap bmOut = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true);
return bmOut;
}
return bm;
}
}
这是LogCat:
10-10 22:30:13.038 27208-27208/com.example.tri.intentchooser W/System﹕ ClassLoader referenced unknown path: /data/app/com.example.tri.intentchooser-2/lib/arm
10-10 22:30:13.156 27208-27223/com.example.tri.intentchooser D/OpenGLRenderer﹕ Use EGL_SWAP_BEHAVIOR_PRESERVED: true
10-10 22:30:13.430 27208-27223/com.example.tri.intentchooser I/Adreno-EGL﹕ <qeglDrvAPI_eglInitialize:379>: QUALCOMM Build: 09/02/15, 76f806e, Ibddc658e36
10-10 22:30:13.468 27208-27223/com.example.tri.intentchooser I/OpenGLRenderer﹕ Initialized EGL, version 1.4
10-10 22:30:38.589 27208-27208/com.example.tri.intentchooser D/ImagePicker﹕ Intent: android.intent.action.PICK package: com.google.android.apps.photos
10-10 22:30:38.590 27208-27208/com.example.tri.intentchooser D/ImagePicker﹕ Intent: android.media.action.IMAGE_CAPTURE package: com.google.android.GoogleCamera
10-10 22:30:38.620 27208-27215/com.example.tri.intentchooser W/art﹕ Suspending all threads took: 25.571ms
10-10 22:30:39.827 27208-27223/com.example.tri.intentchooser E/Surface﹕ getSlotFromBufferLocked: unknown buffer: 0xaefbc490
10-10 22:30:48.058 27208-27208/com.example.tri.intentchooser D/ImagePicker﹕ getImageFromResult, resultCode: -1
10-10 22:30:48.074 27208-27208/com.example.tri.intentchooser D/ImagePicker﹕ selectedImage: null
10-10 22:30:48.082 27208-27208/com.example.tri.intentchooser D/AndroidRuntime﹕ Shutting down VM
10-10 22:30:48.098 27208-27208/com.example.tri.intentchooser E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.example.tri.intentchooser, PID: 27208
java.lang.RuntimeException: Unable to resume activity {com.example.tri.intentchooser/com.example.tri.intentchooser.MainActivity}: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=234, result=-1, data=Intent { }} to activity {com.example.tri.intentchooser/com.example.tri.intentchooser.MainActivity}: java.lang.NullPointerException: uri
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3103)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3134)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2481)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=234, result=-1, data=Intent { }} to activity {com.example.tri.intentchooser/com.example.tri.intentchooser.MainActivity}: java.lang.NullPointerException: uri
at android.app.ActivityThread.deliverResults(ActivityThread.java:3699)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3089)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3134)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2481)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.NullPointerException: uri
at com.android.internal.util.Preconditions.checkNotNull(Preconditions.java:60)
at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:922)
at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:865)
at com.example.tri.intentchooser.ImagePicker.decodeBitmap(ImagePicker.java:110)
at com.example.tri.intentchooser.ImagePicker.getImageResized(ImagePicker.java:133)
at com.example.tri.intentchooser.ImagePicker.getImageFromResult(ImagePicker.java:90)
at com.example.tri.intentchooser.MainActivity.onActivityResult(MainActivity.java:62)
at android.app.Activity.dispatchActivityResult(Activity.java:6428)
at android.app.ActivityThread.deliverResults(ActivityThread.java:3695)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3089)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3134)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2481)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
我找了"Caused by: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=234, result=-1, data=Intent { }} to activity"
但没有运气,也可能与日志selectedImage = NULL
有关。
请告诉我任何想法或建议。 感谢。