একটি পরিচিতির জন্য বিশদ পুনরুদ্ধার করুন

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

এই পাঠের ধাপগুলি অনুমান করে যে ব্যবহারকারীর বেছে নেওয়া পরিচিতির জন্য আপনার কাছে ইতিমধ্যে একটি ContactsContract.Contacts সারি রয়েছে। পরিচিতির নাম পুনরুদ্ধার করার পাঠটি দেখায় কিভাবে পরিচিতিগুলির একটি তালিকা পুনরুদ্ধার করতে হয়।

একটি পরিচিতির জন্য সমস্ত বিবরণ পুনরুদ্ধার করুন

একটি পরিচিতির সমস্ত বিবরণ পুনরুদ্ধার করতে, পরিচিতির LOOKUP_KEY ধারণ করে এমন যেকোনো সারিগুলির জন্য ContactsContract.Data টেবিলে অনুসন্ধান করুন। এই কলামটি ContactsContract.Data টেবিলে উপলব্ধ, কারণ পরিচিতি প্রদানকারী ContactsContract.Contacts টেবিল এবং ContactsContract.Data টেবিলের মধ্যে একটি অন্তর্নিহিত যোগদান করে। LOOKUP_KEY কলামটি পরিচিতির নাম পুনরুদ্ধার পাঠে আরও বিশদে বর্ণনা করা হয়েছে।

দ্রষ্টব্য: একটি পরিচিতির জন্য সমস্ত বিবরণ পুনরুদ্ধার করা একটি ডিভাইসের কর্মক্ষমতা হ্রাস করে, কারণ এটি ContactsContract.Data টেবিলের সমস্ত কলাম পুনরুদ্ধার করতে হবে৷ আপনি এই কৌশলটি ব্যবহার করার আগে কর্মক্ষমতা প্রভাব বিবেচনা করুন।

অনুমতি অনুরোধ

পরিচিতি প্রদানকারী থেকে পড়তে, আপনার অ্যাপের অবশ্যই READ_CONTACTS অনুমতি থাকতে হবে। এই অনুমতির অনুরোধ করতে, আপনার ম্যানিফেস্ট ফাইলে <manifest> এর নিম্নলিখিত চাইল্ড এলিমেন্ট যোগ করুন:

    <uses-permission android:name="android.permission.READ_CONTACTS" />

একটি অভিক্ষেপ সেট আপ করুন

একটি সারিতে থাকা ডেটা টাইপের উপর নির্ভর করে, এটি শুধুমাত্র কয়েকটি কলাম বা অনেকগুলি ব্যবহার করতে পারে। উপরন্তু, ডেটা টাইপের উপর নির্ভর করে বিভিন্ন কলামে ডেটা থাকে। আপনি সমস্ত সম্ভাব্য ডেটা প্রকারের জন্য সমস্ত সম্ভাব্য কলাম পান তা নিশ্চিত করতে, আপনাকে আপনার অভিক্ষেপে সমস্ত কলামের নাম যুক্ত করতে হবে। সর্বদা Data._ID পুনরুদ্ধার করুন._ID যদি আপনি ফলাফল Cursor একটি ListView এর সাথে আবদ্ধ করেন; অন্যথায়, বাঁধাই কাজ করবে না। এছাড়াও Data.MIMETYPE পুনরুদ্ধার করুন যাতে আপনি পুনরুদ্ধার করা প্রতিটি সারির ডেটা প্রকার সনাক্ত করতে পারেন। যেমন:

কোটলিন

private val PROJECTION: Array<out String> = arrayOf(
        ContactsContract.Data._ID,
        ContactsContract.Data.MIMETYPE,
        ContactsContract.Data.DATA1,
        ContactsContract.Data.DATA2,
        ContactsContract.Data.DATA3,
        ContactsContract.Data.DATA4,
        ContactsContract.Data.DATA5,
        ContactsContract.Data.DATA6,
        ContactsContract.Data.DATA7,
        ContactsContract.Data.DATA8,
        ContactsContract.Data.DATA9,
        ContactsContract.Data.DATA10,
        ContactsContract.Data.DATA11,
        ContactsContract.Data.DATA12,
        ContactsContract.Data.DATA13,
        ContactsContract.Data.DATA14,
        ContactsContract.Data.DATA15
)

জাভা

    private static final String[] PROJECTION =
            {
                ContactsContract.Data._ID,
                ContactsContract.Data.MIMETYPE,
                ContactsContract.Data.DATA1,
                ContactsContract.Data.DATA2,
                ContactsContract.Data.DATA3,
                ContactsContract.Data.DATA4,
                ContactsContract.Data.DATA5,
                ContactsContract.Data.DATA6,
                ContactsContract.Data.DATA7,
                ContactsContract.Data.DATA8,
                ContactsContract.Data.DATA9,
                ContactsContract.Data.DATA10,
                ContactsContract.Data.DATA11,
                ContactsContract.Data.DATA12,
                ContactsContract.Data.DATA13,
                ContactsContract.Data.DATA14,
                ContactsContract.Data.DATA15
            };

এই প্রজেকশনটি ContactsContract.Data ক্লাসে সংজ্ঞায়িত কলামের নাম ব্যবহার করে ContactsContract.Data টেবিলের একটি সারির জন্য সমস্ত কলাম পুনরুদ্ধার করে।

ঐচ্ছিকভাবে, আপনি ContactsContract.Data ক্লাসে সংজ্ঞায়িত বা উত্তরাধিকারসূত্রে প্রাপ্ত অন্য কোনো কলামের ধ্রুবক ব্যবহার করতে পারেন। তবে লক্ষ্য করুন, SYNC1 এর মাধ্যমে SYNC4 কলামগুলি সিঙ্ক অ্যাডাপ্টারের দ্বারা ব্যবহার করার জন্য, তাই তাদের ডেটা কার্যকর নয়৷

নির্বাচনের মানদণ্ড নির্ধারণ করুন

আপনার নির্বাচন ধারার জন্য একটি ধ্রুবক সংজ্ঞায়িত করুন, নির্বাচন আর্গুমেন্ট ধরে রাখার জন্য একটি অ্যারে এবং নির্বাচন মান ধরে রাখার জন্য একটি পরিবর্তনশীল। পরিচিতি খুঁজতে Contacts.LOOKUP_KEY কলাম ব্যবহার করুন। যেমন:

কোটলিন

// Defines the selection clause
private const val SELECTION: String = "${ContactsContract.Data.LOOKUP_KEY} = ?"
...
// Defines the array to hold the search criteria
private val selectionArgs: Array<String> = arrayOf("")
/*
 * Defines a variable to contain the selection value. Once you
 * have the Cursor from the Contacts table, and you've selected
 * the desired row, move the row's LOOKUP_KEY value into this
 * variable.
 */
private var lookupKey: String? = null

জাভা

    // Defines the selection clause
    private static final String SELECTION = Data.LOOKUP_KEY + " = ?";
    // Defines the array to hold the search criteria
    private String[] selectionArgs = { "" };
    /*
     * Defines a variable to contain the selection value. Once you
     * have the Cursor from the Contacts table, and you've selected
     * the desired row, move the row's LOOKUP_KEY value into this
     * variable.
     */
    private lateinit var lookupKey: String

ব্যবহার করছেন "?" আপনার নির্বাচন টেক্সট এক্সপ্রেশনে একটি স্থানধারক হিসাবে নিশ্চিত করে যে ফলাফল অনুসন্ধান এসকিউএল সংকলনের পরিবর্তে বাইন্ডিং দ্বারা তৈরি করা হয়েছে। এই পদ্ধতিটি দূষিত SQL ইনজেকশনের সম্ভাবনা দূর করে।

সাজানোর ক্রম সংজ্ঞায়িত করুন

ফলাফল Cursor আপনি যে সাজানোর ক্রম চান তা নির্ধারণ করুন। একটি নির্দিষ্ট ডেটা টাইপের জন্য সমস্ত সারি একসাথে রাখতে, Data.MIMETYPE অনুসারে সাজান। এই ক্যোয়ারী আর্গুমেন্ট সমস্ত ইমেল সারি একত্রিত করে, সমস্ত ফোন সারি একসাথে, এবং আরও অনেক কিছু। যেমন:

কোটলিন

/*
 * Defines a string that specifies a sort order of MIME type
 */
private const val SORT_ORDER = ContactsContract.Data.MIMETYPE

জাভা

    /*
     * Defines a string that specifies a sort order of MIME type
     */
    private static final String SORT_ORDER = ContactsContract.Data.MIMETYPE;

দ্রষ্টব্য: কিছু ডেটা টাইপ একটি সাব-টাইপ ব্যবহার করে না, তাই আপনি সাব-টাইপ অনুসারে সাজাতে পারবেন না। পরিবর্তে, আপনাকে রিটার্ন করা Cursor মাধ্যমে পুনরাবৃত্তি করতে হবে, বর্তমান সারির ডেটা টাইপ নির্ধারণ করতে হবে এবং সাব-টাইপ ব্যবহার করে এমন সারিগুলির জন্য ডেটা সঞ্চয় করতে হবে। আপনি যখন কার্সার পড়া শেষ করেন, তখন আপনি প্রতিটি ডেটা টাইপ সাব-টাইপ অনুসারে সাজাতে পারেন এবং ফলাফলগুলি প্রদর্শন করতে পারেন।

লোডার আরম্ভ করুন

সর্বদা একটি ব্যাকগ্রাউন্ড থ্রেডে পরিচিতি প্রদানকারী (এবং অন্যান্য সমস্ত সামগ্রী প্রদানকারী) থেকে পুনরুদ্ধার করুন। ব্যাকগ্রাউন্ড পুনরুদ্ধার করতে LoaderManager ক্লাস এবং LoaderManager.LoaderCallbacks ইন্টারফেস দ্বারা সংজ্ঞায়িত লোডার ফ্রেমওয়ার্ক ব্যবহার করুন।

আপনি যখন সারিগুলি পুনরুদ্ধার করতে প্রস্তুত হন, তখন initLoader() কল করে লোডার ফ্রেমওয়ার্ক শুরু করুন। পদ্ধতিতে একটি পূর্ণসংখ্যা শনাক্তকারী পাস করুন; এই শনাক্তকারীটি LoaderManager.LoaderCallbacks পদ্ধতিতে পাস করা হয়েছে। শনাক্তকারী আপনাকে তাদের মধ্যে পার্থক্য করার অনুমতি দিয়ে একটি অ্যাপে একাধিক লোডার ব্যবহার করতে সহায়তা করে।

নিম্নলিখিত স্নিপেট দেখায় কিভাবে লোডার ফ্রেমওয়ার্ক শুরু করতে হয়:

কোটলিন

// Defines a constant that identifies the loader
private const val DETAILS_QUERY_ID: Int = 0

class DetailsFragment : Fragment(), LoaderManager.LoaderCallbacks<Cursor> {
    ...
    override fun onCreate(savedInstanceState: Bundle?) {
        ...
        // Initializes the loader framework
        loaderManager.initLoader(DETAILS_QUERY_ID, null, this)

জাভা

public class DetailsFragment extends Fragment implements
        LoaderManager.LoaderCallbacks<Cursor> {
    ...
    // Defines a constant that identifies the loader
    static int DETAILS_QUERY_ID = 0;
    ...
    @Override
    public void onCreate(Bundle savedInstanceState) {
        ...
        // Initializes the loader framework
        getLoaderManager().initLoader(DETAILS_QUERY_ID, null, this);

ক্রিয়েটলোডারে প্রয়োগ করুন()

onCreateLoader() পদ্ধতিটি প্রয়োগ করুন, যা আপনি initLoader() কল করার সাথে সাথে লোডার ফ্রেমওয়ার্ক দ্বারা কল করা হয়। এই পদ্ধতি থেকে একটি CursorLoader ফেরত দিন। যেহেতু আপনি ContactsContract.Data টেবিল অনুসন্ধান করছেন, তাই কনটেন্ট Data.CONTENT_URI ব্যবহার করুন.CONTENT_URI বিষয়বস্তু URI হিসাবে। যেমন:

কোটলিন

override fun onCreateLoader(loaderId: Int, args: Bundle?): Loader<Cursor> {
    // Choose the proper action
    mLoader = when(loaderId) {
        DETAILS_QUERY_ID -> {
            // Assigns the selection parameter
            selectionArgs[0] = lookupKey
            // Starts the query
            activity?.let {
                CursorLoader(
                        it,
                        ContactsContract.Data.CONTENT_URI,
                        PROJECTION,
                        SELECTION,
                        selectionArgs,
                        SORT_ORDER
                )
            }
        }
        ...
    }
    return mLoader
}

জাভা

@Override
    public Loader<Cursor> onCreateLoader(int loaderId, Bundle args) {
        // Choose the proper action
        switch (loaderId) {
            case DETAILS_QUERY_ID:
            // Assigns the selection parameter
            selectionArgs[0] = lookupKey;
            // Starts the query
            CursorLoader mLoader =
                    new CursorLoader(
                            getActivity(),
                            ContactsContract.Data.CONTENT_URI,
                            PROJECTION,
                            SELECTION,
                            selectionArgs,
                            SORT_ORDER
                    );
    }

onLoadFinished() এবং onLoaderReset() প্রয়োগ করুন

onLoadFinished() পদ্ধতি প্রয়োগ করুন। লোডার ফ্রেমওয়ার্ক onLoadFinished() কল করে যখন পরিচিতি প্রদানকারী প্রশ্নের ফলাফল প্রদান করে। যেমন:

কোটলিন

    override fun onLoadFinished(loader: Loader<Cursor>, data: Cursor) {
        when(loader.id) {
            DETAILS_QUERY_ID -> {
                /*
                 * Process the resulting Cursor here.
                 */
            }
            ...
        }
    }

জাভা

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
        switch (loader.getId()) {
            case DETAILS_QUERY_ID:
                    /*
                     * Process the resulting Cursor here.
                     */
                }
                break;
            ...
        }
    }

onLoaderReset() পদ্ধতিটি চালু করা হয় যখন লোডার ফ্রেমওয়ার্ক সনাক্ত করে যে ফলাফল Cursor সমর্থনকারী ডেটা পরিবর্তিত হয়েছে। এই মুহুর্তে, Cursor বিদ্যমান রেফারেন্সগুলিকে শূন্য করে সেট করে সরিয়ে দিন। যদি আপনি না করেন, লোডার ফ্রেমওয়ার্ক পুরানো Cursor ধ্বংস করবে না, এবং আপনি একটি মেমরি লিক পাবেন। যেমন:

কোটলিন

    override fun onLoaderReset(loader: Loader<Cursor>) {
        when (loader.id) {
            DETAILS_QUERY_ID -> {
                /*
                 * If you have current references to the Cursor,
                 * remove them here.
                 */
            }
            ...
        }
    }

জাভা

    @Override
    public void onLoaderReset(Loader<Cursor> loader) {
        switch (loader.getId()) {
            case DETAILS_QUERY_ID:
                /*
                 * If you have current references to the Cursor,
                 * remove them here.
                 */
                }
                break;
    }

একটি পরিচিতির জন্য নির্দিষ্ট বিবরণ পুনরুদ্ধার করুন

একটি পরিচিতির জন্য একটি নির্দিষ্ট ডেটা টাইপ পুনরুদ্ধার করা, যেমন সমস্ত ইমেল, সমস্ত বিবরণ পুনরুদ্ধারের মতো একই প্যাটার্ন অনুসরণ করে। একটি পরিচিতির জন্য সমস্ত বিবরণ পুনরুদ্ধার করুন- এ তালিকাভুক্ত কোডে আপনাকে শুধুমাত্র এই পরিবর্তনগুলি করতে হবে:

অভিক্ষেপ
ডেটা টাইপের জন্য নির্দিষ্ট কলামগুলি পুনরুদ্ধার করতে আপনার অভিক্ষেপ পরিবর্তন করুন। এছাড়াও ডেটা টাইপের সাথে সম্পর্কিত ContactsContract.CommonDataKinds সাবক্লাসে সংজ্ঞায়িত কলাম নামের ধ্রুবকগুলি ব্যবহার করার জন্য প্রজেকশনটি পরিবর্তন করুন।
নির্বাচন
আপনার ডেটা প্রকারের জন্য নির্দিষ্ট MIMETYPE মান অনুসন্ধান করতে নির্বাচন পাঠ্যটি পরিবর্তন করুন।
সাজানোর ক্রম
যেহেতু আপনি শুধুমাত্র একটি একক বিশদ প্রকার নির্বাচন করছেন, তাই ফিরে আসা Cursor Data.MIMETYPE দ্বারা গোষ্ঠীভুক্ত করবেন না।

এই পরিবর্তনগুলি নিম্নলিখিত বিভাগে বর্ণিত হয়েছে।

একটি অভিক্ষেপ সংজ্ঞায়িত করুন

ডেটা টাইপের জন্য ContactsContract.CommonDataKinds এর সাবক্লাসে কলামের নাম ধ্রুবক ব্যবহার করে আপনি যে কলামগুলি পুনরুদ্ধার করতে চান তা সংজ্ঞায়িত করুন। আপনি যদি আপনার Cursor একটি ListView এ আবদ্ধ করার পরিকল্পনা করেন, তাহলে _ID কলামটি পুনরুদ্ধার করতে ভুলবেন না। উদাহরণস্বরূপ, ইমেল ডেটা পুনরুদ্ধার করতে, নিম্নলিখিত অভিক্ষেপ সংজ্ঞায়িত করুন:

কোটলিন

private val PROJECTION: Array<String> = arrayOf(
        ContactsContract.CommonDataKinds.Email._ID,
        ContactsContract.CommonDataKinds.Email.ADDRESS,
        ContactsContract.CommonDataKinds.Email.TYPE,
        ContactsContract.CommonDataKinds.Email.LABEL
)

জাভা

    private static final String[] PROJECTION =
            {
                ContactsContract.CommonDataKinds.Email._ID,
                ContactsContract.CommonDataKinds.Email.ADDRESS,
                ContactsContract.CommonDataKinds.Email.TYPE,
                ContactsContract.CommonDataKinds.Email.LABEL
            };

লক্ষ্য করুন যে এই প্রজেকশনটি ContactsContract.CommonDataKinds.Email ক্লাসে সংজ্ঞায়িত কলামের নাম ব্যবহার করে, শ্রেণী ContactsContract.Data এ সংজ্ঞায়িত কলাম নামের পরিবর্তে। ইমেল-নির্দিষ্ট কলামের নাম ব্যবহার করা কোডটিকে আরও পাঠযোগ্য করে তোলে।

অভিক্ষেপে, আপনি ContactsContract.CommonDataKinds সাবক্লাসে সংজ্ঞায়িত অন্য যে কোনো কলাম ব্যবহার করতে পারেন।

নির্বাচনের মানদণ্ড নির্ধারণ করুন

একটি সার্চ টেক্সট এক্সপ্রেশন সংজ্ঞায়িত করুন যা একটি নির্দিষ্ট পরিচিতির LOOKUP_KEY এবং Data.MIMETYPE জন্য সারি পুনরুদ্ধার করে। আপনি যে বিবরণ চান তার MIMETYPE। ধ্রুবকের শুরু এবং শেষে একটি " ' " (একক-উদ্ধৃতি) অক্ষর সংযুক্ত করে একক উদ্ধৃতিতে MIMETYPE মানটি আবদ্ধ করুন; অন্যথায়, প্রদানকারী ধ্রুবকটিকে একটি স্ট্রিং মান হিসাবে না করে একটি পরিবর্তনশীল নাম হিসাবে ব্যাখ্যা করে। এই মানটির জন্য আপনাকে একটি স্থানধারক ব্যবহার করতে হবে না, কারণ আপনি ব্যবহারকারীর দ্বারা সরবরাহকৃত মানের পরিবর্তে একটি ধ্রুবক ব্যবহার করছেন। যেমন:

কোটলিন

/*
 * Defines the selection clause. Search for a lookup key
 * and the Email MIME type
 */
private const val SELECTION =
        "${ContactsContract.Data.LOOKUP_KEY} = ? AND " +
        "${ContactsContract.Data.MIMETYPE} = '${Email.CONTENT_ITEM_TYPE}'"
...
// Defines the array to hold the search criteria
private val selectionArgs: Array<String> = arrayOf("")

জাভা

    /*
     * Defines the selection clause. Search for a lookup key
     * and the Email MIME type
     */
    private static final String SELECTION =
            Data.LOOKUP_KEY + " = ?" +
            " AND " +
            Data.MIMETYPE + " = " +
            "'" + Email.CONTENT_ITEM_TYPE + "'";
    // Defines the array to hold the search criteria
    private String[] selectionArgs = { "" };

একটি সাজানোর ক্রম সংজ্ঞায়িত করুন

ফিরে আসা Cursor জন্য একটি সাজানোর ক্রম নির্ধারণ করুন। যেহেতু আপনি একটি নির্দিষ্ট ডেটা টাইপ পুনরুদ্ধার করছেন, তাই MIMETYPE এ সাজানো বাদ দিন। পরিবর্তে, আপনি যে ধরনের বিশদ ডেটা অনুসন্ধান করছেন সেটিতে যদি একটি সাব-টাইপ থাকে, তাহলে এটি সাজান। উদাহরণস্বরূপ, ইমেল ডেটার জন্য আপনি Email.TYPE এ সাজাতে পারেন:

কোটলিন

private const val SORT_ORDER: String = "${Email.TYPE} ASC"

জাভা

    private static final String SORT_ORDER = Email.TYPE + " ASC ";