Application that can get Location and runs on android 4.0.3+ - android

For android versions less than 6 just adding these permission requests to the manifest works:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
But for android version 6 I need explicitly request permission too to get the location:
requestPermissions(new String[]{ Manifest.permission.ACCESS_FINE_LOCATION}, 1340);
The problem is that If I add the above code the App works only on android 6 and fails to run on lower versions as requestPermissions does not exist on lower versions. and If I remove it I won't be able to get the location on android 6.
What can I do that my app be able to get the location on android 4.0.3+

You can check the API level of the phone that is running your app like this:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
//later than 4.x - so here you can run the code
//ideally you want to make this call in a helper method which you then annotate with the #TargetApi
requestPermissions(new String[]{ Manifest.permission.ACCESS_FINE_LOCATION}, 1340);
}
else{
//nothing to do in your case ?
}
You can also use #TargetApi(Build.VERSION_CODES.LOLLIPOP) in the methods where you want to make "Lollipop+" calls.

Related

How do I request push notification permissions for android 13?

I've looked through this guide for android 13 push notifications
https://developer.android.com/about/versions/13/changes/notification-permission#user-choice
And I've looked at the guide for requesting permissions
https://developer.android.com/training/permissions/requesting#java
I've updated my compile and target to api 32.
Here is my code so far (in progress). Right now I'm just trying to get the notification prompt to show up.
if (Build.VERSION.SDK_INT >= 32) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_NOTIFICATION_POLICY) == PackageManager.PERMISSION_GRANTED)
return;
ActivityResultLauncher<String> launcher = registerForActivityResult(
new ActivityResultContracts.RequestPermission(), isGranted -> {
}
);
launcher.launch(Manifest.permission.POST_NOTIFICATIONS);
}
The problem I have is I get an error cannot find symbol variable POST_NOTIFICATIONS.
What is the proper manifest permission for push notifications?
Maybe I'm a bit late to the party, I know... But I hope this can help others at least. You need to use compileSdkVersion 33 in your gradle file at the Module level. Then you'll be allowed to use the POST_NOTIFICATIONS permission without any issue.
Android 13 (API level 33) and higher supports a runtime permission for sending non-exempt (including Foreground Services (FGS)) notifications from an app: POST_NOTIFICATIONS. This change helps users focus on the notifications that are most important to them.
reference here
So you need to add this permission to AndroidManifest.xml
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
You need to follow few steps, add post notifications permission in manifest
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
then in your controller as for run time permission like generally we ask:
if (Build.VERSION.SDK_INT >= 33) {
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.POST_NOTIFICATIONS},101);
}
else {
createChannel();
}
}
Then Need to handle permission result as usual
How to add run time permission for notification permission in android studio,
Apps targeting Android 13 will now need to request notification permission from the user before posting notifications,”
Behavior changes: Apps targeting Android 13 or higher
https://developer.android.com/about/versions/13/behavior-changes-13
Add on manifest: uses-permission android: name="android.permission.POST_NOTIFICATIONS
and
Add in MainActivity after onCreate:
if (ContextCompat.checkSelfPermission(this, POST_NOTIFICATIONS) == PackageManager.PERMISSION_DENIED) {
ActivityCompat.requestPermissions(this, new String[]{POST_NOTIFICATIONS}, 1);
}

Android 12 not showing correct permissions request screen

My app requires precise user location because it requires the user to be at specific locations to perform tasks. I have followed the documentation for the proper way to request both ACCESS_FINE_LOCATION and ACCESS_COARSE_LOCATION together.
class LocationChooserFragment : BottomSheetDialogFragment() {
// only relevant parts shown
/**
* A utility class that holds all the code for requesting location updates,
* so that we can re-use it in multiple fragments.
*/
private var locationTracker: LocationTracker? = null
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
// all the other initialization for viewbinding
tryToGetLocationUpdates()
}
private fun tryToGetLocationUpdates() {
val request = registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions ->
if (permissions[Manifest.permission.ACCESS_FINE_LOCATION] == true && permissions[Manifest.permission.ACCESS_FINE_LOCATION] == true) {
requestLocationUpdates()
}
}
when {
ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED -> {
Timber.i("Already have required permissions")
requestLocationUpdates()
}
shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION) ||
shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_COARSE_LOCATION) -> {
Timber.i("Showing permission rationale dialog")
// A wrapper to show a dialog that explains what we need permissions for
alertDialog(
title = getString(R.string.permissions),
msg = getString(R.string.why_we_need_location),
onClick = { yes ->
if (yes) {
request.launch(arrayOf(
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION
))
}
}
)
}
else -> {
Timber.i("Prompting for location permissions")
request.launch(arrayOf(
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION
))
}
}
}
private fun requestLocationUpdates() {
if (locationProvider == null) {
locationProvider = LocationProvider(requireContext())
}
locationProvider?.requestLocationUpdates()
}
}
The problem I have is that my users are not getting prompted to allow precise location.
I expect to see the prompt in Figure 3 from the documentation:
Figure 3. System permissions dialog that appears when your app requests both ACCESS_FINE_LOCATION and ACCESS_COARSE_LOCATION in a single runtime request.
Instead, I see the prompt in Figure 2 from the documentation:
Figure 2. System permissions dialog that appears when your app requests ACCESS_COARSE_LOCATION only.
Additionally, I expect that when I already have COARSE permission and I request FINE and COARSE permission again, I should see the "Upgrade to Precise permission" dialog, but I don't see any prompt at all.
I have tested this on Pixel 3a (physical device and emulator) as well as received reports from other users on various Pixel and Samsung Galaxy devices that are running Android 12.
The problem was not present when we used compileSdk 30 and targetSdkVersion 30 in build.gradle, but we need to be able to support new features and new versions of Android (and to be able to upgrade to dependencies that only support building with newer SDK versions.
Why is the permission dialog not showing properly?
Comparing my AndroidManifest.xml to the generated file in the built app (using the "Analyze APK" feature in Android Studio), I discovered that the generated APK file had the following entry:
<uses-permission
android:name="android.permission.ACCESS_FINE_LOCATION"
android:maxSdkVersion="30" />
Clearly, the maxSdkVersion is preventing the OS from giving me the permission I need.
Using grep on the app\build directory, I found app\build\intermediates\manifest_merge_blame_file\appnameDebug\manifest-merger-blame-appname-debug-report.txt, which included these lines:
17 <uses-permission
17-->C:\path\to\my\appname\app\src\main\AndroidManifest.xml:12:2-76
18 android:name="android.permission.ACCESS_FINE_LOCATION"
18-->C:\path\to\my\appname\app\src\main\AndroidManifest.xml:12:19-73
19 android:maxSdkVersion="30" />
19-->[com.github.50ButtonsEach:flic2lib-android:1.3.1] C:\Users\moshe\.gradle\caches\transforms-3\dced3886509296f1029e8245af379a07\transformed\jetified-flic2lib-android-1.3.1\AndroidManifest.xml:17:9-35
It turns out the developers of this library originally used ACCESS_FINE_LOCATION for connecting to nearby Bluetooth devices, and since Android 12 has separate permissions for that, they don't need it anymore so they added a max SDK version.
I added the tools:remove="android:maxSdkVersion" property to the ACCESS_FINE_LOCATION <uses-permission /> element, and now my permissions work properly.

Android ACTIVITY RECOGNITION permission missing

I am targeting SDK 29, and activity transition API works perfectly on devices running 29 (ie Android 10). According to the docs, if you are targeting SDK 29, but running on a lower SDK, the permission should be granted automatically.
I have tried both, separately and together
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION"/>
<uses-permission android:name="com.google.android.gms.permission.ACTIVITY_REC‌​OGNITION"/>
I can't ask for the permission in a pop-up ( nothing happens). When I try to register the Transitions API on phones < Andorid 10, I get the error:
com.google.android.gms.common.api.b: 10: SecurityException: Activity detection usage requires the ACTIVITY_RECOGNITION permission
If I set the target SDK to 28, everything works perfectly on all phones, but I need to target 29 for other reasons. I am pulling my hair out.
To be clear, it works perfectly on Android 10, just not below. Further code for clarification:
public void askForActivityPermission(View v) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
Log.d(TAG, "askForActivityPermission: q or greater");
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACTIVITY_RECOGNITION}, PERMISSION_REQUEST_ACTIVITY_RECOGNITION);
} else {
Log.d(TAG, "askForActivityPermission: less than q");
moveNextStep();
}
}
#Override
public void onRequestPermissionsResult(
int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
String permissionResult = "Request code: " + requestCode + ", Permissions: " +
Arrays.toString(permissions) + ", Results: " + Arrays.toString(grantResults);
Log.d(TAG, "onRequestPermissionsResult(): " + permissionResult);
if (requestCode == PERMISSION_REQUEST_ACTIVITY_RECOGNITION) {
Log.d(TAG, "onRequestPermissionsResult: permission granted?");
moveNextStep();
}
There were some updates in API Level 29.
1.Add the permission to the manifest file.
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION"/>
2.Check if the permission is granted:
if (ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.ACTIVITY_RECOGNITION)
!= PackageManager.PERMISSION_GRANTED) {
// Permission is not granted
}
3.If permission isn't already granted, request the permission:
ActivityCompat.requestPermissions(thisActivity,
arrayOf(Manifest.permission.ACTIVITY_RECOGNITION),
MY_PERMISSIONS_REQUEST_ACTIVITY_RECOGNITION);
Here are some useful docs.
https://developer.android.com/about/versions/10/privacy/changes#physical-activity-recognition
https://developers.google.com/fit/android/authorization
Ok, i have got it working, but it makes no sense, what so ever, like none.
<uses-permission android:name="com.google.android.gms.permission.ACTIVITY_REC‌​OGNITION" />
<uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION" />
The top one does not work, the bottom one does. Can anyone tell me why?
I have tried all the suggested solutions, but none of them worked out. I've tried all combinations of com.google.android.gms.permission.ACTIVITY_REC‌​OGNITION and com.google.android.gms.permission.ACTIVITY_RECOGNITION
with minSdkVersion 26 and targetSdkVersion 30
using an Android 9 (API 28) Wear OS emulator.

Android - Camera permissions denied without prompting

I was running into issues with the manual process behind requesting permissions (just kept falling into the 'denied' code), so I switched over to using Dexter to simplify. I implemented the following code in onCreate(), and I did a fresh install of the app:
Dexter.withActivity(this)
.withPermission(Manifest.permission.CAMERA)
.withListener(new PermissionListener() {
#Override public void onPermissionGranted(PermissionGrantedResponse response) {
Log.d(TAG, "GRANTED!");
initCamera();
}
#Override public void onPermissionDenied(PermissionDeniedResponse response) {
Log.d(TAG, "DENIED!");
}
#Override public void onPermissionRationaleShouldBeShown(PermissionRequest permission, PermissionToken token) {
Log.d(TAG, "PERMISSION RATIONAL SHOULD BE SHOWN!");
}
}).check();
It immediately falls into the "DENIED!" log, and it never even prompts me. I tried this particular code to attempt multiple permissions (which is ultimately what I need to do):
Dexter.withActivity(activity)
.withPermissions(Manifest.permission.CAMERA,
Manifest.permission.RECORD_AUDIO,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
.withListener(new MultiplePermissionsListener() {
#Override
public void onPermissionsChecked(MultiplePermissionsReport report) {
Log.d(TAG, "Accepted: " + report.getGrantedPermissionResponses().size() + " | Denied: " + report.getDeniedPermissionResponses().get(0).getPermissionName());
}
#Override
public void onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions, PermissionToken token) {
Log.d(TAG, "continuing permissions request..");
token.continuePermissionRequest();
}
})
.check();
It prompts for permissions to Record Audio, then it asks about Access to photos/media/files on the device (it never asks about Camera). Then once that's done, it prints the log: "Accepted 3 | Denied: android.permission.CAMERA". It denies it without even prompting me again.
My Manifest is set properly to have CAMERA in the proper place (outside of the 'application' tag). See below for reference:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.my.app">
<uses-feature
android:name="android.hardware.camera"
android:required="true" />
<permission
android:name="${applicationId}.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
etc..
Odd thing is that when I go into Settings > Applications > MyApp, the Camera option is not even displayed in there.
I don't think it's an issue with Dexter, since it's doing basically the same thing when I set it up manually (and I confirmed that it's definitely setup properly in that case after looking at a few top S.O. posts).
Any thoughts on what the issue could be here? FYI - I'm using a Galaxy S6, OS 6.0.2. The other users experiencing this seem to be other devices with 6.0+ OS. Thanks in advance!
EDIT:
Testing various devices, it works on some and does not work on some:
Moto X (OS 5.0) - Broken
Nexus 5 (OS 7.0) - Works
Samsung S6 (OS 6.0.1) - Broken
Broken Moto X (OS 6.0) - Works
Doesn't seem to be a solid pattern.. Definitely strange. I also started a brand new project and ran the same code - worked fine and allowed access to my camera. So it doesn't appear to be fully device-specific..
The issue with this turned out to be a third-party library, which had this line in their Manifest, overriding our own permission:
<uses-permission android:name="android.permission.CAMERA" tools:node="remove" />
The solution was either to manually import their project as a module (rather than use gradle), and then comment out that line, OR more simple - you can add "tools:node="replace"" to the end of the main project's CAMERA permission line, and it works fine after that; no need to import the project with the latter approach.
What you need is native runtime permissions not dexter, Beginning in Android 6.0 (API level 23), users grant permissions to apps while the app is running, not when they install the app. This approach streamlines the app install process, since the user does not need to grant permissions when they install or update the app. It also gives the user more control over the app's functionality; for example, a user could choose to give a camera app access to the camera but not to the device location. The user can revoke the permissions at any time, by going to the app's Settings screen.
// Assume thisActivity is the current activity
int permissionCheck = ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.YOUR_PERMISSION);
then what you need is to request a certain permission if that check is false,
ActivityCompat.requestPermissions(thisActivity,
new String[]{Manifest.permission.YOUR_PERMISSION},
MY_PERMISSION_CODE);
Bare in ind that you need to as well declare them also in the manifest, based on what you have shown still that was already done. For more information.

use android 6.0 api 23 permissions to low devices(like api 22 almost)

it's my first question here and maybe i'll explain a little bad, but okay look:
I have a project with its using api 22 library, but compiles with android 6.0(api 23), and i wanna continue with api 22 library, but when i run my project with android 6.0 device i have problems with the permissions...
My question: is there a way that you can work in, for example, Android 5.1.1 and compile with Android 6.0 with the necessary permission's methods? i mean, can i add some library, for use callback like onRequestPermissionsResult(...) ? i tried adding api 23 library to my project but isnt works his methods, any suggestion...??
1. Checkout if the permission you need is a dangerous permission at this page.
2. List all dangerous permissions you need in a String array like below.
private static final String[] REQUIRED_PERMISSIONS = new String[]{your_permissions_here};
3. Add the following code to your onCreate().
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
LinkedList<String> missingPermissions = new LinkedList<>();
for(String p : REQUIRED_PERMISSIONS){
if(checkSelfPermission(p) != PackageManager.PERMISSION_GRANTED){
missingPermissions.add(p);
}
}
if(!missingPermissions.isEmpty()){
String[] mpArray = new String[missingPermissions.size()];
missingPermissions.toArray(mpArray);
requestPermissions(mpArray, REQUEST_PERMISSIONS);
}
}
REQUEST_PERMISSIONS is a constant integer to identify this requesting.

Categories

Resources