I'm trying to do a quick test app that allow me to turn on a off Bluetooth and I code the listeners for clicks in the buttons. This is the one that turn Bluetooth on:
mOnBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (!mBlueAdapter.isEnabled()) {
showToast("Turning On Bluetooth...");
//intent to on BT
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
//Android Studio force me to do this check.
if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
showToast("I'm stuck here");
return;
}
startActivityForResult(intent, REQUEST_ENABLE_BT);
} else {
showToast("Bluetooth is already on");
}
}
});
The thing is that Android Studio force me to add the:
if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
showToast("I'm stuck here");
return;
}
check error but even I have all the permissions they asked me in AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.Bluetooth">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
the program always fails the check error and ended up in the "You're stuck message", what is happening here?
Turning bluetooth on and requesting `BLUETOOTH_CONNECT permission is a different thing.
Request permission like BLUETOOTH_CONNECT, see https://developer.android.com/training/permissions/requesting.
Turning bluetooth on
if (bluetoothAdapter?.isEnabled == false) {
val enableBtIntent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT)
}
If enabling Bluetooth succeeds, your activity receives the RESULT_OK result code in the onActivityResult() callback. If Bluetooth was not enabled due to an error (or the user responded "Deny") then the result code is RESULT_CANCELED.
See Set up Bluetooth for details.
Related
public void startScan() {
final List<MyBluetoothDevice> arrayOfFoundBTDevices = new ArrayList<>();
// start looking for bluetooth devices
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
boolean scanStatus = mBluetoothAdapter.startDiscovery();
Timber.d("SCANNING_STATUS : " + scanStatus);
// Discover new devices
// Create a BroadcastReceiver for ACTION_FOUND
mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Timber.d("onReceiveSignal");
String action = intent.getAction();
// When discovery finds a device
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Get the bluetoothDevice object from the Intent
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
Timber.d("Discovery Finished ");
AppUtils.showToast(context, "Scanning restart");
mBluetoothAdapter.startDiscovery();
}
}
};
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothDevice.ACTION_FOUND);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
context.registerReceiver(mReceiver, filter);
}
I am try to scan nearby bluetooth devices.
But, BluetoothAdapter.getDefaultAdapter().startDiscovery() method returns false in API Level 29 but working in API Level 26
-------------Permission defined in AndroidManifest.xml-----------
Can't find solution for Android 10
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.bluetoothexample">
<uses-feature
android:name="android.hardware.bluetooth"
android:required="true" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<application
android:name=".App"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".FoundBTDevices" />
</application>
</manifest>
You need to turn ON location to scan nearby devices in Android 10.
not sure if you are still looking for the answer.
From API 29, Google requires LOCATION group permission to use some Bluetooth function. So you will need to add some <uses-permission> tag to Android Manifest, and DON'T forget to request these permissions at RUNTIME.
I don't remember exactly which location is needed, so you can add all 3 following:
android.permission.ACCESS_FINE_LOCATION
android.permission.ACCESS_COARSE_LOCATION
android.permission.ACCESS_BACKGROUND_LOCATION
Today I got a rejection from Google for my app Facetocall
Your app does not appear to prompt the user to be a default handler prior to requesting related permissions as required by the policy.
Please make necessary changes in order to comply with policy
requirements and resubmit your app through a Declaration Form.
Default handler capability was listed on your declaration form, but your app has no default handler capability.
My goal is to make a default dialer app.
Here is my Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.gazman.beep"
android:installLocation="preferExternal">
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.READ_CALL_LOG" />
<uses-permission android:name="android.permission.WRITE_CALL_LOG" />
<uses-permission android:name="android.permission.SEND_SMS" />
... and other permissions
<application
android:name=".application.BeepApp"
android:allowBackup="false"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
tools:ignore="GoogleAppIndexingWarning">
<activity
android:name=".system_intents.IntentsActivity"
android:launchMode="singleTask"
android:noHistory="true"
android:theme="#style/Theme.Transparent">
<intent-filter>
<action android:name="android.intent.action.DIAL" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.DIAL" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="tel" />
</intent-filter>
</activity>
<activity
android:name=".call.CallActivity"
android:launchMode="singleTop"
android:screenOrientation="portrait"
android:showForAllUsers="true" />
<service
android:name="com.gazman.beep.call.MyInCallService"
android:permission="android.permission.BIND_INCALL_SERVICE">
<meta-data
android:name="android.telecom.IN_CALL_SERVICE_UI"
android:value="true" />
<intent-filter>
<action android:name="android.telecom.InCallService" />
</intent-filter>
</service>
... And other declarations
</application>
</manifest>
And here is what I do when my app launches:
private void checkDefaultHandler() {
if (isAlreadyDefaultDialer()) {
return;
}
Intent intent = new Intent(TelecomManager.ACTION_CHANGE_DEFAULT_DIALER);
intent.putExtra(TelecomManager.EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME, getPackageName());
if (intent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(intent, REQUEST_CODE_SET_DEFAULT_DIALER);
}
else{
throw new RuntimeException("Default phone functionality not found");
}
}
private boolean isAlreadyDefaultDialer() {
TelecomManager telecomManager = (TelecomManager) getSystemService(TELECOM_SERVICE);
return getPackageName().equals(telecomManager.getDefaultDialerPackage());
}
What am I missing here?
I tried submitting the form again and this time I add a video that shows my app on an emulator(I see the same behavior on all the real devices too) here is the reply that I got back:
Your app does not appear to prompt the user to be a default handler prior to requesting related permissions as required by the policy.
Please make necessary changes in order to comply with policy
requirements and resubmit your app through a Declaration Form.
to make default dialer app, you need to do 2 things :
1. add the following permissions in your android manifest
<activity>
<intent-filter>
<action android:name="android.intent.action.DIAL"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
actually performing the check :
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_layout)
...
checkDefaultDialer()
...
}
const val REQUEST_CODE_SET_DEFAULT_DIALER=200
private fun checkDefaultDialer() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M)
return
val telecomManager = getSystemService(TELECOM_SERVICE) as TelecomManager
val isAlreadyDefaultDialer = packageName == telecomManager.defaultDialerPackage
if (isAlreadyDefaultDialer)
return
val intent = Intent(TelecomManager.ACTION_CHANGE_DEFAULT_DIALER)
.putExtra(TelecomManager.EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME, packageName)
startActivityForResult(intent, REQUEST_CODE_SET_DEFAULT_DIALER)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
when (requestCode) {
REQUEST_CODE_SET_DEFAULT_DIALER -> checkSetDefaultDialerResult(resultCode)
}
}
private fun checkSetDefaultDialerResult(resultCode: Int) {
val message = when (resultCode) {
RESULT_OK -> "User accepted request to become default dialer"
RESULT_CANCELED -> "User declined request to become default dialer"
else -> "Unexpected result code $resultCode"
}
Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
}
You don't need to panic. This kind of conversation happened with me also, regarding AdMob content on my app. I declared everything perfectly but still they were saying content rating not fine due to type of Ads my app was showing. When more mails exchanged they sent me screenshot with the proof of wrong Ads, so finally i checked my whole code again and found my mistake.
The point here is that Google is good at what they do, and if they said so, then your app lacks something.
To be very honest, your app did not ask the user anywhere to allow it to be set as default, instead it set itself default in the background. You should ask for every permission required by your app that are critical and can be used by any app or virus or spyware to interfere with user privacy.
You can do that with a function like in the following example, which is asking for Camera permission from the user:
private void requestCameraPermission() {
Log.i(TAG, "CAMERA permission has NOT been granted. Requesting permission.");
// 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.
Log.i(TAG,
"Displaying camera permission rationale to provide additional context.");
Snackbar.make(mLayout, R.string.permission_camera_rationale,
Snackbar.LENGTH_INDEFINITE)
.setAction(R.string.ok, new View.OnClickListener() {
#Override
public void onClick(View view) {
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.CAMERA},
REQUEST_CAMERA);
}
})
.show();
} 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)
}
You can see the complete repository at Google Samples
And don't worry. If you rectify this problem, they will accept your application, as they did for mine.
in case anyone comes cross this post . . .
I used this for asking the user for changing the default dailer.
Know that the there gonna be 2 windows prompting(for me it was fine).
private void setDefaultDialer()
{
AlertDialog.Builder builder;
builder = new AlertDialog.Builder(this);
builder.setMessage("Do you want to make Cricket your default Dialer?(it will not cover or replace your dialer)")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
defaultDialerPackage = "cricket";
Intent intent = new Intent(TelecomManager.ACTION_CHANGE_DEFAULT_DIALER);
startActivityForResult(intent.putExtra(TelecomManager.EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME,getPackageName()),REQUEST_CODE_SET_DEFAULT_DIALER);
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
Toast.makeText(getApplicationContext(),"Cancelled - No action was taken",
Toast.LENGTH_SHORT).show();
}
});
AlertDialog alert = builder.create();
alert.setTitle("Cricket need default dialer permission!!");
alert.show();
}
Yes, I did take a look at all other similar question but they are not working for me.
I am trying to get a list of wifi connections available near me.
This is how I am doing it:
public class WifiFunction {
private final String tag = WifiFunction.class.getSimpleName();
private WifiManager wifiManager;
public List<WifiDetail> getListofWifi(Context context) {
List<WifiDetail> wifiDetails = new ArrayList<>();
List<ScanResult> results = wifiManager.getScanResults();
Log.d(tag,"Wifi Details " + wifiManager.getScanResults().size());
for (ScanResult result : results) {
wifiDetails.add(new WifiDetail(result.BSSID, result.SSID));
Log.d(tag, result.BSSID + result.SSID);
}
return wifiDetails;
}
public void startScan(Context context)
{
wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
wifiManager.startScan();
IntentFilter filter = new IntentFilter();
filter.addAction(SCAN_RESULTS_AVAILABLE_ACTION);
context.registerReceiver(new resultReciever(this),filter);
}
}
Receiver class :
public class resultReciever extends BroadcastReceiver {
private WifiFunction wifiFunction;
resultReciever(WifiFunction wifiFunction)
{
this.wifiFunction = wifiFunction;
}
#Override
public void onReceive(Context context, Intent intent) {
Log.d("Receiver","started");
wifiFunction.getListofWifi(context);
}
}
From Main Activity I am just calling:
(new WifiFunction()).startScan(this);
that is after checking for permissions.
Yes, I did declare receiver in the manifest.
I am asking for access and change of wifi state and access coarse location.
Still, Log prints the size of the returned list to be 0. What am I doing wrong? How to solve it?
Edit: Manifest
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permisiion.ACCESS_COARSE_LOCATION" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".resultReciever"/>
</application>
EDIT 2:
Runtime Permission:
private boolean checkPermission() {
List<String> permissionsList = new ArrayList<String>();
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_WIFI_STATE) != PackageManager.PERMISSION_GRANTED) {
permissionsList.add(Manifest.permission.ACCESS_WIFI_STATE);
}
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CHANGE_WIFI_STATE) != PackageManager.PERMISSION_GRANTED) {
permissionsList.add(Manifest.permission.CHANGE_WIFI_STATE);
}
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
permissionsList.add(Manifest.permission.ACCESS_COARSE_LOCATION);
}
if (permissionsList.size() > 0) {
ActivityCompat.requestPermissions(this, permissionsList.toArray(new String[permissionsList.size()]),
1);
return false;
}
return true;
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions,
int[] grantResults) {
switch (requestCode) {
case 1:
(new WifiFunction()).startScan(this);
break;
}
}
This worked. I just had to give Access_Fine_Location permission.
Adding the following line to your manifest is not necessarily enough to fix the problem!
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
If your targetSdkVersion is 23 or greater, then (because this is one of the dangerous permissions) you must also do something like this
ActivityCompat.requestPermissions(Main.this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION }, 1);
Doing this fixed the problem for both me and the OP. I double-checked the assertion by reversing the changes to recreate the problem.
NB: There are 2 highly remarkable elements here:
(1) Nowhere is it documented that WifiManager.startScan() requires this permission.
(2) My app is based on a working (pre-API 23) app that does NOT have Manifest.permission.ACCESS_FINE_LOCATION
You were missing permission to access Access_Fine_Location, but starting from Android 6 granting all the permissions won't yield the expected output. You have to enable location services in order to get desired results. Granting permissions is just the half work done.
You can also fire an intent to redirect user to this setting:
Intent myIntent = new Intent( Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(myIntent);
Location services are necessary because when you access the scan results, you can access the information like BSSID (address of the access point). This information can also be used to detect the location of device. By requiring location services, OS ensures that user understands their location information is being accessed when they use your app.
Set permission in your AndroidManifest.xml
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Now go to settings > Apps > your app > Permissions. Make sure Location is switched on.
Now go to Settings > Location make sure its switched on.
You should be able to get results in WifiManger.getScanResults()
A successful call to WifiManager.getScanResults() requires any one of the following permissions:
ACCESS_FINE_LOCATION
ACCESS_COARSE_LOCATION
CHANGE_WIFI_STATE
If the calling app does not have any of these permissions, the call fails with a SecurityException.
So Android 8 able to retrive all wifi APs by just enabling the CHANGE_WIFI_STATE
I've a Fragment (support.v4) in a ViewPager with the which calls PlacePicker UI and then updated on a TextView. My code is as follows,
public void openPlacePicker() {
try {
PlacePicker.IntentBuilder intentBuilder = new PlacePicker.IntentBuilder();
Intent intent = intentBuilder.build(getContext());
// Start the Intent by requesting a result, identified by a request code.
startActivityForResult(intent, PLACE_PICKER);
} catch (GooglePlayServicesRepairableException e) {
GooglePlayServicesUtil
.getErrorDialog(e.getConnectionStatusCode(), getActivity(), 0);
} catch (GooglePlayServicesNotAvailableException e) {
Toast.makeText(getContext(), "Google Play Services is not available.",
Toast.LENGTH_LONG)
.show();
}
}
And the OnActivityResult is,
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.i(TAG, "Request Code:" + requestCode);//This is printed
if(requestCode == PLACE_PICKER){
Log.d(TAG,"Reached in if()"); //Never printed
}
switch (requestCode) { //Never reached
case PLACE_PICKER:
if (resultCode == Activity.RESULT_OK) {
final Place place = PlacePicker.getPlace(data, getContext());
final CharSequence name = place.getName();
//EventBus.getDefault().post(new NotifyEvent(NotifyEvent.NotifyType.PLACE_PICKED, (String) name));
}
}
}
So the problem is that, the conditional statements never gets executed. The Log before if() is printed. But the Log inside the if() is not printed.
Weird thing is the android-place-picker sample from GitHub is working fine.
I have tried the following:
Clean Project
Clear Data and re-install on device
IDE clear cache and restart
Any ideas?
--EDIT--
Manifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.apps.maps">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="com.apps.maps.permission.MAPS_RECEIVE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<permission android:name="com.apps.maps.permission.MAPS_RECEIVE" android:protectionLevel="signature" />
<application android:name=".MyApplication" android:allowBackup="true" android:icon="#mipmap/ic_launcher" android:label="#string/app_name" android:supportsRtl="true" android:theme="#style/AppTheme">
<meta-data android:name="com.google.android.geo.API_KEY" android:value="#string/google_maps_key" />
<activity android:name=".activity.MainActivity" android:label="#string/title_activity_maps">
</activity>
</application>
</manifest>
I know this is an older thread but it has helped me to resolve a similar issue to the original problem. Raman Bhavsar's 10/10/15 comment was the right question to ask. I had forgotten to enable the Places API in the Google Developer Console, and once I did I was able to hit my breakpoint in the onActivityResult method.
I am trying to utilize GPS in Android (2.2 and 2.3) but am getting the following error when I try to use the LocationManager object:
WARN/System.err(522): java.lang.SecurityException: Provider network requires ACCESS_FINE_LOCATION or ACCESS_COARSE_LOCATION permission
I have researched the issue in other posts and they are typically due to issues with AndroidManifest.xml. However, mine appears to be fine:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.thedigitalsean.examples"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name=".GetLocation"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permisssion.ACCESS_FINE_LOCATION"></uses-permission>
<uses-permission android:name="android.permisssion.ACCESS_COARSE_LOCATION"></uses-permission>
<uses-permission android:name="android.permisssion.INTERNET"></uses-permission>
</manifest>
Here is the offending line of code in my onCreate method in the GetLocation Activity, encased in a try/catch block:
LocationManager locManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
final LocationListener locListener = new MyLocListener();
try{
locManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locListener);
}
catch (SecurityException se){
((TextView)findViewById(R.id.infobox)).setText(se.toString());
se.printStackTrace();
}
This is the first app I have written where I need to request android permissions and have so far been unsuccessful in being granted any permissions whatsoever. Is there something I am missing in my manifest or perhaps in my eclipse configuration?
You misspelled permission
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
I was having the same problem and could not figure out what I was doing wrong. Turns out, the auto-complete for Android Studio was changing the text to either all caps or all lower case (depending on whether I typed in upper case or lower cast words before the auto-complete). The OS was not registering the name due to this issue and I would get the error regarding a missing permission. As stated above, ensure your permissions are labeled correctly:
Correct:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Incorrect:
<uses-permission android:name="ANDROID.PERMISSION.ACCESS_FINE_LOCATION" />
Incorrect:
<uses-permission android:name="android.permission.access_fine_location" />
Though this may seem trivial, its easy to overlook.
If there is some setting to make permissions non-case-sensitive, please add a comment with the instructions. Thank you!
Compatible with all SDK versions (android.permission.ACCESS_FINE_LOCATION became dangerous permission in Android M and requires user to manually grant it).
In Android versions below Android M ContextCompat.checkSelfPermission(...) always returns true if you add these permission(s) in AndroidManifest.xml)
public void onSomeButtonClick() {
...
if (!permissionsGranted()) {
ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.ACCESS_FINE_LOCATION}, 123);
} else doLocationAccessRelatedJob();
...
}
private Boolean permissionsGranted() {
return ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED);
}
#Override
public void onRequestPermissionsResult(final int requestCode, #NonNull final String[] permissions, #NonNull final int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 123) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission granted.
doLocationAccessRelatedJob();
} else {
// User refused to grant permission. You can add AlertDialog here
Toast.makeText(this, "You didn't give permission to access device location", Toast.LENGTH_LONG).show();
startInstalledAppDetailsActivity();
}
}
}
private void startInstalledAppDetailsActivity() {
Intent i = new Intent();
i.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
i.addCategory(Intent.CATEGORY_DEFAULT);
i.setData(Uri.parse("package:" + getPackageName()));
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
}
in AndroidManifest.xml:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
I Had an strange issue and realized that the text of manifest permission has a a space character at the end. removed it and it is working just fine.
Before
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION "/>
After
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
just remove s from the permission you are using sss you have to use ss