デフォルトのカメラアクティビティで画像をキャプチャし、アクティビティに戻り、その画像をImageViewにロードするアプリケーションを作成しています。問題は、カメラアクティビティが常にnullを返すことです。 onActivityResult(int requestCode, int resultCode, Intent data)
メソッドでは、null
としてデータを取得しています。ここに私のコードがあります:
public class CameraCapture extends Activity {
protected boolean _taken = true;
File sdImageMainDirectory;
Uri outputFileUri;
protected static final String PHOTO_TAKEN = "photo_taken";
private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 0;
@Override
public void onCreate(Bundle savedInstanceState) {
try {
super.onCreate(savedInstanceState);
setContentView(R.layout.cameracapturedimage);
File root = new File(Environment
.getExternalStorageDirectory()
+ File.separator + "myDir" + File.separator);
root.mkdirs();
sdImageMainDirectory = new File(root, "myPicName");
startCameraActivity();
} catch (Exception e) {
finish();
Toast.makeText(this, "Error occured. Please try again later.",
Toast.LENGTH_SHORT).show();
}
}
protected void startCameraActivity() {
outputFileUri = Uri.fromFile(sdImageMainDirectory);
Intent intent = new Intent("Android.media.action.IMAGE_CAPTURE");
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE:
{
if(resultCode==Activity.RESULT_OK)
{
try{
ImageView imageView=(ImageView)findViewById(R.id.cameraImage);
imageView.setImageBitmap((Bitmap) data.getExtras().get("data"));
}
catch (Exception e) {
// TODO: handle exception
}
}
break;
}
default:
break;
}
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
if (savedInstanceState.getBoolean(CameraCapture.PHOTO_TAKEN)) {
_taken = true;
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
outState.putBoolean(CameraCapture.PHOTO_TAKEN, _taken);
}
}
私は何か間違っていますか?
別の方法でやっています。 data.getData()フィールドはUriを返すことが保証されていないため、nullかどうかを確認しています。したがって、コードは次のようになります-
if(data.getData()==null){
bitmap = (Bitmap)data.getExtras().get("data");
}else{
bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), data.getData());
}
私は本番アプリケーションでこのコードを使用していますが、機能しています。
同様の問題がありました。マニフェストファイル内のいくつかの行をコメントアウトしていたため、サムネイルデータがnullとして返されました。
これを機能させるには、次のものが必要です。
<uses-permission Android:name="Android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission Android:name="Android.permission.CAMERA" />
<uses-feature Android:name="Android.hardware.camera" />
<uses-feature Android:name="Android.hardware.camera.autofocus" />
これで問題が解決することを願っています
お使いの携帯電話がサムスンの場合、これに関連している可能性があります http://kevinpotgieter.wordpress.com/2011/03/30/null-intent-passed-back-on-samsung-galaxy-tab/
別の 未解決の質問 があり、追加情報が得られる場合があります
ImageViewを使用してCamera Intentによって返されたビットマップを表示する場合、onSaveInstanceState内にimageview参照を保存し、後でonRestoreInstanceState内に復元する必要があります。以下のonSaveInstanceStateおよびonRestoreInstanceStateのコードを確認してください。
public class MainActivity extends Activity {
private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 1;
String mCurrentPhotoPath;
ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
imageView = (ImageView) findViewById(R.id.imageView1);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
setContentView(R.layout.activity_main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void startCamera(View v) throws IOException {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File photoFile = null;
photoFile = createImageFile();
//intent.putExtra(MediaStore.EXTRA_OUTPUT,Uri.fromFile(photoFile));
if (intent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
}
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE
&& resultCode == RESULT_OK) {
Bundle extras = data.getExtras();
Bitmap imageBitmap = (Bitmap) extras.get("data");
System.out.println(imageBitmap);
imageView.setImageBitmap(imageBitmap);
}
}
private File createImageFile() throws IOException {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss")
.format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = "file:" + image.getAbsolutePath();
System.out.println(mCurrentPhotoPath);
return image;
}
private void setPic() {
// Get the dimensions of the View
int targetW = imageView.getWidth();
int targetH = imageView.getHeight();
// Get the dimensions of the bitmap
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
// Determine how much to scale down the image
int scaleFactor = Math.min(photoW/targetW, photoH/targetH);
// Decode the image file into a Bitmap sized to fill the View
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
bmOptions.inPurgeable = true;
Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
imageView.setImageBitmap(bitmap);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
// TODO Auto-generated method stub
super.onSaveInstanceState(outState);
System.out.println(mCurrentPhotoPath);
imageView = (ImageView) findViewById(R.id.imageView1);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onRestoreInstanceState(savedInstanceState);
System.out.println(mCurrentPhotoPath);
imageView = (ImageView) findViewById(R.id.imageView1);
}
}
多くの検索の後:
private static final int TAKE_PHOTO_REQUEST = 1;
private ImageView mImageView;
String mCurrentPhotoPath;
private File photoFile;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_saisir_frais);
mImageView = (ImageView) findViewById(R.id.imageViewPhoto);
dispatchTakePictureIntent();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == TAKE_PHOTO_REQUEST && resultCode == RESULT_OK) {
// set the dimensions of the image
int targetW =100;
int targetH = 100;
// Get the dimensions of the bitmap
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(photoFile.getAbsolutePath(), bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
// Determine how much to scale down the image
int scaleFactor = Math.min(photoW/targetW, photoH/targetH);
// Decode the image file into a Bitmap sized to fill the View
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
bmOptions.inPurgeable = true;
// stream = getContentResolver().openInputStream(data.getData());
Bitmap bitmap = BitmapFactory.decodeFile(photoFile.getAbsolutePath(),bmOptions);
mImageView.setImageBitmap(bitmap);
}
}
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 = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = "file:" + image.getAbsolutePath();
return image;
}
private void dispatchTakePictureIntent() {
Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
try {
photoFile = createImageFile();
takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
startActivityForResult(takePhotoIntent, TAKE_PHOTO_REQUEST);
} catch (IOException e) {
e.printStackTrace();
}
}
次のコードを試してください
{
final String[] imageColumns = { MediaStore.Images.Media._ID,MediaStore.Images.Media.DATA };
final String imageOrderBy = MediaStore.Images.Media._ID + " DESC";
Cursor imageCursor = managedQuery(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, imageColumns, null, null, imageOrderBy);
imageCursor.moveToFirst();
do {
String fullPath = imageCursor.getString(imageCursor.getColumnIndex(MediaStore.Images.Media.DATA));
if (fullPath.contains("DCIM")) {
//get bitmap from fullpath here.
return;
}
}
while (imageCursor.moveToNext());
File cameraFile = null;
public void openChooser() {
Intent pickIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
cameraFile = new File(Android.os.Environment.getExternalStorageDirectory(), "temp.jpg");
takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(cameraFile));
String pickTitle = "Select or take a new Picture"; // Or get from strings.xml
Intent chooserIntent = Intent.createChooser(pickIntent, pickTitle);
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS,new Intent[]{takePhotoIntent});
startActivityForResult(chooserIntent, SELECT_PHOTO);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case SELECT_PHOTO:
if (resultCode == Activity.RESULT_OK) {
Uri selectedImage = data.getData();
if (selectedImage != null) {
//from gallery
} else if (cameraFile != null) {
//from camera
Uri cameraPictureUri = Uri.fromFile(cameraFile);
}
}
break;
}
}
カメラインテントに送信するファイルからビットマップを生成できます。このコードを使用してください...
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data){
switch (requestCode) {
case CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE:
{
if(resultCode==Activity.RESULT_OK)
{
int orientation = getOrientationFromExif(sdImageMainDirectory);// get orientation that image taken
BitmapFactory.Options options = new BitmapFactory.Options();
InputStream is = null;
Matrix m = new Matrix();
m.postRotate(orientation);//rotate image
is = new FileInputStream(sdImageMainDirectory);
options.inSampleSize = 4 //(original_image_size/4);
Bitmap bitmap = BitmapFactory.decodeStream(is,null,options);
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
bitmap.getHeight(), m, true);
// set bitmap to image view
//bitmap.recycle();
}
break;
}
default:
break;
}
}
private int getOrientationFromExif(String imagePath) {
int orientation = -1;
try {
ExifInterface exif = new ExifInterface(imagePath);
int exifOrientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
switch (exifOrientation) {
case ExifInterface.ORIENTATION_ROTATE_270:
orientation = 270;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
orientation = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_90:
orientation = 90;
break;
case ExifInterface.ORIENTATION_NORMAL:
orientation = 0;
break;
default:
break;
}
} catch (IOException e) {
//Log.e(LOG_TAG, "Unable to get image exif orientation", e);
}
return orientation;
}
このチュートリアルをお試しください。それは私のために機能し、マニフェストで通常どおり許可を使用し、許可を確認します
たくさんの精力的な研究の後、私は最終的に結論に達しました。これを行うには、キャプチャした画像を外部ストレージに保存する必要があります。そして、アップロード中に取得します。この方法では、画像解像度は低下せず、NullPointerExceptionも発生しません!タイムスタンプを使用してファイルに名前を付けたため、毎回一意のファイル名を取得します。
private void fileChooser2() {
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
Intent intent=new Intent(Android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
File pictureDirectory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
String pictureName=getPictureName();
fi=pictureName;
File imageFile=new File(pictureDirectory,pictureName);
Uri pictureUri = Uri.fromFile(imageFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT,pictureUri);
startActivityForResult(intent,PICK_IMAGE_REQUEST2);
}
ファイル名を作成する関数:
private String getPictureName() {
SimpleDateFormat adf=new SimpleDateFormat("yyyyMMdd_HHmmss");
String timestamp = adf.format(new Date());
return "The New image"+timestamp+".jpg";//give a unique string so that the imagename cant be overlapped with other apps'image formats
}
およびonActivityResult:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode==PICK_IMAGE_REQUEST2 && resultCode==RESULT_OK )//&& data!=null && data.getData()!=null)
{
final ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog.setTitle("Uploading");
progressDialog.show();
Toast.makeText(getApplicationContext(),"2",Toast.LENGTH_SHORT).show();
File picDir=Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File imageFile=new File(picDir.getAbsoluteFile(),fi);
filePath=Uri.fromFile(imageFile);
try {
}catch (Exception e)
{
e.printStackTrace();
}
StorageReference riversRef = storageReference.child(mAuth.getCurrentUser().getUid()+"/2");
riversRef.putFile(filePath)
.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
@Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
progressDialog.dismiss();
Toast.makeText(getApplicationContext(), "File Uploaded ", Toast.LENGTH_LONG).show();
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception exception) {
progressDialog.dismiss();
Toast.makeText(getApplicationContext(), exception.getMessage(), Toast.LENGTH_LONG).show();
}
})
.addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
@Override
public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
double progress = (100.0 * taskSnapshot.getBytesTransferred()) / taskSnapshot.getTotalByteCount();
progressDialog.setMessage("Uploaded " + ((int) progress) + "%...");
}
});
お役に立てれば :)
編集:カメラに許可を与え、マニフェストのストレージに書き込みと読み取りを許可します。