Otomatik doldurma hizmeti, diğer uygulamaların görünümlerine veri ekleyerek kullanıcıların formları doldurmasını kolaylaştıran bir uygulamadır. Otomatik doldurma hizmetleri, bir uygulamadaki görünümlerden kullanıcı verilerini alıp daha sonra kullanmak üzere saklayabilir. Otomatik doldurma hizmetleri genellikle kullanıcı verilerini yöneten uygulamalar tarafından sağlanır. Örneğin: izin verir.
Android, Android 8.0 (API seviyesi 26) ve sonraki sürümlerde bulunan otomatik doldurma çerçevesiyle form doldurmayı kolaylaştırır. Kullanıcılar, otomatik doldurma özelliklerinden yalnızca cihazlarında otomatik doldurma hizmetleri sağlayan bir uygulama varsa yararlanabilir.
Bu sayfada, uygulamanıza bir otomatik doldurma hizmetini nasıl uygulayacağınız gösterilmektedir. Eğer
bir hizmetin nasıl uygulanacağını gösteren kod örneğine göz atmak isterseniz
Java'daki AutofillFramework örneği
veya
Kotlin.
Otomatik doldurma hizmetlerinin işleyiş şekli hakkında daha fazla bilgi için AutofillService
ve AutofillManager
sınıflarının referans sayfalarına bakın.
Manifest beyanları ve izinleri
Otomatik doldurma hizmetleri sağlayan uygulamalar şunu içeren bir beyan içermelidir:
ve hizmetin uygulanmasıdır. Beyan etmek için uygulama manifest dosyasına bir <service>
öğesi ekleyin. <service>
öğesi aşağıdaki özellikleri ve öğeleri içermelidir:
- Hizmeti uygulayan uygulamada
AutofillService
alt sınıfını işaret edenandroid:name
özelliği. android:permission
BIND_AUTOFILL_SERVICE
özelliğini tanımlayan özellik izni gerekir.<intent-filter>
zorunlu bir öğe olan<action>
alt öğesiandroid.service.autofill.AutofillService
işlem.- Hizmet için ek yapılandırma parametreleri sağlamak üzere kullanabileceğiniz isteğe bağlı
<meta-data>
öğesi.
Aşağıdaki örnekte bir otomatik doldurma hizmeti beyanı gösterilmektedir:
<service
android: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-data
android:name="android.autofill"
android:resource="@xml/service_configuration" />
</service>
<meta-data>
öğesi, hizmetle ilgili daha fazla ayrıntı içeren bir XML kaynağına işaret eden bir android:resource
özelliği içerir.
Önceki örnekteki service_configuration
kaynağı, kullanıcıların hizmeti yapılandırmasına olanak tanıyan bir etkinlik belirtir. Aşağıdaki örnek
service_configuration
XML kaynağını gösterir:
<autofill-service
xmlns:android="http://schemas.android.com/apk/res/android"
android:settingsActivity="com.example.android.SettingsActivity" />
XML kaynakları hakkında daha fazla bilgi için Uygulama kaynaklarına genel bakış başlıklı makaleyi inceleyin.
Hizmeti etkinleştirme istemi
Bir uygulama, BIND_AUTOFILL_SERVICE
iznini beyan ettikten ve kullanıcı uygulamayı cihaz ayarlarında etkinleştirdikten sonra otomatik doldurma hizmeti olarak kullanılır. Bir uygulama, AutofillManager
sınıfının hasEnabledAutofillServices()
yöntemini çağırarak şu anda etkin hizmetin kendisi olup olmadığını doğrulayabilir.
Uygulama, geçerli otomatik doldurma hizmeti değilse kullanıcıdan şunları yapmasını isteyebilir:
otomatik doldurma ayarlarını değiştirmek için
ACTION_REQUEST_SET_AUTOFILL_SERVICE
isteyebilirsiniz. Kullanıcı, aşağıdaki durumlarda intent RESULT_OK
değerini döndürür.
arayanın paketiyle eşleşen bir otomatik doldurma hizmeti seçer.
Müşteri görünümlerini doldurun
Otomatik doldurma hizmeti, kullanıcılar aşağıdaki işlemleri gerçekleştirdiğinde müşteri görünümlerini doldurma istekleri alır: Kullanıcı diğer uygulamalarla etkileşime girer. Otomatik doldurma hizmetinde isteği karşılayan kullanıcı verileri varsa verileri yanıtta gönderir. Android sistemi, 1. resimde gösterildiği gibi mevcut verileri içeren bir otomatik doldurma kullanıcı arayüzü gösterir:
Otomatik doldurma çerçevesi, Android sisteminin otomatik doldurma hizmetine bağlı olduğu süreyi en aza indirmek için tasarlanmış, görünümleri doldurmaya yönelik bir iş akışı tanımlar. Android sistemi her istekte onFillRequest()
yöntemini çağırarak hizmete bir AssistStructure
nesnesi gönderir.
Otomatik doldurma hizmeti, isteği daha önce depoladığı kullanıcı verileriyle karşılayıp karşılayamayacağını kontrol eder. İsteği karşılayabiliyorsa hizmet, verileri Dataset
nesnelerinde paketler. Hizmet, Dataset
nesnelerini içeren bir FillResponse
nesnesi geçirerek onSuccess()
yöntemini çağırır. Hizmet uyumlu değilse
isteği karşılayacak verilere sahip olduğunda onSuccess()
yöntemine null
iletir.
Hizmet
onFailure()
adını çağırır
yöntemini çağırın. Ayrıntılı
hakkında ayrıntılı bilgi için AutofillService
adresindeki açıklamaya
referans sayfası.
Aşağıdaki kodda onFillRequest()
yönteminin bir örneği gösterilmektedir:
Kotlin
override fun onFillRequest( request: FillRequest, cancellationSignal: CancellationSignal, callback: FillCallback ) { // Get the structure from the request val context: List<FillContext> = request.fillContexts val structure: AssistStructure = context[context.size - 1].structure // Traverse the structure looking for nodes to fill out val parsedStructure: ParsedStructure = parseStructure(structure) // Fetch user data that matches the fields val (username: String, password: String) = fetchUserData(parsedStructure) // Build the presentation of the datasets val usernamePresentation = RemoteViews(packageName, android.R.layout.simple_list_item_1) usernamePresentation.setTextViewText(android.R.id.text1, "my_username") val passwordPresentation = RemoteViews(packageName, android.R.layout.simple_list_item_1) passwordPresentation.setTextViewText(android.R.id.text1, "Password for my_username") // Add a dataset to the response val fillResponse: FillResponse = FillResponse.Builder() .addDataset(Dataset.Builder() .setValue( parsedStructure.usernameId, AutofillValue.forText(username), usernamePresentation ) .setValue( parsedStructure.passwordId, AutofillValue.forText(password), passwordPresentation ) .build()) .build() // If there are no errors, call onSuccess() and pass the response callback.onSuccess(fillResponse) } data class ParsedStructure(var usernameId: AutofillId, var passwordId: AutofillId) data class UserData(var username: String, var password: String)
Java
@Override public void onFillRequest(FillRequest request, CancellationSignal cancellationSignal, FillCallback callback) { // Get the structure from the request List<FillContext> context = request.getFillContexts(); AssistStructure structure = context.get(context.size() - 1).getStructure(); // Traverse the structure looking for nodes to fill out ParsedStructure parsedStructure = parseStructure(structure); // Fetch user data that matches the fields UserData userData = fetchUserData(parsedStructure); // Build the presentation of the datasets RemoteViews usernamePresentation = new RemoteViews(getPackageName(), android.R.layout.simple_list_item_1); usernamePresentation.setTextViewText(android.R.id.text1, "my_username"); RemoteViews passwordPresentation = new RemoteViews(getPackageName(), android.R.layout.simple_list_item_1); passwordPresentation.setTextViewText(android.R.id.text1, "Password for my_username"); // Add a dataset to the response FillResponse fillResponse = new FillResponse.Builder() .addDataset(new Dataset.Builder() .setValue(parsedStructure.usernameId, AutofillValue.forText(userData.username), usernamePresentation) .setValue(parsedStructure.passwordId, AutofillValue.forText(userData.password), passwordPresentation) .build()) .build(); // If there are no errors, call onSuccess() and pass the response callback.onSuccess(fillResponse); } class ParsedStructure { AutofillId usernameId; AutofillId passwordId; } class UserData { String username; String password; }
Bir hizmet, isteği karşılayan birden fazla veri kümesine sahip olabilir. Bu durumda Android sistemi, otomatik doldurma kullanıcı arayüzünde her veri kümesi için bir tane olmak üzere birden fazla seçenek gösterir. Aşağıdaki kod örneğinde, bir yanıtta birden fazla veri kümesinin nasıl sağlanacağı gösterilmektedir:
Kotlin
// Add multiple datasets to the response val fillResponse: FillResponse = FillResponse.Builder() .addDataset(Dataset.Builder() .setValue(parsedStructure.usernameId, AutofillValue.forText(user1Data.username), username1Presentation) .setValue(parsedStructure.passwordId, AutofillValue.forText(user1Data.password), password1Presentation) .build()) .addDataset(Dataset.Builder() .setValue(parsedStructure.usernameId, AutofillValue.forText(user2Data.username), username2Presentation) .setValue(parsedStructure.passwordId, AutofillValue.forText(user2Data.password), password2Presentation) .build()) .build()
Java
// Add multiple datasets to the response FillResponse fillResponse = new FillResponse.Builder() .addDataset(new Dataset.Builder() .setValue(parsedStructure.usernameId, AutofillValue.forText(user1Data.username), username1Presentation) .setValue(parsedStructure.passwordId, AutofillValue.forText(user1Data.password), password1Presentation) .build()) .addDataset(new Dataset.Builder() .setValue(parsedStructure.usernameId, AutofillValue.forText(user2Data.username), username2Presentation) .setValue(parsedStructure.passwordId, AutofillValue.forText(user2Data.password), password2Presentation) .build()) .build();
Otomatik doldurma hizmetleri,ViewNode
Otomatik doldurma verilerini almak için AssistStructure
gereken en önemli şeydir. Bir hizmet, otomatik doldurma verilerini aşağıdakileri kullanarak alabilir:
ViewNode
yöntemleri
sınıfı, örneğin getAutofillId()
.
Bir hizmet, isteği karşılayıp karşılayamayacağını kontrol etmek için bir görünümün içeriğini tanımlayabilmelidir. Bir hizmetin, görünümün içeriğini açıklamak için kullanması gereken ilk yaklaşım autofillHints
özelliğini kullanmaktır. Ancak istemci uygulamaları, özelliğin hizmette kullanılabilmesi için görünümlerinde açıkça sağlamalıdır.
İstemci uygulaması autofillHints
sağlamıyorsa
bir hizmet, içerikleri açıklamak için kendi buluşsal yöntemlerini kullanmalıdır.
Hizmet, görünümün içeriği hakkında bilgi edinmek için getText()
veya getHint()
gibi diğer sınıflardaki yöntemleri kullanabilir.
Daha fazla bilgi için Otomatik doldurma için ipucu sağlama başlıklı makaleyi inceleyin.
Aşağıdaki örnekte, AssistStructure
öğesinin nasıl aktarılacağı ve
ViewNode
nesnesindeki otomatik doldurma verileri:
Kotlin
fun traverseStructure(structure: AssistStructure) { val windowNodes: List<AssistStructure.WindowNode> = structure.run { (0 until windowNodeCount).map { getWindowNodeAt(it) } } windowNodes.forEach { windowNode: AssistStructure.WindowNode -> val viewNode: ViewNode? = windowNode.rootViewNode traverseNode(viewNode) } } fun traverseNode(viewNode: ViewNode?) { if (viewNode?.autofillHints?.isNotEmpty() == true) { // If the client app provides autofill hints, you can obtain them using // viewNode.getAutofillHints(); } else { // Or use your own heuristics to describe the contents of a view // using methods such as getText() or getHint() } val children: List<ViewNode>? = viewNode?.run { (0 until childCount).map { getChildAt(it) } } children?.forEach { childNode: ViewNode -> traverseNode(childNode) } }
Java
public void traverseStructure(AssistStructure structure) { int nodes = structure.getWindowNodeCount(); for (int i = 0; i < nodes; i++) { WindowNode windowNode = structure.getWindowNodeAt(i); ViewNode viewNode = windowNode.getRootViewNode(); traverseNode(viewNode); } } public void traverseNode(ViewNode viewNode) { if(viewNode.getAutofillHints() != null && viewNode.getAutofillHints().length > 0) { // If the client app provides autofill hints, you can obtain them using // viewNode.getAutofillHints(); } else { // Or use your own heuristics to describe the contents of a view // using methods such as getText() or getHint() } for(int i = 0; i < viewNode.getChildCount(); i++) { ViewNode childNode = viewNode.getChildAt(i); traverseNode(childNode); } }
Kullanıcı verilerini kaydetme
Bir otomatik doldurma hizmetinin, uygulamalardaki görünümleri doldurmak için kullanıcı verilerine ihtiyacı vardır. Kullanıcılar bir görünümü manuel olarak doldurduğunda, verileri mevcut otomatik doldurma hizmetine kaydetmeleri istenir (Şekil 2).
Verileri kaydedebilmek için hizmetin, verileri gelecekte kullanmak üzere saklamak istediğini belirtmesi gerekir. Android sistemi veri kaydetme isteği göndermeden önce
hizmetin
görüntüleme. Hizmet, verileri kaydetmek istediğini belirtmek için
SaveInfo
içerir
nesnesini ifade eder. SaveInfo
nesnesi
aşağıdaki verileri içermelidir:
- Kaydedilen kullanıcı verilerinin türü. Kullanılabilir
SAVE_DATA
değerlerinin listesi içinSaveInfo
bölümüne bakın. - Bir kaydetme isteğini tetiklemek için değiştirilmesi gereken minimum görünüm grubu.
Örneğin, bir giriş formunda genellikle kullanıcının kaydetme isteğini tetiklemek için
username
vepassword
görünümlerini güncellemesi gerekir.
Aşağıdaki kod örneğinde gösterildiği gibi, bir SaveInfo
nesnesi bir FillResponse
nesnesi ile ilişkilendirilir:
Kotlin
override fun onFillRequest( request: FillRequest, cancellationSignal: CancellationSignal, callback: FillCallback ) { ... // Builder object requires a non-null presentation val notUsed = RemoteViews(packageName, android.R.layout.simple_list_item_1) val fillResponse: FillResponse = FillResponse.Builder() .addDataset( Dataset.Builder() .setValue(parsedStructure.usernameId, null, notUsed) .setValue(parsedStructure.passwordId, null, notUsed) .build() ) .setSaveInfo( SaveInfo.Builder( SaveInfo.SAVE_DATA_TYPE_USERNAME or SaveInfo.SAVE_DATA_TYPE_PASSWORD, arrayOf(parsedStructure.usernameId, parsedStructure.passwordId) ).build() ) .build() ... }
Java
@Override public void onFillRequest(FillRequest request, CancellationSignal cancellationSignal, FillCallback callback) { ... // Builder object requires a non-null presentation RemoteViews notUsed = new RemoteViews(getPackageName(), android.R.layout.simple_list_item_1); FillResponse fillResponse = new FillResponse.Builder() .addDataset(new Dataset.Builder() .setValue(parsedStructure.usernameId, null, notUsed) .setValue(parsedStructure.passwordId, null, notUsed) .build()) .setSaveInfo(new SaveInfo.Builder( SaveInfo.SAVE_DATA_TYPE_USERNAME | SaveInfo.SAVE_DATA_TYPE_PASSWORD, new AutofillId[] {parsedStructure.usernameId, parsedStructure.passwordId}) .build()) .build(); ... }
Otomatik doldurma hizmeti, kullanıcı verilerinin
onSaveRequest()
yöntemidir. Bu yöntem genellikle istemci etkinliği bittikten sonra veya
commit()
istemci uygulaması çağrısı.
Aşağıdaki kodda onSaveRequest()
yönteminin bir örneği gösterilmektedir:
Kotlin
override fun onSaveRequest(request: SaveRequest, callback: SaveCallback) { // Get the structure from the request val context: List<FillContext> = request.fillContexts val structure: AssistStructure = context[context.size - 1].structure // Traverse the structure looking for data to save traverseStructure(structure) // Persist the data - if there are no errors, call onSuccess() callback.onSuccess() }
Java
@Override public void onSaveRequest(SaveRequest request, SaveCallback callback) { // Get the structure from the request List<FillContext> context = request.getFillContexts(); AssistStructure structure = context.get(context.size() - 1).getStructure(); // Traverse the structure looking for data to save traverseStructure(structure); // Persist the data - if there are no errors, call onSuccess() callback.onSuccess(); }
Otomatik doldurma hizmetleri, hassas verileri kalıcı hale getirmeden önce şifrelemelidir. Ancak kullanıcı verileri hassas olmayan etiketler veya veriler içerebilir. Örneğin, hesabı, verileri iş veya kişisel olarak işaretleyen bir etiket içerebilir hesap. Hizmetler, etiketleri şifrelememelidir. Etiketleri şifrelemeyerek hizmet, sunu görünümlerinde etiketleri kullanabilir (kullanıcı, kimlik doğrulaması yapılmış. Ardından hizmetler, kullanıcı kimliğini doğruladıktan sonra etiketleri gerçek verilerle değiştirebilir.
Otomatik doldurma kaydetme kullanıcı arayüzünü erteleme
Android 10'dan itibaren, otomatik doldurma iş akışını uygulamak için birden fazla ekran kullanıyorsanız (ör. kullanıcı adı alanı için bir ekran, şifre için başka bir ekran) SaveInfo.FLAG_DELAY_SAVE
işaretçisini kullanarak otomatik doldurma kaydetme kullanıcı arayüzünü erteleyebilirsiniz.
Bu işaret ayarlanırsa SaveInfo
yanıtıyla ilişkili otomatik doldurma bağlamı sabitlendiğinde otomatik doldurma kaydetme kullanıcı arayüzü tetiklenmez. Bunun yerine, gelecekteki doldurma isteklerini yayınlamak için aynı görevde ayrı bir etkinlik kullanabilir ve ardından kullanıcı arayüzünü bir kayıt isteği aracılığıyla gösterebilirsiniz. Daha fazla bilgi için SaveInfo.FLAG_DELAY_SAVE
konusuna bakın.
Kullanıcı kimlik doğrulamasını zorunlu kılın
Otomatik doldurma hizmetleri, kullanıcının görünümleri doldurmadan önce kimlik doğrulamasını zorunlu kılarak ek bir güvenlik düzeyi sağlayabilir. Aşağıdaki senaryolar kullanıcı kimlik doğrulamasını uygulamak için iyi adaylardır:
- Uygulamadaki kullanıcı verilerinin kilidinin birincil şifre veya parmak izi taraması.
- Belirli bir veri kümesinin kilidinin açılması gerekir (örneğin, kart doğrulama kodu (CVC) kullanarak.
Hizmetin, kilidin açılmadan önce kullanıcı kimlik doğrulaması gerektirdiği bir senaryoda
hizmet, standart verileri veya bir etiket sunabilir ve
Intent
kimlik doğrulama.
kimlik doğrulama akışı tamamlandığı zaman bu tür verileri
amaca ekleyebilirsiniz. Sizin
kimlik doğrulama etkinliği, verileri AutofillService
sınıfına döndürebilir
dokunun.
Aşağıdaki kod örneğinde, isteğin kimlik doğrulama gerektirdiğinin nasıl belirtileceği gösterilmektedir:
Kotlin
val authPresentation = RemoteViews(packageName, android.R.layout.simple_list_item_1).apply { setTextViewText(android.R.id.text1, "requires authentication") } val authIntent = Intent(this, AuthActivity::class.java).apply { // Send any additional data required to complete the request putExtra(MY_EXTRA_DATASET_NAME, "my_dataset") } val intentSender: IntentSender = PendingIntent.getActivity( this, 1001, authIntent, PendingIntent.FLAG_CANCEL_CURRENT ).intentSender // Build a FillResponse object that requires authentication val fillResponse: FillResponse = FillResponse.Builder() .setAuthentication(autofillIds, intentSender, authPresentation) .build()
Java
RemoteViews authPresentation = new RemoteViews(getPackageName(), android.R.layout.simple_list_item_1); authPresentation.setTextViewText(android.R.id.text1, "requires authentication"); Intent authIntent = new Intent(this, AuthActivity.class); // Send any additional data required to complete the request authIntent.putExtra(MY_EXTRA_DATASET_NAME, "my_dataset"); IntentSender intentSender = PendingIntent.getActivity( this, 1001, authIntent, PendingIntent.FLAG_CANCEL_CURRENT ).getIntentSender(); // Build a FillResponse object that requires authentication FillResponse fillResponse = new FillResponse.Builder() .setAuthentication(autofillIds, intentSender, authPresentation) .build();
Etkinlik, kimlik doğrulama akışını tamamladıktan sonra RESULT_OK
değeri göndererek setResult()
yöntemini çağırmalı ve EXTRA_AUTHENTICATION_RESULT
ekstrasını, doldurulmuş veri kümesini içeren FillResponse
nesnesine ayarlamalıdır. İlgili içeriği oluşturmak için kullanılan
aşağıdaki kod,
kimlik doğrulama akışları tamamlanır:
Kotlin
// The data sent by the service and the structure are included in the intent val datasetName: String? = intent.getStringExtra(MY_EXTRA_DATASET_NAME) val structure: AssistStructure = intent.getParcelableExtra(EXTRA_ASSIST_STRUCTURE) val parsedStructure: ParsedStructure = parseStructure(structure) val (username, password) = fetchUserData(parsedStructure) // Build the presentation of the datasets val usernamePresentation = RemoteViews(packageName, android.R.layout.simple_list_item_1).apply { setTextViewText(android.R.id.text1, "my_username") } val passwordPresentation = RemoteViews(packageName, android.R.layout.simple_list_item_1).apply { setTextViewText(android.R.id.text1, "Password for my_username") } // Add the dataset to the response val fillResponse: FillResponse = FillResponse.Builder() .addDataset(Dataset.Builder() .setValue( parsedStructure.usernameId, AutofillValue.forText(username), usernamePresentation ) .setValue( parsedStructure.passwordId, AutofillValue.forText(password), passwordPresentation ) .build() ).build() val replyIntent = Intent().apply { // Send the data back to the service putExtra(MY_EXTRA_DATASET_NAME, datasetName) putExtra(EXTRA_AUTHENTICATION_RESULT, fillResponse) } setResult(Activity.RESULT_OK, replyIntent)
Java
Intent intent = getIntent(); // The data sent by the service and the structure are included in the intent String datasetName = intent.getStringExtra(MY_EXTRA_DATASET_NAME); AssistStructure structure = intent.getParcelableExtra(EXTRA_ASSIST_STRUCTURE); ParsedStructure parsedStructure = parseStructure(structure); UserData userData = fetchUserData(parsedStructure); // Build the presentation of the datasets RemoteViews usernamePresentation = new RemoteViews(getPackageName(), android.R.layout.simple_list_item_1); usernamePresentation.setTextViewText(android.R.id.text1, "my_username"); RemoteViews passwordPresentation = new RemoteViews(getPackageName(), android.R.layout.simple_list_item_1); passwordPresentation.setTextViewText(android.R.id.text1, "Password for my_username"); // Add the dataset to the response FillResponse fillResponse = new FillResponse.Builder() .addDataset(new Dataset.Builder() .setValue(parsedStructure.usernameId, AutofillValue.forText(userData.username), usernamePresentation) .setValue(parsedStructure.passwordId, AutofillValue.forText(userData.password), passwordPresentation) .build()) .build(); Intent replyIntent = new Intent(); // Send the data back to the service replyIntent.putExtra(MY_EXTRA_DATASET_NAME, datasetName); replyIntent.putExtra(EXTRA_AUTHENTICATION_RESULT, fillResponse); setResult(RESULT_OK, replyIntent);
Bir kredi kartı veri kümesinin kilidinin açılmasının gerektiği senaryoda, hizmet CVC isteyen bir kullanıcı arayüzü görüntüleyebilir. Veri kümesinin kilidi açılana kadar, bankanın adı ve kredi kartı numarasının son dört hanesi gibi standart veriler sunarak verileri gizleyebilirsiniz. Aşağıdaki örnekte, veri kümesi için kimlik doğrulaması gerektirir ve kullanıcı izin verene kadar verileri CVC:
Kotlin
// Parse the structure and fetch payment data val parsedStructure: ParsedStructure = parseStructure(structure) val paymentData: Payment = fetchPaymentData(parsedStructure) // Build the presentation that shows the bank and the last four digits of the // credit card number, such as 'Bank-1234' val maskedPresentation: String = "${paymentData.bank}-" + paymentData.creditCardNumber.substring(paymentData.creditCardNumber.length - 4) val authPresentation = RemoteViews(packageName, android.R.layout.simple_list_item_1).apply { setTextViewText(android.R.id.text1, maskedPresentation) } // Prepare an intent that displays the UI that asks for the CVC val cvcIntent = Intent(this, CvcActivity::class.java) val cvcIntentSender: IntentSender = PendingIntent.getActivity( this, 1001, cvcIntent, PendingIntent.FLAG_CANCEL_CURRENT ).intentSender // Build a FillResponse object that includes a Dataset that requires authentication val fillResponse: FillResponse = FillResponse.Builder() .addDataset( Dataset.Builder() // The values in the dataset are replaced by the actual // data once the user provides the CVC .setValue(parsedStructure.creditCardId, null, authPresentation) .setValue(parsedStructure.expDateId, null, authPresentation) .setAuthentication(cvcIntentSender) .build() ).build()
Java
// Parse the structure and fetch payment data ParsedStructure parsedStructure = parseStructure(structure); Payment paymentData = fetchPaymentData(parsedStructure); // Build the presentation that shows the bank and the last four digits of the // credit card number, such as 'Bank-1234' String maskedPresentation = paymentData.bank + "-" + paymentData.creditCardNumber.subString(paymentData.creditCardNumber.length - 4); RemoteViews authPresentation = new RemoteViews(getPackageName(), android.R.layout.simple_list_item_1); authPresentation.setTextViewText(android.R.id.text1, maskedPresentation); // Prepare an intent that displays the UI that asks for the CVC Intent cvcIntent = new Intent(this, CvcActivity.class); IntentSender cvcIntentSender = PendingIntent.getActivity( this, 1001, cvcIntent, PendingIntent.FLAG_CANCEL_CURRENT ).getIntentSender(); // Build a FillResponse object that includes a Dataset that requires authentication FillResponse fillResponse = new FillResponse.Builder() .addDataset(new Dataset.Builder() // The values in the dataset are replaced by the actual // data once the user provides the CVC .setValue(parsedStructure.creditCardId, null, authPresentation) .setValue(parsedStructure.expDateId, null, authPresentation) .setAuthentication(cvcIntentSender) .build()) .build();
Etkinlik, CVC'yi doğruladıktan sonra setResult()
yöntemini çağırarak bir RESULT_OK
değeri iletmeli ve EXTRA_AUTHENTICATION_RESULT
ekstrasını, kredi kartı numarasını ve son kullanma tarihini içeren bir Dataset
nesnesine ayarlamalıdır. İlgili içeriği oluşturmak için kullanılan
Yeni veri kümesi, kimlik doğrulama gerektiren veri kümesinin yerini alır ve görünümler,
ve hemen doldurulabilir. Aşağıdaki kod,
veri kümesinden bir veri kümesi ile güncelleyin:
Kotlin
// Parse the structure and fetch payment data. val parsedStructure: ParsedStructure = parseStructure(structure) val paymentData: Payment = fetchPaymentData(parsedStructure) // Build a non-null RemoteViews object to use as the presentation when // creating the Dataset object. This presentation isn't actually used, but the // Builder object requires a non-null presentation. val notUsed = RemoteViews(packageName, android.R.layout.simple_list_item_1) // Create a dataset with the credit card number and expiration date. val responseDataset: Dataset = Dataset.Builder() .setValue( parsedStructure.creditCardId, AutofillValue.forText(paymentData.creditCardNumber), notUsed ) .setValue( parsedStructure.expDateId, AutofillValue.forText(paymentData.expirationDate), notUsed ) .build() val replyIntent = Intent().apply { putExtra(EXTRA_AUTHENTICATION_RESULT, responseDataset) }
Java
// Parse the structure and fetch payment data. ParsedStructure parsedStructure = parseStructure(structure); Payment paymentData = fetchPaymentData(parsedStructure); // Build a non-null RemoteViews object to use as the presentation when // creating the Dataset object. This presentation isn't actually used, but the // Builder object requires a non-null presentation. RemoteViews notUsed = new RemoteViews(getPackageName(), android.R.layout.simple_list_item_1); // Create a dataset with the credit card number and expiration date. Dataset responseDataset = new Dataset.Builder() .setValue(parsedStructure.creditCardId, AutofillValue.forText(paymentData.creditCardNumber), notUsed) .setValue(parsedStructure.expDateId, AutofillValue.forText(paymentData.expirationDate), notUsed) .build(); Intent replyIntent = new Intent(); replyIntent.putExtra(EXTRA_AUTHENTICATION_RESULT, responseDataset);
Verileri mantıksal gruplar halinde düzenleme
Otomatik doldurma hizmetleri, verileri farklı alanlardaki kavramları birbirinden ayıran mantıksal gruplar halinde düzenlemelidir. Bu sayfada, bu mantıksal grupların bölüm olarak ayarlanır. Aşağıdaki listede yaygın olarak görülen bölümler ve alanlar:
- Kullanıcı adı ve şifre alanlarını içeren kimlik bilgileri.
- Cadde, şehir, eyalet ve posta kodu alanlarını içeren adres.
- Kredi kartı numarası, son kullanma tarihi ve doğrulama kodu alanlarına girin.
Verileri doğru şekilde bölümlendiren bir otomatik doldurma hizmeti, bir veri kümesinde birden fazla bölümdeki verileri göstermeyerek kullanıcılarının verilerini daha iyi koruyabilir. Örneğin, kimlik bilgileri içeren bir veri kümesinin ödeme bilgilerini içermelidir. Verileri bölümler halinde düzenlemek şunları sağlar: ve böylece kullanıcı olabilir.
Verileri bölümlere ayırmak, hizmetlerin istemci uygulamasına minimum miktarda alakalı veri gönderirken birden fazla bölümden görüntü içeren etkinlikleri doldurmasını sağlar. Örneğin, kullanıcı adı, şifre, sokak ve şehir için görüntüler içeren bir etkinliği ve aşağıdaki verilere sahip bir otomatik doldurma hizmetini düşünün:
Bölüm | Alan 1 | Alan 2 |
---|---|---|
Kimlik Bilgisi | iş_kullanıcı_adı | iş_şifresi |
kişisel_kullanıcı_adı | personal_password | |
Adres | iş_sokağı | iş_şehir |
personal_street | kişisel_şehir |
Hizmet, hem iş hem de kişisel hesaplar için kimlik bilgileri bölümünü içeren bir veri kümesi hazırlayabilir. Kullanıcı bir veri kümesi seçtiğinde, sonraki otomatik doldurma yanıtı, iş veya kişisel bilgi sağlayabilir (kullanıcının ilk tercihine bağlı olarak) adresi.
Bir hizmet,
isFocused()
yöntemini kullanarak AssistStructure
nesnesinden geçiş yapın. Bu sayede hizmet, uygun bölüm verileriyle bir FillResponse
hazırlayabilir.
SMS tek seferlik kodunu otomatik doldurma
Otomatik doldurma hizmetiniz, kullanıcının SMS Retriever API'yi kullanarak SMS.
Bu özelliği kullanabilmek için aşağıdaki koşulların karşılanması gerekir:
- Otomatik doldurma hizmeti Android 9 (API düzeyi 28) veya sonraki sürümlerde çalışıyor olmalıdır.
- Kullanıcı, otomatik doldurma hizmetinizin SMS'deki tek seferlik kodları okumasına izin verir.
- Otomatik doldurma özelliğini sağladığınız uygulama, tek kullanımlık kodları okumak için SMS Retriever API'yi kullanmıyor.
Otomatik doldurma hizmetiniz, Google Play Hizmetleri 19.0.56 veya sonraki sürümlerde SmsCodeRetriever.getAutofillClient()
çağrısı yapılarak kullanılabilen SmsCodeAutofillClient
'i kullanabilir.
Bu API'yi bir otomatik doldurma hizmetinde kullanmak için birincil adımlar şunlardır:
- Otomatik doldurma hizmetinde
hasOngoingSmsRequest
değerini kullanın. olup olmadığını belirlemek içinSmsCodeAutofillClient
tarafından gönderilen otomatik olarak doldurduğunuz uygulamanın paket adı için etkin. Otomatik doldurma bilgileriniz hizmeti yalnızcafalse
değerini döndürürse bir öneri istemi görüntülemelidir. - Otomatik doldurma hizmetinde
checkPermissionState
değerini kullanın. Otomatik doldurma hizmetinin bulunup bulunmadığını kontrol etmek içinSmsCodeAutofillClient
adresinden Tek seferlik kodları otomatik olarak doldurma izni. Bu izin durumuNONE
olabilir.GRANTED
veyaDENIED
. Otomatik doldurma hizmeti,NONE
veGRANTED
eyaletleri için bir öneri istemi göstermelidir. - Otomatik doldurma kimlik doğrulama etkinliğinde
BroadcastReceiver
kaydettirmek içinSmsRetriever.SEND_PERMISSION
izni SMS almak içinSmsCodeRetriever.SMS_CODE_RETRIEVED_ACTION
dinleniyor kullanılabilir olduğunda kod sonucunu verir. SMS ile gönderilen tek seferlik kodları dinlemeye başlamak için
SmsCodeAutofillClient
'dastartSmsCodeRetriever
numaralı telefonu arayın. Kullanıcı, otomatik doldurma hizmetinizin SMS'den tek seferlik kodları almasına izin verirse bu işlem, şu andan itibaren son bir ila beş dakika içinde alınan SMS mesajlarını arar.Otomatik doldurma hizmetinizin bir defalık okuma için kullanıcı izni istemesi gerekiyorsa varsa
startSmsCodeRetriever
tarafından döndürülenTask
,ResolvableApiException
geri döndü. Bu durumda, izin isteği için kullanıcı rızası iletişim kutusu görüntülemek üzereResolvableApiException.startResolutionForResult()
yöntemini çağırmanız gerekir.Intent'ten SMS kodu sonucunu alın ve ardından SMS kodunu otomatik doldurma yanıtı olarak döndürün.
Gelişmiş otomatik doldurma senaryoları
- Klavyeyle entegre etme
- Android 11'den itibaren platformda klavye kullanılabilir ve diğer giriş yöntemi düzenleyicileri (IME'ler) özelliğini kullanabilirsiniz. Otomatik doldurma hizmetinizin bunu nasıl destekleyebileceği hakkında daha fazla bilgi için işlevi için Otomatik doldurmayı Google Haritalar ile klavyeler.
- Veri kümelerini sayfalara ayır
- Büyük bir otomatik doldurma yanıtı,
Binder
nesnesini temsil eden isteği işlemek için gereken tekrarlanabilir nesne. Android sisteminin bu senaryolarda istisna atmasını önlemek için bir seferde en fazla 20Dataset
nesnesi ekleyerekFillResponse
'yi küçük tutabilirsiniz. Yanıtınız için daha fazla veri kümesi gerekiyorsa kullanıcılar daha fazla bilgi olduğunu bilir ve veri kümelerinin sayısını artırır. Daha fazla bilgi içinaddDataset(Dataset)
başlıklı makaleyi inceleyin. - Verileri birden fazla ekrana bölerek kaydetme
Uygulamalar genellikle kullanıcı verilerini aynı etkinlik sırasında birden fazla ekranda böler. özellikle de yeni bir kullanıcı hesabı oluşturmak için kullanılan etkinliklerde kullanılır. Örneğin, ilk ekranda kullanıcı adı istenir ve kullanıcı adı mevcutsa ikinci ekranda şifre istenir. Bu tür durumlarda, otomatik doldurma hizmetinin, kullanıcı her iki özelliği de girene kadar beklemesi gerekir. alanlarının daha görünür olması gerekir. Bu tür senaryoları ele almak için aşağıdaki adımları uygulayın:
- İlk doldurma isteğinde, ekranda bulunan kısmi alanların otomatik doldurma kimliklerini içeren bir istemci durumu paketi yanıta ekleyin.
- İkinci doldurma isteğinde
istemci durumu paketini alma, belirlenen otomatik doldurma kimliklerini alma
değerini kontrol edip bu kimlikleri ve
FLAG_SAVE_ON_ALL_VIEWS_INVISIBLE
flag'ini ikinci yanıtta kullanılanSaveInfo
nesnesine ekleyin. - Kaydet isteği'nde, her alanın değerini almak için uygun
FillContext
nesnelerini kullanın. Doldurma isteği başına bir doldurma bağlamı vardır.
Daha fazla bilgi için Veriler birden fazla ekrana bölündüğünde kaydetme konusuna bakın.
- Her istek için başlatma ve söküm mantığı sağlayın
Otomatik doldurma isteği geldiğinde Android sistemi hizmeti kullanır ve
onConnected()
yöntemini çağırır. Hizmet isteği işledikten sonra Android sistemionDisconnected()
yöntemini çağırır ve hizmetle olan bağlamayı kaldırır. RACI matrisleri içinonConnected()
bir istek işlemeden önce çalıştırılan kod ve sağlamak içinonDisconnected()
bir istek işlendikten sonra çalışan koddur.- Otomatik doldurmayı kaydetme kullanıcı arayüzünü özelleştirme
Otomatik doldurma hizmetleri, kullanıcıların verilerini hizmetin kaydetmesine izin vermek isteyip istemediklerine karar vermelerine yardımcı olmak için otomatik doldurma kaydetme kullanıcı arayüzünü özelleştirebilir. Hizmetler, basit bir metin veya özelleştirilmiş bir görünüm aracılığıyla kaydedilenler hakkında ek bilgi sağlayabilir. Hizmetler, kayıt isteğini iptal eden düğmenin görünümünü de değiştirebilir ve kullanıcı bu düğmeye dokunduğunda bildirim alabilir. Daha fazla bilgi için
SaveInfo
referans sayfasına bakın.- Uyumluluk modu
Uyumluluk modu, otomatik doldurma hizmetlerinin otomatik doldurma amacıyla erişilebilirlik sanal yapısını kullanmasına olanak tanır. Özellikle de tarayıcıdaki otomatik doldurma işlevinin sağlanması için otomatik doldurma API'lerini açıkça uygulamaz.
Uyumluluk modunu kullanarak otomatik doldurma hizmetinizi test etmek için uyumluluk modu gerektiren tarayıcıyı veya uygulamayı izin verilenler listesine ekleyin. Aşağıdaki komutu çalıştırarak hangi paketlerin izin verilenler listesine eklendiğini kontrol edebilirsiniz:
$ adb shell settings get global autofill_compat_mode_allowed_packages
Test ettiğiniz paket listede yoksa şunu çalıştırarak ekleyin:
pkgX
, uygulamanın paketidir:$ adb shell settings put global autofill_compat_mode_allowed_packages pkg1[resId1]:pkg2[resId1,resId2]
Uygulama bir tarayıcıysa oluşturulan sayfanın URL'sini içeren giriş alanının kaynak kimliğini belirtmek için
resIdx
kullanın.
Uyumluluk modunda aşağıdaki sınırlamalar söz konusudur:
- Hizmet
FLAG_SAVE_ON_ALL_VIEWS_INVISIBLE
işaretini kullandığında veyasetTrigger()
yöntemi çağrıldığında bir kayıt isteği tetiklenir.FLAG_SAVE_ON_ALL_VIEWS_INVISIBLE
, şu durumlarda varsayılan olarak ayarlanır: uyumluluk modunu kullanarak kontrol edebilirsiniz. - Düğümlerin metin değeri
onSaveRequest(SaveRequest, SaveCallback)
yöntemidir.
Sınırlamalar da dahil olmak üzere uyumluluk modu hakkında daha fazla bilgi edinmek için
varsa,
AutofillService
sınıf referansını gösterir.