একটি অটোফিল পরিষেবা হল এমন একটি অ্যাপ যা ব্যবহারকারীদের জন্য অন্যান্য অ্যাপের ভিউতে ডেটা ইনজেকশনের মাধ্যমে ফর্ম পূরণ করা সহজ করে তোলে। অটোফিল পরিষেবাগুলি একটি অ্যাপের ভিউ থেকে ব্যবহারকারীর ডেটা পুনরুদ্ধার করতে পারে এবং পরবর্তী সময়ে ব্যবহারের জন্য এটি সংরক্ষণ করতে পারে। অটোফিল পরিষেবাগুলি সাধারণত ব্যবহারকারীর ডেটা পরিচালনা করে এমন অ্যাপ দ্বারা সরবরাহ করা হয়, যেমন পাসওয়ার্ড পরিচালক৷
Android 8.0 (API স্তর 26) এবং উচ্চতর সংস্করণে উপলব্ধ অটোফিল ফ্রেমওয়ার্ক সহ Android ফর্মগুলি পূরণ করা সহজ করে তোলে৷ ব্যবহারকারীরা কেবলমাত্র অটোফিল বৈশিষ্ট্যের সুবিধা নিতে পারেন যদি তাদের ডিভাইসে অটোফিল পরিষেবা সরবরাহ করে এমন কোনও অ্যাপ থাকে।
এই পৃষ্ঠাটি দেখায় কিভাবে আপনার অ্যাপে একটি অটোফিল পরিষেবা বাস্তবায়ন করতে হয়। আপনি যদি একটি কোড নমুনা খুঁজছেন যা দেখায় যে কীভাবে একটি পরিষেবা বাস্তবায়ন করতে হয়, তাহলে 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 অ্যাট্রিবিউট রয়েছে যা পরিষেবা সম্পর্কে আরও বিশদ বিবরণ সহ একটি XML সংস্থানের দিকে নির্দেশ করে। পূর্ববর্তী উদাহরণে service_configuration সংস্থানটি এমন একটি কার্যকলাপ নির্দিষ্ট করে যা ব্যবহারকারীদের পরিষেবাটি কনফিগার করতে দেয়। নিম্নলিখিত উদাহরণটি service_configuration XML সংস্থান দেখায়:
<autofill-service
xmlns:android="http://schemas.android.com/apk/res/android"
android:settingsActivity="com.example.android.SettingsActivity" />
XML সংস্থান সম্পর্কে আরও তথ্যের জন্য, অ্যাপ সংস্থান ওভারভিউ দেখুন।
পরিষেবাটি সক্ষম করার জন্য অনুরোধ করুন
BIND_AUTOFILL_SERVICE অনুমতি ঘোষণা করার পরে এবং ব্যবহারকারী ডিভাইস সেটিংসে এটি সক্ষম করার পরে একটি অ্যাপ স্বয়ংক্রিয়ভাবে পূরণ পরিষেবা হিসাবে ব্যবহৃত হয়৷ একটি অ্যাপ AutofillManager ক্লাসের hasEnabledAutofillServices() পদ্ধতিতে কল করে এটি বর্তমানে সক্ষম পরিষেবা কিনা তা যাচাই করতে পারে।
যদি অ্যাপটি বর্তমান অটোফিল পরিষেবা না হয়, তাহলে এটি ব্যবহারকারীকে ACTION_REQUEST_SET_AUTOFILL_SERVICE উদ্দেশ্য ব্যবহার করে অটোফিল সেটিংস পরিবর্তন করার জন্য অনুরোধ করতে পারে। অভিপ্রায় RESULT_OK এর একটি মান প্রদান করে যদি ব্যবহারকারী একটি স্বতঃপূর্ণ পরিষেবা নির্বাচন করে যা কলারের প্যাকেজের সাথে মেলে৷
ক্লায়েন্ট মতামত পূরণ করুন
ব্যবহারকারী যখন অন্যান্য অ্যাপের সাথে ইন্টারঅ্যাক্ট করে তখন অটোফিল সার্ভিসটি ক্লায়েন্টের ভিউ পূরণ করার অনুরোধ পায়। যদি স্বয়ংক্রিয়ভাবে পূরণ পরিষেবাতে ব্যবহারকারীর ডেটা থাকে যা অনুরোধটি সন্তুষ্ট করে, তবে এটি প্রতিক্রিয়াতে ডেটা পাঠায়। অ্যান্ড্রয়েড সিস্টেম উপলব্ধ ডেটা সহ একটি অটোফিল UI দেখায়, যেমন চিত্র 1 এ দেখানো হয়েছে:

চিত্র 1. অটোফিল UI একটি ডেটাসেট প্রদর্শন করছে।
অটোফিল ফ্রেমওয়ার্ক ভিউ পূরণ করার জন্য একটি ওয়ার্কফ্লোকে সংজ্ঞায়িত করে যা Android সিস্টেমের অটোফিল পরিষেবার সাথে আবদ্ধ হওয়ার সময় কমানোর জন্য ডিজাইন করা হয়েছে। প্রতিটি অনুরোধে, অ্যান্ড্রয়েড সিস্টেম onFillRequest() পদ্ধতিতে কল করে পরিষেবাটিতে একটি AssistStructure অবজেক্ট পাঠায়।
অটোফিল পরিষেবা পরীক্ষা করে যে এটি পূর্বে সংরক্ষিত ব্যবহারকারীর ডেটা দিয়ে অনুরোধটি পূরণ করতে পারে কিনা। যদি এটি অনুরোধটি সন্তুষ্ট করতে পারে, তবে পরিষেবাটি Dataset অবজেক্টে ডেটা প্যাকেজ করে। পরিষেবাটি onSuccess() পদ্ধতিকে কল করে, একটি FillResponse অবজেক্ট পাস করে যাতে Dataset অবজেক্ট রয়েছে। পরিষেবাটিতে অনুরোধটি পূরণ করার জন্য ডেটা না থাকলে, এটি onSuccess() পদ্ধতিতে null হয়ে যায়।
অনুরোধ প্রক্রিয়াকরণে কোনো ত্রুটি থাকলে পরিষেবাটি পরিবর্তে onFailure() পদ্ধতিতে কল করে। কর্মপ্রবাহের বিস্তারিত ব্যাখ্যার জন্য, AutofillService রেফারেন্স পৃষ্ঠায় বিবরণ দেখুন।
নিম্নলিখিত কোডটি onFillRequest() পদ্ধতির একটি উদাহরণ দেখায়:
কোটলিন
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)
জাভা
@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; }
একটি পরিষেবাতে একাধিক ডেটাসেট থাকতে পারে যা অনুরোধটি পূরণ করে। এই ক্ষেত্রে, অ্যানড্রয়েড সিস্টেম স্বতঃফিল UI-তে একাধিক বিকল্প দেখায়—প্রতিটি ডেটাসেটের জন্য একটি। নিম্নলিখিত কোড উদাহরণ দেখায় কিভাবে একটি প্রতিক্রিয়া একাধিক ডেটাসেট প্রদান করতে হয়:
কোটলিন
// 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()
জাভা
// 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 অবজেক্ট থেকে অটোফিল ডেটা পুনরুদ্ধার করতে হয়:
কোটলিন
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) } }
জাভা
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); } }
ব্যবহারকারীর ডেটা সংরক্ষণ করুন
একটি অটোফিল পরিষেবার অ্যাপে ভিউ পূরণ করতে ব্যবহারকারীর ডেটা প্রয়োজন। যখন ব্যবহারকারীরা ম্যানুয়ালি একটি ভিউ পূরণ করেন, তখন তাদেরকে বর্তমান অটোফিল পরিষেবাতে ডেটা সংরক্ষণ করতে বলা হয়, যেমন চিত্র 2-এ দেখানো হয়েছে।

চিত্র 2. অটোফিল সেভ UI।
ডেটা সংরক্ষণ করতে, পরিষেবাটিকে অবশ্যই নির্দেশ করতে হবে যে এটি ভবিষ্যতে ব্যবহারের জন্য ডেটা সংরক্ষণ করতে আগ্রহী। অ্যান্ড্রয়েড সিস্টেম ডেটা সংরক্ষণের জন্য একটি অনুরোধ পাঠানোর আগে, একটি পূরণের অনুরোধ রয়েছে যেখানে পরিষেবাটি দর্শনগুলি পূরণ করার সুযোগ রয়েছে। এটি ডেটা সংরক্ষণ করতে আগ্রহী তা নির্দেশ করার জন্য, পরিষেবাটি পূরণের অনুরোধের প্রতিক্রিয়াতে একটি SaveInfo অবজেক্ট অন্তর্ভুক্ত করে। SaveInfo অবজেক্টে কমপক্ষে নিম্নলিখিত ডেটা রয়েছে:
- ব্যবহারকারীর ডেটার ধরন যা সংরক্ষণ করা হয়। উপলব্ধ
SAVE_DATAমানগুলির একটি তালিকার জন্য,SaveInfoদেখুন। - একটি সংরক্ষণের অনুরোধ ট্রিগার করতে ন্যূনতম ভিউগুলির সেট যা পরিবর্তন করতে হবে৷ উদাহরণস্বরূপ, একটি লগইন ফর্মের জন্য সাধারণত ব্যবহারকারীকে একটি সংরক্ষণের অনুরোধ ট্রিগার করতে
usernameএবংpasswordভিউ আপডেট করতে হয়।
একটি SaveInfo অবজেক্ট একটি FillResponse অবজেক্টের সাথে যুক্ত, যেমনটি নিম্নলিখিত কোড উদাহরণে দেখানো হয়েছে:
কোটলিন
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() ... }
জাভা
@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() পদ্ধতির একটি উদাহরণ দেখায়:
কোটলিন
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() }
জাভা
@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(); }
অটোফিল পরিষেবাগুলিকে সংবেদনশীল ডেটা টিকে থাকার আগে এনক্রিপ্ট করতে হবে৷ যাইহোক, ব্যবহারকারীর ডেটাতে লেবেল বা ডেটা অন্তর্ভুক্ত থাকতে পারে যা সংবেদনশীল নয়। উদাহরণস্বরূপ, একটি ব্যবহারকারীর অ্যাকাউন্টে একটি লেবেল অন্তর্ভুক্ত থাকতে পারে যা ডেটাকে কাজ বা ব্যক্তিগত অ্যাকাউন্ট হিসাবে চিহ্নিত করে৷ পরিষেবাগুলি অবশ্যই লেবেলগুলি এনক্রিপ্ট করবে না৷ লেবেলগুলি এনক্রিপ্ট না করে, ব্যবহারকারী প্রমাণীকরণ না করলে পরিষেবাগুলি উপস্থাপনা দৃশ্যগুলিতে লেবেলগুলি ব্যবহার করতে পারে৷ তারপর, পরিষেবাগুলি ব্যবহারকারীর প্রমাণীকরণের পরে প্রকৃত ডেটার সাথে লেবেলগুলি প্রতিস্থাপন করতে পারে৷
অটোফিল সেভ UI স্থগিত করুন
Android 10 দিয়ে শুরু করে, আপনি যদি একটি স্বতঃপূর্ণ কর্মপ্রবাহ বাস্তবায়ন করতে একাধিক স্ক্রীন ব্যবহার করেন—উদাহরণস্বরূপ, ব্যবহারকারীর নাম ক্ষেত্রের জন্য একটি স্ক্রীন এবং পাসওয়ার্ডের জন্য আরেকটি—আপনি SaveInfo.FLAG_DELAY_SAVE ফ্ল্যাগ ব্যবহার করে অটোফিল সেভ UI স্থগিত করতে পারেন।
এই পতাকা সেট করা থাকলে, SaveInfo প্রতিক্রিয়ার সাথে যুক্ত অটোফিল প্রসঙ্গে প্রতিশ্রুতিবদ্ধ হলে অটোফিল সেভ UI ট্রিগার হয় না। পরিবর্তে, আপনি ভবিষ্যত পূরণের অনুরোধগুলি সরবরাহ করতে একই কাজের মধ্যে একটি পৃথক কার্যকলাপ ব্যবহার করতে পারেন এবং তারপরে একটি সংরক্ষণ অনুরোধের মাধ্যমে UI দেখাতে পারেন। আরও তথ্যের জন্য, SaveInfo.FLAG_DELAY_SAVE দেখুন।
ব্যবহারকারী প্রমাণীকরণ প্রয়োজন
অটোফিল পরিষেবাগুলি ভিউ পূরণ করার আগে ব্যবহারকারীকে প্রমাণীকরণের প্রয়োজন করে একটি অতিরিক্ত স্তরের নিরাপত্তা প্রদান করতে পারে। নিম্নলিখিত পরিস্থিতিগুলি ব্যবহারকারীর প্রমাণীকরণ বাস্তবায়নের জন্য ভাল প্রার্থী:
- অ্যাপের ব্যবহারকারীর ডেটা প্রাথমিক পাসওয়ার্ড বা ফিঙ্গারপ্রিন্ট স্ক্যান ব্যবহার করে আনলক করতে হবে।
- একটি নির্দিষ্ট ডেটাসেট আনলক করা প্রয়োজন, যেমন একটি কার্ড যাচাইকরণ কোড (CVC) ব্যবহার করে ক্রেডিট কার্ডের বিবরণ।
এমন একটি পরিস্থিতিতে যেখানে ডেটা আনলক করার আগে পরিষেবাটির ব্যবহারকারীর প্রমাণীকরণের প্রয়োজন হয়, পরিষেবাটি বয়লারপ্লেট ডেটা বা একটি লেবেল উপস্থাপন করতে পারে এবং প্রমাণীকরণের যত্ন নেয় এমন Intent নির্দিষ্ট করতে পারে। প্রমাণীকরণ প্রবাহ সম্পন্ন হওয়ার পরে অনুরোধটি প্রক্রিয়া করার জন্য আপনার যদি অতিরিক্ত ডেটার প্রয়োজন হয়, তাহলে আপনি অভিপ্রায়ে এই ধরনের ডেটা যোগ করতে পারেন। আপনার প্রমাণীকরণ কার্যকলাপ তারপর আপনার অ্যাপের AutofillService ক্লাসে ডেটা ফেরত দিতে পারে।
নিম্নলিখিত কোড উদাহরণ দেখায় যে অনুরোধের প্রমাণীকরণ প্রয়োজন তা নির্দিষ্ট করতে কিভাবে:
কোটলিন
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()
জাভা
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();
একবার অ্যাক্টিভিটি প্রমাণীকরণ ফ্লো সম্পূর্ণ করে, এটিকে অবশ্যই setResult() পদ্ধতিতে কল করতে হবে, একটি RESULT_OK মান পাস করে, এবং EXTRA_AUTHENTICATION_RESULT FillResponse অবজেক্টে অতিরিক্ত সেট করতে হবে যাতে জনবহুল ডেটাসেট অন্তর্ভুক্ত থাকে। নিম্নলিখিত কোডটি প্রমাণীকরণ প্রবাহ সম্পূর্ণ হওয়ার পরে কীভাবে ফলাফল ফেরত দিতে হয় তার একটি উদাহরণ দেখায়:
কোটলিন
// 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)
জাভা
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);
এমন পরিস্থিতিতে যেখানে একটি ক্রেডিট কার্ড ডেটাসেট আনলক করা প্রয়োজন, পরিষেবাটি CVC-এর জন্য জিজ্ঞাসা করা একটি UI প্রদর্শন করতে পারে। বয়লারপ্লেট ডেটা, যেমন ব্যাঙ্কের নাম এবং ক্রেডিট কার্ড নম্বরের শেষ চারটি সংখ্যা উপস্থাপন করে ডেটাসেট আনলক না হওয়া পর্যন্ত আপনি ডেটা লুকিয়ে রাখতে পারেন৷ নিম্নলিখিত উদাহরণটি দেখায় কিভাবে একটি ডেটাসেটের জন্য প্রমাণীকরণের প্রয়োজন হয় এবং ব্যবহারকারী CVC প্রদান না করা পর্যন্ত ডেটা লুকিয়ে রাখে:
কোটলিন
// 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()
জাভা
// 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();
একবার ক্রিয়াকলাপটি CVC-কে যাচাই করে, এটি setResult() পদ্ধতিতে কল করে, একটি RESULT_OK মান পাস করে এবং EXTRA_AUTHENTICATION_RESULT অতিরিক্ত একটি Dataset অবজেক্টে সেট করে যাতে ক্রেডিট কার্ড নম্বর এবং মেয়াদ শেষ হওয়ার তারিখ রয়েছে৷ নতুন ডেটাসেট সেই ডেটাসেটটিকে প্রতিস্থাপন করে যার জন্য প্রমাণীকরণের প্রয়োজন হয় এবং ভিউগুলি অবিলম্বে পূরণ করা হয়। ব্যবহারকারী একবার CVC প্রদান করলে কীভাবে ডেটাসেট ফেরত দিতে হয় তার একটি উদাহরণ নিম্নলিখিত কোডটি দেখায়:
কোটলিন
// 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) }
জাভা
// 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 | ক্ষেত্র 2 |
|---|---|---|
| শংসাপত্র | কাজের_ব্যবহারকারীর নাম | কাজের_পাসওয়ার্ড |
| ব্যক্তিগত_ব্যবহারকারীর নাম | ব্যক্তিগত_পাসওয়ার্ড | |
| ঠিকানা | কাজের_রাস্তা | কাজের_শহর |
| ব্যক্তিগত_রাস্তা | ব্যক্তিগত_শহর |
পরিষেবাটি একটি ডেটাসেট প্রস্তুত করতে পারে যাতে কাজ এবং ব্যক্তিগত অ্যাকাউন্ট উভয়ের জন্য শংসাপত্র বিভাজন অন্তর্ভুক্ত থাকে। যখন ব্যবহারকারী একটি ডেটাসেট বেছে নেয়, তখন ব্যবহারকারীর প্রথম পছন্দের উপর নির্ভর করে একটি পরবর্তী স্বতঃপূর্ণ প্রতিক্রিয়া কাজ বা ব্যক্তিগত ঠিকানা প্রদান করতে পারে।
AssistStructure অবজেক্টটি অতিক্রম করার সময় একটি পরিষেবা isFocused() পদ্ধতিতে কল করে অনুরোধটি উদ্ভূত ক্ষেত্রটিকে সনাক্ত করতে পারে। এটি পরিষেবাটিকে উপযুক্ত পার্টিশন ডেটা সহ একটি FillResponse প্রস্তুত করার অনুমতি দেয়।
এসএমএস ওয়ান-টাইম কোড অটোফিল
আপনার অটোফিল পরিষেবা SMS রিট্রিভার API ব্যবহার করে SMS এর মাধ্যমে পাঠানো এক-কালীন কোডগুলি পূরণ করতে ব্যবহারকারীকে সহায়তা করতে পারে৷
এই বৈশিষ্ট্যটি ব্যবহার করতে, নিম্নলিখিত প্রয়োজনীয়তা পূরণ করতে হবে:
- অটোফিল পরিষেবাটি Android 9 (API স্তর 28) বা উচ্চতর সংস্করণে চলছে৷
- এসএমএস থেকে এক-কালীন কোড পড়ার জন্য ব্যবহারকারী আপনার স্বতঃপূর্ণ পরিষেবার জন্য সম্মতি দেয়।
- আপনি যে অ্যাপ্লিকেশনটির জন্য অটোফিল প্রদান করছেন সেটি ইতিমধ্যেই এককালীন কোড পড়ার জন্য SMS Retriever API ব্যবহার করছে না।
আপনার অটোফিল পরিষেবা SmsCodeAutofillClient ব্যবহার করতে পারে, Google Play পরিষেবা 19.0.56 বা উচ্চতর থেকে SmsCodeRetriever.getAutofillClient() এ কল করে উপলব্ধ৷
একটি অটোফিল পরিষেবাতে এই API ব্যবহার করার প্রাথমিক পদক্ষেপগুলি হল:
- অটোফিল পরিষেবাতে, আপনি যে অ্যাপ্লিকেশানটি স্বয়ংক্রিয়ভাবে পূরণ করছেন তার প্যাকেজ নামের জন্য কোনও অনুরোধ সক্রিয় আছে কিনা তা নির্ধারণ করতে
SmsCodeAutofillClientথেকেhasOngoingSmsRequestব্যবহার করুন৷ আপনার অটোফিল পরিষেবাটি অবশ্যই একটি পরামর্শ প্রম্পট প্রদর্শন করবে যদি এটিfalseফেরত দেয়। - অটোফিল সার্ভিসে, অটোফিল সার্ভিসের ওয়ান-টাইম কোড অটোফিল করার অনুমতি আছে কিনা তা পরীক্ষা করতে
SmsCodeAutofillClientথেকেcheckPermissionStateব্যবহার করুন। এই অনুমতির অবস্থাNONE,GRANTEDবাDENIEDযাবে না৷ অটোফিল পরিষেবা অবশ্যইNONEএবংGRANTEDরাজ্যগুলির জন্য একটি পরামর্শ প্রম্পট প্রদর্শন করবে৷ - স্বতঃপূর্ণ প্রমাণীকরণ কার্যকলাপে,
SmsRetriever.SEND_PERMISSIONব্যবহার করুন। SmsCodeRetriever-এর জন্য একটিBroadcastReceiverশোনার নিবন্ধন করার জন্যSmsCodeRetriever.SMS_CODE_RETRIEVED_ACTIONঅনুমতি ব্যবহার করুন। এসএমএস কোডের ফলাফল পাওয়া গেলে এটি পেতে SMS_CODE_RETRIEVED_ACTION। SMS-এর মাধ্যমে পাঠানো এককালীন কোড শোনা শুরু করতে
SmsCodeAutofillClientএstartSmsCodeRetrieverএ কল করুন। যদি ব্যবহারকারী আপনার অটোফিল পরিষেবার অনুমতি দেয় SMS থেকে এককালীন কোডগুলি পুনরুদ্ধার করার জন্য, তাহলে এটি এখন থেকে শেষ এক থেকে পাঁচ মিনিটের মধ্যে প্রাপ্ত SMS বার্তাগুলির সন্ধান করে৷যদি আপনার অটোফিল পরিষেবাকে এক-কালীন কোড পড়ার জন্য ব্যবহারকারীর অনুমতির অনুরোধ করতে হয়, তাহলে
startSmsCodeRetrieverদ্বারা প্রত্যাবর্তিতTaskএকটিResolvableApiExceptionফেরত দিয়ে ব্যর্থ হতে পারে। যদি এটি ঘটে, তাহলে অনুমতির অনুরোধের জন্য একটি সম্মতি ডায়ালগ প্রদর্শন করতে আপনাকেResolvableApiException.startResolutionForResult()পদ্ধতিতে কল করতে হবে।অভিপ্রায় থেকে এসএমএস কোড ফলাফল পান এবং তারপর একটি স্বতঃপূর্ণ প্রতিক্রিয়া হিসাবে এসএমএস কোড ফেরত দিন।
Chrome-এ অটোফিল সক্ষম করুন
ক্রোম তৃতীয় পক্ষের অটোফিল পরিষেবাগুলিকে স্বয়ংক্রিয়ভাবে ফর্মগুলিকে স্বতঃপূর্ণ করার অনুমতি দেয় যা ব্যবহারকারীদের একটি মসৃণ এবং সহজ ব্যবহারকারীর অভিজ্ঞতা দেয়৷ পাসওয়ার্ড, পাসকি এবং ঠিকানা এবং অর্থপ্রদানের ডেটার মতো অন্যান্য তথ্য স্বয়ংক্রিয়ভাবে পূরণ করতে তৃতীয় পক্ষের অটোফিল পরিষেবাগুলি ব্যবহার করতে, ব্যবহারকারীদের অবশ্যই Chrome সেটিংসে অন্য পরিষেবা ব্যবহার করে অটোফিল নির্বাচন করতে হবে৷

অ্যান্ড্রয়েডে আপনার পরিষেবা এবং ক্রোমের সাথে ব্যবহারকারীদের সর্বোত্তম অটোফিল অভিজ্ঞতা নিশ্চিত করতে, অটোফিল পরিষেবা প্রদানকারীদের উচিত তাদের ব্যবহারকারীদের Chrome সেটিংসে তাদের পছন্দের পরিষেবা প্রদানকারী নির্দিষ্ট করতে উত্সাহিত করা৷
ব্যবহারকারীদের টগল চালু করতে সাহায্য করতে, বিকাশকারীরা করতে পারেন:
- ক্রোম সেটিংস জিজ্ঞাসা করুন এবং ব্যবহারকারী তৃতীয় পক্ষের অটোফিল পরিষেবা ব্যবহার করতে চান কিনা তা জানুন।
- Chrome সেটিংস পৃষ্ঠার গভীর লিঙ্ক যেখানে ব্যবহারকারীরা তৃতীয় পক্ষের অটোফিল পরিষেবাগুলি সক্ষম করতে পারে৷
সামঞ্জস্য মোডের জন্য সর্বাধিক Chrome সংস্করণগুলি নির্দিষ্ট করুন৷
ক্রোম অ্যান্ড্রয়েড অটোফিলের পক্ষে 137 সংস্করণ থেকে সামঞ্জস্য মোড সমর্থন করা বন্ধ করে দিয়েছে। সামঞ্জস্য মোড রাখা স্থায়িত্ব সমস্যা হতে পারে. নিম্নরূপ স্থায়িত্বের জন্য সামঞ্জস্য মোড সমর্থন করে এমন Chrome প্যাকেজগুলির সর্বাধিক সংস্করণ নির্দিষ্ট করুন৷
<autofill-service>
...
<compatibility-package android:name="com.android.chrome" android:maxLongVersionCode="711900039" />
<compatibility-package android:name="com.chrome.beta" android:maxLongVersionCode="711900039" />
<compatibility-package android:name="com.chrome.dev" android:maxLongVersionCode="711900039" />
<compatibility-package android:name="com.chrome.canary" android:maxLongVersionCode="711900039" />
...
</autofill-service>
Chrome সেটিংস পড়ুন
Chrome 3P অটোফিল মোড ব্যবহার করে যা এটিকে Android অটোফিল ব্যবহার করতে দেয় কিনা তা যেকোনো অ্যাপ পড়তে পারে। Chrome সেই তথ্য যোগাযোগ করতে Android এর ContentProvider ব্যবহার করে। আপনি কোন চ্যানেল থেকে সেটিংস পড়তে চান তা আপনার Android ম্যানিফেস্টে ঘোষণা করুন:
<uses-permission android:name="android.permission.READ_USER_DICTIONARY"/>
<queries>
<!-- To Query Chrome Beta: -->
<package android:name="com.chrome.beta" />
<!-- To Query Chrome Stable: -->
<package android:name="com.android.chrome" />
</queries>
তারপর, কন্টেন্ট ইউআরআই তৈরি করে সেই তথ্যের অনুরোধ করতে Android এর ContentResolver ব্যবহার করুন:
কোটলিন
val CHROME_CHANNEL_PACKAGE = "com.android.chrome" // Chrome Stable. val CONTENT_PROVIDER_NAME = ".AutofillThirdPartyModeContentProvider" val THIRD_PARTY_MODE_COLUMN = "autofill_third_party_state" val THIRD_PARTY_MODE_ACTIONS_URI_PATH = "autofill_third_party_mode" val uri = Uri.Builder() .scheme(ContentResolver.SCHEME_CONTENT) .authority(CHROME_CHANNEL_PACKAGE + CONTENT_PROVIDER_NAME) .path(THIRD_PARTY_MODE_ACTIONS_URI_PATH) .build() val cursor = contentResolver.query( uri, arrayOf(THIRD_PARTY_MODE_COLUMN), // projection null, // selection null, // selectionArgs null // sortOrder ) if (cursor == null) { // Terminate now! Older versions of Chromium don't provide this information. } cursor?.use { // Use the safe call operator and the use function for auto-closing if (it.moveToFirst()) { // Check if the cursor has any rows val index = it.getColumnIndex(THIRD_PARTY_MODE_COLUMN) if (index != -1) { // Check if the column exists val value = it.getInt(index) if (0 == value) { // 0 means that the third party mode is turned off. Chrome uses its built-in // password manager. This is the default for new users. } else { // 1 means that the third party mode is turned on. Chrome uses forwards all // autofill requests to Android Autofill. Users have to opt-in for this. } } else { // Handle the case where the column doesn't exist. Log a warning, perhaps. Log.w("Autofill", "Column $THIRD_PARTY_MODE_COLUMN not found in cursor") } } } // The cursor is automatically closed here
জাভা
final String CHROME_CHANNEL_PACKAGE = "com.android.chrome"; // Chrome Stable. final String CONTENT_PROVIDER_NAME = ".AutofillThirdPartyModeContentProvider"; final String THIRD_PARTY_MODE_COLUMN = "autofill_third_party_state"; final String THIRD_PARTY_MODE_ACTIONS_URI_PATH = "autofill_third_party_mode"; final Uri uri = new Uri.Builder() .scheme(ContentResolver.SCHEME_CONTENT) .authority(CHROME_CHANNEL_PACKAGE + CONTENT_PROVIDER_NAME) .path(THIRD_PARTY_MODE_ACTIONS_URI_PATH) .build(); final Cursor cursor = getContentResolver().query( uri, /*projection=*/new String[] {THIRD_PARTY_MODE_COLUMN}, /*selection=*/ null, /*selectionArgs=*/ null, /*sortOrder=*/ null); if (cursor == null) { // Terminate now! Older versions of Chromium don't provide this information. } cursor.moveToFirst(); // Retrieve the result; int index = cursor.getColumnIndex(THIRD_PARTY_MODE_COLUMN); if (0 == cursor.getInt(index)) { // 0 means that the third party mode is turned off. Chrome uses its built-in // password manager. This is the default for new users. } else { // 1 means that the third party mode is turned on. Chrome uses forwards all // autofill requests to Android Autofill. Users have to opt-in for this. }
Chrome সেটিংসে গভীর লিঙ্ক
Chrome সেটিংস পৃষ্ঠাতে গভীর লিঙ্ক করতে যেখানে ব্যবহারকারীরা তৃতীয় পক্ষের অটোফিল পরিষেবাগুলি সক্ষম করতে পারে, একটি Android Intent ব্যবহার করুন৷ এই উদাহরণে দেখানো ক্রিয়া এবং বিভাগগুলি কনফিগার করতে ভুলবেন না:
কোটলিন
val autofillSettingsIntent = Intent(Intent.ACTION_APPLICATION_PREFERENCES) autofillSettingsIntent.addCategory(Intent.CATEGORY_DEFAULT) autofillSettingsIntent.addCategory(Intent.CATEGORY_APP_BROWSER) autofillSettingsIntent.addCategory(Intent.CATEGORY_PREFERENCE) // Invoking the intent with a chooser allows users to select the channel they // want to configure. If only one browser reacts to the intent, the chooser is // skipped. val chooser = Intent.createChooser(autofillSettingsIntent, "Pick Chrome Channel") startActivity(chooser) // If the caller knows which Chrome channel they want to configure, // they can instead add a package hint to the intent, e.g. val specificChromeIntent = Intent(Intent.ACTION_APPLICATION_PREFERENCES) // Create a *new* intent specificChromeIntent.addCategory(Intent.CATEGORY_DEFAULT) specificChromeIntent.addCategory(Intent.CATEGORY_APP_BROWSER) specificChromeIntent.addCategory(Intent.CATEGORY_PREFERENCE) specificChromeIntent.setPackage("com.android.chrome") // Set the package on the *new* intent startActivity(specificChromeIntent) // Start the *new* intent
জাভা
Intent autofillSettingsIntent = new Intent(Intent.ACTION_APPLICATION_PREFERENCES); autofillSettingsIntent.addCategory(Intent.CATEGORY_DEFAULT); autofillSettingsIntent.addCategory(Intent.CATEGORY_APP_BROWSER); autofillSettingsIntent.addCategory(Intent.CATEGORY_PREFERENCE); // Invoking the intent with a chooser allows users to select the channel they // want to configure. If only one browser reacts to the intent, the chooser is // skipped. Intent chooser = Intent.createChooser(autofillSettingsIntent, "Pick Chrome Channel"); startActivity(chooser); // If the caller knows which Chrome channel they want to configure, // they can instead add a package hint to the intent, e.g. autofillSettingsIntent.setPackage("com.android.chrome"); startActivity(autofillSettingsInstent);
উন্নত অটোফিল পরিস্থিতি
- কীবোর্ডের সাথে একীভূত করুন
- অ্যান্ড্রয়েড 11 দিয়ে শুরু করে, প্ল্যাটফর্মটি পুলডাউন মেনু ব্যবহার করার পরিবর্তে কীবোর্ড এবং অন্যান্য ইনপুট-ম্যাথড এডিটর ( IMEs ) কে অটোফিল সাজেশন ইনলাইনে প্রদর্শন করতে দেয়। আপনার অটোফিল পরিষেবা কীভাবে এই কার্যকারিতা সমর্থন করতে পারে সে সম্পর্কে আরও তথ্যের জন্য, কীবোর্ডগুলির সাথে অটোফিল একীভূত করুন দেখুন।
- পেজিনেট ডেটাসেট
- একটি বড় অটোফিল প্রতিক্রিয়া
Binderঅবজেক্টের অনুমোদিত লেনদেনের আকারকে অতিক্রম করতে পারে যা অনুরোধটি প্রক্রিয়া করার জন্য প্রয়োজনীয় রিমোটেবল অবজেক্টের প্রতিনিধিত্ব করে। অ্যান্ড্রয়েড সিস্টেমকে এই পরিস্থিতিতে একটি ব্যতিক্রম ছোঁড়া থেকে রোধ করতে, আপনি একবারে 20টির বেশিDatasetঅবজেক্ট যোগ করেFillResponseছোট রাখতে পারেন। যদি আপনার প্রতিক্রিয়ার জন্য আরও ডেটাসেটের প্রয়োজন হয়, আপনি একটি ডেটাসেট যোগ করতে পারেন যা ব্যবহারকারীদের জানতে দেয় যে আরও তথ্য রয়েছে এবং নির্বাচিত হলে পরবর্তী ডেটাসেটগুলি পুনরুদ্ধার করে৷ আরও তথ্যের জন্য,addDataset(Dataset)দেখুন। - একাধিক স্ক্রিনে ডেটা বিভক্ত সংরক্ষণ করুন
অ্যাপ্লিকেশানগুলি প্রায়শই একই কার্যকলাপে একাধিক স্ক্রিনে ব্যবহারকারীর ডেটা বিভক্ত করে, বিশেষ করে একটি নতুন ব্যবহারকারীর অ্যাকাউন্ট তৈরি করতে ব্যবহৃত কার্যকলাপগুলিতে। উদাহরণস্বরূপ, প্রথম স্ক্রীনটি একটি ব্যবহারকারীর নাম জিজ্ঞাসা করে, এবং যদি ব্যবহারকারীর নাম উপলব্ধ থাকে, একটি দ্বিতীয় স্ক্রীন একটি পাসওয়ার্ডের জন্য জিজ্ঞাসা করে। এই পরিস্থিতিতে, অটোফিল পরিষেবাটিকে অটোফিল সেভ UI দেখানোর আগে ব্যবহারকারী উভয় ক্ষেত্রে প্রবেশ না করা পর্যন্ত অপেক্ষা করতে হবে। এই ধরনের পরিস্থিতি পরিচালনা করতে এই পদক্ষেপগুলি অনুসরণ করুন:
- প্রথম পূরণের অনুরোধে , প্রতিক্রিয়াতে একটি ক্লায়েন্ট স্টেট বান্ডেল যোগ করুন যাতে স্ক্রিনে উপস্থিত আংশিক ক্ষেত্রগুলির স্বয়ংক্রিয়ভাবে পূরণ আইডি রয়েছে৷
- দ্বিতীয় ফিল রিকোয়েস্টে, ক্লায়েন্ট স্টেট বান্ডেল পুনরুদ্ধার করুন, ক্লায়েন্ট স্টেট থেকে আগের রিকোয়েস্টে সেট করা অটোফিল আইডি পান এবং এই আইডি এবং
FLAG_SAVE_ON_ALL_VIEWS_INVISIBLEপতাকাটিSaveInfoঅবজেক্টে যোগ করুন। - সংরক্ষণের অনুরোধে , প্রতিটি ক্ষেত্রের মান পেতে সঠিক
FillContextঅবজেক্ট ব্যবহার করুন। প্রতি ফিল রিকোয়েস্টে একটি ফিল কনটেক্সট আছে।
আরও তথ্যের জন্য, একাধিক স্ক্রিনে ডেটা বিভক্ত হলে সংরক্ষণ দেখুন।
- প্রতিটি অনুরোধের জন্য প্রাথমিককরণ এবং টিয়ারডাউন যুক্তি প্রদান করুন
প্রতিবার অটোফিলের অনুরোধ আসে, Android সিস্টেম পরিষেবার সাথে আবদ্ধ হয় এবং এর
onConnected()পদ্ধতিতে কল করে। পরিষেবাটি অনুরোধটি প্রক্রিয়া করার পরে, অ্যান্ড্রয়েড সিস্টেমonDisconnected()পদ্ধতিতে কল করে এবং পরিষেবা থেকে আনবাইন্ড করে। আপনি একটি অনুরোধ প্রক্রিয়া করার আগে চলে এমন কোড প্রদান করতেonConnected()এবং একটি অনুরোধ প্রক্রিয়াকরণের পরে চলে এমন কোড প্রদান করতেonDisconnected()প্রয়োগ করতে পারেন।- অটোফিল সেভ UI কাস্টমাইজ করুন
অটোফিল পরিষেবাগুলি অটোফিল সেভ UI কাস্টমাইজ করতে পারে যাতে ব্যবহারকারীরা পরিষেবাটিকে তাদের ডেটা সংরক্ষণ করতে দিতে চান কিনা তা নির্ধারণ করতে সহায়তা করে৷ পরিষেবাগুলি একটি সাধারণ পাঠ্যের মাধ্যমে বা একটি কাস্টমাইজড দৃশ্যের মাধ্যমে কী সংরক্ষণ করা হয় সে সম্পর্কে অতিরিক্ত তথ্য সরবরাহ করতে পারে। পরিষেবাগুলি সেই বোতামটির চেহারাও পরিবর্তন করতে পারে যা সংরক্ষণের অনুরোধ বাতিল করে এবং ব্যবহারকারী সেই বোতামটি আলতো চাপলে একটি বিজ্ঞপ্তি পেতে পারে৷ আরও তথ্যের জন্য,
SaveInfoরেফারেন্স পৃষ্ঠা দেখুন।- সামঞ্জস্য মোড
সামঞ্জস্য মোড অটোফিল পরিষেবাগুলিকে অটোফিল উদ্দেশ্যে অ্যাক্সেসিবিলিটি ভার্চুয়াল কাঠামো ব্যবহার করার অনুমতি দেয়। এটি এমন ব্রাউজারগুলিতে অটোফিল কার্যকারিতা প্রদানের জন্য বিশেষভাবে উপযোগী যেগুলি স্পষ্টভাবে স্বতঃপূরণ APIগুলি প্রয়োগ করে না৷
সামঞ্জস্য মোড ব্যবহার করে আপনার অটোফিল পরিষেবা পরীক্ষা করতে, সামঞ্জস্য মোড প্রয়োজন এমন ব্রাউজার বা অ্যাপকে স্পষ্টভাবে অনুমতি দিন। নিম্নলিখিত কমান্ডটি চালিয়ে আপনি কোন প্যাকেজগুলি ইতিমধ্যে অনুমোদিত তালিকাভুক্ত তা পরীক্ষা করতে পারেন:
$ 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]
অ্যাপটি যদি একটি ব্রাউজার হয়, তাহলে রেন্ডার করা পৃষ্ঠার URL ধারণ করে ইনপুট ক্ষেত্রের রিসোর্স আইডি নির্দিষ্ট করতে
resIdxব্যবহার করুন।
সামঞ্জস্য মোডের নিম্নলিখিত সীমাবদ্ধতা রয়েছে:
- যখন পরিষেবাটি
FLAG_SAVE_ON_ALL_VIEWS_INVISIBLEপতাকা ব্যবহার করে বাsetTrigger()পদ্ধতি কল করা হয় তখন একটি সংরক্ষণের অনুরোধ ট্রিগার হয়৷ সামঞ্জস্য মোড ব্যবহার করার সময়FLAG_SAVE_ON_ALL_VIEWS_INVISIBLEডিফল্টরূপে সেট করা হয়৷ - নোডের পাঠ্য মান
onSaveRequest(SaveRequest, SaveCallback)পদ্ধতিতে উপলব্ধ নাও হতে পারে।
সামঞ্জস্য মোড সম্পর্কে আরও তথ্যের জন্য, এর সাথে সম্পর্কিত সীমাবদ্ধতা সহ, AutofillService ক্লাস রেফারেন্স দেখুন।