我正在使用相机意图在我的应用程序中捕获图像。我的应用在使用相机时Android 5.0.2
崩溃的问题。我正在使用片段的意图。下面是片段内的代码:
拍照的方法
private void takePhoto() {
mHighQualityImageUri = Util.generateTimeStampPhotoFileUri(getActivity());
Log.d(UploadPicturesFragment.class.getSimpleName(),
"URI: " + mHighQualityImageUri.toString());
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, mHighQualityImageUri);
startActivityForResult(intent, REQUEST_IMAGE_CAPTURE);
}
片段中的onActivityResult
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode != Activity.RESULT_OK) {
return;
}
if (requestCode == REQUEST_IMAGE_CAPTURE) {
Log.d(UploadPicturesFragment.class.getSimpleName(),
"IMAGE URI NOT NULL: " + (mHighQualityImageUri == null));
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(),
mHighQualityImageUri);
DroomUtil.beginCrop(mHighQualityImageUri, getActivity(), this, true, bitmap.getWidth(),
bitmap.getHeight());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
记录跟踪
12-29 10:28:03.491: E/AndroidRuntime(9780): java.lang.RuntimeException: Unable to resume activity {in.droom/in.droom.activity.MainActivity}: java.lang.RuntimeException: Failure delivering result ResultInfo{who=android:fragment:2, request=1, result=-1, data=null} to activity {in.droom/in.droom.activity.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.net.Uri.getScheme()' on a null object reference
12-29 10:28:03.491: E/AndroidRuntime(9780): at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3224)
12-29 10:28:03.491: E/AndroidRuntime(9780): at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3257)
12-29 10:28:03.491: E/AndroidRuntime(9780): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2479)
12-29 10:28:03.491: E/AndroidRuntime(9780): at android.app.ActivityThread.access$800(ActivityThread.java:144)
12-29 10:28:03.491: E/AndroidRuntime(9780): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1359)
12-29 10:28:03.491: E/AndroidRuntime(9780): at android.os.Handler.dispatchMessage(Handler.java:102)
12-29 10:28:03.491: E/AndroidRuntime(9780): at android.os.Looper.loop(Looper.java:155)
12-29 10:28:03.491: E/AndroidRuntime(9780): at android.app.ActivityThread.main(ActivityThread.java:5702)
12-29 10:28:03.491: E/AndroidRuntime(9780): at java.lang.reflect.Method.invoke(Native Method)
12-29 10:28:03.491: E/AndroidRuntime(9780): at java.lang.reflect.Method.invoke(Method.java:372)
12-29 10:28:03.491: E/AndroidRuntime(9780): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1029)
12-29 10:28:03.491: E/AndroidRuntime(9780): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:824)
12-29 10:28:03.491: E/AndroidRuntime(9780): Caused by: java.lang.RuntimeException: Failure delivering result ResultInfo{who=android:fragment:2, request=1, result=-1, data=null} to activity {in.droom/in.droom.activity.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.net.Uri.getScheme()' on a null object reference
12-29 10:28:03.491: E/AndroidRuntime(9780): at android.app.ActivityThread.deliverResults(ActivityThread.java:3881)
12-29 10:28:03.491: E/AndroidRuntime(9780): at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3197)
12-29 10:28:03.491: E/AndroidRuntime(9780): ... 11 more
12-29 10:28:03.491: E/AndroidRuntime(9780): Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.net.Uri.getScheme()' on a null object reference
12-29 10:28:03.491: E/AndroidRuntime(9780): at android.content.ContentResolver.openInputStream(ContentResolver.java:651)
12-29 10:28:03.491: E/AndroidRuntime(9780): at android.provider.MediaStore$Images$Media.getBitmap(MediaStore.java:1019)
12-29 10:28:03.491: E/AndroidRuntime(9780): at in.droom.fragments.UploadPicturesFragment.onActivityResult(UploadPicturesFragment.java:395)
12-29 10:28:03.491: E/AndroidRuntime(9780): at android.app.Activity.dispatchActivityResult(Activity.java:6164)
12-29 10:28:03.491: E/AndroidRuntime(9780): at android.app.ActivityThread.deliverResults(ActivityThread.java:3877)
12-29 10:28:03.491: E/AndroidRuntime(9780): ... 12 more
第一行395是:
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(),
mHighQualityImageUri);
答案 0 :(得分:12)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.net.Uri.getScheme()' on a null object reference
这意味着mHighQualityImageUri
很可能是null
。如果您未能使用Uri
保留onSaveInstanceState()
,则会发生这种情况。当您的应用处于后台并且相机应用程序位于前台时,您的流程完全可能会被终止。
答案 1 :(得分:6)
按照以下步骤从相机拍摄照片并显示在Uri fileUri;
String photoPath = "";
private void startingCameraIntent()
{
String fileName = System.currentTimeMillis()+".jpg";
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, fileName);
fileUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
startActivityForResult(intent, YOUR_REQ_CODE);
}
1)启动相机意图
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (resultCode == Activity.RESULT_OK)
{
try
{
photoPath = getPath(fileUri);
System.out.println("Image Path : " + photoPath);
Bitmap b = decodeUri(fileUri);
your_image_view.setImageBitmap(b);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
2)回调onActivityResult功能
private Bitmap decodeUri(Uri selectedImage) throws FileNotFoundException
{
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(getContentResolver()
.openInputStream(selectedImage), null, o);
final int REQUIRED_SIZE = 72;
int width_tmp = o.outWidth, height_tmp = o.outHeight;
int scale = 1;
while (true)
{
if (width_tmp / 2 < REQUIRED_SIZE || height_tmp / 2 < REQUIRED_SIZE)
{
break;
}
width_tmp /= 2;
height_tmp /= 2;
scale *= 2;
}
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver()
.openInputStream(selectedImage), null, o2);
return bitmap;
}
3)decodeUri功能
@SuppressWarnings("deprecation")
private String getPath(Uri selectedImaeUri)
{
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(selectedImaeUri, projection, null, null,
null);
if (cursor != null)
{
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
return cursor.getString(columnIndex);
}
return selectedImaeUri.getPath();
}
4)图像的getPath
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
最后在Manifest中定义权限
$foo = "2, 4, 33, 25, 66";
$new_foo = implode("', '1-",explode(",",$foo));
echo "'1-".$new_foo."'";
注意: 如果您使用的是marshmallow(Android 6.0),则必须在使用相机应用之前设置权限检查。您可以阅读有关Android Requesting Permissions at Run Time
的信息答案 2 :(得分:4)
首先检查data
中null
onActivityResult
是否为public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode != Activity.RESULT_OK && data !=null) {
return;
}
}
,方法是添加额外的代码,这样可以防止您的应用崩溃,就像这样
self
然后考虑本课说明how to capture photos using an existing camera application.
使用Requesting camera permission,uses-feature tag,Getting a thumbnail提供了关于Saving full size photo的完整参考资料,以及更多可能对您完成任务非常有帮助的内容......
答案 3 :(得分:2)
在Android上,我看到不同的设备在使用相机和图库选择图像时表现出不同的行为。我发现更好的方法是:
此方法使您的代码独立于已返回的Uri,因为您拥有Uri。此外,这也支持图库图片选择,只需稍加修改。
我发现相机也存在设备方向问题。这(不幸的是)需要在您的应用程序中处理,您需要在后处理步骤中获取图像。我也在下面概述了它的代码。大多数情况下,定位问题发生在三星设备上,其中相机仅以横向模式捕获图像。
为图片创建Uri:
string imageId = "IMG" + System.currentTimeMillis();
Uri attachmentUri = Uri.parse("content://"+ AttachmentContentProvider.AUTHORITY + "/images/" + imageId);
// Store this as a member in your activity/fragment as mAttachmentUri
注意:使用onSaveInstanceState()使用共享首选项或活动包保持mAttachmentUri
非常重要,否则当应用程序被杀时,Uri可能会丢失。
获取相机意图:
public static Intent getImageCaptureIntent(Context context, Uri outputFileUri)
{
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
return cameraIntent;
}
阅读图片:
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (resultCode != Activity.RESULT_OK) {
return;
}
if (requestCode == REQUEST_IMAGE_CAPTURE)
{
try {
Bitmap bitmap = decodeSampledBitmapFromResource(getActivity(), mAttachmentUri, Config.RGB_565);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static Bitmap decodeSampledBitmapFromResource(Context context, Uri uri, Config config)
{
Bitmap bmp = null;
InputStream is = null;
if (uri != null)
{
try
{
is = context.getContentResolver().openInputStream(uri);
boolean resize = true;
// First decode with inJustDecodeBounds=true to check dimensions
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(is, null, options);
mLogger.d("Image Original Width:" + options.outWidth + " Height:" + options.outHeight );
// close and open the stream again
is.close();
is = context.getContentResolver().openInputStream(uri);
int reqWidth = options.outWidth;
int reqHeight = options.outHeight;
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
options.inPreferredConfig = config;
bmp = BitmapFactory.decodeStream(is, null, options);
if(bmp != null)
{
bmp = correctImageRotation(context, bmp, uri);
}
else
{
mLogger.e("BitmapFactory.decodeStream returned null bitmap , skip correctImageRotation");
}
}
catch (FileNotFoundException fnfex)
{
mLogger.e("FileNotFoundException : while decoding inline image bitmap: " + fnfex.getMessage());
}
catch (IOException ioex)
{
mLogger.e("IOException : while decoding inline image bitmap: " + ioex.getMessage());
}
catch (OutOfMemoryError e)
{
mLogger.e("OutOfMemoryError : in decodeSampledBitmapFromResource BitmapFactory.decodeStream . Skip loading Resource");
}
finally
{
try
{
if (is != null)
{
is.close();
}
}
catch (IOException ioex2)
{
mLogger.e("IOException2 : while decoding inline image bitmap: " + ioex2.getMessage());
}
}
}
return bmp;
}
// Seemed necessary on a lot of Samsung devices
public static Bitmap correctImageRotation( Context context, Bitmap bitmap , Uri inputUri ) throws FileNotFoundException
{
int orientation = ExifInterface.ORIENTATION_UNDEFINED;
try
{
String appfilesDir = context.getApplicationContext().getFilesDir().getAbsolutePath();
String attachmentDirPath = appfilesDir + ('/') + "images");
String fileName = ContentUris.parseId(uri) + ".jpg";
String absolutePath = attachmentDirPath + ('/') + fileName;
ExifInterface exif = new ExifInterface(path);
orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED);
}
catch (IOException e)
{
}
return rotateBitmap(bitmap, orientation);
}
/**
* rotate bitmap code reference:
* http://stackoverflow.com/questions/20478765/how-to-get-the-correct-orientation-of-the-image-selected-from-the-default-image
*/
private static Bitmap rotateBitmap(Bitmap bitmap, int orientation)
{
Matrix matrix = new Matrix();
switch (orientation)
{
case ExifInterface.ORIENTATION_FLIP_HORIZONTAL:
matrix.setScale(-1, 1);
break;
case ExifInterface.ORIENTATION_ROTATE_180:
matrix.setRotate(180);
break;
case ExifInterface.ORIENTATION_FLIP_VERTICAL:
matrix.setRotate(180);
matrix.postScale(-1, 1);
break;
case ExifInterface.ORIENTATION_TRANSPOSE:
matrix.setRotate(90);
matrix.postScale(-1, 1);
break;
case ExifInterface.ORIENTATION_ROTATE_90:
matrix.setRotate(90);
break;
case ExifInterface.ORIENTATION_TRANSVERSE:
matrix.setRotate(-90);
matrix.postScale(-1, 1);
break;
case ExifInterface.ORIENTATION_ROTATE_270:
matrix.setRotate(-90);
break;
case ExifInterface.ORIENTATION_NORMAL:
case ExifInterface.ORIENTATION_UNDEFINED:
default:
return bitmap;
}
try
{
Bitmap bmRotated = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
bitmap.recycle();
return bmRotated;
}
catch (OutOfMemoryError e)
{
mLogger.e("OutOfMemoryError occured while rotating the image");
return bitmap;
}
}
内容提供商:
对于内容提供程序实现,您可以使用android的FileProvider或实现如下的内容提供程序。此内容提供商将在您的应用容器中打开一个文件,供相机应用写入。
public class AttachmentContentProvider extends ContentProvider
{
public static final String AUTHORITY = "com.yourcompany.yourapp.AttachmentContentProvider";
public static final int ENTITY_ATTACHMENT = 1;
public static final int ENTITY_ATTACHMENT_ID = 2;
private static final UriMatcher sUriMatcher;
static
{
sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
sUriMatcher.addURI(AUTHORITY, "images", ENTITY_ATTACHMENT);
sUriMatcher.addURI(AUTHORITY, "images"+"/#", ENTITY_ATTACHMENT_ID);
}
@Override
public boolean onCreate()
{
return true;
}
@Override
public int delete(Uri uri, String where, String[] whereArgs)
{
return 0;
}
@Override
public String getType(Uri uri)
{
int match = sUriMatcher.match(uri);
switch (match)
{
case ENTITY_ATTACHMENT:
case ENTITY_ATTACHMENT_ID:
return "image/jpeg";
default:
return null;
}
}
@Override
public Uri insert(Uri uri, ContentValues initialValues)
{
return null;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
{
return null;
}
@Override
public int update(Uri uri, ContentValues values, String where, String[] whereArgs)
{
return 0;
}
public static File getAttachmentFile(String fileName)
{
String appfilesDir = context.getApplicationContext().getFilesDir().getAbsolutePath();
String attachmentDirPath = appfilesDir + ('/') + "images");
File newFile = new File(AttachmentHelper.getAttachmentsDir() + File.separator + fileName);
newFile.getParentFile().mkdirs();
return newFile;
}
@Override
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException
{
long id = -1;
try
{
id = ContentUris.parseId(uri);
}
catch (NumberFormatException e)
{
m_logger.e("Invalid id for Uri : " + uri );
}
String filename = id + ".jpg"; // id will be IMG+current time millis
File imageFile = getAttachmentFile(id);
return (ParcelFileDescriptor.open(file, parseMode(mode)));
}
}
总而言之,此代码应适用于大多数经过测试的设备,并在需要时对从相机接收的图像进行校正。
答案 4 :(得分:2)
try
{
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
System.out.println("connected successfully");
Connection con = DriverManager.getConnection("jdbc:sqlserver://server name/dbname","username","password");
Statement statement = con.createStatement() ;
ResultSet resultset = statement.executeQuery("select FileName_WO_Ext from dbo.ALLOTMENT WHERE STR_TO_DATE(DATE, '%d/%m/%Y') >= DATE_SUB(CURRENT_DATE(), INTERVAL 1 DAY) AND STR_TO_DATE(DATE, '%d/%m/%Y') <= DATE_ADD(CURRENT_DATE(), INTERVAL 1 DAY);") ;
while(resultset.next())
{
String datee =resultset.getString("FileName_WO_Ext ");
out.println(datee);
}
}
catch(SQLException ex){
System.out.println("exception--"+ex);
}
答案 5 :(得分:2)
根据日志
func List(bucket string) []Data{
//Open BoltDB database
Open()
defer Close()
//Use a predefined struct to make an array
d:=make([]Data, 0)
//Fetch and unmarshal data as it is saved in byte form
db.View(func(tx *bolt.Tx) error {
cur := tx.Bucket([]byte(bucket)).Cursor()
for k, v := cur.First(); k != nil; k, v = cur.Next() {
d1:=Data{}
err:= json.Unmarshal(v, &d1)
if err !=nil{
return err
}
d=append(d, d1)
}
return nil
})
//Return the array of data
return d
}
它清楚地表明您在空对象上调用Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.net.Uri.getScheme()' on a null object reference
。因此,在处理之前,您需要检查空目标数据。
此外,从Android M开始,您需要向用户询问相机权限。由于缺乏相机许可,应用程序将崩溃。
要了解如何使用新的权限架构,请查看它:http://developer.android.com/training/permissions/index.html
答案 6 :(得分:0)
以下是我在项目中经常做的事情,请看看。希望它有所帮助!
片段类:
btnCapturePicture.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
captureImage();
}
});
btnSelectPicture.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
selectImage();
}
});
...
private void captureImage() {
mFileUri = Uri.fromFile(Utils.getOutputMediaFile(MEDIA_TYPE_IMAGE));
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, mFileUri);
startActivityForResult(intent, CAMERA_CAPTURE_IMAGE_REQUEST_CODE);
}
private void selectImage() {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType(MIME_IMAGE_ALL);
startActivityForResult(intent, SELECT_PHOTO_CODE);
}
...
@Override
public void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) {
super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
switch (requestCode) {
case SELECT_PHOTO_CODE:
if (resultCode == Activity.RESULT_OK) {
mFileUri = imageReturnedIntent.getData();
if (mFileUri != null) {
mFilePath = Utils.getRealPathFromUri(mContext, mFileUri);
mFilePath = mFilePath.replace("file://", "");
// do something such as display ImageView...
}
}
break;
case CAMERA_CAPTURE_IMAGE_REQUEST_CODE:
if (resultCode == Activity.RESULT_OK) {
if (mFileUri != null) {
mFilePath = mFileUri.toString();
mFilePath = mFilePath.replace("file://", "");
// do something such as display ImageView...
}
}
break;
}
// refresh phone's folder content
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
mediaScanIntent.setData(mFileUri);
getActivity().sendBroadcast(mediaScanIntent);
} else {
getActivity().sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory())));
}
}
Utils类:
//returning image, video
public static File getOutputMediaFile(int type) {
// External sdcard location
File mediaStorageDir = new File(Environment.getExternalStorageDirectory(), "DCIM/Camera");
// Create the storage directory if it does not exist
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg");
} else if (type == MEDIA_TYPE_VIDEO) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator + "VID_" + timeStamp + ".mp4");
} else {
return null;
}
return mediaFile;
}
//For select picture
public static String getRealPathFromUri(Context context, Uri contentUri) {
Cursor cursor = null;
try {
String[] proj = {MediaStore.Images.Media.DATA};
cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
} finally {
if (cursor != null) {
cursor.close();
}
}
}
答案 7 :(得分:0)
我认为,如果您使用片段中的意图,并且如果您正在使用它
getActivity()
确保你已经将你的片段附加到你的活动,否则它可能会抛出空指针。
因此在我的情况下,我使用了一种解决方法来获取上下文,您可以使用它
创建一个gobal变量
View rootView
并初始化OnViewCreated() method
,您可以相应地使用它。
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode != Activity.RESULT_OK) {
return;
}
if (requestCode == REQUEST_IMAGE_CAPTURE) {
Log.d(UploadPicturesFragment.class.getSimpleName(),
"IMAGE URI NOT NULL: " + (mHighQualityImageUri == null));
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap( rootView.getContext().getContentResolver(),
mHighQualityImageUri);
DroomUtil.beginCrop(mHighQualityImageUri, rootView.getContext(), this, true, bitmap.getWidth(),
bitmap.getHeight());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}}