范围:我想通过意图拍照并将照片保存到我应用的内部存储空间。 然后我想将一个缩放版本加载到一个字节数组(来自inputstream),将这个缩放后的图像作为字节数组保存到SQLight中。 保存到数据库后,我想删除图片。
(这个问题只是关于将图像保存到内部存储,范围仅限于此处,因为总会有人询问它)
问题:我坚持将图片保存到内部存储空间。
我会在调试会话中添加示例作为变量后面的注释,以显示测试时获得的值。
我有一个ImageView,它有一个启动takePictureIntent的onClickListener:
具有以下全局属性:
..
创建文件路径:
Uri mCurrentPhotoUri; //URI to file
File mCurrentPicture; //the current picture don't know if I need it somewhere but for complete understanding of code
imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//Intent for the on-board camera
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
//device has camera
if(takePictureIntent.resolveActivity(getPackageManager()) != null) {
File photoFile = null;
try {
//create a file with path the code below
photoFile = createImageFile(); //sets photoFile to: /data/data/my.app.project/app_photo/JPEG_20151105_092219_-1434131481.jpg
} catch (IOException e) {
e.printStackTrace();
}
//file has been created, set members and add Extra to intent, then start intent.
if(photoFile != null) {
mCurrentPicture = photoFile; // well, same as above
mCurrentPhotoUri = Uri.fromFile(photoFile); // this looks somehow wrong, but I don't know much about URIs: file:///data/data/my.app.project/app_photo/JPEG_20151105_092219_-1434131481.jpg
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile)); //same URI as above that extra should be needed to tell the cam that I don't want to save to the default path but my app path
startActivityForResult(takePictureIntent, 10); //start the intent and use requestcode 10 for onActivityResult ...
}
}
}
});
因此相机打开,我可以拍照,我问是否要保存该照片(所有这些都来自内置相机应用程序,设备是三星星系注释)。
然后调用我的onActivityResult-Method: 我使用数据作为参数,因为我使用了迷你字节数组,但是使用自定义存储,它返回null 并且它不再被使用。
//code from google developers with some changes.
private File createImageFile() throws IOException {
String timestamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); //from today value: 20151105_092219
String imageFilename = "JPEG_" + timestamp + "_"; // concat is this: JPEG_20151105_092219_
File storageDir = this.getDir("photo", MODE_PRIVATE); //String path is: /data/data/my.app.project/app_photo
storageDir.mkdirs();
File image = File.createTempFile(imageFilename, ".jpg", storageDir); //String path is: /data/data/my.app.project/app_photo/JPEG_20151105_092219_-1434131481.jpg
mCurrentPhotoPath = "file:" + image.getAbsolutePath(); //here I put the absolute path into static mCurrentPhotoPath, concate with the "file:" from googledeveloper guide: file:/data/data/my.app.project/app_photo/JPEG_20151105_092219_-1434131481.jpg
return image;
}
方法setImageView:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
switch(requestcode) {
...
case 10:
setImageView(ivPreview1, data, 0);
ivPreview.setVisibility(View.VISIBLE);
break;
...
}
...
}
}
我用来解码文件的以下方法(自定义:http://developer.android.com/downloads/samples/DisplayingBitmaps.zip):
BitmapFactory.decodeFile(filename,options)的行;还会创建一个日志条目:D / skia:--- SkImageDecoder :: Factory返回null
private void setImageView(ImageView iv, Intent data, int index) {
try {
Uri u = mCurrentPhotoUri; //sets u to: file:///data/data/my.app.project/app_photo/JPEG_20151105_092219_-1434131481.jpg
File file = new File(u.getPath()); //sets file to: /data/data/my.app.project/app_photo/JPEG_20151105_092219_-1434131481.jpg
Bitmap bm = null;
ByteArrayOutputStream baos = null;
int orientation = 0;
if (file.exists()) { //this is true
//found that somewhere in the developer training:
ExifInterface exif = null;
try {
exif = new ExifInterface(photoUri.getPath());
} catch (IOException e) {
e.printStackTrace();
}
if(exif != null)
orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0); //is 0 (i didn't rotate the tablet)
//resulution I want to resize the image to:
int reqWidth = 960, reqHeight = 1280;
//exchange values if orientation doesn't match landscape
if (orientation == 0 || orientation == 270) {
int temp = reqWidth;
reqWidth = reqHeight;
reqHeight = temp;
}
//this I used before I changed to internal storage to change the size of the image code below
bm = ImageManager.decodeSampledBitmapFromFile(u.getPath(), reqWidth, reqHeight); // returns null because of this everything following is null too.
if (orientation == 90 || orientation == 180 || orientation == 270) {
Matrix matrix = new Matrix();
// rotate the Bitmap
if (orientation == 90)
matrix.postRotate(90F);
else if (orientation == 270)
matrix.postRotate(-90F);
else
matrix.postRotate(180F);
// recreate the new Bitmap
bm = Bitmap.createBitmap(bm, 0, 0,
bm.getWidth(), bm.getHeight(), matrix, true);
}
baos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.JPEG, 50, baos);
}
iv.setImageBitmap(bm);
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "Could not take Photo: ", e);
}
}
我已经坚持了好几天了,现在我没有任何想法可以解决我的问题。这也是由于缺乏Android知识以及我无法在我的电脑上使用模拟器这一事实,所以我甚至无法查看应用程序文件夹以查看是否拍摄了照片。
答案 0 :(得分:1)
尝试获取存储临时图像的路径,如下所示。这将返回您的应用程序文件夹位置。并添加权限。
File dir = context.getExternalFilesDir(null)+"/"+"photo";
为相机访问添加用途功能。
<manifest ... >
<uses-feature android:name="android.hardware.camera"
android:required="true" />