Android 试图访问图像内容信息时,游标返回null(旋转)
这只是个概念,但我失败了。我的应用程序要求提供图像,我想为用户提供使用多媒体资料、文件浏览器或照相机获取图像的选项。然后图像被旋转、缩放并上传到服务器 首先,我创建意图Android 试图访问图像内容信息时,游标返回null(旋转),android,android-intent,Android,Android Intent,这只是个概念,但我失败了。我的应用程序要求提供图像,我想为用户提供使用多媒体资料、文件浏览器或照相机获取图像的选项。然后图像被旋转、缩放并上传到服务器 首先,我创建意图 protected void openImageIntent() { // Determine Uri of camera image to save. final File root = new File(Environment.getExternalStorageDirectory() + File.separator +
protected void openImageIntent() {
// Determine Uri of camera image to save.
final File root = new File(Environment.getExternalStorageDirectory() + File.separator + "tpics" + File.separator);
root.mkdirs();
final String fname = "img_"+ System.currentTimeMillis() + ".jpg";
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);
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, Constants.PICK_EXISTING_PHOTO_RESULT_CODE);
}
这是我的奖杯图像课
public class TrophyImage {
private Context mCtx;
private Uri mImageUri;
private static int MAX_IMAGE_DIMENSION = 720;
private String type;
private JSONServerClient mClient;
public TrophyImage(Context mCtx, Uri imageUri) {
this.mCtx = mCtx;
this.mImageUri = imageUri;
this.mClient = new JSONServerClient((Activity) mCtx);
}
/**
* Scales and orients images taken from the gallery.
*
* @param context
* @param photoUri
* @return
* @throws IOException
*/
public byte[] scaleImage() throws IOException {
InputStream is = mCtx.getContentResolver().openInputStream(mImageUri);
BitmapFactory.Options dbo = new BitmapFactory.Options();
dbo.inJustDecodeBounds = true;
BitmapFactory.decodeStream(is, null, dbo);
is.close();
int rotatedWidth, rotatedHeight;
int orientation = getOrientation();
if (orientation == 90 || orientation == 270) {
rotatedWidth = dbo.outHeight;
rotatedHeight = dbo.outWidth;
} else {
rotatedWidth = dbo.outWidth;
rotatedHeight = dbo.outHeight;
}
Bitmap srcBitmap;
is = mCtx.getContentResolver().openInputStream(mImageUri);
if (rotatedWidth > MAX_IMAGE_DIMENSION
|| rotatedHeight > MAX_IMAGE_DIMENSION) {
float widthRatio = ((float) rotatedWidth)
/ ((float) MAX_IMAGE_DIMENSION);
float heightRatio = ((float) rotatedHeight)
/ ((float) MAX_IMAGE_DIMENSION);
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);
}
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 bMapArray;
}
public int getOrientation() {
/* it's on the external media. */
Log.d("mImageUri", mImageUri.toString());
Cursor cursor = mCtx.getContentResolver().query(mImageUri,
new String[] { MediaStore.Images.ImageColumns.ORIENTATION },
null, null, null);
if (cursor.getCount() != 1) {
return -1;
}
cursor.moveToFirst();
return cursor.getInt(0);
}
public String uploadPhoto(final byte[] imageBytes, final String fileName) throws IOException {
String fileID = null;
String encodedImage = Base64.encodeToString(imageBytes, Base64.DEFAULT);
try {
JSONObject dataOut = new JSONObject();
dataOut.put("file", encodedImage);
dataOut.put("filename", fileName);
mClient.call(dataOut, JSONServerClient.FILE_UPLOAD);
// get the result so we know the file id (fid)
// and we can assign it to the correct field.
String js = mClient.getResponse();
JSONObject jo = new JSONObject(js);
fileID = jo.getString("fid");
} catch (JSONException e) {
e.printStackTrace();
}
return fileID;
};
public String getFileName() {
return Utility.getFileNameByUri(mImageUri, mCtx);
}
public Uri getmImageUri() {
return mImageUri;
}
}
我在TrophyImage.getOrientation第118行的下一行得到一个nullPointerException
if (cursor.getCount() != 1)
我测试游标的值,当然,它是空的。我不明白为什么它是空的。它似乎应该返回我需要的数据
以防万一。这是整个错误堆栈
07-28 14:15:51.573: E/AndroidRuntime(29734): FATAL EXCEPTION: main
07-28 14:15:51.573: E/AndroidRuntime(29734): java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=2, result=-1, data=Intent { dat=file:///storage/sdcard0/tpics/img_1375038937506.jpg }} to activity {com.seine.trophy.main/com.seine.trophy.main.TrophyCreate}: java.lang.NullPointerException
07-28 14:15:51.573: E/AndroidRuntime(29734): at android.app.ActivityThread.deliverResults(ActivityThread.java:3322)
07-28 14:15:51.573: E/AndroidRuntime(29734): at android.app.ActivityThread.handleSendResult(ActivityThread.java:3365)
07-28 14:15:51.573: E/AndroidRuntime(29734): at android.app.ActivityThread.access$1200(ActivityThread.java:141)
07-28 14:15:51.573: E/AndroidRuntime(29734): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1315)
07-28 14:15:51.573: E/AndroidRuntime(29734): at android.os.Handler.dispatchMessage(Handler.java:99)
07-28 14:15:51.573: E/AndroidRuntime(29734): at android.os.Looper.loop(Looper.java:137)
07-28 14:15:51.573: E/AndroidRuntime(29734): at android.app.ActivityThread.main(ActivityThread.java:5059)
07-28 14:15:51.573: E/AndroidRuntime(29734): at java.lang.reflect.Method.invokeNative(Native Method)
07-28 14:15:51.573: E/AndroidRuntime(29734): at java.lang.reflect.Method.invoke(Method.java:511)
07-28 14:15:51.573: E/AndroidRuntime(29734): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:792)
07-28 14:15:51.573: E/AndroidRuntime(29734): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:555)
07-28 14:15:51.573: E/AndroidRuntime(29734): at dalvik.system.NativeStart.main(Native Method)
07-28 14:15:51.573: E/AndroidRuntime(29734): Caused by: java.lang.NullPointerException
07-28 14:15:51.573: E/AndroidRuntime(29734): at com.seine.trophy.main.TrophyImage.getOrientation(TrophyImage.java:118)
07-28 14:15:51.573: E/AndroidRuntime(29734): at com.seine.trophy.main.TrophyImage.scaleImage(TrophyImage.java:58)
07-28 14:15:51.573: E/AndroidRuntime(29734): at com.seine.trophy.main.TrophyCreate.onActivityResult(TrophyCreate.java:333)
07-28 14:15:51.573: E/AndroidRuntime(29734): at android.app.Activity.dispatchActivityResult(Activity.java:5242)
07-28 14:15:51.573: E/AndroidRuntime(29734): at android.app.ActivityThread.deliverResults(ActivityThread.java:3318)
07-28 14:15:51.573: E/AndroidRuntime(29734): ... 11 more
非常感谢您的帮助。是的,他们的关键是返回的uri的格式不正确content://.. 这告诉我图像没有被添加到mediastore,所以光标当然是空的。解决方案是改变这样的意图
protected void openImageIntent() {
final String fname = "img_" + System.currentTimeMillis() + ".jpg";
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, fname);
values.put(MediaStore.Images.Media.DESCRIPTION,
"Image capture by camera");
// outputFileUri is the current activity attribute, define and save it
// for later usage (also in onSaveInstanceState)
outputFileUri = getContentResolver().insert(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
// Camera.
final List<Intent> cameraIntents = new ArrayList<Intent>();
final Intent captureIntent = new Intent(
android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
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,
Constants.PICK_EXISTING_PHOTO_RESULT_CODE);
}
现在图像捕获是mediastore的一部分,当传递url时,游标值不为null 好吧,我想我已经接近了。从照相机返回的Uri类型为file:///mydir/mydir2/img_12345.jpg.. 但文件系统,这是工作返回content://media/external/images/media/178043. GetContentResolver.query特别声明uri参数必须使用content://scheme以uri格式表示,以便检索内容。我怀疑这是问题的一部分。
protected void openImageIntent() {
final String fname = "img_" + System.currentTimeMillis() + ".jpg";
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, fname);
values.put(MediaStore.Images.Media.DESCRIPTION,
"Image capture by camera");
// outputFileUri is the current activity attribute, define and save it
// for later usage (also in onSaveInstanceState)
outputFileUri = getContentResolver().insert(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
// Camera.
final List<Intent> cameraIntents = new ArrayList<Intent>();
final Intent captureIntent = new Intent(
android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
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,
Constants.PICK_EXISTING_PHOTO_RESULT_CODE);
}