I am creating an app which captures image from camera and saves image in a file. In onActivityResult() method i am getting null object reference error.
My Fragment class is here:
public class HomeFragment extends Fragment {
private static final int REQUEST_IMAGE_CAPTURE = 1;
private static final String JPEG_FILE_PREFIX = "IBR_";
private static final String JPEG_FILE_SUFFIX = ".jpg";
File photoFile = null;
ImageButton camera_button;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_home, container, false);
camera_button = (ImageButton) rootView.findViewById(R.id.camera);
camera_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (cameraIntent.resolveActivity(getActivity().getPackageManager()) != null) {
// Create the File where the photo should go
try {
photoFile = createImageFile();
} catch (IOException ex) {
// Error occurred while creating the File
Log.i("File error", "File");
}
}
// Continue only if the File was successfully created
if (photoFile != null) {
Uri fileUri = Uri.fromFile(photoFile);
cameraIntent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT,
fileUri);
Toast.makeText(getActivity(), photoFile.toString(), Toast.LENGTH_SHORT).show();
startActivityForResult(cameraIntent, REQUEST_IMAGE_CAPTURE);
}
}
});
return rootView;
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == Activity.RESULT_OK) {
Bundle extras = data.getExtras();
Bitmap imageBitmap = (Bitmap) extras.get("data");
camera_button.setImageBitmap(imageBitmap);
}
}
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = JPEG_FILE_PREFIX + timeStamp + "_";
File storageDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES);
File imageF = File.createTempFile(imageFileName, JPEG_FILE_SUFFIX, storageDir);
return imageF;
}
}
Actually i am getting error in this line Bundle extras = data.getExtras();
Any suggestion how can i solve this problem?
If you specify MediaStore.EXTRA_OUTPUT then no thumb pick is returned in intent extra - in activityOnResult - you have to read manually filepath you have provided as MediaStore.EXTRA_OUTPUT.
You can read in docs for ACTION_IMAGE_CAPTURE:
The caller may pass an extra EXTRA_OUTPUT to control where this image will be written. *If the EXTRA_OUTPUT is not present, then a small sized image is returned as a Bitmap object in the extra field.
Related
I'm using the android documentation:
training/camera/photobasics
and this is the code implementing:
public class CFoto extends AppCompatActivity {
private ImageView img;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cfoto);
img = findViewById(R.id.imageView);
if (ContextCompat.checkSelfPermission(CFoto.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(CFoto.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(CFoto.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA}, 1000);
}
}
//Create unic name
String mCurrentPhotoPath;
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "Backup_" + timeStamp + "_";
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(imageFileName, ".jpg", storageDir);
mCurrentPhotoPath = image.getAbsolutePath();
return image;
}
//take foto
static final int REQUEST_TAKE_PHOTO = 1;
public void tomarFoto(View view) {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
}
if (photoFile != null) {
Uri photoURI = FileProvider.getUriForFile(this, "com.example.android.fileprovider", photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI.toString());
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
}
}
}
//preview image
static final int REQUEST_IMAGE_CAPTURE = 1;
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
Bundle extras = data.getExtras();
Bitmap imageBitmap = (Bitmap) extras.get("data");
img.setImageBitmap(imageBitmap);
}
}
}
the camera is working and saves the photo locally
What should I change to save the photo in a database?
in the database I have assigned the longblob format for the image
the database is remote
You can save the path of your photo in your database or convert it to base64 and then save it .
I think this post can help you :Take picture and convert to Base64
I am trying to capture an image and go to next intent with the image. This following code going to Camera Intent. But not going to second intent. Its returning java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=0, result=-1, data=null} to activity error. that means there is no data going to onResultActivity. If I put data!=null in the argument then its returning to 1st Activity. What I am missing? I have tested the mCurrentPhotoPath. Its returning the filePath.
String shopName;
double latitude, longitude;
private int REQUEST_IMAGE_CAPTURE = 0;
private Bitmap imageBitmap;
String mCurrentPhotoPath;
static final int REQUEST_TAKE_PHOTO = 0;
private File createImageFile() throws IOException {
// Create an image file name
#SuppressLint("SimpleDateFormat") 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;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnNext = (Button)findViewById(R.id.btnNext);
btnNext.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
// Error occurred while creating the File
}
if (photoFile != null) {
//Toast.makeText(getApplicationContext(), "OK", Toast.LENGTH_LONG).show();
Uri photoURI = FileProvider.getUriForFile(MainActivity.this,
"com.marketaccess.data.collector.fileprovider",
photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode != RESULT_CANCELED) {
Uri filePath = data.getData();
Bitmap bitmap = null;
try {
bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), filePath);
} catch (IOException e) {
e.printStackTrace();
}
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 50, stream);
byte[] imageResource = stream.toByteArray();
Intent sendDataIntent = new Intent(MainActivity.this, SendData.class);
Bundle extras = new Bundle();
sendDataIntent.putExtras(extras);
sendDataIntent.putExtra("imageResource", imageResource);
startActivity(sendDataIntent);
}
}
I have tested the Manifest fileprover block. It seems like ok and returing path.
I have an activity where I want the user to press a view and take a picture several places and theyre then inserted for each place he "presses". Like a photo folder.
So I have made a class to handle taking a picture and making a bitmap.
But I cannot figure out how to decode the bitmap in the activity I need it, I just get a static cannot be referenced from non-static error, because Im not instantiating it properly I guess.
Heres my approach:
case R.id.pButton2:
new CameraActivity();
Bitmap bitmap = BitmapFactory.decodeStream(CameraActivity.openFileInput("myImage"));
mImageView = (ImageView)findViewById(R.id.imageView2);
mImageView.setImageBitmap(bitmap);
mImageView.setRotation(180);
mImageView.setVisibility(View.VISIBLE);
break;
Calling this class:
public class CameraActivity extends Activity{
private String mCurrentPhotoPath;
private ImageView mImageView;
private Bitmap mImageBitmap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
dispatchTakePictureIntent();
}
public void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
// Error occurred while creating the File
System.out.println("ERR CANNOT CREATE FILE");
}
// Continue only if the File was successfully created
if (photoFile != null) {
Uri photoURI = FileProvider.getUriForFile(this,
"com.example.android.fileprovider",
photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
}
}
}
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 = "file:" + image.getAbsolutePath();
return image;
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
try {
mImageBitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), Uri.parse(mCurrentPhotoPath));
createImageFromBitmap(mImageBitmap);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public String createImageFromBitmap(Bitmap bitmap) {
String fileName = "myImage";//no .png or .jpg needed
try {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
FileOutputStream fo = openFileOutput(fileName, Context.MODE_PRIVATE);
fo.write(bytes.toByteArray());
// remember close file output
fo.close();
} catch (Exception e) {
e.printStackTrace();
fileName = null;
}
return fileName;
}
}
Im using a sample from this; how do you pass images (bitmaps) between android activities using bundles?
Delete new CameraActivity().
Most likely, you can then replace:
Bitmap bitmap = BitmapFactory.decodeStream(CameraActivity.openFileInput("myImage"));
with:
Bitmap bitmap = BitmapFactory.decodeStream(openFileInput("myImage"));
since this case seems to be UI code and therefore probably is in an activity already. If it is in a fragment, use getActivity().openFileInput(). If it is somewhere else use mImageView.getContext().openFileInput().
I'm trying to take a photo with the camera and in the activity result method I want to save it and launch a new activity to display the photo from where I saved it, but the imageView stay empty, I used the code from android developer
and here is my code:
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException e) {
e.printStackTrace();
}
// Continue only if the File was successfully created
if (photoFile != null) {
Uri photoURI = FileProvider.getUriForFile(this,
"com.example.android.fileprovider",
photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
}
}
}
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 = "file:" + image.getAbsolutePath();
return image;
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode,resultCode,data);
if (requestCode == REQUEST_TAKE_PHOTO && resultCode == RESULT_OK) {
//Bundle extras = data.getExtras();
// Bitmap imageBitmap =(Bitmap) extras.get("data");
Intent formIntent= new Intent(MainActivity.this,FormActivity.class);
// formIntent.putExtra("img",imageBitmap);
formIntent.putExtra("path",mCurrentPhotoPath);
startActivity(formIntent);
}
}
the activity that shoud display the photo
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_form);
String path = getIntent().getStringExtra("path");
mImageView = (ImageView) findViewById(R.id.imageView);
File imgFile = new File(path);
Toast.makeText(this, path, Toast.LENGTH_LONG).show();
if(imgFile.exists()){
Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
mImageView.setImageBitmap(myBitmap);
}
}
So, I have an app where I want to take a picture, store it to internal storage, and then be able to retrieve it later (presumably via its Uri). Here is what I have thus far:
This code is triggered when my custom camera button is pressed.
cameraButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final Intent takePic = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File file = herp(MEDIA_TYPE_IMAGE);
if (file != null) {
fileUri = getOutputMediaFileUri(file);
Log.d("AddRecipeActivity", fileUri.toString());
takePic.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
startActivityForResult(takePic, CAMERA_REQUEST);
}
}
});
Next, I've defined two methods later on in the code(mostly taken from the android developer site):
/** Create a file Uri for saving an image or video */
private static Uri getOutputMediaFileUri(File file){
return Uri.fromFile(file);
}
/** Create a File for saving an image or video */
public File herp(int type){
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
Boolean a = false;
String externalDirectory= getFilesDir().getAbsolutePath();
File folder= new File(externalDirectory + "/NewFolder");
// This location works best if you want the created images to be shared
// between applications and persist after your app has been uninstalled.
// Create the storage directory if it does not exist
if (!folder.exists()){
a = folder.mkdirs();
Log.d("AddRecipeActivity", String.valueOf(a));
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE){
mediaFile = new File(folder.getPath() + File.separator +
"IMG_"+ timeStamp + ".jpg");
} else {
return null;
}
if(mediaFile == null){
Log.d("AddRecipeActivity", "Media file is null");
}
return mediaFile;
}
When I print my Uri (right before triggering the intent) I get the following output.
04-04 04:22:40.757 22402-22402/scissorkick.com.project2 D/AddRecipeActivity: file:///data/user/0/scissorkick.com.project2/files/NewFolder/IMG_20160404_042240.jpg
Also, when I check if the directory is made, the boolean is true.
When my camera intent's onActivityResult is run, however, the result code is 0.
Why might it fail at this point? I've defined the appropriate permissions in the manifest, and also request external storage write permissions during run time.
Edit: Added the onActivityResult:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data){
if(requestCode == CAMERA_REQUEST){
Log.d("AddRecipe", String.valueOf(resultCode));
if(resultCode == RESULT_OK){
photo = (Bitmap) data.getExtras().get("data");
thumb = ThumbnailUtils.extractThumbnail(photo, 240, 240);
photoView.setImageBitmap(thumb);
//Toast.makeText(getApplicationContext(), "image saved to:\n" + data.getData(), Toast.LENGTH_SHORT).show();
}
else{
Toast.makeText(getApplicationContext(), "Fail", Toast.LENGTH_SHORT).show();
}
}
}
There's some nonsense code in the onActivityResult, but the point is that the resultCode = 0 and I don't know why.
In your final activity, put the below code
data.putExtra("uri", uri);//uri = your image uri
getActivity().setResult(""result_code", data);
getActivity().finish();
Then in your onActivityResult code you can get the uri like
Uri uri = data.getExtras().getParcelable("uri");
Then you can use this Uri value to retrieve your image.
There is how i take picture in my app!
When i press my own Image Button
static final int REQUEST_IMAGE_CAPTURE = 1;
static final int REQUEST_TAKE_PHOTO = 1
static final String STATE_PHOTO_PATH = "photoPath";
ImageButton photoButton = (ImageButton) this.findViewById(R.id.take_picture_button);
photoButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dispatchTakePictureIntent();
}
});
And here how manage and create/store the file with image
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;
}
//Create a new empty file for the photo, and with intent call the camera
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException e) {
// Error occurred while creating the File
Log.e("Error creating File", String.valueOf(e.getMessage()));
}
// Continue only if the File was successfully created
if (photoFile != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photoFile));
//I have the file so now call the Camera
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
}
}
}
private void openImageReader(String imagePath) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
Uri imgUri = Uri.parse(imagePath);
intent.setDataAndType(imgUri, "image/*");
startActivity(intent);
}
In the ActivityResult i only save a record in DB, with the Path of the image so i can retrieve it back and read the photo stored like file.
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
//Save the path of image in the DB
db.addCompito(new Compiti(activity_name, null, mCurrentPhotoPath));
refreshListView();
}
}
If you have some screen rotation don't forget to add something like
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// Save the user's current game state
savedInstanceState.putString(STATE_PHOTO_PATH, mCurrentPhotoPath);
// Always call the superclass so it can save the view hierarchy state
super.onSaveInstanceState(savedInstanceState);
}
public void onRestoreInstanceState(Bundle savedInstanceState) {
// Always call the superclass so it can restore the view hierarchy
super.onRestoreInstanceState(savedInstanceState);
// Restore state members from saved instance
mCurrentPhotoPath = savedInstanceState.getString(STATE_PHOTO_PATH);
}
WHY?
Because when the rotation change you can lose the file that you have created for the "new photo" and when you accept it and save it, your photopath is null and no image is created.