在我的应用程序中从库中选择图像时,它不会崩溃,而是无法解码路径流。直接从相机拍摄照片工作正常,但从画廊来看,这里不是我的活动结果中的代码。
//enter code here
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Uri selectedImageUri = null;
String filePath = null;
switch (requestCode) {
case PICK_IMAGE:
if (resultCode == Activity.RESULT_OK)
{
selectedImageUri = data.getData();
name = getPath(selectedImageUri);
}
break;
case PICK_Camera_IMAGE:
if (resultCode == RESULT_OK) {
//use imageUri here to access the image
selectedImageUri = imageUri;
} else if (resultCode == RESULT_CANCELED) {
Toast.makeText(this, "Picture was not taken", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Picture was not taken", Toast.LENGTH_SHORT).show();
}
break;
}
if(selectedImageUri != null)
{
try
{
// OI FILE Manager
String filemanagerstring = selectedImageUri.getPath();
// MEDIA GALLERY
String selectedImagePath = getPath(selectedImageUri);
if (selectedImagePath != null) {
filePath = selectedImagePath;
} else if (filemanagerstring != null) {
filePath = filemanagerstring;
} else {
Toast.makeText(getApplicationContext(), "Unknown path",
Toast.LENGTH_LONG).show();
Log.e("Bitmap", "Unknown path");
}
if (filePath != null)
{
decodeFile(filePath);
} else {
bitmap = null;
}
}
catch (Exception e)
{
Toast.makeText(getApplicationContext(), "Internal error",
Toast.LENGTH_LONG).show();
Log.e(e.getClass().getName(), e.getMessage(), e);
}
}
}
public String getPath(Uri uri)
{
// just some safety built in
if( uri == null ) {
// TODO perform some logging or show user feedback
return null;
}
// try to retrieve the image from the media store first
// this will only work for images selected from gallery
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(uri, projection, null, null, null);
if( cursor != null ){
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
// this is our fallback here
return uri.getPath();
}
public void decodeFile(String filePath)
{
// Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filePath, o);
// The new size we want to scale to
final int REQUIRED_SIZE = 1024;
// Find the correct scale value. It should be the power of 2.
int width_tmp = o.outWidth, height_tmp = o.outHeight;
int scale = 1;
while (true)
{
if (width_tmp < REQUIRED_SIZE && height_tmp < REQUIRED_SIZE)
break;
width_tmp /= 2;
height_tmp /= 2;
scale *= 2;
}
// Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
bitmap = BitmapFactory.decodeFile(filePath, o2);
//imgView.setImageBitmap(bitmap);
}
任何帮助将不胜感激。
答案 0 :(得分:4)
在Android的更高版本(KitKat and above)中,从图库选取器返回的Uri
格式已更改,并且始终无法从Uri
获取文件路径没有太多的麻烦,有时根本不可能。因此,最好直接使用Uri
解码位图。
更改您的decodeFile()函数以接受Uri
并使用BitmapFactory.decodeStream()解码图像,如下所示:
public void decodeFile(Uri fileUri)
{
// Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(getContentResolver().openInputStream(fileUri), null, o);
// The new size we want to scale to
final int REQUIRED_SIZE = 1024;
// Find the correct scale value. It should be the power of 2.
int width_tmp = o.outWidth, height_tmp = o.outHeight;
int scale = 1;
while (true)
{
if (width_tmp < REQUIRED_SIZE && height_tmp < REQUIRED_SIZE)
break;
width_tmp /= 2;
height_tmp /= 2;
scale *= 2;
}
// Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(fileUri), null, o2);
//imgView.setImageBitmap(bitmap);
}
然后,您可以将onActivityResult()代码简化为:
if(selectedImageUri != null)
{
try
{
decodeFile(selectedImageUri);
}
catch (Exception e)
{
Toast.makeText(getApplicationContext(), "Internal error",
Toast.LENGTH_LONG).show();
Log.e(e.getClass().getName(), e.getMessage(), e);
}
}
如果您在获取有效Uri
时遇到问题,请参阅this question的已接受答案,了解如何在KitAat及更高版本上获得具有正确权限的OnActivityResult()内的Uri
。
答案 1 :(得分:0)
我为这件事选择了另一种方法。您无法在从库中选择图片或从相机意图中选择图片之间进行区分。
这是我的代码。
public class Chooser extends Activity {
ImageView imageView1;
private Uri outputFileUri;
@Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate (savedInstanceState);
setContentView (R.layout.activity_main);
imageView1 = (ImageView) this.findViewById (R.id.imageView1);
Button frag1 = (Button) this.findViewById (R.id.frag1);
frag1.setOnClickListener (new OnClickListener () {
@Override
public void onClick (View v) {
choosePic (null);
}
});
}
public void choosePic (View view) {
// Determine Uri of camera image to save.
final File root = new File (Environment.getExternalStorageDirectory () + File.separator + "DCIM/Camera" + File.separator);
root.mkdirs ();
final String fname = "image_" + getRandomName () + ".jpeg";
final File sdImageMainDirectory = new File (root, fname);
outputFileUri = Uri.fromFile (sdImageMainDirectory);
// Camera.
final List<Intent> cameraIntents = new ArrayList<Intent> ();
final Intent captureIntent = new Intent (android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
captureIntent.putExtra (MediaStore.EXTRA_OUTPUT, Uri.fromFile (sdImageMainDirectory));
final PackageManager packageManager = getPackageManager ();
final List<ResolveInfo> listCam = packageManager.queryIntentActivities (captureIntent, 0);
for (ResolveInfo res : listCam) {
final String packageName = res.activityInfo.packageName;
final Intent intent = new Intent (captureIntent);
intent.setComponent (new ComponentName (res.activityInfo.packageName, res.activityInfo.name));
intent.setPackage (packageName);
intent.putExtra (MediaStore.EXTRA_OUTPUT, outputFileUri);
cameraIntents.add (intent);
}
// Filesystem.
final Intent galleryIntent = new Intent ();
galleryIntent.setType ("image/*");
galleryIntent.setAction (Intent.ACTION_GET_CONTENT);
// Chooser of filesystem options.
final Intent chooserIntent = Intent.createChooser (galleryIntent, "Select Source");
// Add the camera options.
chooserIntent.putExtra (Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toArray (new Parcelable[] {}));
startActivityForResult (chooserIntent, 1);
}
@Override
protected void onActivityResult (int requestCode, int resultCode, Intent data) {
super.onActivityResult (requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
if (requestCode == 1) {
final boolean isCamera;
if (data == null) {
isCamera = true;
}
else {
final String action = data.getAction ();
if (action == null) {
isCamera = false;
}
else {
isCamera = action.equals (android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
}
}
Uri selectedImageUri;
if (isCamera) {
selectedImageUri = outputFileUri;
}
else {
selectedImageUri = data == null ? null : data.getData ();
}
imageView1.setImageURI (selectedImageUri);
}
}
}
public String getRandomName () {
Random r = new Random (); // just create one and keep it around
String alphabet = "abcdefghijklmnopqrstuvwxyz1234567890";
final int N = 10;
StringBuilder sb = new StringBuilder ();
for (int i = 0; i < N; i++) {
sb.append (alphabet.charAt (r.nextInt (alphabet.length ())));
}
return sb.toString ();
}