পণ্যের খবর

যোগাযোগ বাছাইকারী: গোপনীয়তাকে অগ্রাধিকার দিয়ে যোগাযোগ শেয়ার করা

৪ মিনিটের পাঠ
Roxanna Aliabadi Walker
পণ্য ব্যবস্থাপক

গোপনীয়তা এবং ব্যবহারকারীর নিয়ন্ত্রণ অ্যান্ড্রয়েড অভিজ্ঞতার কেন্দ্রবিন্দুতে রয়েছে। ঠিক যেমন ফটো পিকার মিডিয়া শেয়ারিংকে নিরাপদ এবং বাস্তবায়নে সহজ করে তুলেছিল, আমরা এখন কন্টাক্ট নির্বাচনের ক্ষেত্রেও সেই একই স্তরের গোপনীয়তা, সরলতা এবং চমৎকার ব্যবহারকারীর অভিজ্ঞতা নিয়ে আসছি।

যোগাযোগের গোপনীয়তার জন্য একটি নতুন মানদণ্ড

ঐতিহাসিকভাবে, কোনো নির্দিষ্ট ব্যবহারকারীর কন্ট্যাক্ট অ্যাক্সেস করার জন্য অ্যাপ্লিকেশনগুলো ব্যাপক READ_CONTACTS পারমিশনের উপর নির্ভর করত। কার্যকরী হলেও, এই পদ্ধতিটি প্রায়শই অ্যাপগুলোকে প্রয়োজনের চেয়ে বেশি ডেটা দিয়ে দিত। অ্যান্ড্রয়েড ১৭-এ চালু হওয়া নতুন অ্যান্ড্রয়েড কন্ট্যাক্ট পিকার, কন্ট্যাক্ট নির্বাচনের জন্য একটি মানসম্মত, সুরক্ষিত এবং অনুসন্ধানযোগ্য ইন্টারফেস প্রদান করে এই ধারাটি পরিবর্তন করে।

এই ফিচারটি ব্যবহারকারীদেরকে শুধুমাত্র তাদের নির্বাচিত নির্দিষ্ট কন্ট্যাক্টগুলোতে অ্যাপগুলোকে অ্যাক্সেস দেওয়ার সুযোগ দেয়, যা ডেটা স্বচ্ছতা এবং পারমিশনের ব্যবহার সীমিত রাখার ব্যাপারে অ্যান্ড্রয়েডের অঙ্গীকারের সাথে সামঞ্জস্যপূর্ণ।

picker.png
নির্বাচন.png

এটি কীভাবে কাজ করে

ডেভেলপাররা Intent.ACTION_PICK_CONTACTS ইন্টেন্ট ব্যবহার করে কন্টাক্ট পিকারটি ইন্টিগ্রেট করতে পারেন। এই আপডেট করা API-টি বেশ কিছু শক্তিশালী সক্ষমতা প্রদান করে:

  • সুনির্দিষ্ট ডেটার অনুরোধ: অ্যাপগুলো সম্পূর্ণ কন্ট্যাক্ট রেকর্ড গ্রহণ না করে, তাদের ঠিক কোন কোন ফিল্ড প্রয়োজন, যেমন ফোন নম্বর বা ইমেল অ্যাড্রেস, তা নির্দিষ্ট করে দিতে পারে।
  • একাধিক নির্বাচন সমর্থন: পিকারটি একক এবং একাধিক উভয় প্রকার কন্ট্যাক্ট নির্বাচন সমর্থন করে, যা ডেভেলপারদের গ্রুপ ইনভাইটেশনের মতো ফিচারগুলোর জন্য আরও বেশি নমনীয়তা প্রদান করে।
  • নির্বাচনের সীমা: একজন ব্যবহারকারী একবারে কতগুলো কন্ট্যাক্ট নির্বাচন করতে পারবে, তার উপর ডেভেলপাররা নিজস্ব সীমা নির্ধারণ করতে পারেন।
  • অস্থায়ী অ্যাক্সেস: এটি নির্বাচন করা হলে, সিস্টেম একটি সেশন ইউআরআই (Session URI) ফেরত দেয় যা অনুরোধকৃত ডেটাতে অস্থায়ী পঠন অ্যাক্সেস প্রদান করে, এবং এটি নিশ্চিত করে যে অ্যাক্সেস প্রয়োজনের চেয়ে বেশি সময় ধরে স্থায়ী না হয়।
  • অন্যান্য প্রোফাইলে প্রবেশাধিকার: এই নতুন ইন্টেন্টটি ব্যবহার করার সময়, ইন্টারফেসটি ব্যবহারকারীদেরকে অন্যান্য ব্যবহারকারীর প্রোফাইল, যেমন কর্মক্ষেত্রের প্রোফাইল, ক্লোন করা প্রোফাইল বা ব্যক্তিগত স্থান থেকে বিষয়বস্তু নির্বাচন করার অনুমতি দেবে।
  • উন্নত কর্মক্ষমতা: কন্টাক্ট পিকার একটি একক ইউআরআই (Uri) রিটার্ন করে, যা দিয়ে একসাথে একাধিক ফলাফল কোয়েরি করা যায়। এর ফলে ACTION_PICK এর মতো প্রতিটি কন্টাক্টের ইউআরআই আলাদাভাবে কোয়েরি করার প্রয়োজন হয় না। এই কার্যকারিতা একটিমাত্র Binder ট্রানজ্যাকশন ব্যবহারের মাধ্যমে সিস্টেম ওভারহেড আরও কমিয়ে আনে।

পশ্চাৎ সামঞ্জস্যতা এবং বাস্তবায়ন

অ্যান্ড্রয়েড ১৭ বা তার উচ্চতর সংস্করণে চালিত ডিভাইসগুলির জন্য, সিস্টেম স্বয়ংক্রিয়ভাবে কন্টাক্ট ডেটা টাইপ নির্দিষ্টকারী পুরোনো ACTION_PICK ইন্টেন্টগুলিকে নতুন, আরও সুরক্ষিত ইন্টারফেসে আপগ্রেড করে। তবে, মাল্টি-সিলেকশনের মতো উন্নত বৈশিষ্ট্যগুলির সম্পূর্ণ সুবিধা নিতে, ডেভেলপারদের তাদের ইমপ্লিমেন্টেশন কোড আপডেট করতে এবং ফেরত আসা সেশন ইউআরআই (Session URI) কোয়েরি করার জন্য ContentResolver ব্যবহার করতে উৎসাহিত করা হচ্ছে।


কন্টাক্ট পিকার ইন্টিগ্রেট করতে, ডেভেলপাররা ACTION_PICK_CONTACTS ইন্টেন্ট ব্যবহার করেন। নিচে একটি কোড উদাহরণ দেওয়া হলো, যেখানে দেখানো হয়েছে কীভাবে পিকারটি চালু করতে হয় এবং ইমেল ও ফোন নম্বরের মতো নির্দিষ্ট ডেটা ফিল্ডের জন্য অনুরোধ করতে হয়।

// State to hold the list of selected contacts
var contacts by remember { mutableStateOf<List>(emptyList()) }
// Launcher for the Contact Picker intent
val pickContact = rememberLauncherForActivityResult(StartActivityForResult()) {
if (it.resultCode == Activity.RESULT_OK) {
val resultUri = it.data?.data ?: return@rememberLauncherForActivityResult
    // Process the result URI in a background thread
    coroutine.launch {
        contacts = processContactPickerResultUri(resultUri, context)
    }
}
}
// Define the specific contact data fields you need
val requestedFields = arrayListOf(
Email.CONTENT_ITEM_TYPE,
Phone.CONTENT_ITEM_TYPE,
)
// Set up the intent for the Contact Picker
val pickContactIntent = Intent(ACTION_PICK_CONTACTS).apply {
putExtra(EXTRA_PICK_CONTACTS_SELECTION_LIMIT, 5)
putStringArrayListExtra(
EXTRA_PICK_CONTACTS_REQUESTED_DATA_FIELDS,
requestedFields
)
putExtra(EXTRA_PICK_CONTACTS_MATCH_ALL_DATA_FIELDS, false)
}
// Launch the picker
pickContact.launch(pickContactIntent)

ব্যবহারকারী কোনো কিছু নির্বাচন করার পর, অ্যাপটি প্রাপ্ত সেশন ইউআরআই (Session URI) থেকে অনুরোধ করা যোগাযোগের তথ্য বের করার জন্য ফলাফলটি প্রক্রিয়া করে।

// Data class representing a parsed Contact with selected details
data class Contact(val id: String, val name: String, val email: String?, val phone: String?)

// Helper function to query the content resolver with the URI returned by the Contact Picker.
// Parses the cursor to extract contact details such as name, email, and phone number
private suspend fun processContactPickerResultUri(
    sessionUri: Uri,
    context: Context
): List<Contact> = withContext(Dispatchers.IO) {
    // Define the columns we want to retrieve from the ContactPicker ContentProvider
    val projection = arrayOf(
        ContactsContract.Contacts._ID,
        ContactsContract.Contacts.DISPLAY_NAME_PRIMARY,
        ContactsContract.Data.MIMETYPE, // Type of data (e.g., email or phone)
        ContactsContract.Data.DATA1, // The actual data (Phone number / Email string)
    )

    val results = mutableListOf<Contact>()

    // Note: The Contact Picker Session Uri doesn't support custom selection & selectionArgs.
    context.contentResolver.query(sessionUri, projection, null, null, null)?.use { cursor ->
        // Get the column indices for our requested projection
        val contactIdIdx = cursor.getColumnIndex(ContactsContract.Contacts._ID)
        val mimeTypeIdx = cursor.getColumnIndex(ContactsContract.Data.MIMETYPE)
        val nameIdx = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME_PRIMARY)
        val data1Idx = cursor.getColumnIndex(ContactsContract.Data.DATA1)

        while (cursor.moveToNext()) {
            val contactId = cursor.getString(contactIdIdx)
            val mimeType = cursor.getString(mimeTypeIdx)
            val name = cursor.getString(nameIdx) ?: ""
            val data1 = cursor.getString(data1Idx) ?: ""

            // Determine if the current row represents an email or a phone number
            val email = if (mimeType == Email.CONTENT_ITEM_TYPE) data1 else null
            val phone = if (mimeType == Phone.CONTENT_ITEM_TYPE) data1 else null

            // Add the parsed contact to our results list
            results.add(Contact(contactId, name, email, phone))
        }
    }

    return@withContext results
}

সম্পূর্ণ ডকুমেন্টেশনটি এখানে দেখুন।

ডেভেলপারদের জন্য সেরা অনুশীলন

সর্বোত্তম ব্যবহারকারী অভিজ্ঞতা প্রদান এবং উচ্চ নিরাপত্তা মান বজায় রাখার জন্য, আমরা নিম্নলিখিত সুপারিশ করছি:

  • ডেটা হ্রাসকরণ: শুধুমাত্র আপনার অ্যাপের প্রয়োজনীয় নির্দিষ্ট ডেটা ফিল্ডগুলোর (যেমন, ইমেল) জন্য অনুরোধ করুন।
  • তাৎক্ষণিক স্থায়িত্ব: নির্বাচিত ডেটা অবিলম্বে সংরক্ষণ করুন, কারণ সেশন ইউআরআই অ্যাক্সেস অস্থায়ী।
    লিখেছেন:

    পড়তে থাকুন