Android autofill: dispatchProvideAutofillStructure() not laid out - android

I have configured my app to support Android Oreo with compileSdkVersion 26. I've also set up android:autofillHints="phone" for my phone number input field. When I tap on the field, I can see "Autofill" popping up. However, when I tap on "Autofill", "Contents can't be autofilled" toast appears and I see the following trace in logcat:
RemoteFillService Not handling { when=-3ms what=3 target=com.android.internal.os.HandlerCaller$MyHandler } as service for ComponentInfo{com.google.android.gms/com.google.android.gms.autofill.service.AutofillService} is already destroyed
View dispatchProvideAutofillStructure(): not laid out, ignoring
How should I fix this? I've confirmed that I have the phone number configured in Settings > System > Languages & input > Advanced > Input assistance > Autofill service.
UPDATE with a sample XML: In API 26 emulator settings, I can select "Autofill with Google". Using the Design tab of Android Studio, I added a "Phone" type EditText, and then manually inserted android:autofillHints="phone" in the XML element:
<EditText
android:id="#+id/editText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="phone"
android:autofillHints="phone" />
Logcat peculiarities described above can be observed using this XML.

I'm the Android Frameworks engineer leading the Autofill Framework project, so I'll answer some questions:
The "Contents can't be autofilled" message typically means the Autofill Service does not know how to autofill the screen. When you're adding autofill support to your app, it's often easier to use an Autofill Service you can control first, rather than a "real" service like a password manager. As mentioned in a previous reply, we provide a sample service that can be used for this purpose.
When you long-press a text field and select AUTOFILL, you are in fact "forcing" an autofill request as mentioned in another reply (i.e., behind the scenes the text field is calling AutofillManager.requestAutofill()). If the Autofill Service knows how to autofill your screen, you shouldn't need to do that, as the autofill suggestions would show up right away once you focus the input field.
You shouldn't need to set importantForAutofill or call AutofillManager.cancel() in your case.
So, my recommendation is to try to use the sample Autofill Service implementation to test your app first. Most likely, the first time you access your app the autofill popup won't be shown because the service does not have data for it. But once your app triggers the save UI (for example, after you manually enter the phone number and the activity finishes) and you tap save, that data should be available the next time you launch the activity.
Hope that helps,
-- Felipe

This may well be the issue - as
as service for ComponentInfo{com.google.android.gms/com.google.android.gms.autofill.service.AutofillService} is already destroyed
Ensuring data is available
In some special cases, you need to take
additional steps to make sure that the data is available to the
Autofill Framework to save. For example, an activity can present a
layout with standard text views, but then destroy the layout and
replace it with one without child views, such as GLSurfaceView.
In this case, the data in the original layout is not available to the
framework. To make the data available to the framework, you should
call commit() on the AutofillManager object before replacing the
original layout.
You'll need to fix some of these issues within your java code.
Add IMPORTANT_FOR_AUTOFILL_AUTO and check that autofill isenabled().
You may need to manage some of the settings within the java force the Autofill request:
Sometimes, you may need to force an autofill request to occur in response to a user action. .../...
public void eventHandler(View view) {
AutofillManager afm = context.getSystemService(AutofillManager.class);
if (afm != null) {
afm.requestAutofill();
}
}

Do you have an app on you phone that implements an Autofill service? I tried it with "Autofill with Google" service, and could got my phone number autofilled without problems (with emulator running SDK 26). You will need a service part for get the autofill working. See this example.

Get the latest OS image. After downloading and installing the update that became available on 2017-09-21 for my Google Pixel XL device, autofill works perfectly. So, it suffices to have android:autofillHints="phone" in XML, no other changes are required to enable the autofill feature.

The "Contents can't be autofilled" - this was caused for me because i did not agree to the auto fill service. So go into your android settings in Oreo and above and search for "autofill" . find your service (mine was default googles) and there should be a prompt to agree to its service. toggle it off and one if it does not appear. Afterwards i was able to use autofill.

Related

Can censoring of text in Android native Speech-to-Text API be turned off at the code level?

I saw this Q&A: https://android.stackexchange.com/questions/12578/how-the-f-to-stop-voice-to-text-from-censoring-profanity
So censoring behaviour of Android in general, and also Speech-to-Text can be turned off from the device settings. But can it be changed at the code level, i.e. can I write code in my app that will change this setting programmatically ? And if so, how?
Say i am looking specifically for profanities ,not to show the user but for background processing, if profanities are blocked by the user, will I be able to get the profanity in my code from Speech-to-text output?
Android's speech-to-text API does not have a parameter for turning off profanities, but can't I request the user to grant me 'write settings' permission android.settings.WRITE_SETTINGS and after acquiring that programmatically set the profanities settings to what i need it to be? I noticed that android.settings.WRITE_SETTINGS is not listed under 'Secure Settings'
Android's speech-to-text API does not have a parameter for turning off profanities. All the available parameters are in the RecognizerIntent class.

What's "AutomaticZenRule" ? What is it used for?

Background
I just noticed some functions of NotificationManager that handle a class that's called AutomaticZenRule :
https://developer.android.com/reference/android/app/NotificationManager.html#addAutomaticZenRule(android.app.AutomaticZenRule)
and others...
The problem
Looking at the docs of AutomaticZenRule, it still doesn't tell much about what it is, and what can it be used for:
Rule instance information for zen mode.
What I tried
Searching the Internet, I can see just in a Commonsware blog post, that they wonder what it is:
It is unclear what AutomaticZenRule is ...
There is practically nothing more that I've found about it. Not "zen mode" and not "AutomaticZenRule".
The questions
What is "zen mode" ?
What is "AutomaticZenRule" , and what can I do with it? How is it related to notifications?
Is there anything special on Android N, that this API was added on this version?
Is there a sample for using it?
Zen Mode is just another name for Do Not Disturb (DND) mode. Android can activate DND mode based on rules. These rules can be provided either by the system, or by a third-party app.
In the following screenshot you can see two system-provided rules, together with a "Driving" rule provided by the third-party app "Pixel Ambient Services":
AutomaticZenRule is there to integrate your own rules into the Android system. To integrate your own rules, you have to follow these rough steps:
Make sure that you have sufficient permissions to access the DND policy (android.permission.ACCESS_NOTIFICATION_POLICY). See NotificationManager.isNotificationPolicyAccessGranted() for details.
Add an activity for your rule:
<activity android:name="MyRuleConfigurationActivity">
<meta-data android:name="android.service.zen.automatic.ruleType" android:value="My Rule" />
<intent-filter>
<action android:name="android.app.action.AUTOMATIC_ZEN_RULE"/>
</intent-filter>
</activity>
Android will show your activity whenever the user wants to create or edit a rule of the specified rule type. In the latter case, Android will supply the ID of the existing rule in NotificationManager#EXTRA_AUTOMATIC_RULE_ID. To propagate changes in your activity back to android, you need to construct an AutomaticZenRuleinstance and call NotificationManager.addAutomaticZenRule / updateAutomaticZenRule.
After that, you can tell Android that the conditions for your rule are currently satisfied / not satisfied by calling NotificationManager.setAutomaticZenRuleState.
From digging in into the other documents available, i was able to understand ZenMode to some extent(although it can be my own version and not the correct one).
What my understanding is as follows -
Zen Mode is the Do not Disturb mode which now in latest updates can be enabled automatically which depends on factors such as late time of the day, etc. AutomaticZenrule can be used by applications who want their notifications to not be masked or suppressed when in do not disturb mode.
For this your application should make request to policy access by sending the user to the activity that matches the system intent action ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS.
If user has granted access to notification policy for your app, then you will be able to set a priority notification even in do not disturb mode. AutomaticZenrule thus plays a vital role to state the system that the application's notifications not be suppressed.
Although, i dont have a running sample code for it, i guess it should be on similar lines like the enabling device admin code or requesting a permission use case.
Thanks to you i got to read something new :)

Avoid Screen Overlay Detected for service that uses SYSTEM_ALERT_WINDOW

My app main usage is overlay, the overlay is running from a service.
Android Security add the nice "Screen Overlay Detected"
I want to avoid "Screen Overlay Detected" when user tries to change permissions. so... I've add an AccessiblityService that detects:
if ( event.getPackageName().equals("com.google.android.packageinstaller") ){
stopService(myServiceIntent);
}
However, even now I see this message popping. (when my service is stopped...).
I saw Twilight does it without problem.
What am I missing?
p.s. - I've also tried building a signed apk but saw exact same behavior.
It seems I've been able to resolve this.
a) stopService isn't assured your service will be stopped.
as described here :
It will not be destroyed until all of these bindings are removed. See > the Service documentation for more details on a service's lifecycle.
b) I was able to kill my service by sending intent that called stopSelf().
However process killing/starting can be slow.
c) Best resolution: so it seems Android checks for view visibility. no need to kill services or do anything more complicated.
Current way I'm doing it:
- AccessibilityService (already used by my app) monitor "com.google.android.packageinstaller" though it can be refined to class: "com.android.packageinstaller.permission.ui.ManagePermissionsActivity"
Once detected in this class, we send Intent to "duck", and when we're out, we send another intent that we're back on.
The service handles those calls by:
[ourView].setVisibility(View.INVISIBLE); // when permission settings shown
[ourView].setVisibility(View.VISIBLE); // when normal flow
As long as Android 6.x is buggy on some devices where this "overlay alert" is displayed without any reason (on 2 to 5% of the devices according to my analytics data), the best solution is to avoid the whole permission process by defining the targetSdk to 22. Take care that you can't downgrade the target sdk for a new version or this will induce a INSTALL_FAILED_PERMISSION_DOWNGRADE error when the user updates requiring an unisntall/install of the app.

android Outbound caller id - on/off

I wan to hide/show my caller id from my activity programmatically. I tried to find it in the android documentation but without the luck. Maybe you have any ideas?
I posted a question asking this on the Android Google group and got absolutely no answers at all. I've also seen a couple of other question on SO which also had no answers (or none that work).
I came to the conclusion that it simply isn't possible. My reasoning is this...
If I go to Settings -> Call -> Additional settings, I see an AlertDialog which has a HeaderTitle of 'Call settings' and I see a circular progress indicator and a message saying 'Reading settings...'.
It occurs to me that my phone is, at that point, accessing my phone/network provider. The resulting 'chooser' dialog gives me options for 'Network default', 'Hide number' and 'Show number' and when I make a selection (or even if I just 'Cancel' the dialog), I get another AlertDialog with circular progress indicator with the message 'Updating settings...'.
In short, it seems the Caller ID setting is not entirely 'local' to the phone settings and relies on interaction with the provider and, for whatever reason, as a result of this the Android APIs don't allow this to be manipulated programatically.
I'm not sure if this is something on the 'To Do' list for future versions of Android or if there are legal/security implications in allowing it to be done or some other reason. Whatever the case may be, I haven't found anybody so far who is able to explain why there isn't a method for TelephonyManager (for example) to simply switch this.
EDIT: No luck on getting the Additional Settings AlertDialog with the standard APIs either.
The reason I say that is that it is possible to pull up various parts of the device's 'Settings', e.g., in one of my apps I use android.provider.Settings.ACTION_WIRELESS_SETTINGS in the constructor of an Intent passed to startActivity(). This brings up the Settings page for enabling/disabling wi-fi, mobile internet and bluetooth.
android.provider.Settings has other similar ACTIONs for other Settings pages but there isn't even one for 'Call' never mind Call -> Additional Settings and nothing for the AlertDialog to allow you to choose to Hide/Show the outgoing Caller ID.
If this can be done then it would have to be an undocumented API unless I completely missed it (I spent a long time looking). I suspect examining the Android source-code may be the only way to find an answer and I haven't attempted that yet.
I have managed to get Additional call settings dialog. Explanation below:
Although it looks like it is part of the Settings, in fact it is part of the Native PhoneApp. If you take a look at the AndroidManifest.xml of the PhoneApp you will see that Activity GsmUmtsAdditionalCallOptions has defined IntentFilter for the android.intent.action.MAIN.
So, the code that I checked to work correctly on several phones:
Intent additionalCallSettingsIntent = new Intent("android.intent.action.MAIN");
ComponentName distantActivity = new ComponentName("com.android.phone", "com.android.phone.GsmUmtsAdditionalCallOptions");
additionalCallSettingsIntent.setComponent(distantActivity);
startActivity(additionalCallSettingsIntent);
If the #31# trick works for your needs for a single call then you could add a broadcast receiver that listens for the outgoing call notification and modifies the number to include #31# at the start before it gets dialled. Android allows the number to be changed on the way through like that.
Only works if your default is to enable caller ID and your network support #31# and you want to toggle it off using a widget, say.
The Caller ID is network specific not something that the phone controls. In fact in certain mobile network configurations the phone doesn't even 'know' its own phone number.
Some networks support sending an activate/deactivate caller ID network command. In GSM this is normally #31#. It can be permanent or on a per call basis.
Permanent requests the network to hide the caller ID for all calls.
Per call requests the network to hide the caller ID only for that call. The latter is achieved by prefixing the number being called by #31#, so for example calling #31#85432786426 would call 85432786426 hiding the caller.
Some networks support both, some only support one of them, and some do not enable it. Try your luck and try prefixing the dialed number with #31# and see if it works.
http://www.gsm-security.net/faq/gsm-caller-id-clip-clir.shtml
If you want a shortcut to the additional call settings, you can use App Cut and select GSM settings. It will place a shortcut on your home screen.

Android: Enable/Disable Auto Sync and Background Data

I want to develop an application that disables the Background Data (new feature in Android 1.5) and Auto Sync and then enables GPRS/EDGE connection and vice versa.
I figured out how to enable/disable GPRS/EDGE by changing the APN settings. (weird solution. However; Android developers couldn't think a user may want to disable GPRS/EDGE) But, I couldn't find a way to enable/disable Auto Sync and Background data.
I investigated the Android code and as I understood, the Sync operation is an intent. So, I wanted to reach with putExtra to the intent and trigger the enabling/disabling. But; I couldn't find the correct keyword. Or maybe I was totally wrong.
What is the right way to solve this?
In my HTC dreams, there is a checkbox to disable the auto sync. I can look for the menu arborescence if you wish so you can find what the callback function is in the Android source code. But I am pretty sure auto sync cannot be completely disabled. Unchecking auto sync will prevent sync from being performed on a timed basis, but it will occur everytime you run an app with sync capabilities if any network data connection is available.
Good luck anyway.
EDIT :
There are two ways to get the info you desire.
First, I think you can use the code in android-sources/packages/apps/Settings/src/com/android/settings/Utils.java to create an activity that will enlist all the keys of the intent then find the one you want.
The other way is to write a nice mail to the guy who made the Toggle Setting app (http://smartphoneandroid.com/2008/12/28/toggle-setting-perfect-app-for-android-phone.html) since he obviously found a solution to your problem. His email address is written in the app sheet on the android market. I won't write it here, but if you do not have access to real android phone, I can mail it to you on your mail address.
Background data is a secure setting, so cannot be changed by user applications. But bear in mind, it's just a setting - it's not enforced. Apps are meant to read it and respect it but I bet some don't.
To Disable the AutoSynch
ContentResolver.setMasterSyncAutomatically(false);
To Enable the AutoSynch
ContentResolver.setMasterSyncAutomatically(true);
Permission you require is
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
setMasterSyncAutomatically() on ContentResolver should do it. Check: general-sync-settings-auto-sync-checkbox-programtically

Categories

Resources