I just started using Android Studio to develop an experimental application. My current problem in trying to get one of my navigation bar tabs set to a camera tab so that when pressed, the camera opens, user takes a picture, then the program does something with that picture. However, when I tried to set the tab as a camera, the program immediately crashes after clicking on the tab. I have this portion of the code currently set as my Main for that specific tab.
case R.id.navigation.dashboard:
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
startActivity(intent);
return true;
Should I use a button as an alternative?
EDIT: changed title and some details to the question for more clarification
EDIT2: Got the problem fixed, thanks! The problem for me was actually not checking for app permissions manually via the app info even though I had these permission scripts on the XML file already.
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
So I forgot to add a permission popup on my program.
Couple of thing are wrong with this:
Why use tabs for camera if you are just going to use an intent for the camera picture.
The intent should look something like this:
Note: imageUri should be set here to be used later
void takePhoto(View view) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File photo = new File(Environment.getExternalStorageDirectory(), "image.jpg");
intent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photo));
imageUri = Uri.fromFile(photo);
startActivityForResult(intent, TAKE_PICTURE);
}
Since starting an activity for result you need to declare a variable TAKE_PICTURE:
private static final int TAKE_PICTURE = 123
Maybe you want to use tab for showing the picture, and that can look like this:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case TAKE_PICTURE:
if (resultCode == Activity.RESULT_OK) {
Uri selectedImage = imageUri;
getContentResolver().notifyChange(selectedImage, null);
Bitmap bitmap;
try {
bitmap = android.provider.MediaStore.Images.Media
.getBitmap(getContentResolver(), selectedImage);
// show image here in an imageView
} catch (Exception e) {
Log.e("Camera", e.toString());
}
}
}
}
If you don't want to open new Activity you can use CameraX library.
Here you have nice sample how to use it.
Related
I have some troubles to display images in OpenGL.
Actually I'm able to display images from gallery in opengl. The problem occurs when I try to show one from the camera.
For me, OpenGL have to display the image from the camera as it does with the gallery ones. Obviously I'm making something wrong.
Any help will be appreciated.
Intent from gallery:
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
intent.setType("image/");
startActivityForResult(intent, 2);
Intent from camera:
Intent takePic = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePic.resolveActivity(getPackageManager()) != null) {
File imagen = controler.createPhotoFile(getExternalFilesDir(Environment.DIRECTORY_PICTURES));
if (imagen != null) {
photoUri = FileProvider.getUriForFile(this, "my.fileprovider", imagen);
takePic.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
startActivityForResult(takePic, 1);
}
}
This is my onActivityResult where I send the URI to a method which convert it to a bitmap and send it.
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
switch (requestCode) {
case 1:
sendImagenPanel(photoUri);
break;
case 2:
sendImagenPanel(data.getData());
break;
}
}
}
private void sendImagenPanel(Uri uri) {
Bitmap bitmap = null;
try {
bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), uri);
} catch (IOException e) {
e.printStackTrace();
}
final Bitmap imagen = controler.getCroppedBitmap(controler.scaledBitmap(bitmap, 256));
final CasillaOG casilla = ((GLSurfacePanel) gLViewPanel).getRendererPanel().getCuboSelected();
gLViewPanel.queueEvent(new Runnable() {
#Override
public void run() {
casilla.loadNewTexture(imagen);
casilla.setImagen(imagen);
}
});
gLViewPanel.requestRender();
}
In case someone is interested. I realize that the problem is not on the method that calls OpenGL. If I run the same code on the onActivityResult works from the gallery requestCode but not on the camera one, in my Samsung Galaxy Tab A. Why I mention my device? because if I run the app on a Huawei P9 lite, the gallery images are not display either. In both cases appears the next problem on the console:
call to opengl es api with no current context (logged once per thread)
After search that problem, I suppose that the intents of the camera and gallery use OpenGL and its originate a conflict with my own OpenGL environment.
Finally, I opted to set a bitmap field and add the texture in on the onDrawFrame. Obviously, with a boolean to make it one time.
One feature of my app includes the camera. The user takes a picture and the app displays the image.
I start an intent with ACTION_IMAGE_CAPTURE using StartActivityForResult and capture the response with onActivityResult. Usually I can simply call getData() on the intent I receive in onActivityResult and get the content uri for the MediaProvider.
My problem is the following: One one of my test devices, a Huawei ALE-L21, the intent I get in onActivityResult has no data, but instead, it has a parcellable extra. How could I get the users photo from that? Android Studio doesn't tell me the name of the parcellable extra either
Disclaimer: I call getActivity() because I'm using this code in a fragment
This is what I use to get the camera.
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getActivity().getPackageManager()) != null) {
startActivityForResult(takePictureIntent, getResources().getInteger(R.integer.RQ_PERMISSION_WRITE_EXTERNAL_STORAGE));
}
And here's the code in my onActivityResult
#Override
public void onActivityResult(int requestCode, int resultCode, Intent resultIntent) {
super.onActivityResult(requestCode, resultCode, resultIntent);
switch (requestCode) {
case 1: //RQ_ImageCapture
case 2: //RQ_ImageSelected
if (resultIntent != null) {
try {
Uri selectedImage = resultIntent.getData();
if(selectedImage != null) {
Bitmap bitmap =
MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(), selectedImage);
setImageAsBackground(selectedImage, bitmap);
}
} catch (IOException e) {
e.printStackTrace();
}
}
break;
}
}
Usually I can simply call getData() on the intent I receive in onActivityResult and get the content uri for the MediaProvider.
Your code will fail on many of them, including all recent Nexus devices. ACTION_IMAGE_CAPTURE is not supposed to return a Uri. Quoting the documentation:
If the EXTRA_OUTPUT is not present, then a small sized image is returned as a Bitmap object in the extra field. This is useful for applications that only need a small image. If the EXTRA_OUTPUT is present, then the full-sized image will be written to the Uri value of EXTRA_OUTPUT.
Since you are not including EXTRA_OUTPUT, you will get a data extra (getData().getExtra("data")) with a thumbnail image.
the intent I get in onActivityResult has no data, but instead, it has a parcellable extra
Given your ACTION_IMAGE_CAPTURE request, that is what you are supposed to get.
If you want a full-size image, include EXTRA_OUTPUT, perhaps pointing to a FileProvider in your app, such as I demonstrate in this sample app. Then, you know the Uri where the photo should go, because you specified that Uri.
I want to display the image when I click on the photo and want to set in my ImageView without user select yes or not....
I had searched for it and I also know it very well that the camera app itself gives you the ability to review/retake the image, and once an image is accepted, the activity displays it. But, I want to do it without review/retake the activity display it.....
I am trying this code fine
Initialise
Uri mImageCaptureUri;
For Click on Button
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_SCREEN_ORIENTATION, ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
File file = new File(Environment.getExternalStorageDirectory(),
"tmp_avatar_" + String.valueOf(System.currentTimeMillis()) + ".jpg");
mImageCaptureUri = Uri.fromFile(file);
try {
intent.putExtra(MediaStore.AUTHORITY, true);
intent.putExtra("return-data", true);
intent.putExtra(MediaStore.EXTRA_OUTPUT, mImageCaptureUri);
startActivityForResult(intent, PICK_FROM_CAMERA);
} catch (Exception e) {
e.printStackTrace();
}
onActivityResult
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
Bitmap bitmap = null;
mPath = mImageCaptureUri.getPath();
System.out.println("THE PAtH:_" + mPath);
BitmapFactory.Options o2 = new BitmapFactory.Options();
bitmap = BitmapFactory.decodeFile(mPath, o2);
ivSelfie.setImageBitmap(bitmap);
}
When I am Click the Photo Than I am Take this screen to select yes or not......
But My requirement is not select review/retake task and direct set to ImageView on activity display when just click and set.....
Actually it's quite useful to have confirmation of taken picture. But, in case if you really don't want to have it, you have to use SurfaceView inside your app and show camera stream here. There is tones of example how to do it, for example consider to check that one.
Use method setImageURI() it will get the bitmap from the uri and set it for you.
Yes it will set the image weather the user press ok or cancel no matter because your file exists on your given path while launching intent.
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == PICK_FROM_CAMERA) {
// only one line code
ivSelfie.setImageURI(mImageCaptureUri);
}
}
You cannot avoid that screen. The reason is that when you use new MediaStore.ACTION_IMAGE_CAPTURE you are using a different camera application for clicking image. Showing this screen might be the default functionality of the. This screen will be different in different devices depending upon the camera application.
So to get rid of this the only thing you can do is to implement your custom camera instead of using default camera application.
As per default camera app you can't breach that functionality. Instead of, you can use SurfaceView to capture image inside you application. Please have a look at this answer thread.
May be this link will help you.
Thank you
Use "android.intent.extra.quickCapture" for your picture intent.
// File ImagePickerModule.java#248
cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra("android.intent.extra.quickCapture",true);
See https://github.com/react-native-community/react-native-image-picker/issues/647 for details.
I am making an android album app where I can create an album and add photos and delete photos from the album. Adding a photo is a bit tricky where I need a photo filename with a file path. This was very easy using JFileChooser in java but this is android and I have no clue on getting the filename and file path. Is there any thing in the android api where I can get the same functionality as the JFileChooser.
I am looking for a solution to this problem either using a file chooser of some sort or an entire to new approach. Any help is appreciated..
Or is there any other approach I can implement to add a photo...
You may use Intent.ACTION_PICK to invoke an image picker. This intent may be caught by the default gallery app, or some other app installed on the device.
private static final int REQUEST_PICKER = 1;
private void invokePicker() {
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
intent.setType("image/*");
startActivityForResult(Intent.createChooser(intent, "Complete action using"), REQUEST_PICKER);
}
Then receive the result on onActivityResult.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode != RESULT_OK)
return;
if (requestCode == PICK_FROM_FILE) {
// Get Uri of the file selected,
Uri theImageUri = data.getData();
// Or if you want a Bitmap,
Bitmap theBitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), theImageUri);
}
}
Edited:
Though in this way you don't need a real file path, you can get it from MediaStore if you need.
If a user has an external camera app, such as camera+ that is set as their camera default, how do I make sure that after capturing a photo, it will go back to my original application activity?
public void onClick(View v) {
switch (v.getId()){
case R.id.photo_camera_button:
Intent photoIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(photoIntent, CAMERA_PHOTO_REQUEST);
break;
}
}
protected void onActivityResult(int requestCode, int resultCode, Intent data){
super.onActivityResult(requestCode, resultCode, data);
if(resultCode == RESULT_OK){
if(requestCode == CAMERA_PHOTO_REQUEST){
Bundle extras = data.getExtras();
Bitmap bmp = (Bitmap) extras.get("data");
ImageView imv = (ImageView) findViewById(R.id.ReturnedImageView);
imv.setImageBitmap(bmp);
}
}
}
This application is supposed to capture an image and send it back to an imageview, but after capturing a photo, the camera application is still there. I would like it to go back, or would I have to set up from scratch a new camera application?
Although, I would like it to use camera+ features and then when the user saves the image (typically it'll go to my SDcard, I believe) it'll kill the app, and then go back to my activity? Maybe override something?
Any help? Thank you!
What your asking is very hard to answer as i dnt know weather your third party app provide the feature of throwing back the result .You question could be answered properly if you have code of that third party app / see the doc weather they offer there app to be used by some third party
And developing new camera app by your self is not a such big task .