Android Default Video Camera Intent Opens Image Camera - java

I am trying to open the android default video camera from my app, using the following code:
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
startActivityForResult(intent, 1);
But on my two phones (Samsung Note 2, and Google Pixel), it opens the image camera instead. I have this permission in my manifest:
<uses-permission android:name="android.permission.CAMERA"/>
Any ideas what causes this issue?
I've also requested the permission at runtime.

Add follow permission CAPTURE_SECURE_VIDEO_OUTPUT and CAPTURE_VIDEO_OUTPUT

Android 6.0 and later requieres to ask permissions at run time. Read the official doc here: https://developer.android.com/training/permissions/requesting.html
I hope it helps.

You must add next code. Devices have Android 6.0 or later.
if(ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED){
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
startActivityForResult(intent, 1);
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 2);
}
If your the app has the permission for use the STORAGE we open the STORAGE.
If your the app doesn't have permission for use STORAGE, we open system-dialog.
Result from the dialog you can see in the onRequestPermissionsResult. (You must override it on your Activity).
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions,
#NonNull int[] grantResults) {
if (requestCode == 2) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
startActivityForResult(intent, 1);
}
}
}
I think you must extract next lines to the private method.
private void takePhoto() {
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
startActivityForResult(intent, 1);
}
For more information see : https://developer.android.com/training/permissions/requesting.html

Related

Handle Intent Camera

I make an application that can update images to the server. There are 2 options : Take picture from camera and select from library. the code works for Select from library choice and when I click on Take picture the app crash with these report.
How to handle this ?
My code for capture image intent :
capture.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
captureImage();
}
});
private void captureImage() {
Intent intentCap = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intentCap.setType("image/*");
startActivityForResult(intentCap, 0);
}
error
Seems like Android cant found suitable Intent for this.
Try this Intent:
try{
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_REQUEST);
} catch (ActivityNotFoundException e) {
// show message to user
}
You should always check for the resolveActivity when calling intent like this of third party.
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
Refer this
First and foremost check that you have added the required permissions in your Manifest file and then test your app. Even if the app doesn't run after that then that maybe occurring because of the following reasons:
1) There may not be a camera on your device
2) There is no SD card in your phone
In this case you can refer the following links which describe solutions to the similar problem link 1 and link 2
Most probably it could be possible that you must have forgot to add Runtime Permissions to access Camera API and thus resulting in App Crash when you try to open camera. Below is the code snipped which you can use to do the same:
public void showCamera(View view) {
// BEGIN_INCLUDE(camera_permission)
// Check if the Camera permission is already available.
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
// Camera permission has not been granted.
requestCameraPermission();
} else {
// Camera permissions is already available, show the camera preview.
Log.i(TAG,
"CAMERA permission has already been granted. Displaying camera preview.");
showCameraPreview();
}
// END_INCLUDE(camera_permission)
}
private void requestCameraPermission() {
// BEGIN_INCLUDE(camera_permission_request)
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.CAMERA)) {
// Provide an additional rationale to the user if the permission was not granted
// and the user would benefit from additional context for the use of the permission.
// For example if the user has previously denied the permission.
} else {
// Camera permission has not been granted yet. Request it directly.
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA},
REQUEST_CAMERA);
}
// END_INCLUDE(camera_permission_request)
}
Here is Google Runtime Permission Model Video to have an better understanding.
Also check official documentation for further details.
Hope this helps.

java.lang.SecurityException: was not granted this permission: android.permission.WRITE_SETTINGS

I going to change some system setting in android and i use this code :
ContentResolver cr = getContentResolver();
Settings.System.putInt(cr, Settings.System.HAPTIC_FEEDBACK_ENABLED, 0);
this code used for change screen Brightness use Brightness sensor,
but in android 6 I get this exception
java.lang.SecurityException: com.vpn.sabalan was not granted this permission: android.permission.WRITE_SETTINGS.
i can use this method to get permission from user , but i need get permission programmetically can any one help me ?
private void showBrightnessPermissionDialog( )
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !android.provider.Settings.System.canWrite(this))
{
Intent intent = new Intent(android.provider.Settings.ACTION_MANAGE_WRITE_SETTINGS);
intent.setData(Uri.parse("package:"+getPackageName()));
startActivity(intent);
}
}
Update Android Marshmallow and Higher
You can start System settings to grant Write System Settings. Once this permission is grant by user you can set brightness without any issues
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (Settings.System.canWrite(this)) {
Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
intent.setData(Uri.parse("package:" + getPackageName()));
startActivity(intent);
}
}
Follow the step by step provided in documentation. It is very thorough.
https://developer.android.com/training/permissions/requesting.html
All you have to do is request permission, and override the callback for onRequestPermissionsResult to check if you got it or not. If you did, then you are good to go. You still need it in your manifest though or it won't work.
UPDATE to show details based on your comments.
public class MainActivity extends AppCompatActivity implements ActivityCompat.OnRequestPermissionsResultCallback{
private static final int REQUEST_WRITE_PERMISSION = 1001;
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == REQUEST_WRITE_PERMISSION && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
doFileWork();
}else{
//handle user denied permission, maybe dialog box to user
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
requestPermission();
}
private void requestPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_WRITE_PERMISSION);
} else {
doFileWork();
}
}
}
There are also many good libraries out there that wrap this callback context if you really want to go that route, but it isn't that complex. Make sure you also have write permission in your Manifest.

Can't click Allow External Write Access Permissions in Android

I'm not able to allow the app to write to external storage when other background app like twilight (dims screen) runs in the background. In this case, I can only deny it and it says screen overlay detected. But can't allow.
My code:
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
boolean hasPermission = (ContextCompat.checkSelfPermission(Timetable.this,
Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED);
if (!hasPermission) {
ActivityCompat.requestPermissions(Timetable.this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
1);
}
}
Override code:
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode)
{
case 1: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
{
//Intent i=new Intent(this,Timetable.class);
//startActivity(i);
//reload my activity with permission granted or use the features what required the permission
} else
{
Toast.makeText(Timetable.this, "The app was not allowed to write to your storage. Hence, it cannot function properly. Please consider granting it this permission", Toast.LENGTH_LONG).show();
}
}
}
}
I want it running even if some background apps like twilight are running.
Downloading a certain file using Android's built in Download Manager provides integrity and a more User Friendly approach. Also the requestPermission method should be called before doing that if the devices having Marshmallow and above are to be supported as well.
And about the allow button not working, that issue is because of apps or activities who capture the screen overlay. Like for instance Facebook messenger or any screen dimming apps. Hence to make it robust you need to check the permission everytime you download something.
public void downloadFile(String uRl) {
File direct = new File(Environment.getExternalStorageDirectory()
+ "/" + "MyFolder");
if (!direct.exists()) {
direct.mkdirs();
}
DownloadManager mgr = (DownloadManager) getSystemService(this.DOWNLOAD_SERVICE);
Uri downloadUri = Uri.parse(uRl);
DownloadManager.Request request = new DownloadManager.Request(downloadUri);
request.setAllowedNetworkTypes(
DownloadManager.Request.NETWORK_WIFI
| DownloadManager.Request.NETWORK_MOBILE)
.setAllowedOverRoaming(false)
.setTitle("AppNameAsTitle")
.setDescription("Downloaded using My app")
.setDestinationInExternalPublicDir("/MyFolder", "filename.jpg")
.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
mgr.enqueue(request);
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
downloadFile(url);
} else {
Toast.makeText(this, "Permission not granted", Toast.LENGTH_SHORT).show();
}
}

Camera Intent keeps crashing Android App

I am writing a simple inventory management app that takes a picture of items to be logged. So the expected behaviour is that users hit a button to launch the camera, take a picture and return to the app to enter text information. But I keep getting the following Security Exception error
java.lang.SecurityException: Permission Denial: starting Intent {
act=android.media.action.IMAGE_CAPTURE cmp=com.android.camera/.Camera }
from ProcessRecord{734dbfd 22169:com.virgo19.tinni.teatracker/u0a58}
(pid=22169, uid=10058) with revoked permission android.permission.CAMERA
I have looked around the web for days and there doesn't seem to be any solution since I am already following the Android Developer instructions. Including the instruction about asking for permission at runtime. Code fragments below,
//Code calling camera intent
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (cameraIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(cameraIntent, RETURN_FROM_CAMERA);
}
//On activity return request fragment
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == RETURN_FROM_CAMERA && data != null){
//Check permissions
int permissionCheck = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA);
if(permissionCheck == PackageManager.PERMISSION_GRANTED){
//Permission is okay, so get on with getting image from Camera
Bundle extras = data.getExtras();
tinImage = (Bitmap) extras.get("data");
//set image view
setImage();
} else if (permissionCheck != PackageManager.PERMISSION_GRANTED){
//Permission not granted, ask for permission
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA},
REQUEST_CAMERA);
}
}
}
Can anyone see why this keeps crashing? Thanks!
You need to request the CAMERA permission before taking the picture via startActivityForResult(). Your current code attempts to request this permission after taking the picture.

"Permission denied" on file after taking photo in ACTION_IMAGE_CAPTURE intent

In my activity, I have the following code:
public void myMethod() {
final File root = new File(Environment.getExternalStorageDirectory() + File.separator + "MyDir" + File.separator);
root.mkdirs();
final String fname = "img_" + System.currentTimeMillis() + ".jpg";
outputFileUri = Uri.fromFile(new File(root, fname));
Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
takePhotoIntent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, outputFileUri);
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 232);
startActivityForResult(takePhotoIntent, 1);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 232) {
myMethod();
} else {
System.out.println("returned...");
ImageView imageView = (ImageView) findViewById(R.id.test_image_view);
imageView.setImageURI(outputFileUri);
}
}
My test device is a rooted nexus 6 on Android 6.0.1. When "myMethod" is called, it lets me take the photo, but upon returning to the activity I get the following error:
java.io.FileNotFoundException: /storage/emulated/0/MyDir/img_1466772411267.jpg: open failed: EACCES (Permission denied)
I have the valid permissions declared in my manifest:
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-feature android:name="android.hardware.camera"/>
This error happens on the end of the method (I guess because the prior takes some time to throw the error?) Anyway, from what I see, I appear to be doing things the way I should be. Does anything seem off?
Your code will work till Android 5.0 but not in marshmallow os.
As Beginning in Android 6.0 (API level 23), users grant permissions to apps while the app is running, not when they install the app even though you had given permission in manifest file.
So app need to ask permission from user at runtime and if user does not give that permission you will get permission denial error. So you have to manage code for that.
Refer following link for more details:
https://developer.android.com/training/permissions/requesting.html
Runtime Permissions for Android 6.0
private static final int REQUEST_RUNTIME_PERMISSION = 1;
void checkPremission() {
//select which permission you want
final String permission = Manifest.permission.CAMERA;
//final String permission = Manifest.permission.Storage;
// if in fragment use getActivity()
if (ContextCompat.checkSelfPermission(ActivityName.this, permission)
!= PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(ActivityName.this, permission)) {
} else {
ActivityCompat.requestPermissions(ActivityName.this, new String[]{android.permission.CAMERA,android.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_RUNTIME_PERMISSION);
}
} else {
// you have permission go ahead
myMethod();
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch (requestCode) {
case REQUEST_RUNTIME_PERMISSION:
final int numOfRequest = grantResults.length;
final boolean isGranted = numOfRequest == 1
&& PackageManager.PERMISSION_GRANTED == grantResults[numOfRequest - 1];
if (isGranted) {
// you have permission go ahead
myMethod();
}else{
// you dont have permission show toast
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}

Categories