im trying to record sound from dictaphone but on android 6+ i get permission error.
I add code for asking permission (have 3 permissions for ask ) 2 work but
CAPTURE_AUDIO_OUTPUT show error. Its just not ask me to grant permission. In logs its just "not granted"
Any one know in what problem ?
public static boolean PermissionCheck(Activity context, String permission, int code) {
boolean state = false;
int permissionCheck = ContextCompat.checkSelfPermission(context,
permission);
if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(context, new String[]{permission}, code); // define this constant yourself
} else {
// you have the permission
return true;
}
return state;
}
case CAPTURE_AUDIO_OUTPUT_CONSTANT: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Logger.e("CAPTURE PERMISSION GRANTED");
INIT();
} else {
Logger.e("CAPTURE PERMISSION NOT GRANTED");
finish();
}
return;
}
error
W/PackageManager: Not granting permission android.permission.CAPTURE_AUDIO_OUTPUT to package blabla_package (protectionLevel=18 flags=0x3848be46)
in manifest
<uses-permission android:name="android.permission.CAPTURE_AUDIO_OUTPUT"/>
[UPD] After a lot of tries and researches i now can answer :
Thank to google , now we cant record calls.
Its possible only if using C code and NDK .
CAPTURE_AUDIO_OUTPUT is not a dangerous permission and so does not work with the runtime permission system. CAPTURE_AUDIO_OUTPUT has android:protectionLevel="signature|privileged", so it can only be held by apps that are installed on the privileged (a.k.a., system) partition or are signed by the platform signing key.
Related
I need Photo, Media & File permission to keep my app data in CSV format in my local phone storage.
public void permissionTake() {
if (ContextCompat.checkSelfPermission(Activity_login.this,
Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(Activity_login.this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
} else {
ActivityCompat.requestPermissions(Activity_login.this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
}
} else {
}
}
Those line of codes works fine in a previous project with min android
version 16 and targeted version 27. But in a new project it only ask
for 'photos and media' permission. Not 'Files'. For that the CSV file
is failed to stored in my storage.
I am new to Android, now I am working on a Project which is based on GPS. I got source code from internet(traccar). my requirement is like the app should update location on each 1Km or each 1hr. but the problem is the app not working in background after some time(10 - 20 mins). Is there any solution for this ?
what should I do(in code) to exclude this app from battery optimisation when the app is launching ? is it possible ?
I think you're having 2 different problems:
1) If you want to keep your app in background you should use a foreground Service. That way your app won't be considered to be in background by the system and the chances of its process being killed are reduced drastically. The downside is that as long as your Service is in foreground you need to show a permanent notification.
2) You cannot exclude your app from battery optimization yourself, but you can prompt the user the settings to whitelist your app. In order to do that you can refer to the official docs, you'll need to add the Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS permission to the manifest and then launch an intent with action ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS. The user will then be able to whitelist your app, only she/he can do that because otherwise every app would whitelist itself and the purpose of the battery optimization would be defied.
Add this permission in your manifest file Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
Request Permission at runtime inside onCreate method of your activity...
PowerManager powerManager = (PowerManager) getApplicationContext().getSystemService(POWER_SERVICE);
String packageName = "org.traccar.client";
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
Intent i = new Intent();
if (!powerManager.isIgnoringBatteryOptimizations(packageName)) {
i.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
i.setData(Uri.parse("package:" + packageName));
startActivity(i);
}
}
This is the image of the code in debug mode:
This will be the view in app:
but the application not working as it is in No Restriction mode (background activity).
I want the application to work as No Restriction mode.
Add this permission in your manifest file
Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
Request Permission at runtime inside onCreate method of your activity...
private final int MY_PERMISSIONS_IGNORE_BATTERY_OPTIMIZATIONS =1;
if (ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)
!= PackageManager.PERMISSION_GRANTED) {
// Permission is not granted
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(this,
arrayOf(Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS),
MY_PERMISSIONS_IGNORE_BATTERY_OPTIMIZATIONS)
// app-defined int constant. The callback method gets the
// result of the request.
}
} else {
// Permission has already been granted
}
Here is the kotlin version of #Shafeeq Mohammed Answer and it worked for me. Thank you
fun checkBatteryOptimization(mContext: Context) {
val powerManager =
mContext.getSystemService(POWER_SERVICE) as PowerManager
val packageName = mContext.packageName
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val i = Intent()
if (!powerManager.isIgnoringBatteryOptimizations(packageName)) {
i.action = Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
i.data = Uri.parse("package:$packageName")
mContext.startActivity(i)
}
}
}
Hey everyone, thank you for assisting with my Question..
I'm attempting to implement the new Permissions request in an App for the first time, so I just need a tiny bit of help..
Basically, my step 1 involves checking to see if the permission is already granted, and then request it in the next step if its not already granted.. But I need to check and make sure ALL the permissions I need are granted, not just one.. So heres what I have for checking the one single permission:
private void checkPermission() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
// Permission already available, continue to Method "finishPermissionCheck"
finishPermissionCheck();
} else {
// Permission needs to be requested, continue to Method "requestPermission"
requestPermission();
}
}
Ok so, this is fine for only ONE Permission, but I need to check for MULTIPLE Permissions (and if needed, request multiple Permissions).. I tried using && to include the rest of the Permissions, but to no avail.. I also tried creating a String of multiple Permissions, as shown below..This is what my attempt looks like..First I create a string of multiple Permissions in the scope (in this case, I'm just trying 2 Permissions):
private static final String[] requiredPermissions = {
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.RECEIVE_BOOT_COMPLETED
};
Then I changed the Permission Check code to look like this:
private void checkPermission() {
if (ActivityCompat.checkSelfPermission(this, String.valueOf(requiredPermissions))
== PackageManager.PERMISSION_GRANTED) {
// Permission already available, continue to Method "finishPermissionCheck"
finishPermissionCheck();
} else {
// Permission needs to be requested, continue to Method "requestPermission"
requestPermission();
}
}
However, I'm not sure if this is correct way to do this..
What would be the best way to accomplish this task?
..And Yes Moderators, I've taken a look around at the other posts related to this topic.
Thanks a ton ahead of time for any help!
in your finishPermissionCheck(); method call this following code ->
ActivityCompat.requestPermissions(SendMoneyByDetailsActivity.this, requiredPermissions , REQUEST_CODE);
Hi I faced the same problem recently. I will share my implementation. In my case I needed to check for all TWO permissions but it looks scalable to me.
MyPermissionHandler.java
// return true if all permissions are granted
public boolean getPermissions() {
// if version is smaller, the permissions in the xml file are enough
if(Build.VERSION.SDK_INT<Build.VERSION_CODES.M) {
return true;
}
// create an array list with needed permissions if they are not granted already
ArrayList<String> perms = new ArrayList<String>() {{
if(!hasCameraPermission()) add(Manifest.permission.CAMERA);
if(!hasWritePermission()) add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
}};
if(perms.size()>0) {
ActivityCompat.requestPermissions(activity, perms.toArray(new String[0]), MainActivity.MY_PERMISSIONS_REQUEST_CAMERA);
return false;
} else {
return true;
}
}
private boolean hasCameraPermission() {
return ContextCompat.checkSelfPermission(activity, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED;
}
private boolean hasWritePermission() {
return ContextCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
}
In the MainActivity.java
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
// if at least one permission is denied, finish the activity
for(int permission : grantResults) {
if(permission != PackageManager.PERMISSION_GRANTED) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Error")
.setMessage("This application needs all permissions.")
.setCancelable(false)
.setNeutralButton("Ok", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
})
.show();
return;
}
}
// all permissions are granted
}
If you need to add more permissions you must only change the code in the MyPermissionHandler.java file. Hope this helps! :)
BTW, you can add some checking in the onResume() method of the activity, in case of when a user minimizes the program and goes to settings to disable, for instance, the camera permission. After he goes back to the application and the app tries to open the camera, the app will crash. So you must be careful.
I am facing checking permission value in Android 6.0 (API 23). Always get 0 value even permission enable or disable from app's settings.
Below is step which I taken.
Contact permission manually disable from device settings->apps-> My apps-> permission -> Disable contact permission.
Still In Android 6.0 every time got 0 value when execute below line of code.
ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_CONTACTS)
Below is my code. which I define in main launcher activity class
// Identifier for the permission request
private static final int WRITE_CONTACTS_PERMISSIONS_REQUEST = 9;
........
#Override
public void onCreate(Bundle savedInstanceState) {
....
if (android.os.Build.VERSION.SDK_INT <= android.os.Build.VERSION_CODES.LOLLIPOP_MR1)
{
sharedPreferencesEditor.putBoolean(getString(R.string.ALLOW_ACCESS_PHONEBOOK), true);
sharedPreferencesEditor.commit();
}
else {
getPermissionToReadUserContacts();
}
....
}
// Called when the user is performing an action which requires the app to read the
// user's contacts
public void getPermissionToReadUserContacts() {
// 1) Use the support library version ContextCompat.checkSelfPermission(...) to avoid
// checking the build version since Context.checkSelfPermission(...) is only available
// in Marshmallow
// 2) Always check for permission (even if permission has already been granted)
// since the user can revoke permissions at any time through Settings
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {
// The permission is NOT already granted.
// Check if the user has been asked about this permission already and denied
// it. If so, we want to give more explanation about why the permission is needed.
if (shouldShowRequestPermissionRationale(
Manifest.permission.WRITE_CONTACTS)) {
// Show our own UI to explain to the user why we need to read the contacts
// before actually requesting the permission and showing the default UI
}
// Fire off an async request to actually get the permission
// This will show the standard permission request dialog UI
requestPermissions(new String[]{Manifest.permission.WRITE_CONTACTS},
WRITE_CONTACTS_PERMISSIONS_REQUEST);
}
}
// Callback with the request from calling requestPermissions(...)
#Override
public void onRequestPermissionsResult(int requestCode,
#NonNull String permissions[],
#NonNull int[] grantResults) {
// Make sure it's our original READ_CONTACTS request
if (requestCode == WRITE_CONTACTS_PERMISSIONS_REQUEST) {
if (grantResults.length == 1 &&
grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "Write Contacts permission granted", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Write Contacts permission denied", Toast.LENGTH_SHORT).show();
}
} else {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
If you target SDK 23 (Android 6), all of the permissions (in your manifest) are disabled by default, whereas if your targetSDK is 22 (Android 5.1) and your app is running on Android 6, all of the permissions are enabled by default when the user installs the app, and even if the user revokes the permissions later on, checkSelfPermission returns incorrect value of PERMISSION_GRANTED
It is also available in the documentation of PermissionChecker
In the new permission model permissions with protection level dangerous are runtime permissions. For apps targeting M and above the user may not grant such permissions or revoke them at any time. For apps targeting API lower than M these permissions are always granted as such apps do not expect permission revocations and would crash. Therefore, when the user disables a permission for a legacy app in the UI the platform disables the APIs guarded by this permission making them a no-op which is doing nothing or returning an empty result or default error.
I had the same issue but I realized that there were locals modules with target version below 23. After removing them, the bug was resolved.
I have a phone specific problem when I open a camera on this one particular Nexus 5. Its the An error occurred while connecting to camera: 0 --- Fail to connect to camera service error. On at least a dozen other phones everything works just fine. Other apps that use the camera on the Nexus 5 are not crashing (indicating its not all apps that can't access the camera, just mine).
There are a number of other questions on this and I have tried all of them. They all talk about missing permissions, and making sure the camera is destroyed after use.
To be clear my manifest requests and uses the camera properly:
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera2" />
And I am releasing the camera when destroying:
public void releaseCamera()
{
if (_camera != null)
{
_camera.stopPreview();
_camera.setPreviewCallback(null);
_camera.release();
_camera = null;
}
_surfaceHolder.removeCallback(this);
}
Can you think of any reason what-so-ever that I am getting this. I have a suspicion that theres some sort of bug because I am using camera and not camera2 but that is a wild guess. Reading the updates for API 6.0 there is a section on camera that says:
In This release, the model for accessing shared resources in the
camera service has been changed from the previous “first come, first
serve” access model to an access model where high-priority processes
are favored.
Again without re-writing the entire app to use camera2 (not an option) I can't say for certain what's going on.
Here is my code where I open the camera (and what works on every other phone except the Nexus 5)
private void setInitialCamera()
{
try
{
if (_isBackFacing == true)
{
_camera = Camera.open(0);
} else
{
_camera = Camera.open(1);
}
} catch (RuntimeException e)
{
Log.d("Runtime Exception","Error " + e);
e.printStackTrace();
} catch (Exception e)
{
Log.d("Camera Error: ", " Android is unable tell what the error was");
e.printStackTrace();
}
}
So it looks like the culprit has something to do with the 6.0.1 update this phone went through.
While this didn't happen on other phones, it did on the failing Nexus 5.
What happened was the 6.0.1 update allows users to set individual permissions for an app. So somehow the persmission for the camera were toggled off. Turning this back on fixed the issue.
To get there you go to Settings -> Apps -> [App Name] -> Permissions
Making user to set permissions manually for your app is not a good approach. Use following code instead, which wil prompt user permission when your app is launched for first time.
First set your request code, which is used to recognize accepted or refused request:
private static final int MY_CAMERA_REQUEST_CODE = 100;
Then ask the user if you can use the camera:
if (checkSelfPermission(Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.CAMERA}, MY_CAMERA_REQUEST_CODE);
}
else {
// permission has been already granted, you can use camera straight away
}
Finally check whether permissions were granted:
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions,
#NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == MY_CAMERA_REQUEST_CODE) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// user accepted your request, you can use camera now from here
}
else {
// user denied your request, you can now handle their decision
}
}
}