on click
takePic.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
Intent m_intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
imageUri = getImageUri();
m_intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(m_intent, REQUEST_IMAGE_CAPTURE);
}
});
On Result:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_IMAGE_CAPTURE
&& resultCode == RESULT_OK) {
Log.d("test1",""+imageUri);
Intent shareIntent = new Intent(this, SharePicForm.class);
shareIntent.putExtra("photo",""+imageUri);
startActivity(shareIntent);
}
}
getImageUri()
private Uri getImageUri(){
Uri m_imgUri = null;
File m_file;
try {
SimpleDateFormat m_sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
m_curentDateandTime = m_sdf.format(new Date());
m_imagePath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + m_curentDateandTime + ".jpg";
m_file = new File(m_imagePath);
m_imgUri = Uri.fromFile(m_file);
} catch (Exception p_e) {
}
return m_imgUri;
}
What I would like to achieve is very simple, call camera intent and get the uri of the result photo. But it seems there is an inconsistent of different device and on my device it isn't work at all. I tried to store the path on a public variable but when I retrieve it , it is null, is there formal and standard way to implement it and should be work on all device? Also, are there any way for not provide the custom path but get the default uri path from the camera intent ?
Thanks for helping
If your device does not respect cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, you still can use
Uri imageUri = data.getData();
in onActivityResult(int requestCode, int resultCode, Intent data). But in most cases, the problem is that RAM is limited, and the system destroys your activity to give enough memory to the camera app to fulfill your intent. Therefore, when the result is returned, the fields of your activity are not initialized, and you should follow Amit's suggestion and implement onSavedInstance() and onRestoreInstanceState().
First of all make sure that your directory is created......
final String dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)+ "/Folder/";
File newdir = new File(dir);
newdir.mkdirs();
on button click call this function.
private void capturarFoto() {
String file = dir+DateFormat.format("yyyy-MM-dd_hhmmss", new Date()).toString()+".jpg";
File newfile = new File(file);
try {
newfile.createNewFile();
} catch (IOException e) {}
Uri outputFileUri = Uri.fromFile(newfile);
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(cameraIntent, TAKE_PHOTO_CODE);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == TAKE_PHOTO_CODE && resultCode == RESULT_OK) {
Log.d("Demo Pic", "Picture is saved");
}
}
Make sure You add permission in manifest
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
To just get the thumbnail, you can use this:
val imageBitmap = data.extras.get("data") as Bitmap
To get the full picture:
See the specific steps from here (official docs)
You can read more from the docs.
After a lot of research I found this solution. Just to make things clear I created an entire app for this question which serves the purpose of opening the camera clicking a photo and setting the image as the ImageBitmap of an ImageView. The code asked in this question starts at the second block i.e. the setView() method which is below the onCreate() method following which we have the onActivityResult() method
Here is a demo of the app.
Below I have Attached the MainActivity.java file
package com.cr7.opencamera;
import android.Manifest;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.widget.Button;
import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import java.io.IOException;
public class MainActivity extends AppCompatActivity {
private Button buttonCaptureImageFromCamera;
private Uri imageUri;
private ImageView imageViewCameraImage;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Button that will open the camera
buttonCaptureImageFromCamera = findViewById(R.id.buttonCaptureImageFromCamera);
// ImageView that will store the image
imageViewCameraImage = findViewById(R.id.imageViewCameraImage);
askPermission();
}
This what you need for geting the Uri of the image here imageUri is a global variable so that it can be used in the onActivityResult() method
// Sets OnClickListener for the button if storage permission is given
private void setView() {
buttonCaptureImageFromCamera.setOnClickListener(v -> {
String fileName = "new-photo-name.jpg";
// Create parameters for Intent with filename
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, fileName);
values.put(MediaStore.Images.Media.DESCRIPTION, "Image capture by camera");
imageUri =
getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
values);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(intent, 1231);
});
}
This is the onActivityResult method. Here I've used imageUri i.e. the global variable of type Uri which was initialized in the OnClickListener of the button in the setView() method above.
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 1231 && resultCode == Activity.RESULT_OK) {
try {
ContentResolver cr = getContentResolver();
try {
// Creating a Bitmap with the image Captured
Bitmap bitmap = MediaStore.Images.Media.getBitmap(cr, imageUri);
// Setting the bitmap as the image of the
imageViewCameraImage.setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
} catch (IllegalArgumentException e) {
if (e.getMessage() != null)
Log.e("Exception", e.getMessage());
else
Log.e("Exception", "Exception");
e.printStackTrace();
}
}
}
Remaining code...
// Asking user for storage permission
public void askPermission() {
// Checking if the permissions are not granted.
if (
ContextCompat.checkSelfPermission(
this,
android.Manifest.permission.WRITE_EXTERNAL_STORAGE
) != PackageManager.PERMISSION_GRANTED ||
ContextCompat.checkSelfPermission(
this,
android.Manifest.permission.READ_EXTERNAL_STORAGE
) != PackageManager.PERMISSION_GRANTED
) {
// If not granted requesting Read and Write storage
ActivityCompat.requestPermissions(this, /*You can ask for multiple request by adding
more permissions to the string*/new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE}, 60);
} else {
// If permissions are granted we proceed by setting an OnClickListener for the button
// which helps the user pick the image
setView();
}
}
// This method is called after the permissions have been asked i.e. the dialog that says
// allow or deny
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions,
#NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
// Now by default we assume that the permission has not been granted
boolean allPermissionsGranted = false;
// Now we check if the permission was granted
if ( requestCode == 60 && grantResults.length > 0) {
// If all the permissions are granted allPermissionsGranted is set to true else false
allPermissionsGranted = grantResults[0] == PackageManager.PERMISSION_GRANTED
&&
grantResults[1] == PackageManager.PERMISSION_GRANTED;
}
// If permissions are granted we call the setView Method which prompts the user to pick
// an Image either by the clicking it now or picking from the gallery
if ( allPermissionsGranted ) {
setView();
}
}
}
These blocks of code are in sequence i.e. if you merge all these blocks you get the complete MainActivity.java class.
If you wan to Implement this app you need yo create a layout file with an ImageView with an id "imageViewCameraImage"and a button with an id "buttonCaptureImageFromCamera".
Hope this helps. I know this is long and I'm making it longer by writing this.
Regards,
Joel
simply use this Uri imageUri = data.getData();
Related
I'm trying to activate camera with intent by the following codes :
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private ImageView mImageView;
static final int REQUEST_IMAGE_CAPTURE = 1;
static final int REQUEST_TAKE_PHOTO = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.button);
mImageView = findViewById(R.id.imageView);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "clicked", Toast.LENGTH_SHORT).show();
dispatchTakePictureIntent();
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.d(TAG, "onActivityResult: 0");
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
Log.d(TAG, "onActivityResult: 1");
Bundle extras = data.getExtras();
Bitmap imageBitmap = (Bitmap) extras.get("data");
mImageView.setImageBitmap(imageBitmap);
}
}
private void dispatchTakePictureIntent() {
Log.d(TAG, "dispatchTakePictureIntent: 0");
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
Log.d(TAG, "dispatchTakePictureIntent: 1");
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
}
The app crashes every time I click the button(it's supposed to open the camera). I can get "dispatchTakePictureIntent: 1" from logcat, so takePictureIntent.resolveActivity(getPackageManager()) isn't returning null. I think it's startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE) that causes the app to crash.
The codes are replicated from the official documents : https://developer.android.com/training/camera/photobasics#java.
I've tried dispatchTakePictureIntent(View v), but the app still crashed. I've also replaced dispatchTakePictureIntent() with the method below and it still crashed.
private void TakePicture(){
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
startActivityForResult(intent, 0);
}
I've been trying other solutions I found on the internet, non of them helped. What could be the problem that causes my app to crash?
I think you have not used any permission check because for an android device below 23 need not to ask for permssion but above 23 you need to declare or ask user to access features of an android.
If the device is running Android 6.0 (API level 23) or higher, and the app's targetSdkVersion is 23 or higher, the user isn't notified of any app permissions at install time. Your app must ask the user to grant the dangerous permissions at runtime. When your app requests permission, the user sees a system dialog (as shown in figure 1, left) telling the user which permission group your app is trying to access. The dialog includes a Deny and Allow button.
According to this Doc..
https://developer.android.com/guide/topics/permissions/overview
if (ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.WRITE_CALENDAR)
!= PackageManager.PERMISSION_GRANTED) {
// Permission is not granted
}
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {
// Permission is not granted
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
Manifest.permission.READ_CONTACTS)) {
// Show an explanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
} else {
// No explanation needed; request the permission
ActivityCompat.requestPermissions(thisActivity,
new String[]{Manifest.permission.READ_CONTACTS},
MY_PERMISSIONS_REQUEST_READ_CONTACTS);
// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
// app-defined int constant. The callback method gets the
// result of the request.
}
} else {
// Permission has already been granted
}
Sample code from Android doc
https://developer.android.com/training/permissions/requesting#java
Please try to give the permission of camera in android manifest file.
<uses-permission android:name="android.permission.CAMERA"> </uses-permission>.
and then try replace your intent code with this Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
startActivity(intent);
if you don't want to use device camera then you can also make you own Custom camera with the help of this library https://github.com/natario1/CameraView
you can use this way
public static final int REQUEST_PICTURE_FROM_GALLERY = 10001;
public static final int REQUEST_PICTURE_FROM_CAMERA = 10002;
private File tempFileFromSource = null;
private Uri tempUriFromSource = null;
public void selectImageFromGallery() {
try {
tempFileFromSource = File.createTempFile("choose", "png", context.getExternalCacheDir());
tempUriFromSource = Uri.fromFile(tempFileFromSource);
Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
intent.putExtra(MediaStore.EXTRA_OUTPUT, tempUriFromSource);
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
context.startActivityForResult(intent, REQUEST_PICTURE_FROM_GALLERY);
} catch (IOException e) {
e.printStackTrace();
}
}
public void takePhotoWithCamera() {
try {
tempFileFromSource = File.createTempFile("choose_", ".png", context.getExternalCacheDir());
tempUriFromSource = FileProvider.getUriForFile(context, context.getPackageName() + ".fileprovider", tempFileFromSource);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, tempUriFromSource);
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
context.startActivityForResult(intent, REQUEST_PICTURE_FROM_CAMERA);
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((requestCode == REQUEST_PICTURE_FROM_GALLERY) && (resultCode == Activity.RESULT_OK)) {
Log.d(TAG, "Image selected from gallery");
prepareImage(data.getData(), tempFileFromSource);
} else if ((requestCode == REQUEST_PICTURE_FROM_CAMERA) && (resultCode == Activity.RESULT_OK)) {
Log.d(TAG, "Image selected from camera");
prepareImage(tempUriFromSource, tempFileFromSource);
}
}
private void prepareImage(Uri uri, File imageFile) {
try {
if (uri == null)
return;
Bitmap bitmap = BitmapUtils.decodeBitmap(context, uri, 300, 300);
if (bitmap == null)
return;
// now you have bitmap
} catch (IOException e) {
e.printStackTrace();
}
}
public static Bitmap decodeBitmap(Context context, Uri uri, int maxWidth, int maxHeight) throws IOException {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
InputStream imageStream = context.getContentResolver().openInputStream(uri);
BitmapFactory.decodeStream(imageStream, null, options);
if (imageStream != null)
imageStream.close();
// Calculate inSampleSize
options.inSampleSize = calculateSize(options, maxWidth, maxHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
imageStream = context.getContentResolver().openInputStream(uri);
Bitmap img = BitmapFactory.decodeStream(imageStream, null, options);
img = rotateImageIfRequired(context, img, uri);
return img;
}
I am developing an android mobile application in which i am trying to upload the picture on server from android app. The .php files are working fine but the java code is not working and showing error that path is null. I have tried the several types of code but not working at all. Please help.
Thank you
Here is the code.
package com.example.pt_connect.attachmentuploadingandgetting;
import android.Manifest;
import android.content.Context;
import android.content.CursorLoader;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;
import net.gotev.uploadservice.MultipartUploadRequest;
import net.gotev.uploadservice.UploadNotificationConfig;
import java.io.IOException;
import java.util.UUID;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
//Declaring views
private Button buttonChoose;
private Button buttonUpload;
private ImageView imageView;
private EditText editText;
//Image request code
private int PICK_IMAGE_REQUEST = 1;
//storage permission code
private static final int STORAGE_PERMISSION_CODE = 123;
//Bitmap to get image from gallery
private Bitmap bitmap;
//Uri to store the image uri
private Uri filePath;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Requesting storage permission
requestStoragePermission();
//Initializing views
buttonChoose = (Button) findViewById(R.id.buttonChoose);
buttonUpload = (Button) findViewById(R.id.buttonUpload);
imageView = (ImageView) findViewById(R.id.imageView);
editText = (EditText) findViewById(R.id.editTextName);
//Setting clicklistener
buttonChoose.setOnClickListener(this);
buttonUpload.setOnClickListener(this);
}
/*
* This is the method responsible for image upload
* We need the full image path and the name for the image in this method
* */
**public void uploadMultipart() {
//getting name for the image
String name = editText.getText().toString().trim();
//getting the actual path of the image
String path = getPath(MainActivity.this,filePath);
//Uploading code
try {
String uploadId = UUID.randomUUID().toString();
//Creating a multi part request
new MultipartUploadRequest(this, uploadId, Constants.UPLOAD_URL)
.addFileToUpload(path, "image") //Adding file
.addParameter("name", name) //Adding text parameter to the request
.setNotificationConfig(new UploadNotificationConfig())
.setMaxRetries(2)
.startUpload(); //Starting the upload
} catch (Exception exc) {
Toast.makeText(this, exc.getMessage(), Toast.LENGTH_SHORT).show();
}
}**
//method to show file chooser
private void showFileChooser() {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE_REQUEST);
}
//handling the image chooser activity result
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 1 && resultCode == RESULT_OK) {
//Bitmap photo = (Bitmap) data.getData().getPath();
filePath = data.getData();
try {
bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), filePath);
imageView.setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
}
}
//method to get the file path from uri
public String getPath(Context context, Uri contentUri) {
Cursor cursor = null;
try {
String[] proj = { MediaStore.Images.Media.DATA };
cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
} finally {
if (cursor != null) {
cursor.close();
}
}
}
//Requesting permission
private void requestStoragePermission() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)
return;
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_EXTERNAL_STORAGE)) {
//If the user has denied the permission previously your code will come to this block
//Here you can explain why you need this permission
//Explain here why you need this permission
}
//And finally ask for the permission
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, STORAGE_PERMISSION_CODE);
}
//This method will be called when the user will tap on allow or deny
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
//Checking the request code of our request
if (requestCode == STORAGE_PERMISSION_CODE) {
//If permission is granted
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//Displaying a toast
Toast.makeText(this, "Permission granted now you can read the storage", Toast.LENGTH_LONG).show();
} else {
//Displaying another toast if permission is not granted
Toast.makeText(this, "Oops you just denied the permission", Toast.LENGTH_LONG).show();
}
}
}
#Override
public void onClick(View v) {
if (v == buttonChoose) {
showFileChooser();
}
if (v == buttonUpload) {
uploadMultipart();
}Error
}
}
You have to get the file path like below
String FilePath = data.getData().getPath();
String FileName = data.getData().getLastPathSegment();
on the onActivityResult. I made change to your code. Check below
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 1 && resultCode == RESULT_OK) {
//Bitmap photo = (Bitmap) data.getData().getPath();
filePath = data.getData().getPath();
try {
bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), filePath);
imageView.setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
}
}
I think it will work. If not comment here, we will go for another method
I'm new to Android developing and following the training course on google now, I meet a problem. After executing Bundle extra = data.getExtras(), extra is null. Also it will throw a nullpointerexception before I add the code "if(extra!=null)"
Here is the code of onActivityResult() method
Here is the code part to start the camera and save photo locally
All my code follows the training course and I am confused where is wrong.
Can someone help me?
Please update your onActivityResult(), the result from capture photo doesn't response an image. It returns a Uri that you passed in photo_intent.putExtra(MediaStore.EXTRA_OUTPUT, <<uri>>). So please declare the <<uri>> as global then you can get this value in onActivityResult()
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
hasWriteContactsPermission = checkSelfPermission(Manifest.permission.CAMERA);
if (hasWriteContactsPermission != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.CAMERA},
REQUEST_CODE_ASK_PERMISSIONS);
return;
}
} else {
Intent intent = new Intent(
MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(getPackageManager()) != null) {
File photo = new File(Environment
.getExternalStorageDirectory(),
"Journal" + Utils_class.getID() + ".jpeg");
intent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photo));
mSelectedFilePath = photo.getAbsolutePath();
startActivityForResult(intent,
ACTION_TAKE_PICTURE);
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
try {
if (resultCode == RESULT_OK) {
if (requestCode == ACTION_TAKE_PICTURE) {
// flag = true;
// new Utils();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
checkPermissionForStorageForCam();
} else {
Uri selectedImageUri = data.getData();
}
}
}
} catch (Exception e) {
}
}
If you pass the extra parameter MediaStore.EXTRA_OUTPUT with the camera intent then camera activity will write the captured image to that path and it will not return the bitmap in the onActivityResult method.
If you will check the path which you are passing then you will know that actually camera had write the captured file in that path.
This same code runs like a charm in other devices but in nexus 5 (OS version 5.1.1) am unable to run it.
When I run the below code in nexus 5 I get NullPointerException, and value of resultCode=0 and that of RESULT_OK=-1, thus my if condition in getActivityForResult do not run.
Whereas in other devices (other models like samsung,htc etc) the same code runs like a charm without and exception and the value of resultCode=-1 and RESULT_OK=-1, both the values come same , so the if condition runs and thus the rest of my program.
JAVA CODE
mainActivity.java
public void callCamera() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
// start the image capture Intent
startActivityForResult(intent, 100);
Log.i("hello", "callCamera");
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.i("hello", "" + requestCode);
Log.i("hello", "" + resultCode);
Log.i("hello", "" + this.RESULT_OK);
if (requestCode == 100 && resultCode == RESULT_OK) {
// fileUri=data.getExtras().get("data");
photo = (Bitmap) data.getExtras().get("data");
//*selectedImage = data.getData();
//photo = (Bitmap) data.getExtras().get("data");
Log.i("hello","onActivityResult");
uploadImage();
}
}
LOGCAT IN CASE OF NEXUS 5
FATAL EXCEPTION: main Process: com.google.android.GoogleCamera, PID: 24887
java.lang.NullPointerException at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:187)
at com.google.common.base.Optional.of(Optional.java:84)
at com.android.camera.captureintent.state.StateSavingPicture.onEnter(StateSavingPicture.java:77)
at com.android.camera.captureintent.stateful.StateMachineImpl.jumpToState(StateMachineImpl.java:62)
at com.android.camera.captureintent.stateful.StateMachineImpl.processEvent(StateMachineImpl.java:110)
at com.android.camera.captureintent.state.StateOpeningCamera$9.onClick(StateOpeningCamera.java:307)
at android.view.View.performClick(View.java:4780)
at android.view.View$PerformClick.run(View.java:19866)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Remove the intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); line from callCamera() method, this will fix the crash. As if you are getting the uri from the onActivityResult() intent then the intent will recived data as null since you are putting a extra value of uri in the intent at time of starting the camera intent, this defines that you already have a file uri for your camera image and you don't want a data intent in onActivityResult(), also i will suggest you to remove the fileuri variable used inside the callCamera() method as it is of no use.
so your callCamera method should look like:
public void callCamera() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, 100);
}
/*** Created by wildcoder on 06/06/16.*/
import android.Manifest;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.Intent;
import android.media.CameraProfile;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.widget.Toast;
public class FragmentVideoRecorder extends BaseFragment {
private Uri fileUri;
private static final int CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE = 200;
public static Activity ActivityContext = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityContext = getActivity();
}
/**
* #param parentDirectory Your folder name
*/
protected void startRecording(File parentDirectory) {
if (Utilities.isGranted(getActivity(), Manifest.permission.RECORD_AUDIO) && Utilities.isGranted(getActivity(), Manifest.permission.CAMERA)) {
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
// create a file to save the video
fileUri = getOutputMediaFileUri(parentDirectory);
// set the image file name
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
intent.putExtra(MediaStore.EXTRA_SIZE_LIMIT, 10000000);
// set the video image quality to high
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, CameraProfile.QUALITY_LOW);
// start the Video Capture Intent
startActivityForResult(intent, CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE);
} else {
Utilities.openAppSetting(ActivityContext);
}
}
/**
* #param contentResolver
* #param file to delete
*/
public void deleteFileFromMediaStore(final ContentResolver contentResolver, final File file) {
String canonicalPath;
try {
canonicalPath = file.getCanonicalPath();
} catch (IOException e) {
canonicalPath = file.getAbsolutePath();
}
final Uri uri = MediaStore.Files.getContentUri("external");
final int result = contentResolver.delete(uri,
MediaStore.Files.FileColumns.DATA + "=?", new String[]{canonicalPath});
if (result == 0) {
final String absolutePath = file.getAbsolutePath();
if (!absolutePath.equals(canonicalPath)) {
contentResolver.delete(uri,
MediaStore.Files.FileColumns.DATA + "=?", new String[]{absolutePath});
}
}
}
/**
* Create a file Uri for saving an image or video
*/
private Uri getOutputMediaFileUri(File parent) {
return Uri.fromFile(getOutputMediaFile(parent));
}
/**
* Create a File for saving an image or video
*/
private File getOutputMediaFile(File mediaStorageDir) {
// Check that the SDCard is mounted
// Create the storage directory(MyCameraVideo) if it does not exist
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Toast.makeText(ActivityContext, "Failed to create directory MyCameraVideo.",
Toast.LENGTH_LONG).show();
Log.d("MyCameraVideo", "Failed to create directory MyCameraVideo.");
return null;
}
}
File mediaFile = new File(mediaStorageDir, "intro_video.mp4");
if (mediaFile.exists()) {
deleteFileFromMediaStore(ActivityContext.getContentResolver(), mediaFile);
}
return mediaFile;
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
// After camera screen this code will excuted
if (requestCode == CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE) {
if (resultCode == Activity.RESULT_OK) {
// Video captured and saved to fileUri specified in the Intent
Toast.makeText(ActivityContext, "Video saved to: " + data.getData(), Toast.LENGTH_LONG).show();
} else if (resultCode == Activity.RESULT_CANCELED) {
// User cancelled the video capture
Toast.makeText(ActivityContext, "User cancelled the video capture.",
Toast.LENGTH_LONG).show();
} else {
// Video capture failed, advise user
Toast.makeText(ActivityContext, "Video capture failed.",
Toast.LENGTH_LONG).show();
}
}
}
}
Make sure that after the video is captured you click on the tick mark (blue in Nexus 5, Android 8). It is only after the tick that the result is set to RESULT_OK. If you click on any other button, the result code is not set appropriately.
The problem is that Android 11 requires that you use Fileprovider. Solution:
[1] Make sure you use FileProvider to generate fileUri, e.g.:
File outputDir = getExternalCacheDir();
File out = File.createTempFile("android_upload", ".jpg", outputDir);
fileUri = FileProvider.getUriForFile(this, "com.your.app.id.fileprovider", out);
(replace com.your.app.id with your application id).
[2] Add to your AndroidManifest.xml:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.your.app.id.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_provider_paths"/>
</provider>
[3] Create a file res/xml/file_provider_paths.xml:
<paths>
<external-cache-path name="cache" path="/" />
</paths>
This is code i'm using
Intent i = new Intent(
android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(i, cameraData);
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
try {
InputStream is = getContentResolver().openInputStream(data.getData());
Main.this.getContentResolver().delete(data.getData(), null,
null);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
String error = e.toString();
Dialog d = new Dialog(this);
TextView tv = new TextView(this);
tv.setText(error);
d.setContentView(tv);
d.show();
}
} else {
is = null;
}
}
I'm doing this way because i don't want to save pics to dcim folder.
It is working fine on samsung, htc and some other devices but it crashes on alcatel one touch 5020x Jelly Bean 4.1.1,
returns null pointer exception.
Is there another way to do this, but not to save pics to dcim folder.
I have seen many solutions to do this but all of them save a pic to dcim folder
Thanx
I'm doing this way because i don't want to save pics to dcim folder.
Then include EXTRA_OUTPUT in your ACTION_IMAGE_CAPTURE Intent, to tell whichever camera app handles your request where to put the image. Quoting the documentation:
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.
Your code is written to not do anything of what is documented. Instead, you are assuming that the camera app will return a Uri of where an image is. This is not part of the documented protocol, and so your code will fail when interacting with many camera apps.
Is there another way to do this, but not to save pics to dcim folder.
This code will put the image in another spot on external storage:
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import java.io.File;
public class CameraContentDemoActivity extends Activity {
private static final int CONTENT_REQUEST=1337;
private File output=null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent i=new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
output=new File(getExternalFilesDir(null), "CameraContentDemo.jpeg");
i.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(output));
startActivityForResult(i, CONTENT_REQUEST);
}
#Override
protected void onActivityResult(int requestCode, int resultCode,
Intent data) {
if (requestCode == CONTENT_REQUEST) {
if (resultCode == RESULT_OK) {
// use the output File object
}
}
}
}
This is not the best solution but it works!
final static int cameraData = 13579;
final static int camera2Data = 97531;
InputStream is = null;
int camera2 = 0;
SharedPreferences spData;
public static String spName = "MySharedString";
camera start:
if (camera2 == 1) {
Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
output = new File(getExternalFilesDir(null),
"CameraContentDemo.jpg");
i.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(output));
startActivityForResult(i, camera2Data);
} else {
Intent i = new Intent(
android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(i, cameraData);
}
onActivitrForResult:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == cameraData) {
if (resultCode == RESULT_OK) {
try {
is = getContentResolver().openInputStream(data.getData());
Main.this.getContentResolver().delete(data.getData(), null,
null);
} catch (Exception e) {
// TODO Auto-generated catch block
camera2 = 1;
if (camera2 == 1) {
Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
output = new File(getExternalFilesDir(null),
"CameraContentDemo.jpeg");
i.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(output));
startActivityForResult(i, camera2Data);
}
SharedPreferences.Editor editor = spData.edit();
editor.putInt("cam2", 1);
editor.commit();
}
} else {
is = null;
}
}
if (requestCode == camera2Data) {
if (resultCode == RESULT_OK) {
try {
is = new FileInputStream(output);
} catch (Exception e) {
// TODO Auto-generated catch block
SharedPreferences.Editor editor = spData.edit();
editor.putInt("cam2", 0);
editor.commit();
}
} else {
is = null;
}
}
}
So, like i said, its not the best solution but it works.
When the app starts for the first time on Alcatel, it starts with the old code, crashes and catcher the exception, saves camera2 variable to be 1, and starts the camera again with the second code that works fine.
When i load on other devices, it works fine to and no pics are saved to DCIM folder