Android 8.0 AutoFill自动填写框架实践
生活随笔
收集整理的這篇文章主要介紹了
Android 8.0 AutoFill自动填写框架实践
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
1.構(gòu)建表單界面
為 TextInputEditText 添加 android:importantForAutofill="yes"
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@color/white"> ?<com.google.android.material.textfield.TextInputLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"> ?<com.google.android.material.textfield.TextInputEditTextandroid:id="@+id/username"android:layout_width="match_parent"android:layout_height="wrap_content"android:hint="Username"android:importantForAutofill="yes"/></com.google.android.material.textfield.TextInputLayout> ?<com.google.android.material.textfield.TextInputLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"> ?<com.google.android.material.textfield.TextInputEditTextandroid:id="@+id/password"android:layout_width="match_parent"android:layout_height="wrap_content"android:hint="Password"android:importantForAutofill="yes"android:selectAllOnFocus="false"android:singleLine="true"/></com.google.android.material.textfield.TextInputLayout> ?<com.google.android.material.button.MaterialButtonandroid:id="@+id/login"style="@style/Widget.MaterialComponents.Button.UnelevatedButton"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:text="Login"/> ? </LinearLayout>復(fù)制代碼2.處理表單
使用SharedPreferences將用戶信息儲(chǔ)存
package com.iwakeup.learnandroid.Fragment; ? import android.content.Context; import android.content.SharedPreferences; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.EditText; ? import com.google.android.material.button.MaterialButton; import com.iwakeup.learnandroid.R; import com.iwakeup.learnandroid.impl.BaseFragment; ? import androidx.fragment.app.Fragment; ? public class AutoFilFragment extends Fragment implements BaseFragment { ?EditText username,password;MaterialButton login; ?@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {View view=inflater.inflate(R.layout.fragment_autofill,container,false);initView(view);return view;} ?@Overridepublic void initView(View view) {username=view.findViewById(R.id.username);password=view.findViewById(R.id.password);login=view.findViewById(R.id.login);login.setOnClickListener(loginC);} ?View.OnClickListener loginC =new View.OnClickListener() {@Overridepublic void onClick(View view) { ?SharedPreferences sp=getActivity().getSharedPreferences("user",Context.MODE_PRIVATE);SharedPreferences.Editor editor=sp.edit();editor.putString("username",username.getText().toString());editor.putString("password",password.getText().toString());editor.apply();}}; ? ? } ?復(fù)制代碼3.構(gòu)建AutoFillService
重寫(xiě) onFillRequest() 和 onSaveRequest
? public class MyAutoFillService extends AutofillService {List<AssistStructure.ViewNode> viewNodeList;@Overridepublic void onFillRequest(FillRequest fillRequest, CancellationSignal cancellationSignal, FillCallback fillCallback) {List<FillContext> context = fillRequest.getFillContexts();AssistStructure structure = context.get(context.size() - 1).getStructure(); ?viewNodeList = new ArrayList<>(); ?traverseStructure(structure,viewNodeList); ?SharedPreferences sharedPreferences=getSharedPreferences("user",MODE_PRIVATE);String spusername=sharedPreferences.getString("username",null);String sppassword=sharedPreferences.getString("password",null); ? ?//加載自動(dòng)填充的布局,可更換為自定義ViewRemoteViews usernamePresentation = new RemoteViews(getPackageName(), android.R.layout.simple_list_item_1);usernamePresentation.setTextViewText(android.R.id.text1, spusername);RemoteViews passwordPresentation = new RemoteViews(getPackageName(), android.R.layout.simple_list_item_1);passwordPresentation.setTextViewText(android.R.id.text1, sppassword); ? ?ParsedStructure parsedStructure=new ParsedStructure();parsedStructure.setUsernameId(viewNodeList.get(0).getAutofillId());parsedStructure.setPasswordId(viewNodeList.get(1).getAutofillId());//構(gòu)建填充的數(shù)據(jù)FillResponse fillResponse = new FillResponse.Builder().addDataset(new Dataset.Builder().setValue(ParsedStructure.usernameId,AutofillValue.forText(spusername), usernamePresentation).setValue(ParsedStructure.passwordId,AutofillValue.forText(sppassword), passwordPresentation).build()).build();fillCallback.onSuccess(fillResponse); ? ?} ?@Overridepublic void onSaveRequest(SaveRequest saveRequest, SaveCallback saveCallback) { ?// Get the structure from the requestList<FillContext> context = saveRequest.getFillContexts();AssistStructure structure = context.get(context.size() - 1).getStructure(); ?// Traverse the structure looking for data to savetraverseStructure(structure, viewNodeList); ?// Persist the data, if there are no errors, call onSuccess()saveCallback.onSuccess(); ?} ? ?public void traverseStructure(AssistStructure structure, List<AssistStructure.ViewNode> viewNodeList) {int nodes = structure.getWindowNodeCount(); ?for (int i = 0; i < nodes; i++) {AssistStructure.WindowNode windowNode = structure.getWindowNodeAt(i);AssistStructure.ViewNode viewNode = windowNode.getRootViewNode();traverseNode(viewNode,viewNodeList);}} ?public void traverseNode(AssistStructure.ViewNode viewNode, List<AssistStructure.ViewNode> viewNodeList) {if(viewNode.getAutofillHints() != null && viewNode.getAutofillHints().length > 0) {// If the client app provides autofill hints, you can obtain them using:// viewNode.getAutofillHints();return;} else {// Or use your own heuristics to describe the contents of a view// using methods such as getText() or getHint().//遍歷EditText布局if (viewNode.getClassName().contains("EditText")) {String viewId = viewNode.getIdEntry();if (viewId != null && (viewId.contains("username") || viewId.contains("username") || viewId.contains("password"))) {//添加到listviewNodeList.add(viewNode);return;}} ? ?} ?for(int i = 0; i < viewNode.getChildCount(); i++) {AssistStructure.ViewNode childNode = viewNode.getChildAt(i);traverseNode(childNode, viewNodeList);}} ?static class ParsedStructure {static AutofillId usernameId;static AutofillId passwordId; ?public AutofillId getPasswordId() {return passwordId;} ?public void setPasswordId(AutofillId passwordId) {ParsedStructure.passwordId = passwordId;} ?public AutofillId getUsernameId() {return usernameId;} ?public void setUsernameId(AutofillId usernameId) {this.usernameId = usernameId;}} ?復(fù)制代碼4.清單聲明和權(quán)限
<serviceandroid:name=".MyAutofillService"android:label="My Autofill Service"android:permission="android.permission.BIND_AUTOFILL_SERVICE"><intent-filter><action android:name="android.service.autofill.AutofillService" /></intent-filter><meta-dataandroid:name="android.autofill"android:resource="@xml/service_configuration" /> </service>復(fù)制代碼<autofill-servicexmlns:android="http://schemas.android.com/apk/res/android"android:settingsActivity="com.example.android.SettingsActivity" />復(fù)制代碼5.在設(shè)備上啟用該服務(wù)
最后手機(jī)中設(shè)置一下:設(shè)置 > 系統(tǒng) > 語(yǔ)言和輸入 > 高級(jí) > 輸入幫助 > 自動(dòng)填充服務(wù)>復(fù)制代碼總結(jié)
以上是生活随笔為你收集整理的Android 8.0 AutoFill自动填写框架实践的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: react路由按需加载方法
- 下一篇: android sina oauth2.