I'm trying to take a picture with the back camera and then get it's bytes in a serice I am using this code:
Camera camera = Camera.open();
SurfaceView view = new SurfaceView(getApplicationContext());
SurfaceHolder holder = view.getHolder();
camera.getParameters().setPreviewSize(1, 1);
camera.setPreviewDisplay(holder);
camera.startPreview();
camera.takePicture(null, pictureCallback, null);
But it is not working. I am not getting an exception but pictureCallback is never being called.
Taken from the android docs: http://developer.android.com/training/camera/photobasics.html
You should call the camera intent like this:
First add the necessary permissions to your app in the androidmanifest file:
<manifest ... >
<uses-feature android:name="android.hardware.camera"
android:required="true" />
...
</manifest>
After that call the corresponding intent to start the camera:
static final int REQUEST_IMAGE_CAPTURE = 1;
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
The data you receive from the camera will be called in the following method, where you will be able to store or use it as you wish:
#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");
mImageView.setImageBitmap(imageBitmap);
}
}
In case you want to implement this in a service, taking the code from this link, you should be able to take a picture from a service:
mPreview = new CameraPreview(this, mCamera, jpegCallback);
WindowManager wm = (WindowManager) this
.getSystemService(Context.WINDOW_SERVICE);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
PixelFormat.TRANSPARENT);
params.height = 1;
params.width = 1;
wm.addView(mPreview, params);
As stated by the comments, please note that this needs the permission SYSTEM_ALERT_WINDOW to work, users might not want to allow an App to use this permission.
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.
i'm writing an android app on java and need to let my users select and crop images from the gallery.
There is no problem when choosing an image from any native gallery, but when a user chooses to eater crop or choose an image from google photos app the app crushes.
I cannot figure out what is the source of the problem so any answer will be helpful
this is the code i'm using
class fields:
private Uri imageUri;
opening the camera:
private void camOpen() {
Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File f = new File(Environment.getExternalStorageDirectory(), "file" + String.valueOf(System.currentTimeMillis()) + ".png");
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
imageUri = Uri.fromFile(f);
i.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
i.putExtra("return-data", true);
startActivityForResult(i, CAMERA_CODE);
}
opening the gallery:
private void galleryOpen() {
Intent i = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(Intent.createChooser(i, "select file"), SELECT_PHOTO_CODE);
}
cropping the image:
private void cropImage() {
try {
Intent cropIntent = new Intent("com.android.camera.action.CROP");
cropIntent.setDataAndType(imageUri, "image/*");
cropIntent.putExtra("crop", true);
cropIntent.putExtra("aspectX", 1);
cropIntent.putExtra("aspectY", 1);
cropIntent.putExtra("return-data", true);
startActivityForResult(cropIntent, CROP_CODE);
} catch (Exception e) {}
}
the result handler:
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CAMERA_CODE && resultCode == Activity.RESULT_OK) {
cropImage();
} else if (requestCode == SELECT_PHOTO_CODE && resultCode == Activity.RESULT_OK) {
if (data != null) {
imageUri = data.getData();
cropImage();
}
} else if (requestCode == CROP_CODE && resultCode == Activity.RESULT_OK) {
Bundle bundle = data.getExtras();
Bitmap b = bundle.getParcelable("data");
hasImageChanged=true;
ivProfilePic.setImageBitmap(b);
capturedImage = b;
}
}
thank you for any useful help...
Android does not support crop intent because croping is not part of android api.
So i recommend you for Using library
the issue was with the crop intent. I ended up using the uCrop library and it fixed the problem.
This show the box with the applications to choose an image or take a picture with camera. If I select Camera this let me to take a picture but there is no return or save option. I updated my answer posting the activity result code.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
switch (requestCode)
{
case 1:
if (data != null)
{
Log.e("TAG", "Only called when a image from gallery is selected");
}
else
{
Log.e("TAG", "Data is null");
}
break;
}
}
private void ChooseImage()
{
// Create gallery intent
Intent _intentGallery = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
_intentGallery.setAction(Intent.ACTION_PICK);
_intentGallery.putExtra("return-data", true);
// startActivityForResult(_intentGallery, 1);
// Create camera intent
Intent galleryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
// Create chooser
Intent chooser = Intent.createChooser(galleryIntent, getString(R.string.choose_an_application));
// Create list of gallery intents
List<Intent> galleryIntents = new ArrayList<Intent>();
// Add intents to list
PackageManager pm = getApplicationContext().getPackageManager();
for (ResolveInfo ri: pm.queryIntentActivities(_intentGallery, PackageManager.MATCH_DEFAULT_ONLY))
{
Intent intent = pm.getLaunchIntentForPackage(ri.activityInfo.packageName);
intent.setAction(Intent.ACTION_PICK);
intent.putExtra("return-data", true);
galleryIntents.add(intent);
}
// Show dialog
chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, galleryIntents.toArray(new Parcelable[] {}));
startActivityForResult(chooser, 1);
}
Manifest permissions:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET" />
You have to implement onActivityResult. Then you can get data.
#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");
mImageView.setImageBitmap(imageBitmap);
}
}
In this case, REQUEST_IMAGE_CAPTURE is 1 as you defined it, so change it to 1.
Don't forget the manifest rule uses-feature.
See more: https://developer.android.com/training/camera/photobasics.html
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 6 years ago.
Hey so I have been trying to fix this problem for a couple of hours and checked a lot of the other questions extensively in an attempt to remedy this problem.
So in my Main Activity I have two activities that both either grabs an image from the gallery or is a photo depending on the button
public void DoTakePhoto(View v) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(intent, TAKE_PICTURE);
}
}
public void DoShowSelectImage(View v) {
Intent i = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, SELECT_PICTURE);
}
So I know the problem likes on my onActivityResult where the data seems to be null I tried using the super so it gets back the lost activity or checking to see if data is
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == SELECT_PICTURE || requestCode == TAKE_PICTURE && null != data) {
if (resultCode == RESULT_OK && null != data) {
Uri selectedimage = data.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(selectedimage, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
mImageFullPathAndName = cursor.getString(columnIndex);
cursor.close();
jobID = "";
File file = new File(mImageFullPathAndName);
Bitmap mCurrentSelectedBitmap = decodeFile(file);
if (mCurrentSelectedBitmap != null) {
ivSelectedImg.setImageBitmap(mCurrentSelectedBitmap);
int w = mCurrentSelectedBitmap.getWidth();
int h = mCurrentSelectedBitmap.getHeight();
int length = (w > h) ? w : h;
if (length > OPTIMIZED_LENGTH) {
float ratio = (float) w / h;
int newW, newH = 0;
if (ratio > 1.0) {
newW = OPTIMIZED_LENGTH;
newH = (int) (OPTIMIZED_LENGTH / ratio);
} else {
newH = OPTIMIZED_LENGTH;
newW = (int) (OPTIMIZED_LENGTH * ratio);
}
mCurrentSelectedBitmap = rescaleBitmap(mCurrentSelectedBitmap, newW, newH);
}
mImageFullPathAndName = SaveImage(mCurrentSelectedBitmap);
}
}
}
}
So my Error
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1, result=-1, data=Intent { act=inline-data (has extras) }} to activity {com.example.zola.capchem/com.example.zola.capchem.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.net.Uri.getScheme()' on a null object reference
I have tried most of the things on this site but the app still ends up crashing. No clue what to do here.
Your code would crash if you try to take a picture from the camera.
The method for taking a photo via camera and obtaining a photo from the gallery/file system is quite different.
For doing both, you fire an intent with an ACTION and some extras. You launch an activity for a result with this intent. The result is returned to you in onActivityResult() via the intent passed to it.
However, the result stored in the returned intent is different for both cases.
1) Taking a photo through camera: The bitmap itself of the image taken is returned to you, as an extra in the intent bundle. You can access it as:
Bundle extras = data.getExtras();
Bitmap bitmap = (Bitmap) extras.get("data");
//use bitmap however you like...
2) Select a photo from gallery: You may or may not get a URI of the selected image (via data.getUri()). In case you get an URI, you can obtain your image through that URI. However, this uri may be null sometimes, in which case the android system has chosen to write the image on to the image URI that you had passed as an intent extra while launching the activity for result.
Hence, first, define a temporary URI and use it to launch the activity to select image from gallery:
private URI getTempFile()
{
if (isExternalStorageWritable())
{
File file = new File(Environment.getExternalStorageDirectory(), "temporary_file.jpg");
try
{
if(!file.exists())
{
file.createNewFile();
}
} catch (IOException e)
{
}
return Uri.fromFile(file);
} else
{
return null;
}
}
public void DoShowSelectImage(View v) {
Intent i = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
i.putExtra(MediaStore.EXTRA_OUTPUT, getTempFile());
startActivityForResult(i, SELECT_PICTURE);
}
and inside your onActivityResult:
Uri selectedimage = data.getData();
if(selectedimage == null)
{
selectedimage = getTempFile();
}
You need to handle both these cases seperately in your onActivityResult:
if(result == RESULT_OK && data != null)
{
Bitmap mCurrentSelectedBitmap;
if(requestCode == SELECT_PICTURE)
{
Uri selectedimage = data.getData();
if(selectedimage == null)
{
selectedimage = getTempFile();
}
......
......
mCurrentSelectedBitmap = decodeFile(file);
}
else if(requestCode == TAKE_PICTURE)
{
Bundle extras = data.getExtras();
mCurrentSelectedBitmap = (Bitmap) extras.get("data");
}
.......
.......
//Do your thing
}
NOTE: you might need to add permission in your manifest to write to external storage
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
I currently have an activity that hosts multiple fragments and I am on my third fragment of a collection.
In that fragment I use an Intent to launch either the Camera or Gallery. See code:
public Intent getImageIntent() {
// Camera.
final List<Intent> cameraIntents = new ArrayList<Intent>();
final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
final PackageManager packageManager = context.getPackageManager();
final List<ResolveInfo> listCam = packageManager.queryIntentActivities(captureIntent, 0);
for (ResolveInfo res : listCam) {
final String packageName = res.activityInfo.packageName;
final Intent intent = new Intent(captureIntent);
intent.setComponent(new ComponentName(res.activityInfo.packageName,
res.activityInfo.name));
intent.setPackage(packageName);
cameraIntents.add(intent);
}
// Filesystem.
final Intent galleryIntent = new Intent();
galleryIntent.setType("image/*");
galleryIntent.setAction(Intent.ACTION_GET_CONTENT);
// Chooser of filesystem options.
final Intent chooserIntent = Intent.createChooser(galleryIntent, "Select Source");
// Add the camera options.
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS,
cameraIntents.toArray(new Parcelable[] {}));
// Calling activity should exeecute:
// startActivityForResult(chooserIntent, 1);
return chooserIntent;
}
After that the onActivityResult executes:
private void handleSmallCameraPhoto(Intent intent) {
Bundle extras = intent.getExtras();
mProductBitmap = (Bitmap) extras.get("data");
imgProduct.setImageBitmap(mProductBitmap);
}
Where mProductBitmap is a Bitmap Global Variable and imgProduct is an ImageView already initialized.
For some reason, first: The Camera option force closes the app, and gets a null pointer from the actual fragment itself, like the fragment items are all null again.
Second: The gallery options (More then one) don't error out but don't show the image either.
Any help would be appreciated. I've looked at every response possible, but not many people call an intent from a fragment that isn't the initial fragment that the activity is hosting.
Thanks!
EDIT:
Found out sometimes my Context is Null after the onActivityResult. If anyone has encountered this help is appreciated. Thanks.
EDIT: Below is by onActivityResult method, most of the time the first if should be executed.
#Override
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
if (resultCode == Activity.RESULT_OK) {
handleSmallCameraPhoto(intent);
} else {
if (requestCode == 1) {
InputStream stream = null;
if (intent == null) {
System.out.println("DATA IS NULL..");
} else {
try {
if (mProductBitmap != null) {
mProductBitmap.recycle();
}
stream = getActivity().getContentResolver().openInputStream(
intent.getData());
mProductBitmap = BitmapFactory.decodeStream(stream);
System.out.println(mProductBitmap);
System.out.println("Setting image result");
imgProduct.setImageBitmap(mProductBitmap);
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (stream != null)
try {
stream.close();
} catch (IOException e2) {
e2.printStackTrace();
}
}
}
}
}
}
Your photo is saved in PATH_TO_SAVE location.
You should in onActivityResult do something like this:
File file = new File(PATH_TO_SAVE);
Bitmap bmp = BitmapFactory.decodeFile(file.getPath());