जानकारी ऑटोमैटिक भरने की सुविधा दें

ऑटोमैटिक भरने की सुविधा देने वाला ऐप्लिकेशन, एक ऐसा ऐप्लिकेशन होता है जो उपयोगकर्ताओं को दूसरे ऐप्लिकेशन के व्यू में डेटा डालकर, फ़ॉर्म भरने में आसानी करता है. ऑटोमैटिक जानकारी भरने की सेवाएं, किसी ऐप्लिकेशन के व्यू से उपयोगकर्ता का डेटा भी हासिल कर सकती हैं. साथ ही, बाद में इस्तेमाल करने के लिए उसे सेव भी कर सकती हैं. ऑटोमैटिक भरने की सुविधाएं, आम तौर पर ऐसे ऐप्लिकेशन उपलब्ध कराते हैं जो उपयोगकर्ता का डेटा मैनेज करते हैं. जैसे, पासवर्ड मैनेजर.

Android 8.0 (एपीआई लेवल 26) और इसके बाद के वर्शन में, ऑटोमैटिक भरने की सुविधा उपलब्ध है. इसकी मदद से, फ़ॉर्म आसानी से भरे जा सकते हैं. उपयोगकर्ता, ऑटोमैटिक भरने की सुविधाओं का फ़ायदा सिर्फ़ तब ले सकते हैं, जब उनके डिवाइस पर कोई ऐसा ऐप्लिकेशन हो जो ऑटोमैटिक भरने की सेवाएं देता हो.

इस पेज पर, अपने ऐप्लिकेशन में ऑटोमैटिक भरने की सुविधा को लागू करने का तरीका बताया गया है. अगर आपको किसी सेवा को लागू करने का तरीका बताने वाला कोड सैंपल चाहिए, तो Java या Kotlin में AutofillFramework का सैंपल देखें. ऑटोमैटिक भरने की सुविधाएं कैसे काम करती हैं, इस बारे में ज़्यादा जानने के लिए, AutofillService और AutofillManager क्लास के रेफ़रंस पेज देखें.

मेनिफ़ेस्ट में किए गए एलान और अनुमतियां

अपने-आप जानकारी भरने की सेवा देने वाले ऐप्लिकेशन में, एक एलान शामिल होना चाहिए. इसमें, सेवा को लागू करने के बारे में जानकारी दी गई होनी चाहिए. एलान करने के लिए, ऐप्लिकेशन मेनिफ़ेस्ट में <service> एलिमेंट शामिल करें. <service> एलिमेंट में ये एट्रिब्यूट और एलिमेंट होने चाहिए:

  • android:name एट्रिब्यूट, सेवा को लागू करने वाले ऐप्लिकेशन में AutofillService के सबक्लास पर ले जाता है.
  • android:permission एट्रिब्यूट, जो BIND_AUTOFILL_SERVICE अनुमति के बारे में बताता है.
  • <intent-filter> एलिमेंट, जिसके लिए ज़रूरी <action> चाइल्ड, android.service.autofill.AutofillService कार्रवाई के बारे में बताता है.
  • <meta-data> एलिमेंट, जो ज़रूरी नहीं है. इसका इस्तेमाल, सेवा के लिए अतिरिक्त कॉन्फ़िगरेशन पैरामीटर देने के लिए किया जा सकता है.

यहां ऑटोमैटिक जानकारी भरने की सेवा का एलान दिखाया गया है:

<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> एलिमेंट में एक android:resource एट्रिब्यूट शामिल होता है. यह एट्रिब्यूट, सेवा के बारे में ज़्यादा जानकारी वाले एक्सएमएल संसाधन पर ले जाता है. पिछले उदाहरण में, service_configuration संसाधन एक ऐसी गतिविधि के बारे में बताता है जो उपयोगकर्ताओं को सेवा कॉन्फ़िगर करने की अनुमति देती है. यहां दिए गए उदाहरण में, service_configuration एक्सएमएल रिसॉर्स दिखाया गया है:

<autofill-service
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:settingsActivity="com.example.android.SettingsActivity" />

एक्सएमएल संसाधनों के बारे में ज़्यादा जानने के लिए, ऐप्लिकेशन के संसाधनों की खास जानकारी देखें.

सेवा चालू करने के लिए प्रॉम्प्ट

जब कोई ऐप्लिकेशन BIND_AUTOFILL_SERVICE अनुमति का एलान करता है और उपयोगकर्ता डिवाइस की सेटिंग में जाकर उसे चालू करता है, तब उस ऐप्लिकेशन का इस्तेमाल ऑटोमैटिक भरने की सेवा के तौर पर किया जाता है. कोई ऐप्लिकेशन, AutofillManager क्लास के hasEnabledAutofillServices() तरीके को कॉल करके पुष्टि कर सकता है कि वह फ़िलहाल चालू सेवा है या नहीं.

अगर ऐप्लिकेशन, जानकारी अपने-आप भरने की मौजूदा सेवा नहीं है, तो वह उपयोगकर्ता से जानकारी अपने-आप भरने की सेटिंग बदलने का अनुरोध कर सकता है. इसके लिए, वह ACTION_REQUEST_SET_AUTOFILL_SERVICE इंटेंट का इस्तेमाल करता है. अगर उपयोगकर्ता, कॉलर के पैकेज से मैच करने वाली ऑटोमैटिक भरने की सेवा चुनता है, तो इंटेंट RESULT_OK की वैल्यू दिखाता है.

क्लाइंट व्यू भरना

जब उपयोगकर्ता किसी दूसरे ऐप्लिकेशन के साथ इंटरैक्ट करता है, तो जानकारी अपने-आप भरने की सेवा को क्लाइंट व्यू भरने के अनुरोध मिलते हैं. अगर ऑटोमैटिक भरने की सेवा में उपयोगकर्ता का ऐसा डेटा है जो अनुरोध के मुताबिक है, तो वह डेटा जवाब में भेजता है. Android सिस्टम, उपलब्ध डेटा के साथ ऑटोमैटिक भरने की सुविधा वाला यूज़र इंटरफ़ेस (यूआई) दिखाता है, जैसा कि पहले चित्र में दिखाया गया है:

यूज़र इंटरफ़ेस (यूआई) अपने-आप भरने की सुविधा

पहली इमेज. डेटासेट दिखाने वाला, ऑटोमैटिक भरने की सुविधा वाला यूज़र इंटरफ़ेस (यूआई).

ऑटोमैटिक भरने वाला फ़्रेमवर्क, व्यू को भरने के लिए वर्कफ़्लो को तय करता है. इसे इस तरह से डिज़ाइन किया गया है कि Android सिस्टम, जानकारी ऑटोमैटिक भरने की सुविधा से लगने वाले समय को कम कर सके. हर अनुरोध में, Android सिस्टम onFillRequest() तरीके को कॉल करके, सेवा को AssistStructure ऑब्जेक्ट भेजता है.

ऑटोमैटिक भरने की सेवा यह जांच करती है कि वह उपयोगकर्ता के पहले से सेव किए गए डेटा के अनुरोध को पूरा कर सकती है या नहीं. अगर यह अनुरोध पूरा कर सकती है, तो सेवा Dataset ऑब्जेक्ट में डेटा पैकेज करती है. सेवा onSuccess() मेथड को कॉल करती है और ऐसे FillResponse ऑब्जेक्ट को पास करती है जिसमें Dataset ऑब्जेक्ट होता है. अगर सेवा के पास अनुरोध को पूरा करने के लिए डेटा नहीं है, तो वह null को onSuccess() तरीके पर भेजती है.

अगर अनुरोध को प्रोसेस करने में कोई गड़बड़ी होती है, तो सेवा onFailure() के तरीके को कॉल करती है. वर्कफ़्लो के बारे में ज़्यादा जानने के लिए, AutofillService रेफ़रंस पेज पर दिया गया ब्यौरा देखें.

यहां दिया गया कोड, onFillRequest() तरीके का एक उदाहरण दिखाता है:

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;
}

किसी सेवा में, अनुरोध को पूरा करने वाला एक से ज़्यादा डेटासेट हो सकता है. इस मामले में, Android सिस्टम अपने-आप जानकारी भरने की सुविधा के यूज़र इंटरफ़ेस (यूआई) में, हर डेटासेट के लिए एक विकल्प दिखाता है. कोड का यह उदाहरण दिखाता है कि रिस्पॉन्स में एक से ज़्यादा डेटासेट कैसे दिए जाएं:

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();

ऑटोमैटिक भरने की सुविधाएं, AssistStructure में मौजूद ViewNode ऑब्जेक्ट पर नेविगेट कर सकती हैं. इससे, अनुरोध पूरा करने के लिए ऑटोमैटिक भरने की सुविधा से जुड़ा ज़रूरी डेटा हासिल किया जा सकता है. कोई सेवा, ऑटोमैटिक भरने की सुविधा से जुड़ा डेटा, ViewNode क्लास के तरीकों का इस्तेमाल करके हासिल कर सकती है. जैसे, getAutofillId().

यह ज़रूरी है कि कोई सेवा, किसी व्यू के कॉन्टेंट के बारे में बता सके, ताकि यह पता चल सके कि वह अनुरोध को पूरा कर सकती है या नहीं. autofillHints एट्रिब्यूट का इस्तेमाल करना पहला तरीका है जिसका इस्तेमाल किसी सेवा को व्यू के कॉन्टेंट की जानकारी देने के लिए करना चाहिए. हालांकि, क्लाइंट ऐप्लिकेशन को सेवा के लिए उपलब्ध कराने से पहले, अपने व्यू में एट्रिब्यूट को साफ़ तौर पर देना होगा.

अगर कोई क्लाइंट ऐप्लिकेशन autofillHints एट्रिब्यूट की वैल्यू नहीं देता है, तो सेवा को कॉन्टेंट के बारे में बताने के लिए, अपने हेयुरिस्टिक्स का इस्तेमाल करना होगा. व्यू के कॉन्टेंट की जानकारी पाने के लिए, सेवा अन्य क्लास के तरीकों का इस्तेमाल कर सकती है. जैसे, getText() या getHint(). ज़्यादा जानकारी के लिए, ऑटोमैटिक भरने की सुविधा के लिए संकेत देना लेख पढ़ें.

इस उदाहरण में, AssistStructure को ट्रैवर्स करने और ViewNode ऑब्जेक्ट से ऑटोमैटिक भरने की सुविधा का डेटा पाने का तरीका बताया गया है:

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);
    }
}

उपयोगकर्ता का डेटा सेव करना

अपने-आप जानकारी भरने की सेवा को ऐप्लिकेशन में व्यू भरने के लिए, उपयोगकर्ता के डेटा की ज़रूरत होती है. जब उपयोगकर्ता किसी व्यू को मैन्युअल तरीके से भरते हैं, तो उन्हें ऑटोमैटिक भरने की मौजूदा सेवा में डेटा सेव करने के लिए कहा जाता है. इसकी जानकारी, दूसरी इमेज में दी गई है.

ऑटोमैटिक भरने की सुविधा सेव करने के लिए यूज़र इंटरफ़ेस (यूआई)

दूसरी इमेज. ऑटोमैटिक भरने की सुविधा सेव करने के लिए यूज़र इंटरफ़ेस (यूआई).

डेटा सेव करने के लिए, सेवा को यह बताना होगा कि वह आने वाले समय में डेटा का इस्तेमाल करने के लिए, उसे स्टोर करना चाहती है. Android सिस्टम, डेटा सेव करने का अनुरोध भेजने से पहले, एक अनुरोध भेजता है. इस अनुरोध में, सेवा को व्यू भरने का मौका मिलता है. यह बताने के लिए कि वह डेटा सेव करना चाहती है, सेवा इसके लिए किए गए अनुरोध के जवाब में SaveInfo ऑब्जेक्ट शामिल करती है. SaveInfo ऑब्जेक्ट में कम से कम यह डेटा शामिल होता है:

  • उपयोगकर्ता का सेव किया गया डेटा किस तरह का है. उपलब्ध SAVE_DATA वैल्यू की सूची के लिए, SaveInfo देखें.
  • सेव करने का अनुरोध ट्रिगर करने के लिए, व्यू के कम से कम उस सेट को बदलना होगा. उदाहरण के लिए, सेव करने का अनुरोध ट्रिगर करने के लिए, लॉगिन फ़ॉर्म को आम तौर पर username और password व्यू को अपडेट करना पड़ता है.

SaveInfo ऑब्जेक्ट, FillResponse ऑब्जेक्ट से जुड़ा होता है, जैसा कि नीचे दिए गए कोड के उदाहरण में दिखाया गया है:

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();
    ...
}

ऑटोमैटिक भरने की सेवा, उपयोगकर्ता के डेटा को onSaveRequest() तरीके से सेव करने के लिए लॉजिक लागू कर सकती है. आम तौर पर, क्लाइंट गतिविधि खत्म होने के बाद या क्लाइंट ऐप्लिकेशन के commit() को कॉल करने पर, इसे कॉल किया जाता है. यहां दिया गया कोड, onSaveRequest() तरीके का एक उदाहरण दिखाता है:

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();
}

अपने-आप जानकारी भरने की सेवाओं को संवेदनशील डेटा को सेव करने से पहले, उसे एन्क्रिप्ट करना होगा. हालांकि, उपयोगकर्ता डेटा में ऐसे लेबल या डेटा शामिल हो सकते हैं जो संवेदनशील नहीं हैं. उदाहरण के लिए, किसी उपयोगकर्ता खाते में ऐसा लेबल शामिल हो सकता है जो डेटा को ऑफ़िस या निजी खाते के तौर पर मार्क करता है. सेवाओं को लेबल को एन्क्रिप्ट नहीं करना चाहिए. लेबल को एन्क्रिप्ट न करने पर, सेवाएं प्रज़ेंटेशन व्यू में लेबल का इस्तेमाल कर सकती हैं. ऐसा तब होता है, जब उपयोगकर्ता ने पुष्टि न की हो. इसके बाद, उपयोगकर्ता की पुष्टि करने के बाद सेवाएं, लेबल को असल डेटा से बदल सकती हैं.

ऑटोमैटिक भरने की सुविधा को सेव करने के लिए, यूज़र इंटरफ़ेस (यूआई) को रोकें

अगर ऑटोमैटिक भरने की सुविधा का वर्कफ़्लो लागू करने के लिए, एक से ज़्यादा स्क्रीन का इस्तेमाल किया जाता है, तो Android 10 और उसके बाद के वर्शन में उपयोगकर्ता नाम वाले फ़ील्ड के लिए एक स्क्रीन और पासवर्ड के लिए दूसरी स्क्रीन इस्तेमाल करने पर, SaveInfo.FLAG_DELAY_SAVE फ़्लैग का इस्तेमाल करके, ऑटोमैटिक भरने की सुविधा के लिए सेव किए गए यूज़र इंटरफ़ेस (यूआई) को बाद में रोका जा सकता है.

अगर यह फ़्लैग सेट है, तो SaveInfo रिस्पॉन्स से जुड़ा ऑटोमैटिक भरने का कॉन्टेक्स्ट लागू होने पर, ऑटोमैटिक भरने की सुविधा सेव करने वाला यूज़र इंटरफ़ेस ट्रिगर नहीं होता. इसके बजाय, आने वाले समय में डेटा भरने के अनुरोधों को डिलीवर करने के लिए, उसी टास्क में किसी अलग गतिविधि का इस्तेमाल किया जा सकता है. इसके बाद, सेव करने के अनुरोध के ज़रिए यूज़र इंटरफ़ेस (यूआई) दिखाया जा सकता है. ज़्यादा जानकारी के लिए, SaveInfo.FLAG_DELAY_SAVE देखें.

उपयोगकर्ता की पुष्टि करना ज़रूरी है

जानकारी अपने-आप भरने की सुविधा, व्यू भरने से पहले उपयोगकर्ता को पुष्टि करने के लिए कहती है. इससे, सुरक्षा का एक और लेवल मिल जाता है. उपयोगकर्ता की पुष्टि करने की प्रक्रिया को लागू करने के लिए, ये स्थितियां अच्छी हैं:

  • ऐप्लिकेशन में उपयोगकर्ता के डेटा को अनलॉक करने के लिए, मुख्य पासवर्ड या उंगली के निशान का इस्तेमाल करना ज़रूरी है.
  • किसी खास डेटासेट को अनलॉक करना हो, जैसे कि कार्ड की पुष्टि करने वाले कोड (सीवीसी) का इस्तेमाल करके क्रेडिट कार्ड की जानकारी.

अगर डेटा को अनलॉक करने से पहले, सेवा को उपयोगकर्ता की पुष्टि की ज़रूरत है, तो सेवा कोई बोइलरप्लेट डेटा या लेबल दिखा सकती है. साथ ही, पुष्टि करने वाले Intent की जानकारी दे सकती है. अगर पुष्टि करने की प्रोसेस पूरी होने के बाद, अनुरोध को प्रोसेस करने के लिए आपको ज़्यादा डेटा चाहिए, तो इस तरह का डेटा इंटेंट में जोड़ा जा सकता है. इसके बाद, पुष्टि करने की आपकी गतिविधि, आपके ऐप्लिकेशन में डेटा को AutofillService क्लास में वापस ला सकती है.

यहां दिए गए कोड के उदाहरण में, यह बताने का तरीका बताया गया है कि अनुरोध के लिए पुष्टि करना ज़रूरी है:

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();

पुष्टि करने का फ़्लो पूरा होने के बाद, गतिविधि को RESULT_OK वैल्यू पास करके, setResult() तरीके को कॉल करना होगा. साथ ही, FillResponse ऑब्जेक्ट में EXTRA_AUTHENTICATION_RESULT एक्सट्रा सेट करना होगा. इसमें, पॉप्युलेट किया गया डेटासेट शामिल होता है. यहां दिया गया कोड एक उदाहरण में बताया गया है कि पुष्टि की प्रोसेस पूरी होने के बाद, नतीजे कैसे दिखाए जाते हैं:

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);

ऐसी स्थिति में जहां क्रेडिट कार्ड के डेटासेट को अनलॉक करने की ज़रूरत होती है, सेवा सीवीसी मांगने वाला यूज़र इंटरफ़ेस (यूआई) दिखा सकती है. डेटासेट को अनलॉक किए जाने तक, डेटा को छिपाया जा सकता है. इसके लिए, बॉयलरप्लेट डेटा की जानकारी देनी होगी, जैसे कि बैंक का नाम और क्रेडिट कार्ड नंबर के आखिरी चार अंक. यहां दिए गए उदाहरण में, किसी डेटासेट के लिए पुष्टि करने की ज़रूरत बताने और उपयोगकर्ता के सीवीसी डालने तक डेटा छिपाने का तरीका बताया गया है:

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();

गतिविधि के सीवीसी की पुष्टि करने के बाद, उसे setResult() तरीके को कॉल करना चाहिए. इसके लिए, RESULT_OK वैल्यू को पास करना चाहिए और EXTRA_AUTHENTICATION_RESULT एक्सट्रा को Dataset ऑब्जेक्ट में सेट करना चाहिए. इस ऑब्जेक्ट में क्रेडिट कार्ड नंबर और खत्म होने की तारीख होती है. नया डेटासेट, पुष्टि की ज़रूरत वाले डेटासेट की जगह ले लेता है. साथ ही, व्यू तुरंत भर जाते हैं. नीचे दिया गया कोड, उपयोगकर्ता के सीवीसी डालने के बाद डेटासेट को दिखाने का उदाहरण दिखाता है:

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);

डेटा को लॉजिकल ग्रुप में व्यवस्थित करना

अपने-आप जानकारी भरने की सेवाओं को डेटा को ऐसे लॉजिकल ग्रुप में व्यवस्थित करना चाहिए जो अलग-अलग डोमेन के कॉन्सेप्ट को अलग रखते हों. इस पेज पर, इन लॉजिकल ग्रुप को पार्टिशन कहा जाता है. यहां दी गई सूची में, सेगमेंट और फ़ील्ड के सामान्य उदाहरण दिए गए हैं:

  • क्रेडेंशियल, जिनमें उपयोगकर्ता नाम और पासवर्ड वाले फ़ील्ड शामिल हों.
  • पता, जिसमें सड़क, शहर, राज्य, और पिन कोड के फ़ील्ड शामिल हैं.
  • पेमेंट की जानकारी, जिसमें क्रेडिट कार्ड नंबर, कार्ड की समयसीमा खत्म होने की तारीख, और पुष्टि करने के लिए कोड वाले फ़ील्ड शामिल हैं.

डेटा को सही तरीके से बांटने वाली ऑटोमैटिक भरने की सेवा, डेटासेट में एक से ज़्यादा सेक्शन का डेटा ज़ाहिर किए बिना, अपने उपयोगकर्ताओं के डेटा को बेहतर तरीके से सुरक्षित रख सकती है. उदाहरण के लिए, क्रेडेंशियल वाले डेटासेट में पेमेंट की जानकारी शामिल करने की ज़रूरत नहीं होती. डेटा को सेगमेंट में व्यवस्थित करने की सुविधा से, आपकी सेवा को अनुरोध पूरा करने के लिए, ज़रूरी कम से कम ज़रूरी जानकारी ज़ाहिर करने की अनुमति मिलती है.

डेटा को अलग-अलग सेक्शन में व्यवस्थित करने से, सेवाओं को उन गतिविधियों को भरने में मदद मिलती है जिनमें कई सेक्शन के व्यू शामिल होते हैं. साथ ही, क्लाइंट ऐप्लिकेशन को ज़रूरी डेटा की कम से कम जानकारी भेजी जाती है. उदाहरण के लिए, ऐसी गतिविधि जिसमें उपयोगकर्ता नाम, पासवर्ड, सड़क, और शहर के व्यू शामिल हों. साथ ही, ऑटोमैटिक भरने की सेवा में यह डेटा शामिल हो:

सेगमेंट फ़ील्ड 1 दूसरा फ़ील्ड
क्रेडेंशियल Work_उपयोगकर्ता नाम Work_password
निजी_उपयोगकर्ता नाम निजी पासवर्ड
पता काम करने की जगह work_city
personal_street personal_city

यह सेवा, ऐसा डेटासेट तैयार कर सकती है जिसमें काम और निजी, दोनों खातों के क्रेडेंशियल का सेगमेंट शामिल हो. जब उपयोगकर्ता कोई डेटासेट चुनता है, तो ऑटोमैटिक भरने की सुविधा के बाद, उपयोगकर्ता की पहली पसंद के आधार पर, ऑफ़िस या निजी पता दिया जा सकता है.

कोई सेवा, AssistStructure ऑब्जेक्ट को देखते हुए isFocused() तरीके का इस्तेमाल करके, अनुरोध करने वाले फ़ील्ड की पहचान कर सकती है. इससे सेवा, सही सेटअप किए गए partition के डेटा के साथ FillResponse तैयार कर सकती है.

एसएमएस के लिए एक बार इस्तेमाल होने वाला कोड ऑटोमैटिक भरने की सुविधा

ऑटोमैटिक भरने की आपकी सेवा, SMS Retriever API का इस्तेमाल करके, उपयोगकर्ता को एसएमएस के ज़रिए भेजे गए एक बार इस्तेमाल होने वाले कोड भरने में मदद कर सकती है.

इस सुविधा का इस्तेमाल करने के लिए, ये ज़रूरी शर्तें पूरी करनी होंगी:

  • ऑटोमैटिक भरने की सुविधा, Android 9 (एपीआई लेवल 28) या उसके बाद के वर्शन पर काम कर रही हो.
  • उपयोगकर्ता, ऑटोमैटिक भरने की सुविधा को मैसेज से मिले एक बार इस्तेमाल होने वाले कोड पढ़ने की अनुमति देता है.
  • आपने जिस ऐप्लिकेशन के लिए ऑटोमैटिक भरने की सुविधा चालू की है वह एक बार इस्तेमाल होने वाले कोड पढ़ने के लिए, पहले से ही SMS Retriever API का इस्तेमाल नहीं कर रहा है.

ऑटोमैटिक भरने की सुविधा, SmsCodeAutofillClient का इस्तेमाल कर सकती है. यह सुविधा, Google Play services के 19.0.56 या इसके बाद के वर्शन में SmsCodeRetriever.getAutofillClient() को कॉल करके उपलब्ध होती है.

जानकारी ऑटोमैटिक भरने की सुविधा में, इस एपीआई का इस्तेमाल करने के लिए मुख्य तरीके ये हैं:

  1. ऑटोमैटिक भरने की सुविधा में, SmsCodeAutofillClient से hasOngoingSmsRequest का इस्तेमाल करके यह पता लगाएं कि जिस ऐप्लिकेशन के पैकेज के नाम को ऑटोमैटिक भरने के लिए कहा जा रहा है उसके लिए कोई अनुरोध चालू है या नहीं. ऑटोमैटिक भरने की सुविधा देने वाली आपकी सेवा को सिर्फ़ तब सुझाव वाला प्रॉम्प्ट दिखाना चाहिए, जब यह false दिखाए.
  2. ऑटोमैटिक भरने की सुविधा में, SmsCodeAutofillClient से checkPermissionState का इस्तेमाल करके देखें कि ऑटोमैटिक भरने की सुविधा के पास, एक बार इस्तेमाल होने वाले कोड अपने-आप भरने की अनुमति है या नहीं. अनुमति की यह स्थिति NONE, GRANTED या DENIED हो सकती है. अपने-आप जानकारी भरने की सुविधा, NONE और GRANTED राज्यों के लिए सुझाव वाला प्रॉम्प्ट दिखाए.
  3. अपने-आप भरने की सुविधा से जुड़ी पुष्टि की गतिविधि में, SmsCodeRetriever.SMS_CODE_RETRIEVED_ACTION के लिए BroadcastReceiver सुनने की सुविधा को रजिस्टर करने के लिए SmsRetriever.SEND_PERMISSION अनुमति का इस्तेमाल करें, ताकि एसएमएस के लिए कोड उपलब्ध होने पर वह आपको मिल सके.
  4. एसएमएस से भेजे गए, एक बार इस्तेमाल किए जा सकने वाले कोड सुनने के लिए, SmsCodeAutofillClient पर startSmsCodeRetriever कॉल करें. अगर उपयोगकर्ता, ऑटोमैटिक भरने की आपकी सेवा को एसएमएस से एक बार इस्तेमाल होने वाले कोड पाने की अनुमति देता है, तो यह पिछले एक से पांच मिनट में मिले मैसेज (एसएमएस) को ढूंढता है.

    अगर आपकी ऑटोमैटिक भरने की सेवा को, एक बार इस्तेमाल होने वाले कोड पढ़ने के लिए उपयोगकर्ता की अनुमति का अनुरोध करना पड़ता है, तो हो सकता है कि startSmsCodeRetriever से मिला Task, ResolvableApiException के तौर पर दिखे. अगर ऐसा होता है, तो आपको अनुमति के अनुरोध के लिए सहमति वाला डायलॉग बॉक्स दिखाने के लिए, ResolvableApiException.startResolutionForResult() तरीके को कॉल करना होगा.

  5. इंटेंट से एसएमएस कोड का नतीजा पाएं और फिर एसएमएस कोड को ऑटोमैटिक भरने की सुविधा के तौर पर दिखाएं.

ऑटोमैटिक भरने की बेहतर स्थितियां

कीबोर्ड के साथ इंटिग्रेट करना
Android 11 से, प्लैटफ़ॉर्म पर कीबोर्ड और अन्य इनपुट-मेथड एडिटर (आईएमई) को, अपने-आप भरने की सुविधा के सुझावों को इनलाइन दिखाने की अनुमति मिलती है. इसके लिए, उन्हें अब पुलबडाउन मेन्यू का इस्तेमाल नहीं करना पड़ता. जानकारी अपने-आप भरने की सेवा, इस सुविधा के साथ कैसे काम कर सकती है, इस बारे में ज़्यादा जानने के लिए, कीबोर्ड के साथ जानकारी अपने-आप भरने की सुविधा को इंटिग्रेट करना लेख पढ़ें.
डेटासेट को पेज पर दिखाना
ऑटोमैटिक भरने की सुविधा से मिलने वाला बड़ा रिस्पॉन्स, Binder ऑब्जेक्ट के लिए तय किए गए ट्रांज़ैक्शन साइज़ से ज़्यादा हो सकता है. यह ऑब्जेक्ट, अनुरोध को प्रोसेस करने के लिए ज़रूरी, रिमोट किए जा सकने वाले ऑब्जेक्ट को दिखाता है. इन स्थितियों में Android सिस्टम को अपवाद न छोड़ने के लिए, FillResponse को छोटा रखें. इसके लिए, एक बार में 20 से ज़्यादा Dataset ऑब्जेक्ट न जोड़ें. अगर आपके जवाब के लिए ज़्यादा डेटासेट की ज़रूरत है, तो ऐसा डेटासेट जोड़ा जा सकता है जिससे उपयोगकर्ताओं को पता चल सके कि ज़्यादा जानकारी उपलब्ध है. साथ ही, चुने जाने पर, डेटासेट का अगला ग्रुप भी वापस लाता है. ज़्यादा जानकारी के लिए, addDataset(Dataset) देखें.
डेटा को कई स्क्रीन में बांटकर सेव करना

ऐप्लिकेशन अक्सर एक ही गतिविधि में, उपयोगकर्ता के डेटा को कई स्क्रीन में बांटते हैं. ऐसा खास तौर पर, नई उपयोगकर्ता खाता बनाने के लिए इस्तेमाल की जाने वाली गतिविधियों में किया जाता है. उदाहरण के लिए, पहली स्क्रीन पर उपयोगकर्ता नाम मांगा जाता है. अगर उपयोगकर्ता नाम उपलब्ध होता है, तो दूसरी स्क्रीन पर पासवर्ड मांगा जाता है. ऐसे मामलों में, ऑटोमैटिक भरने की सुविधा को तब तक इंतज़ार करना होगा, जब तक उपयोगकर्ता दोनों फ़ील्ड में जानकारी नहीं डाल देता. इसके बाद ही, ऑटोमैटिक भरने की सुविधा सेव करने के लिए यूज़र इंटरफ़ेस (यूआई) दिखाया जा सकता है. ऐसे मामलों को हैंडल करने के लिए यह तरीका अपनाएं:

  1. पहले फ़िल करने के अनुरोध में, रिस्पॉन्स में क्लाइंट स्टेटस बंडल जोड़ें. इसमें स्क्रीन पर मौजूद कुछ फ़ील्ड के ऑटोमैटिक भरने वाले आईडी शामिल होते हैं.
  2. जानकारी भरने के दूसरे अनुरोध में, क्लाइंट स्टेट बंडल को वापस पाएं. इसके बाद, क्लाइंट स्टेटस से पिछले अनुरोध में सेट किए गए ऑटोमैटिक भरने वाले आईडी पाएं. इसके बाद, इन आईडी के साथ-साथ FLAG_SAVE_ON_ALL_VIEWS_INVISIBLE फ़्लैग को दूसरे रिस्पॉन्स में इस्तेमाल किए गए SaveInfo ऑब्जेक्ट से जोड़ें.
  3. सेव करने का अनुरोध में, हर फ़ील्ड की वैल्यू पाने के लिए, सही FillContext ऑब्जेक्ट का इस्तेमाल करें. हर फ़िल अनुरोध के लिए एक फ़िल कॉन्टेक्स्ट होता है.

ज़्यादा जानकारी के लिए, डेटा को कई स्क्रीन में बांटने पर सेव करना लेख पढ़ें.

हर अनुरोध के लिए, शुरू करने और बंद करने का लॉजिक दें

ऑटोमैटिक भरने का अनुरोध मिलने पर, Android सिस्टम इस सेवा से जुड़ जाता है और इसके onConnected() तरीके को कॉल करता है. अनुरोध को प्रोसेस करने के बाद Android सिस्टम, onDisconnected() तरीके को कॉल करता है और सेवा से जुड़े डेटा को हटा देता है. अनुरोध को प्रोसेस करने से पहले चलने वाला कोड देने के लिए, onConnected() को लागू किया जा सकता है. साथ ही, अनुरोध को प्रोसेस करने के बाद चलने वाला कोड देने के लिए, onDisconnected() को लागू किया जा सकता है.

ऑटोमैटिक भरने की सुविधा सेव करने के यूज़र इंटरफ़ेस को पसंद के मुताबिक बनाना

ऑटोमैटिक भरने की सुविधा देने वाली सेवाएं, ऑटोमैटिक भरने की सुविधा सेव करने के यूज़र इंटरफ़ेस (यूआई) को पसंद के मुताबिक बना सकती हैं. इससे उपयोगकर्ता यह तय कर पाते हैं कि उन्हें सेवा को अपना डेटा सेव करने की अनुमति देनी है या नहीं. सेवाएं, सेव किए गए डेटा के बारे में अतिरिक्त जानकारी दे सकती हैं. यह जानकारी, सामान्य टेक्स्ट या पसंद के मुताबिक बनाए गए व्यू के ज़रिए दी जा सकती है. सेवाएं, सेव करने के अनुरोध को रद्द करने वाले बटन का रंग भी बदल सकती हैं. साथ ही, जब उपयोगकर्ता उस बटन पर टैप करता है, तो उन्हें सूचना भी मिल सकती है. ज़्यादा जानकारी के लिए, SaveInfo रेफ़रंस पेज देखें.

कंपैटिबिलिटी मोड

कम्पैटबिलिटी मोड की मदद से, ऑटोमैटिक भरने की सेवाएं, ऑटोमैटिक भरने के लिए सुलभता के वर्चुअल स्ट्रक्चर का इस्तेमाल कर सकती हैं. यह खास तौर पर, उन ब्राउज़र में ऑटोमैटिक भरने की सुविधा देने के लिए मददगार है जो साफ़ तौर पर, ऑटोमैटिक भरने वाले एपीआई को लागू नहीं करते.

साथ काम करने वाले मोड का इस्तेमाल करके, ऑटोमैटिक भरने की सेवा की जांच करने के लिए, उस ब्राउज़र या ऐप्लिकेशन को साफ़ तौर पर अनुमति दें जिसके लिए साथ काम करने वाले मोड की ज़रूरत है. यह पता लगाया जा सकता है कि कौनसे पैकेज पहले से अनुमति वाली सूची में शामिल हैं. इसके लिए, यह कमांड चलाएं:

$ adb shell settings get global autofill_compat_mode_allowed_packages

अगर जिस पैकेज की जांच की जा रही है वह सूची में शामिल नहीं है, तो उसे जोड़ने के लिए यह निर्देश चलाएं. यहां pkgX, ऐप्लिकेशन का पैकेज है:

$ adb shell settings put global autofill_compat_mode_allowed_packages pkg1[resId1]:pkg2[resId1,resId2]

अगर ऐप्लिकेशन एक ब्राउज़र है, तो उस इनपुट फ़ील्ड का संसाधन आईडी बताने के लिए resIdx का इस्तेमाल करें जिसमें रेंडर किए गए पेज का यूआरएल हो.

कम्पैटिबिलिटी मोड की सीमाएं नीचे दी गई हैं:

  • सेव करने का अनुरोध तब ट्रिगर होता है, जब सेवा FLAG_SAVE_ON_ALL_VIEWS_INVISIBLE फ़्लैग का इस्तेमाल करती है या setTrigger() तरीका इस्तेमाल किया जाता है. कंपैटिबिलिटी मोड का इस्तेमाल करने पर, FLAG_SAVE_ON_ALL_VIEWS_INVISIBLE डिफ़ॉल्ट रूप से सेट होता है.
  • हो सकता है कि नोड की टेक्स्ट वैल्यू, onSaveRequest(SaveRequest, SaveCallback) वाले तरीके में उपलब्ध न हो.

साथ ही, इस मोड से जुड़ी सीमाओं के बारे में ज़्यादा जानने के लिए, AutofillService क्लास रेफ़रंस देखें.