单击图像时我试图拍照,然后将Image Uri保存在FileProvide中。
在我的应用中,当我拍照并保存时。 我无法将图片保存在数据库中。
我得到零点错误 Error message
Process: com.example.android.inventoryapp, PID: 7732
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1, result=-1, data=Intent { act=inline-data (has extras) }} to activity {com.example.android.inventoryapp/com.example.android.inventoryapp.EditorActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.net.Uri.toString()' on a null object reference
at android.app.ActivityThread.deliverResults(ActivityThread.java:4360)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:4402)
at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:49)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.net.Uri.toString()' on a null object reference
at com.example.android.inventoryapp.EditorActivity.onActivityResult(EditorActivity.java:483)
at android.app.Activity.dispatchActivityResult(Activity.java:7454)
at android.app.ActivityThread.deliverResults(ActivityThread.java:4353)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:4402)
at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:49)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
如何解决这个问题?这是我的代码,
TakePicture方法
private void takePicture() {
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
try {
File photoFile = createImageFile();
Log.d(LOG_TAG, "File: " + photoFile.getAbsolutePath());
if (cameraIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(cameraIntent, REQUEST_IMAGE_CAPTURE);
}
} catch (IOException e) {
e.printStackTrace();
}
CreateImageFile方法
private File createImageFile() throws IOException {// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = image.getAbsolutePath();
return image;
}
saveItem方法
ContentValues values = new ContentValues();
if (mHasImage) {
values.put(ItemContract.ItemEntry.COLUMN_PICTURE, mImgUri.toString());
} else {
Toast.makeText(this, "Take photo", Toast.LENGTH_SHORT).show();
return;
}
onActivity方法
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
Log.i(LOG_TAG, "Uri: " + mImgUri.toString());
mImgTxt.setText(mImgUri.toString());
mImgBitmap = getBitmapFromUri(mImgUri);
mImageClick.setImageBitmap(mImgBitmap);
}
}
getBitmapFromUri方法
private Bitmap getBitmapFromUri(Uri uri) {
ParcelFileDescriptor parcelFileDescriptor = null;
try {
parcelFileDescriptor =
getContentResolver().openFileDescriptor(uri, "r");
FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor);
parcelFileDescriptor.close();
return image;
} catch (Exception e) {
Log.e(LOG_TAG, "Failed to load image.", e);
return null;
} finally {
try {
if (parcelFileDescriptor != null) {
parcelFileDescriptor.close();
}
} catch (IOException e) {
e.printStackTrace();
Log.e(LOG_TAG, "Error closing ParcelFile Descriptor");
}
}
}
答案 0 :(得分:1)
在res中创建一个文件夹xml,然后在此文件夹中创建一个文件“ my_paths”并粘贴以下代码
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path
name="my_images"
path="Android/data/YOUR_APP_PACKAGE_NAME/files" />//Don't forget to add package name here i.e. com.android.example
</paths>
在应用程序标记中将其添加到您的AndroidManifest.xml中。
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="YOUR_APP_PACKAGE_NAME"////Don't forget to add package name here i.e. com.android.example
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/my_paths" />
</provider>
现在您需要权限才能在存储中写入文件
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
获得许可后,调用此方法打开相机
private void displayCamera() {
File imagesFolder = new File(Environment
.getExternalStorageDirectory(), getContext().getResources()
.getString(R.string.app_name));
try {
if (!imagesFolder.exists()) {
boolean isCreated = imagesFolder.mkdirs();
if (!isCreated) {
Toast.makeText(getContext(), R.string.str_storage_error, Toast.LENGTH_LONG).show();
return;
}
}
} catch (Exception e) {
e.printStackTrace();
}
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
String imageFileName = "IMG_" + timeStamp + "_";
File storageDir = getContext().getExternalFilesDir(Environment.DIRECTORY_PICTURES);
try {
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
Uri uri = FileProvider.getUriForFile(getContext(), getContext().getPackageName(), image);
String imagePath=image.getAbsolutePath();//Store this path as globe variable
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
startActivityForResult(intent, Constants.CAMERA);
} catch (ActivityNotFoundException | IOException e) {
e.printStackTrace();
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
//Here you need to show image
//if you want to show using glid then use
Glide.with(this)
.load("file://" + imagePath)//here you need image path which is stored in globel variable
.apply(RequestOptions.circleCropTransform())
.into(mBinder.ivDp);
}
}
答案 1 :(得分:0)
如果您知道kotlin
语言,请在应用程序中复制粘贴代码。如果要写java
,请参阅逻辑。
在“相机”按钮上,单击:-
/**
* Handle camera button click
*/
private fun onCameraButtonClick() {
try {
mPhotoFile = CommonUtils.createImageFile(this)
// Continue only if the File was successfully created
if (mPhotoFile != null) {
dispatchTakePictureIntent(mPhotoFile!!)
}
} catch (ex: IOException) {
// Error occurred while creating the File
onError(R.string.some_error)
}
}
创建图像文件:-
/**
* Create image file to save capture image
* @return Image File
*/
@Throws(IOException::class)
fun createImageFile(context: Context): File {
// Create an image file name
val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(Date())
val imageFileName = "JPEG_" + timeStamp + "_"
val storageDir = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES)
return File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
)
}
创建图像文件后,检查天气是否授予许可:-
/**
* Launch camera application to take picture
*/
private fun dispatchTakePictureIntent(photoFile: File) {
if (hasPermission(Manifest.permission.CAMERA) && hasPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(this.packageManager) != null) {
val photoURI = FileProvider.getUriForFile(this,
"your packege name.fileprovider",
photoFile)
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI)
startActivityForResult(takePictureIntent, AppConstants.REQUEST_IMAGE_CAPTURE)
}
} else {
requestPermissionsSafely(arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA), AppConstants.REQUEST_CAMERA_PERMISSION_CODE)
}
}
处理相机结果:-
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (resultCode == Activity.RESULT_OK) {
when (requestCode) {
AppConstants.REQUEST_IMAGE_CAPTURE -> {
// Get the camera result
mActivityEditProfileBinding.imgProfilePic.setImageBitmap(CommonUtils.getBitmapImageFromFilePath(mPhotoFile!!))
}
else -> super.onActivityResult(requestCode, resultCode, data)
}
}
}
从文件获取位图:-
/**
* @return Bitmap from saved image file path
*/
fun getBitmapImageFromFilePath(file: File): Bitmap? {
if (file.exists()) {
val myBitmap = BitmapFactory.decodeFile(file.absolutePath)
val ei = ExifInterface(file.absolutePath)
val orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_UNDEFINED)
val rotatedBitmap: Bitmap?
rotatedBitmap = when (orientation) {
ExifInterface.ORIENTATION_ROTATE_90 -> rotateImage(myBitmap, 90.0f, file)
ExifInterface.ORIENTATION_ROTATE_180 -> rotateImage(myBitmap, 180.0f, file)
ExifInterface.ORIENTATION_ROTATE_270 -> rotateImage(myBitmap, 270.0f, file)
ExifInterface.ORIENTATION_NORMAL -> myBitmap
else -> myBitmap
}
return rotatedBitmap
}
return null
}
粘贴到您的manifest
中:-
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="your package.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
在您的res文件夹中创建一个xml名称文件夹,粘贴以下代码:-
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path
name="external_files"
path="." />
</paths>