How to enable NFC setting - android

I am able to read and wirte in my NFC demo app but I need to check if the NFC option in setting menu is enabled or not . If its not enable I want to direct the user to the setting menu(I know how to do this) similar to NFC TagWriter by NXP.
In my application I am using the following SDK version
<uses-sdk android:minSdkVersion="7" />
<uses-sdk android:maxSdkVersion="16"/>
I am unable to check if the setting is enabled or not.

TNR gets it right, however also note that from Android version 16, there is a more specific settings action for NFC:
protected void startNfcSettingsActivity() {
if (android.os.Build.VERSION.SDK_INT >= 16) {
startActivity(new Intent(android.provider.Settings.ACTION_NFC_SETTINGS));
} else {
startActivity(new Intent(android.provider.Settings.ACTION_WIRELESS_SETTINGS));
}
}

Use the below code to get the NFCAdapter.
NfcAdapter nfcAdpt = NfcAdapter.getDefaultAdapter(this);
if(nfcAdpt!=null)
{
if(nfcAdpt.isEnabled())
{
//Nfc settings are enabled
}
else
{
//Nfc Settings are not enabled
}
}
If you want to navigate user to Settings of NFC then use below Code
Intent setnfc = new Intent(Settings.ACTION_WIRELESS_SETTINGS);
startActivity(setnfc);
There is no NFC for API version 7. So change you manifest file as below
<uses-sdk android:minSdkVersion="10" />
<uses-sdk android:maxSdkVersion="16"/>

if (Build.VERSION.SDK_INT >= 10) {
i = new Intent("android.settings.NFC_SETTINGS");
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(i);
} else {
i = new Intent(Settings.ACTION_WIRELESS_SETTINGS);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(i);
}

Related

Allow WRITE_SETTINGS permission with Android 11 from manifest

I have an application that is meant for "locked Android phones" meaning the application is the only application users will have access to on that phone and that is done using MySync.
Before the application had to support Android 11 (complieSdkVersion 30), the user was able to change screen brightness and other system settings from the application (Since the user did not have access to the settings app). But now the WRITE_SETTINGS and CHANGE_CONFIGURATION are deprecated and no longer have desirable effects.
I am aware that it is possible to prompt the user to accept the settings with this prompt:
boolean permission;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
permission = Settings.System.canWrite(context);
} else {
permission = ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_SETTINGS) == PackageManager.PERMISSION_GRANTED;
}
if (permission) {
initApp();
} else {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
intent.setData(Uri.parse("package:" + context.getPackageName()));
startActivityForResult(intent, SettingsActivity.CODE_WRITE_SETTINGS_PERMISSION);
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_SETTINGS}, SettingsActivity.CODE_WRITE_SETTINGS_PERMISSION);
}
}
But since the user does not have access to the settings application in my app eco-system, I can not give the user a prompt that would open up the settings and allow the user to stay in the settings.
Is there no way around this permission request and is there no way to do it on the manifest level or some other way?

Android request ACCESS_NOTIFICATION_POLICY and mute phone

I am a beginner Android developer and I have an interesting question at hand. I am trying to mute the phone with
AudioManager audioManager = (AudioManager) getApplicationContext().getSystemService(Context.AUDIO_SERVICE);
audioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
But I am getting the following error
java.lang.SecurityException: Not allowed to change Do Not Disturb state
Now I do not understand this, as I am using EasyPermissions (https://github.com/googlesamples/easypermissions) and requesting the permission
Manifest.permission.ACCESS_NOTIFICATION_POLICY
But it does not ask me to allow anything on app startup. I figured this is because ACCESS_NOTIFICATION_POLICY is a non dangerous permission and thus granted at installation time, for which I also added it to my manifest.xml as thus
<uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" />
But it is still not working, my app is crashing because it throws the "Not allowed to change to Do Not Disturb state" error. Wierdly I found that I can request to go to the "Do Not Disturb access" screen with the following code
Intent intent = new Intent(
android.provider.Settings
.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS);
startActivity(intent);
What am I doing wrong here? Why cannot I request this permissions as a normal permission? Do I really have to go through the intent to allow my app to mute the phone?
From the AudioManager#setRingerMode() reference:
From N onward, ringer mode adjustments that would toggle Do Not Disturb are not allowed unless the app has been granted Do Not Disturb Access.
From API level 23 and onward, you have to declare ACCESS_NOTIFICATION_POLICY permission in the manifest AND then the user needs to grant your app access to toggle Do Not Disturb. You can check if the access is granted with NotificationManager#isNotificationPolicyAccessGranted(). If your package do not have access, start an ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS intent so the user can give your app access.
NotificationManager n = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
if(n.isNotificationPolicyAccessGranted()) {
AudioManager audioManager = (AudioManager) getApplicationContext().getSystemService(Context.AUDIO_SERVICE);
audioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
}else{
// Ask the user to grant access
Intent intent = new Intent(android.provider.Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS);
startActivityForResult(intent);
}
I will post an answer on how I managed to solve this issue for androids over 23 and under 23 with a startActivityForResult callback
the requestMutePhonePermsAndMutePhone() function is called in the main actions onCreate function.
Mind you the code is very much intrusive, since the Settings menu is permacalled until you accept the Do Not Disturb permissions, but one can easily accomodate this code for their personal needs and maybe build a question prompt, etc...
private void requestMutePhonePermsAndMutePhone() {
try {
if (Build.VERSION.SDK_INT < 23) {
AudioManager audioManager = (AudioManager) getApplicationContext().getSystemService(Context.AUDIO_SERVICE);
audioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
} else if( Build.VERSION.SDK_INT >= 23 ) {
this.requestDoNotDisturbPermissionOrSetDoNotDisturbApi23AndUp();
}
} catch ( SecurityException e ) {
}
}
private void requestDoNotDisturbPermissionOrSetDoNotDisturbApi23AndUp() {
//TO SUPPRESS API ERROR MESSAGES IN THIS FUNCTION, since Ive no time to figrure our Android SDK suppress stuff
if( Build.VERSION.SDK_INT < 23 ) {
return;
}
NotificationManager notificationManager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
if ( notificationManager.isNotificationPolicyAccessGranted()) {
AudioManager audioManager = (AudioManager) getApplicationContext().getSystemService(Context.AUDIO_SERVICE);
audioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
} else{
// Ask the user to grant access
Intent intent = new Intent(android.provider.Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS);
startActivityForResult( intent, MainActivity.ON_DO_NOT_DISTURB_CALLBACK_CODE );
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// Check which request we're responding to
if (requestCode == MainActivity.ON_DO_NOT_DISTURB_CALLBACK_CODE ) {
this.requestDoNotDisturbPermissionOrSetDoNotDisturbApi23AndUp();
}
}

Programmatically check 'Work Profile' support in android

I would like to check whether the device is supporting "Work Profile" pr not via code
Noticed that Native Support for "Work profile" from Android 5.0+ though on HTC device it is not supporting.
Could anyone share how to achieve this...
Android must have the hardware feature android.software.managed_users declared. It can be checked
PackageManager pm = getPackageManager();
if (!pm.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS)) {
// This device does not support work profiles!
}
https://developer.android.com/reference/android/content/pm/PackageManager.html
https://developers.google.com/android/work/build-dpc
For anyone reading this, I thought that checking FEATURE_MANAGED_USERS was sufficient, but in some devices you need to check too if there is anyone who will resolve the managed provisioning intent.
public boolean isManagedProvisioningAvailable() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
return false;
}
PackageManager pm = getApplicationContext().getPackageManager();
if (!pm.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS)) {
return false;
}
Intent intent = new Intent(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE);
ComponentName resolved = intent.resolveActivity(pm);
return resolved != null;
}

BluetoothLeScanner.startScan with Android 6.0 does not discover devices

I'm trying to use the function BluatoothLeScanner.startScan instead of the deprecated one BluetoothAdapter.startLeScan.
Yesterday I updated my Nexus 5 to Android 6.0 and since that moment my app does not work anymore.
I firstly add the preferences required ACCESS_COARSE_LOCATION as found here, https://developer.android.com/about/versions/marshmallow/android-6.0-changes.html#behavior-hardware-id.
Then I added the permission as described here: https://developer.android.com/training/permissions/requesting.html.
But at the end it seems not working, it does not send back the ble devices.
This is my code:
manifest
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.stm.sensitronapp">
<uses-sdk android:maxSdkVersion="23"/>
<uses-feature android:name="android.hardware.bluetooth_le" 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"/>`
DeviceScanActivity
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
if (ContextCompat.checkSelfPermission(this,Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED){
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_COARSE_LOCATION)) {
} else {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
MY_PERMISSIONS_REQUEST_ACCESS_COARSE);
}
}
// Device scan callback.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (ContextCompat.checkSelfPermission(this,Manifest.permission.ACCESS_COARSE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
mScanCallback = new ScanCallback() {
#Override
public void onScanResult(int callbackType, ScanResult result) {
super.onScanResult(callbackType, result);
mLeDeviceListAdapter.addDevice(result.getDevice());
mLeDeviceListAdapter.notifyDataSetChanged();
}
};
}
}
}
final BluetoothManager bluetoothManager =
(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
if (mBluetoothAdapter.getState() == BluetoothAdapter.STATE_ON) {
mSwipeRefreshLayout.setRefreshing(true);
mLeDeviceListAdapter.clear();
mBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();
if(ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_COARSE_LOCATION ) == PackageManager.PERMISSION_GRANTED) {
mBluetoothLeScanner.startScan(mScanCallback);
}
}
EDIT: to solve this problem I only turned on the GPS. It is easy to do it programmatically in this way.
if permissions granted, have a try: turn ON the GPS.
Is you app prompting for Location permission on startup? If it's not, handle the code somewhere else so that it is being prompted.
Also you can check this to test if your app is working fine:
Open Settings > Apps > YourApplication > Permissions
and enable Location and then try to scan for results.
Location will be listed under permissions only if you have provided ACCESS_COARSE_LOCATION on manifest.
Using the solutions provided above works but the side effect is that you have to have location services turned on for something that doesn't need it. An ugly and unsatisfying work around is to specify the target version in your manifest to
android:targetSdkVersion="21"
It allows scanning on my Nexus 7 even though the installed version is 6.0.1. I do not know what the side effects are of targeting a lower version than the installed version but at least scanning works. Might be the only solution for GPS-less devices (if such devices exist).
Google should be crucified for this.
One - not perfect answer, is that you can still use the same old method BT scan method, once you have the new runtime Location permission enabled.
mBluetoothAdapter.startDiscovery();
.......
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = (BluetoothDevice) intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
mDeviceList.add(device);
}
}
};
It's an old question, but I will answer to help someone.
Unfortunately, the combination of ACCESS_COARSE_LOCATION and targetSdkVersion 22 does not work on some devices.This is not a good method, but I have solved it in the following way without using runtime permissions (ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION)
Set your 'targetSdkVersion' to 19 (I think maybe api19 ~ api22 will be possible)
Add the following permission to your manifest file
<uses-permission android:name="android.permission.READ_OWNER_DATA" />
<uses-permission android:name="android.permission.WRITE_OWNER_DATA" />
tested to Android 4.4 ~ 7.1.1
Set your 'minSdkVersion' to 18
targetSdkVersion 22

How to check whether NFC is enabled or not in android?

How can i check whether NFC is enabled or not programmatically? Is there any way to enable the NFC on the device from my program? Please help me
NfcManager manager = (NfcManager) context.getSystemService(Context.NFC_SERVICE);
NfcAdapter adapter = manager.getDefaultAdapter();
if (adapter != null && adapter.isEnabled()) {
// adapter exists and is enabled.
}
You cannot enable the NFC programmatically. The user has to do it manually through settings or hardware button.
This can be done simply using the following code:
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (nfcAdapter == null) {
// NFC is not available for device
} else if (!nfcAdapter.isEnabled()) {
// NFC is available for device but not enabled
} else {
// NFC is enabled
}
Remember that the user can turn off NFC, even while using your app.
Source: https://developer.android.com/guide/topics/connectivity/nfc/nfc#manifest
Although you can't programically enable NFC yourself, you can ask the user to enable it by having a button to open NFC settings like so:
Intent intent
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
intent = new Intent(Settings.ACTION_NFC_SETTINGS);
} else {
Intent intent = new Intent(Settings.ACTION_WIRELESS_SETTINGS);
}
startActivity(intent);
I might be a little late here, but I've implemented a 'complete' example with detection of
NFC capability (hardware), and
Initial NFC state (enabled or disabled in settings), and
Changes to the state
I've also added a corresponding Beam example which uses the
nfcAdapter.isNdefPushEnabled()
method introduced in later Android versions to detect beam state like in 2) and 3).
Use PackageManager and hasSystemFeature("android.hardware.nfc"), matching the <uses-feature android:name="android.hardware.nfc" android:required="false" /> element you should have in your manifest.
Since 2.3.3 you can also use NfcAdapter.getDefaultAdapter() to get the adapter (if available) and call its isEnabled() method to check whether NFC is currently turned on.
mNfcAdapter = NfcAdapter.getDefaultAdapter(this.getApplicationContext());
try {
if (mNfcAdapter != null) {
result = true;
}
}
We can verify using NfcAdapter with context.

Categories

Resources