How can I enable NFC reader via API? - android

There is any way I can enable Android NFC reader using API?

So apparently there is no way to enable the NFC from the API, even though Google does so within their source code (see below).
If you look at a line from the API for NfcAdapter.isEnabled():
Return true if this NFC Adapter has
any features enabled.
Application may use this as a helper
to suggest that the user should turn
on NFC in Settings.
If this method returns false, the NFC
hardware is guaranteed not to generate
or respond to any NFC transactions.
It looks like there is no way to do it within the API. Bummer. Your best bet is a dialog to inform the user they need to enable it in the settings, and perhaps launch a settings intent.
EDIT: The following is from the source, but it looks like they didn't allow the user to implement the methods in the API (I'm confused about this).
I found this from the android source code to help enable and disable the adapter.
Relevant source:
public boolean onPreferenceChange(Preference preference,
Object value) {
// Turn NFC on/off
final boolean desiredState = (Boolean) value;
mCheckbox.setEnabled(false);
// Start async update of the NFC adapter state, as the API is
// unfortunately blocking...
new Thread("toggleNFC") {
public void run() {
Log.d(TAG, "Setting NFC enabled state to: "
+ desiredState);
boolean success = false;
if (desiredState) {
success = mNfcAdapter.enable();
} else {
success = mNfcAdapter.disable();
}
if (success) {
Log.d(TAG,
"Successfully changed NFC enabled state to "
+ desiredState);
mHandler.post(new Runnable() {
public void run() {
handleNfcStateChanged(desiredState);
}
});
} else {
Log.w(TAG, "Error setting NFC enabled state to "
+ desiredState);
mHandler.post(new Runnable() {
public void run() {
mCheckbox.setEnabled(true);
mCheckbox
.setSummary(R.string.nfc_toggle_error);
}
});
}
}
}.start();
return false;
}

I got it working through reflection
This code works on API 15, haven't checked it against other verions yet
public boolean changeNfcEnabled(Context context, boolean enabled) {
// Turn NFC on/off
final boolean desiredState = enabled;
mNfcAdapter = NfcAdapter.getDefaultAdapter(context);
if (mNfcAdapter == null) {
// NFC is not supported
return false;
}
new Thread("toggleNFC") {
public void run() {
Log.d(TAG, "Setting NFC enabled state to: " + desiredState);
boolean success = false;
Class<?> NfcManagerClass;
Method setNfcEnabled, setNfcDisabled;
boolean Nfc;
if (desiredState) {
try {
NfcManagerClass = Class.forName(mNfcAdapter.getClass().getName());
setNfcEnabled = NfcManagerClass.getDeclaredMethod("enable");
setNfcEnabled.setAccessible(true);
Nfc = (Boolean) setNfcEnabled.invoke(mNfcAdapter);
success = Nfc;
} catch (ClassNotFoundException e) {
} catch (NoSuchMethodException e) {
} catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {
}
} else {
try {
NfcManagerClass = Class.forName(mNfcAdapter.getClass().getName());
setNfcDisabled = NfcManagerClass.getDeclaredMethod("disable");
setNfcDisabled.setAccessible(true);
Nfc = (Boolean) setNfcDisabled.invoke(mNfcAdapter);
success = Nfc;
} catch (ClassNotFoundException e) {
} catch (NoSuchMethodException e) {
} catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {
}
}
if (success) {
Log.d(TAG, "Successfully changed NFC enabled state to "+ desiredState);
} else {
Log.w(TAG, "Error setting NFC enabled state to "+ desiredState);
}
}
}.start();
return false;
}//end method
This requires 2 permissions though, put them in the manifest:
<!-- change NFC status toggle -->
<uses-permission android:name="android.permission.NFC" />
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
The NFC button's state switches accordingly when the code is used, so there are no issues when doing it manually in the seetings menu.

If you can see the NfcService Application Source Code, there is a Interface file INfcAdapter.aidl. In the file two API's are there namely "boolean enable()" and "boolean disable()". You can directly use this API's to enable and disable NfcService through an android application. But the trick over here is that you can not compile the code using SDK provided by the Android. You have to compile the application using the a makefile. I have successfully build a application.

I hope this forum would be help you to resolve this issue as well to get the clear understanding on the NFC power on/off API barries.
http://ranjithdroid.blogspot.com/2015/11/turn-onoff-android-nfc-by.html

Related

How to customize the pop up message content (I want to customize according to the app's language(my app contains multiple language))

I have implemented In-app updates to notify user when new version is available using this library, https://developer.android.com/guide/playcore/in-app-updates
mAppUpdateManager = AppUpdateManagerFactory.create(this);
mAppUpdateManager.getAppUpdateInfo().addOnSuccessListener(new OnSuccessListener<AppUpdateInfo>() {
#Override
public void onSuccess(AppUpdateInfo appUpdateInfo) {
if(appUpdateInfo.updateAvailability()==UpdateAvailability.UPDATE_AVAILABLE && appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.FLEXIBLE))
{
try {
mAppUpdateManager.startUpdateFlowForResult(appUpdateInfo,AppUpdateType.FLEXIBLE,MainActivity.this,RC_APP_UPDATE);
} catch (IntentSender.SendIntentException e) {
throw new RuntimeException(e);
}
}
}
});
By default, when an update is available, it shows pop up message and gets updated as expected but, I want to change the language and message content(not update XXX?? XXX recommends that you *****) so that I can change the message contents according to the language of user(my app supports multiple language selections)
Thank you.
mAppUpdateManager = AppUpdateManagerFactory.create(this); mAppUpdateManager.getAppUpdateInfo().addOnSuccessListener(new OnSuccessListener<AppUpdateInfo>() { #Override public void onSuccess(AppUpdateInfo appUpdateInfo) { if(appUpdateInfo.updateAvailability()==UpdateAvailability.UPDATE_AVAILABLE && appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.FLEXIBLE)) { try { mAppUpdateManager.startUpdateFlowForResult(appUpdateInfo,AppUpdateType.FLEXIBLE,MainActivity.this,RC_APP_UPDATE); } catch (IntentSender.SendIntentException e) { throw new RuntimeException(e); } } } });
I tried this according to the official website and other articles too but, couldn't find the way to customize it.

Settings.canDrawOverlays is returning false even after turning the permission on from settings

I am trying billow Code from this answer to check if the permission is enabled. but it is returning false even when the permission is enabled from the settings.
public static boolean canDrawOverlayViews(Context con){
if(Build.VERSION.SDK_INT< Build.VERSION_CODES.LOLLIPOP){return true;}
try {
return Settings.canDrawOverlays(con);
}
catch(NoSuchMethodError e){
return canDrawOverlaysUsingReflection(con);
}
}
public static boolean canDrawOverlaysUsingReflection(Context context) {
try {
AppOpsManager manager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
Class clazz = AppOpsManager.class;
Method dispatchMethod = clazz.getMethod("checkOp", new Class[] { int.class, int.class, String.class });
//AppOpsManager.OP_SYSTEM_ALERT_WINDOW = 24
int mode = (Integer) dispatchMethod.invoke(manager, new Object[] { 24, Binder.getCallingUid(), context.getApplicationContext().getPackageName() });
return AppOpsManager.MODE_ALLOWED == mode;
} catch (Exception e) { return false; }
}
Recently I've also faced the same issue and got the following workaround .
Referenced from
https://code.google.com/p/android/issues/detail?id=198671#c7
public boolean getWindoOverLayAddedOrNot2() {
String sClassName = "android.provider.Settings";
try {
Class classToInvestigate = Class.forName(sClassName);
if (context == null)
context = activity;
Method method = classToInvestigate.getDeclaredMethod("isCallingPackageAllowedToDrawOverlays", Context.class, int.class, String.class, boolean.class);
Object value = method.invoke(null, context, Process.myUid(), context.getPackageName(), false);
Log.i("Tag", value.toString());
// Dynamically do stuff with this class
// List constructors, fields, methods, etc.
} catch (ClassNotFoundException e) {
// Class not found!
} catch (Exception e) {
// Unknown exception
e.printStackTrace();
}
return false;
}
does the check involves the device admin?
I have encountered this problem when disabling device admin, I have checked this permission in the DeviceAdminReceiver->onDisabled() and on some devices, and canDrawOverlays returned false, despite the fact i had the permission.
The above answer helped sometimes but not all the time. the thing that did work is Thread.sleep before the check.
try {
Thread.sleep(20);
} catch (InterruptedException e) {
// some exception here
}
The minimal time that worked for me was 20 millis. than canDrawOverlays returned true
Note: this is not a good practice however this is the only thing that worked for me
Based on BennyP's answer, I've made a Runnable run the required code after 500ms and that worked very well. The feedback is a bit delayed, but the user won't even notice the delay.
This is the code I've added to my onResume()
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
if(!Settings.canDrawOverlays(ControllerActivity.this)){
//Handle overlay permission not given here
}
else{
//Handle overlay permission given here
}
}
}, 500);
Hope it helps!
I tried restarting the activity after the user accessed the setting . This is code :
public static void restartActivity(Activity act){
Intent intent = getIntent();
finish();
startActivity(intent);
}
First of all, I am really very surprised with this strange behaviour of
Settings.canDrawOverlays(this);
I also faced the same issue with its usage, it was returning false even if the permission is already assigned.
What I noticed that, I was using this check in my onStart() method, where it was creating this wired behavior. To resolve this, I searched over internet and no result was there that can satisfy me and the one I can use.
Solution
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
Log.e("Overlay Permission", "" + Settings.canDrawOverlays(this));
if (!Settings.canDrawOverlays(this)) {
MyPreferences.saveBoolean(HomeScreen.this, "showOverlayPermissionDialog", true);
} else {
MyPreferences.saveBoolean(HomeScreen.this, "showOverlayPermissionDialog", false);
}
}
I did something lake this, in my onCreate(). Here I saved the values accordingly in my SharedPreferences, and according to these Shared Preference values, I created a check for showing an overlay dialog in my onStart(). This worked fine!
You can try this solution, and mark this answer useful if your problem is solved.
Thanks

handling slow internet connection in android

Am fetching JSON data from a remote server and before triggering the asynctask am checking for the availability of internet connection with the help of below code
if (isOnline()==true){
new DownloadJSON().execute();
}
//do whatever you want to do
else
{
try {
Toast.makeText(context, "Slow or No Internet Connection", Toast.LENGTH_SHORT).show();
}
catch(Exception e)
{
}
}
public boolean isOnline() {
try {
Process p1 = Runtime.getRuntime().exec("ping -c 1 www.google.com");
int returnVal = p1.waitFor();
boolean reachable = (returnVal == 0);
if (reachable) {
return true;
} else {
return false;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
p1.destroy();
}
return false;
}
This works fine for no internet connection. Even it works in cases like, there is wifi but no internet access. But the problem is it blacks out my activity if the internet connectivity is slow and gets force closed.
Please guide me how can I add a timeout value to isOnline() or is there any better way to handle such error in catch block
Why don't you use the AsyncTask class ? It won't block the UI thread.

Try Catch method for open bluetooth function

I made a simple android appication for connect with bluetooth serial device and I want to add closeBT if android not connected maybe the device is out of range because crash.
How do I do this? This code is correct?
protected void onStart() {
super.onStart();
findBT(); //Check if bluettoth enable and paired devices
try {
openBT(); //open sockets,streams
} catch (IOException e) {
e.printStackTrace();
closeBT();
}
}
Try-catch is not for the application logic! It is for doing stuff when something went wrong! You want to use an if-else here, like
if (findBT() != null) { // I don't know what findBT does, but maybe it returns BT-devices
try {
openBT(); //open sockets,streams
} catch (IOException e) {
e.printStackTrace();
// inform the user that a connection could not be established or something similar
}
} else {
// inform the user, that no BT-device was found.
}
you want to use closeBT() for instance when the user or your application decides to disconnect the BT-devices.

Is there a better way to do this ? Checking periodically hot spot creation status

In my android application i am creating(code is shown below) a hot spot(access point) on load of the application for some purpose which has to remain active throughout the life cycle of the application(i know it has some disadvantages), now, how can i make sure that it remains active throughout ? The only idea that i have is to run a timer which checks for method.getName().equals("setWifiApEnabled") status and determines if it is inactive ? is there a better way to get some indication when AP is disabled ?
IntentFilter filter = new IntentFilter();
filter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
filter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
filter.addAction(WifiManager.EXTRA_NEW_STATE);
filter.addAction(WifiManager.EXTRA_SUPPLICANT_CONNECTED);
registerReceiver(wifiEventReceiver, filter);
private BroadcastReceiver wifiEventReceiver = new BroadcastReceiver() {
private boolean enabled = false;
#Override
public void onReceive(Context context, Intent intent) {
System.out.println ("WiFi Event BroadReceiver:onReceive()=======================================");
if(intent.getAction().equals(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)) {
System.out.println("===== SUPPLICANT_STATE_CHANGE_ACTION event happened....");
intent.getBooleanExtra(WifiManager.EXTRA_SUPPLICANT_CONNECTED, false);
}
}
};
private void createWifiAccessPoint() {
if(wifiManager.isWifiEnabled())
{
wifiManager.setWifiEnabled(false);
}
Method[] wmMethods = wifiManager.getClass().getDeclaredMethods(); //Get all declared methods in WifiManager class
boolean methodFound=false;
for(Method method: wmMethods){
if(method.getName().equals("setWifiApEnabled")){
methodFound=true;
WifiConfiguration netConfig = new WifiConfiguration();
netConfig.SSID = ssid;
netConfig.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
try {
boolean apstatus=(Boolean) method.invoke(wifiManager, netConfig,true);
for (Method isWifiApEnabledmethod: wmMethods)
{
if(isWifiApEnabledmethod.getName().equals("isWifiApEnabled")){
while(!(Boolean)isWifiApEnabledmethod.invoke(wifiManager)){
};
for(Method method1: wmMethods){
if(method1.getName().equals("getWifiApState")){
int apstate;
apstate=(Integer)method1.invoke(wifiManager);
}
}
}
}
if(apstatus)
{
Log.d("Splash Activity", "Access Point created");
}else
{
Log.d("Splash Activity", "Access Point creation failed");
}
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
if(!methodFound){
Log.d("Splash Activity", "Your phone's API does not contain setWifiApEnabled method to configure an access point");
}
}
It seems that you have to register a BroadcastReceiver for intent SUPPLICANT_STATE_CHANGED_ACTION or SUPPLICANT_CONNECTION_CHANGE_ACTION
I assume you know about registering receivers.
It isn't clear exactly what you are trying to achieve here given that it is impossible to guarantee WiFi connectivity. The best you can do is to fail "gracefully" if it is lost.
To monitor the state of the WiFi network you need to register a listener for NETWORK_STATE_CHANGED_ACTION. Forget about the suppliant state.
To keep the WiFi radio awake use the WiFiLock.
I thinky you can establish a TCP connection and check its status, or you can send UDP packet and check its status.

Categories

Resources