Otomatik doldurma hizmetleri oluşturma

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 şunları da yapabilir: bir uygulamadaki görünümlerden kullanıcı verilerini alıp daha sonra kullanmak üzere depolayabilir gerekir. Otomatik doldurma hizmetleri genellikle kullanıcı verilerini yöneten uygulamalar tarafından sağlanır. Örneğin: izin verir.

Android, Android 8.0 (API düzeyi 26) ve sonraki sürümler. Kullanıcılar otomatik doldurma özelliğinden yararlanabilir Yalnızca mobil cihazlarında otomatik doldurma hizmetleri sağlayan bir uygulama varsa olanak tanır.

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 referansa bakın AutofillService sayfaları ve AutofillManager sınıflar.

Manifest beyanları ve izinleri

Otomatik doldurma hizmeti sunan uygulamalar, hizmetin uygulanmasını açıklayan bir beyan içermelidir. Beyan etmek için uygulama manifest dosyasına bir <service> öğesi ekleyin. İlgili içeriği oluşturmak için kullanılan <service> öğesi, aşağıdaki özellikleri ve öğeleri içerir:

  • android:name özelliği özelliğini uygulayan uygulamada AutofillService alt sınıfına işaret eden geri dönelim.
  • android:permission BIND_AUTOFILL_SERVICE özelliğini tanımlayan özellik izni gerekir.
  • android.service.autofill.AutofillService işlemini belirten zorunlu <action> alt öğesine sahip <intent-filter> öğesi.
  • İsteğe bağlı <meta-data> öğesi için ek yapılandırma parametreleri sağlamak üzere geri dönelim.

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, bir android:resource özelliğiyle ilgili daha fazla ayrıntı içeren bir XML kaynağına işaret eden özellik değeridir. Önceki örnekteki service_configuration kaynağı, kullanıcıların hizmeti yapılandırmasına olanak tanıyan bir etkinlik belirtir. Aşağıdaki örnekte service_configuration XML kaynağı gösterilmektedir:

<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, aşağıdakileri beyan ettikten sonra otomatik doldurma hizmeti olarak kullanılır: BIND_AUTOFILL_SERVICE izni varsa ve kullanıcı bu izni cihazda etkinleştirirse Ayarlar'da devre dışı bırakabilirsiniz. Bir uygulama, hasEnabledAutofillServices() yöntemini AutofillManager sınıfında bulabilirsiniz.

Uygulama, geçerli otomatik doldurma hizmeti değilse ACTION_REQUEST_SET_AUTOFILL_SERVICE intent'ini kullanarak kullanıcıdan otomatik doldurma ayarlarını değiştirmesini isteyebilir. 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üşlerini doldurma

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 hizmetinin, ardından verileri yanıta 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 arayüzü

Şekil 1. Bir veri kümesini gösteren otomatik doldurma kullanıcı arayüzü.

Otomatik doldurma çerçevesi, şu şekilde tasarlanmış görünümleri doldurmak için bir iş akışı tanımlar: Android sisteminin otomatik doldurma hizmetine bağlı olduğu süreyi en aza indirir. 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şılayabilirse hizmet paketleri Dataset bünyesindeki veriler nesneler'i tıklayın. Hizmet, Dataset nesnelerini içeren bir FillResponse nesnesi geçirerek onSuccess() yöntemini çağırır. Hizmet, isteği karşılayacak verilere sahip değilse null değerini onSuccess() yöntemine 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 hizmetin, isteği karşılayan birden fazla veri kümesi 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, yanıtta birden fazla veri kümesi sağlar:

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, isteği yerine getirmek için gereken otomatik doldurma verilerini almak üzere AssistStructure içindeki ViewNode nesnelerinde gezinebilir. Bir hizmet, ViewNode sınıfının getAutofillId() gibi yöntemlerini kullanarak otomatik doldurma verilerini alabilir.

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. autofillHints'ı kullanma özelliğinin ilk bir hizmetin bir görünümün içeriğini tanımlamak için kullanması gereken yaklaşımdır. Ancak, Bu özellik, etkinleştirilmeden önce kendi görünümlerinde açıkça sunulmalıdır. kullanılabilir.

Bir istemci uygulaması autofillHints özelliğini sağlamazsa hizmet, içerikleri tanımlamak için kendi sezgisel yaklaşımlarını kullanmalıdır. Hizmet, getText() gibi diğer sınıfların yöntemlerini kullanabilir veya getHint(), görünümün içeriğiyle ilgili bilgi almak için 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 kaydedin.

Otomatik doldurma hizmetlerinin, 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, kullanıcılardan verileri mevcut otomatik doldurma hizmeti ile yapılandırın.

Otomatik doldurma kaydetme kullanıcı arayüzü

Şekil 2. Otomatik doldurmayı kaydetme kullanıcı arayüzü.

Verileri kaydedebilmek için hizmetin, verileri gelecekte kullanmak üzere saklamak istediğini belirtmesi gerekir. Android sistemi verileri kaydetme isteği göndermeden önce, hizmetin görünümleri doldurma fırsatı bulduğu bir doldurma isteği gönderilir. Verileri kaydetmek istediğini belirtmek için hizmet, doldurma isteğine yanıt olarak bir SaveInfo nesnesi ekler. SaveInfo nesnesi en az aşağıdaki verileri içerir:

  • Kaydedilen kullanıcı verisi türü. Mevcut programların SAVE_DATA değerleri için SaveInfo 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 ve password görünümlerini güncellemesi gerekir.

Bir SaveInfo nesnesi, şurada gösterildiği gibi bir FillResponse nesnesiyle ilişkilendirilmiş: aşağıdaki kod örneği:

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 saklamadan önce şifrelemelidir. Ancak, Kullanıcı verileri, hassas olmayan etiketler veya veriler içerebilir. Örneğin, bir kullanıcı hesabı, verileri veya kişisel hesap olarak işaretleyen bir etiket içerebilir. Hizmetler, etiketleri şifrelemelidir. 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

Otomatik doldurmayı uygulamak için birden fazla ekran kullanıyorsanız Android 10'dan itibaren Örneğin, kullanıcı adı alanı için bir ekran, parolayı girin. SaveInfo.FLAG_DELAY_SAVE tıklayın.

Bu işaret ayarlanırsa otomatik doldurma sırasında otomatik doldurmayı kaydetme kullanıcı arayüzü tetiklenmez SaveInfo yanıtıyla ilişkili bağlam kaydedilir. Bunun yerine gelecekteki doldurma isteklerini teslim etmek için aynı görevde ayrı bir etkinlik kullanır. kullanıcı arayüzünü kaydetme isteği aracılığıyla gösterin. 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ı kullanılarak açılması gerekir.
  • Kart doğrulama kodu (CVC) kullanılarak kredi kartı bilgileri gibi belirli bir veri kümesinin kilidinin açılması gerekir.

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. Aşağıdaki kodda, kimlik doğrulama akışları tamamlandıktan sonra sonucun nasıl döndürüleceğine dair bir örnek gösterilmektedir:

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ümesi tamamlanana kadar verileri bankanın adı ve banka numarası gibi ortak veriler sunarak kilidi açılır. kredi kartı numarasının son dört hanesi. 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ğırır. RESULT_OK değeri iletmek ve EXTRA_AUTHENTICATION_RESULT ekstra değerini Kredi kartı numarasını ve son kullanma tarihini içeren bir Dataset nesnesi. İ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 birbirinden ayıran mantıksal gruplar halinde düzenlemelidir. farklı alan adlarındaki kavramlardır. Bu sayfadaki mantıksal gruplara bölümler denir. Aşağıdaki listede, bölüm ve alanlara ilişkin tipik örnekler verilmiştir:

  • Kullanıcı adı ve şifre alanlarını içeren kimlik bilgileri.
  • Sokak, ş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ümleyen bir otomatik doldurma hizmeti, tek bir bölümde birden fazla bölümden veri göstermeyerek, veri kümesiyle eşleştirilir. Örneğin, kimlik bilgilerini içeren bir veri kümesinin ödeme bilgilerini içermesi gerekmez. Verileri bölümler halinde düzenlemek şunları sağlar: ve böylece kullanıcı olabilir.

Verilerin bölümler halinde düzenlenmesi, hizmetlerin şu bölümü içeren etkinlikleri doldurmasını sağlar: minimum miktarda alakalı içerik göndererek, birden fazla bölümden gelen görüntüleme sayısını aktarmanızı sağlar. Örneğin, görüntüleme sayısı içeren bir etkinliği düşünün ve bu bilgileri içeren otomatik doldurma hizmeti için, aşağıdaki veriler:

Bölüm Alan 1 Alan 2
Kimlik Bilgisi work_username iş_şifresi
personal_username personal_password
Adres iş_sokağı work_city
personal_street personal_city

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ı, kullanıcının ilk seçimine bağlı olarak iş veya kişisel adresi sağlayabilir.

Bir hizmet, AssistStructure nesnesini gezerken isFocused() yöntemini çağırarak isteği başlatan alanı tanımlayabilir. Bu sayede hizmet, uygun bölüm verileriyle bir FillResponse hazırlayabilir.

SMS ile tek seferlik kod otomatik doldurma

Otomatik doldurma hizmetiniz, kullanıcının SMS Retriever API'yi kullanarak SMS.

Bu özelliği kullanmak 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.
  • Kullanıcı, otomatik doldurma hizmetinizin SMS'e dokunun.
  • Otomatik doldurma özelliğini sağladığınız uygulama, Tek seferlik kodları okumak için SMS Retriever API.

Otomatik doldurma hizmetiniz SmsCodeAutofillClient kullanabilir, Google Play'den SmsCodeRetriever.getAutofillClient() numaralı telefonu arayarak kullanılabilir Hizmetler 19.0.56 veya sonraki sürümler.

Bu API'yi bir otomatik doldurma hizmetinde kullanmanın temel adımları şunlardır:

  1. Otomatik doldurma hizmetinde, otomatik olarak doldurduğunuz uygulamanın paket adı için etkin istek olup olmadığını belirlemek üzere SmsCodeAutofillClient'dan hasOngoingSmsRequest kullanın. Otomatik doldurma bilgileriniz hizmeti yalnızca false değerini döndürürse bir öneri istemi görüntülemelidir.
  2. Otomatik doldurma hizmetinde checkPermissionState değerini kullanın. Otomatik doldurma hizmetinin bulunup bulunmadığını kontrol etmek için SmsCodeAutofillClient adresinden Tek seferlik kodları otomatik olarak doldurma izni. Bu izin durumu NONE olabilir. GRANTED veya DENIED. Otomatik doldurma hizmeti bir öneri istemi göstermelidir NONE ve GRANTED eyaletleri için.
  3. Otomatik doldurma kimlik doğrulama etkinliğinde BroadcastReceiver kaydettirmek için SmsRetriever.SEND_PERMISSION izni SMS almak için SmsCodeRetriever.SMS_CODE_RETRIEVED_ACTION dinleniyor kullanılabilir olduğunda kod sonucunu verir.
  4. startSmsCodeRetriever numaralı telefonu arayın SMS ile gönderilen tek seferlik kodları dinlemeye başlamak için SmsCodeAutofillClient tarihinde. 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ülen Task, ResolvableApiException geri döndü. Bu durumda, izin isteği için kullanıcı rızası iletişim kutusu görüntülemek üzere ResolvableApiException.startResolutionForResult() yöntemini çağırmanız gerekir.

  5. 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 platform, klavyelerin ve diğer giriş yöntemi düzenleyicilerin (IME'ler) açılır menü kullanmak yerine satır içi otomatik doldurma önerilerini görüntülemesine olanak tanır. Otomatik doldurma hizmetinizin bu işlevi nasıl destekleyebileceği hakkında daha fazla bilgi için Otomatik doldurmayı klavyelerle entegre etme başlıklı makaleyi inceleyin.
Veri kümelerini sayfalara ayır
Büyük bir otomatik doldurma yanıtı, isteği işlemek için gereken uzaktan taşınabilir nesneyi temsil eden Binder nesnesinin izin verilen işlem boyutunu aşabilir. Android sisteminin istisnayı oluşturduktan sonra FillResponse 20'den fazla Dataset nesne eklenmeden küçük oluşturabilirsiniz. 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çin addDataset(Dataset) başlıklı makaleyi inceleyin.
Verileri birden fazla ekrana bölerek kaydetme

Uygulamalar genellikle kullanıcı verilerini aynı etkinlikteki birden fazla ekrana böler. Özellikle yeni bir kullanıcı hesabı oluşturmak için kullanılan etkinliklerde bu durumla karşılaşı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. Bunları takip et: şu adımları izleyin:

  1. İlk doldurma isteğinde, istemci durumu paketi ekleyin kısmi alanların otomatik doldurma kimliklerini içeren yanıtta ekranda görünür.
  2. İkinci doldurma isteğinde, istemci durumu paketini alın, önceki istemede istemci durumunda ayarlanan otomatik doldurma kimliklerini alın ve bu kimlikleri ile FLAG_SAVE_ON_ALL_VIEWS_INVISIBLE işaretini ikinci yanıtta kullanılan SaveInfo nesnesine ekleyin.
  3. Kaydetme isteğinde, doğru FillContext nesnelerini kullanır. Her biri için bir dolgu bağlamı var isteği doldur.

Daha fazla bilgi için Veriler birden fazla ekrana bölündüğünde kaydetme konusuna bakın.

Her istek için başlatma ve yıkım mantığı sağlayın

Android sistemi, her otomatik doldurma isteği aldığında hizmete bağlanır ve onConnected() yöntemini çağırır. Hizmet isteği işledikten sonra Android sistemi onDisconnected() yöntemini kullanarak hizmet ile bağlantısını keser. RACI matrisleri için onConnected() bir istek işlemeden önce çalıştırılan kod ve sağlamak için onDisconnected() 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 otomatik doldurmayı kaydetme kullanıcı arayüzünü özelleştirerek kullanıcıların hizmetin verilerini kaydetmesine izin vermek istiyor. Hizmetler, basit bir metin veya özelleştirilmiş bir görünüm aracılığıyla kaydedilenler hakkında ek bilgi sağlayabilir. Hizmetler, düğmenin görünümünü de değiştirebilir Kullanıcı, kaydetme isteğini iptal eder ve kullanıcı buna dokunduğunda bildirim alır. düğmesini tıklayın. Daha fazla bilgi için SaveInfo referans sayfasına bakın.

Uyumluluk modu

Uyumluluk modu, otomatik doldurma hizmetlerinin erişilebilirliği kullanmasına izin verir. sanal yapı . Özellikle, otomatik doldurma API'lerini açıkça uygulamayan tarayıcılarda otomatik doldurma işlevi sağlamak için kullanışlıdır.

Uyumluluk modunu kullanarak otomatik doldurma hizmetinizi test etmek için uyumluluk modunu gerektiren tarayıcı veya uygulamayı açıkça 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 veya setTrigger() yöntemi çağrılır. 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.

Uyumluluk modu ve bu modla ilişkili sınırlamalar hakkında daha fazla bilgi için AutofillService sınıf referansına bakın.