Set default service for 'Other' category | HCE - android

If there are multiple services(apps) capable of NFC HCE payments are installed. Those application services are visible under settings NFC Tap and Pay.
There are two AID group defined, one for payment and second for other cateogy.
How to programmatically change your application to be the default 'other category'service if it's not?
Below is the code that I'm executing, but dialog is not invoked to select running application for 'other category'. However for 'payment category' dialog is opened successfully. Below is the code:
CardEmulation cardEmulation = CardEmulation.getInstance(NfcAdapter.getDefaultAdapter(this));
boolean isDefaultCategorySelected = cardEmulation.isDefaultServiceForAid(new ComponentName(this, MyOffHostApduService.class), "F4100000040001");
if(!isDefaultCategorySelected(CardEmulation.CATEGORY_OTHER)){
Intent intent = new Intent(CardEmulation.ACTION_CHANGE_DEFAULT);
intent.putExtra(CardEmulation.EXTRA_CATEGORY, CardEmulation.CATEGORY_OTHER);
intent.putExtra(CardEmulation.EXTRA_SERVICE_COMPONENT, new ComponentName(this, MyOffHostApduService.class));
startActivityForResult(intent, REQUEST_CODE_SET_DEFAULT_TRANSIT_SERVICE);
return;
}

You can't.
Global defaults are currently only supported for CATEGORY_PAYMENT. The resolution strategy for CATEGORY_OTHER is always set to SELECTION_MODE_ASK_IF_CONFLICT. Hence, your application must either be the only application that registers a certain AID group in CATEGORY_OTHER or Android will ask the user upon a transaction which app should be used.
You may be able to use CardEmulation.setPreferredService() though in order to set your HCE service as the default while one of your activities is in the foreground.

Related

Set Default Android Launcher on Huawei devices?

My Goal is here is to set my app as default launcher on Huawei devices.
1 - Explanations:
1.1 - Current situation:
I am already able to:
Check if my app is the default launcher
Display the 'launcher picker' (with the 'use once' / 'always' choice)
This all works fine.. except on Huawei devices!
From my point of view, Huawei's Android flavor does not properly 'honor' the "ACTION_MANAGE_DEFAULT_APPS_SETTINGS" intent action contract.
// this displays the list of default apps on all tested devices, except on Huawei devices!
// instead, it does display apps permissions, app links and apps'advanced settings
intent.setAction(Settings.ACTION_MANAGE_DEFAULT_APPS_SETTINGS);
activity.startActivity(intent);
As a B Plan, I am able to display the 'Applications & Notifications' settings 'page' using this:
String packageName = "com.android.settings";
String className = "Settings$AppAndNotificationDashboardActivity";
intent.setClassName(packageName, packageName + "." + className);
activity.startActivity(intent);
So the user can navigate from there, pressing this sequence of menu items:
-> Advanced Parameters ( expandable menu item : not present on tablet, and not sure it's present on phone)
-> Default Apps
-> Default Launcher
This requires 2 or 3 steps that I would like to avoid.
1.2 - This can be improved!
I found out that when the "-> Default Apps" menu item is selected, a (com.android.settings, .SubSettings) Intent (with extra) is launched but I was not able to make this works (permission denial).
But I installed Nova Launcher and it turns out it's able to display the "-> Default Apps" settings page on Huawei devices!
So the user land on a page where she/he only has to tap on "-> Default Launcher" then choose a default launcher: much easier.
2 - Questions:
As I think it's just not possible to display the 'Lancher Picker' on Huawei devices, here is my question:
How can I display the "-> Default Apps" settings page (image down here) on Huawei devices (like Nova Launcher does)?
Are they using another intent action on Huawei devices?
Thanks beforehand your help.
Yes on Huawei devices, Nova uses a different intent to open to the correct screen. I likely found this by using apktool on the Settings.apk pulled from a Huawei device and looking at the AndroidManifest.
Note that "com.android" is always a code smell as it means it's not part of the public API. Also this isn't even really "com.android" as it doesn't exist on AOSP and com.android.settings.PREFERRED_SETTINGS is purely a Huawei invention. It's very likely that some Huawei devices won't have this at all. It's also possible that in the future this intent might continue to work but not do what it currently does. So handle it carefully.
/* Some Huawei devices don't let us reset normally, handle it by opening preferred apps */
Intent preferredApps = new Intent("com.android.settings.PREFERRED_SETTINGS");
preferredApps.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
if (pm.resolveActivity(preferredApps, 0) != null) {
context.startActivity(preferredApps);
} else {
...
}
In fact, the accepted answer is not 100% correct, because it opens a general default apps chooser activity.
It works, but it's better to bring user right to the launcher chooser activity — it's com.google.android.permissioncontroller/com.android.packageinstaller.role.ui.HomeSettingsActivity (at least for the Android 10 Huawei Honors).
So, the correct code snippet is:
Intent()
.apply {
component = ComponentName("com.google.android.permissioncontroller", "com.android.packageinstaller.role.ui.HomeSettingsActivity")
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
}
.takeIf {
packageManager.resolveActivity(it, 0) != null
}
?.let(context::startActivity)

How to enable Android Open Application voice interaction

According to the system voice command docs, you can open an application with a voice command. e.g. OK Google - open foobar. Also according to the docs, this Works by default; no specific intent.
In my sample development app, this isn't working. I've tried adding a few combinations of action and category permutations to the intent-filter, but no luck so far.
I'm targeting a minimum SDK of 23, testing on a device with 6.0.1.
Should this work, and if so, what are the changes to a new empty activity project I need to enable it?
As far as I am aware, Google simply iterates over a list of installed applications and opens the corresponding application if it finds an exact match.
To test this, use the following Intent
final String PACKAGE_NAME_GOOGLE_NOW = "com.google.android.googlequicksearchbox";
final String GOOGLE_NOW_SEARCH_ACTIVITY = ".SearchActivity";
final String APP_NAME = "Open " +getString(R.string.app_name);
final Intent startMyAppIntent = new Intent(Intent.ACTION_WEB_SEARCH);
startMyAppIntent.setComponent(new ComponentName(PACKAGE_NAME_GOOGLE_NOW,
PACKAGE_NAME_GOOGLE_NOW + GOOGLE_NOW_SEARCH_ACTIVITY));
startMyAppIntent.putExtra(SearchManager.QUERY, APP_NAME);
startMyAppIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {
startActivity(startMyAppIntent);
} catch (final ActivityNotFoundException e) {
e.printStackTrace();
}
If this opens your application, then it is simply a case of the phonetics of your application name, or how Google interprets your pronunciation of it.
I do think that there should be an option to add a 'phonetic app label' to the application's manifest (or some other globally available configuration file), so Google could open your application if the unique name is not common enough to generate a voice search result.
If this doesn't open your application, check that you are correctly defining your application name in the manifest as follows:
<application
android:label="#string/app_name"

How to detect the default payment method type of a tap and pay wallet app in Android programmatically?

X wallet app that supports only HCE (Host Card Based Emulation) is installed on an Android device that supports both HCE and SE(Secure Element) payment methods. The default 'tap and pay ' app is the X wallet app but the default selected payment method registered to it is SE.
How can I detect the default payment method? So that I could warn the user to change the payment method type to HCE for the X wallet.
You can tell the Android system that you want your app to manage the tap&pay, and it will display a Dialog with the name of the app the actually manages the payment along with the name your app.
This is explained in the answer to the question:
Set application default payment service
The code you can find there is the following:
Intent intent = new Intent();
intent.setAction(CardEmulation.ACTION_CHANGE_DEFAULT);
intent.putExtra(CardEmulation.EXTRA_SERVICE_COMPONENT,
new ComponentName(this, my.package.MyPaymentService.class));
intent.putExtra(CardEmulation.EXTRA_CATEGORY, CardEmulation.CATEGORY_PAYMENT);
startActivity(intent);
where "my.package.MyPaymentService" is the service in your app that manage the payment.
Try this, it worked for me:
#RequiresApi(api = Build.VERSION_CODES.R)
private boolean isGoogleWalletDefaultPaymentMethod(){
NfcManager manager = (NfcManager) this.getSystemService(Context.NFC_SERVICE);
CardEmulation cardEmulation = CardEmulation.getInstance(manager.getDefaultAdapter());
if (cardEmulation.getDescriptionForPreferredPaymentService().equals("Google Pay"))
return true;
else
return false;
}

Setup a new user after it's created

From my device owner application, I'd like to create a new user and switch directly to it. For now, I can only create a new user, switch to it but:
it brings me to the keyguard screen, that I need to manually unlock.
then, tells me to setup the newly created user - with firstname, lastname, WIFI settings, and 3 Google usage statistics/reporting options.
I'd like to know if there's a way to programmatically setup the new user and switch directly to it's "session". I'd like to programmatically avoid the "unlock" page et pre-setup the newly created user with name, WIFI settings, but also available apps and security settings.
here's what I do so far :
// init block (in onCreate...)
DevicePolicyManager mDPM = (DevicePolicyManager) this.getSystemService(Context.DEVICE_POLICY_SERVICE);
ComponentName mDeviceAdminRcvr = new ComponentName(this, DeviceAdminRcvr.class);
// in my button "create a new user"
ComponentName profileOwnerComponent = new ComponentName(this, ProfileAdminRcvr.class);
Bundle adminExtras = new Bundle();
UserHandle userHandle = mDPM.createAndInitializeUser(mDeviceAdminRcvr, name, ownerName, profileOwnerComponent, adminExtras);
// TODO : place here missing instructions to provision the user...
mDPM.switchUser(mDeviceAdminRcvr, userHandle);
I couldn't find any documentation on the official Google page about device owner apps or profile apps.
Could anyone help me or point me to useful links ?
As far as I've seen, there is no way to programmatically unlock the screen lock. Even the Smart lock functionnality added in Lollipop will just disable the Key Guard, which means that the "PIN" or "Pattern" will transform into a "Swipe Lock" when a trusted agent unlocks the device. Even in this case, you'll need to manually swipe the screen to unlock the device.
Concerning the second point, it's possible to avoid the "Setup Wizard" proposed the first time you unlock a newly created user. Here's how to do it :
in your ProfileAdminRcvr.java, you'll need to hide the system application called com.google.android.setupwizard. You could do this in the onEnabled() method of your DeviceAdminReceiver's implementation (the one you set for your profile when creating the user).
To complete this, you can disable the "first use hint", by setting the Settings.Secure.SKIP_FIRST_USE_HINTS property.
Here's the code to do it :
public class ProfileOwnerRcvr extends DeviceAdminReceiver {
private DevicePolicyManager mDPM;
private ComponentName mProfileAdminRcvr;
#Override
public void onEnabled(Context context, Intent intent) {
mDPM.setProfileName(mProfileAdminRcvr, "My new user");
// ... setup other things by yourself...
mDPM.setApplicationHidden( mProfileAdminRcvr, "com.google.android.setupwizard", true);
mDPM.setSecureSetting(mProfileAdminRcvr, Settings.Secure.SKIP_FIRST_USE_HINTS, "1");
}
Google updated its demo app to use Android-N preview version, it seems that there will be a flag called DevicePolicyManager.SKIP_SETUP_WIZARD to do part of what you are trying to do (i.e skipping the wizard) in N.

Showing WiFi setting and selecting one network among the list

I'm able to send the user to the WiFi settings when it is necessary in my application:
Intent wfintent = new Intent( Settings.ACTION_WIFI_SETTINGS );
wfintent.addFlags( Intent.FLAG_ACTIVITY_NEW_TASK );
this.startActivity( wfintent );
So far, so good...! Now, among the list of WiFi networks displayed, I know exactly which one I want to connect to (by using WifiManager.startScan(), .getScanResult(), no problem with that) and I can also know if this network was previously configurated (given a password) (by using WifiManager.getConfiguredNetworks()).
The problem is that I would like not only to open and display the WiFi settings pane but also select the network and open the dialog that prompt for the password.
Is it possible to do that directly with the intent I previously gave in example?
Thank you for your help!
No, the WifiSettings only make a call to WifiManager.connect in PreferenceFragment.onPreferenceTreeClick, Fragment.onContextItemSelected, and DialogInterface.OnClickListener.onClick. There is no Intent extra it looks for, or any other way to select a connection using the Intent alone.

Categories

Resources