Content Provider হল একটি Android কম্পোনেন্ট যা অ্যাপ্লিকেশনের মধ্যে ডেটা অ্যাক্সেসের জন্য একটি ইউনিফাইড ইন্টারফেস প্রদান করে। এটি ফিজিক্যাল স্টোরেজ (SQLite, ফাইল, নেটওয়ার্ক উৎস) অ্যাবস্ট্রাক্ট করে এবং ContentResolver-এর মাধ্যমে নিরাপদ তথ্য আদান-প্রদান সক্ষম করে। Android Developer Guide, 2026 অনুযায়ী, Content Provider Activity, Service এবং BroadcastReceiver-এর পাশাপাশি Android অ্যাপ্লিকেশনের চারটি প্রধান কম্পোনেন্টের একটি। এর কাজ হল পড়া এবং লেখার অনুমতি নিয়ন্ত্রণ সহ অন্যান্য অ্যাপ্লিকেশনের জন্য ডেটা উপলব্ধ করা।
মূল বিষয়
Content Provider হল একটি Android কম্পোনেন্ট যা কেন্দ্রীয় ডেটা স্টোরে অ্যাক্সেস পরিচালনা করে এবং একটি ইউনিফাইড কন্ট্রাক্ট ইন্টারফেসের মাধ্যমে অন্যান্য অ্যাপ্লিকেশনকে তা প্রদান করে। এটি স্টোরেজ বাস্তবায়নের বিবরণ লুকায়: ডেটা SQLite, ফাইল সিস্টেম, ক্লাউডে সংরক্ষণ করা যেতে পারে বা নেটওয়ার্ক অনুরোধের ফলাফল হতে পারে।
Android-এ সিস্টেম ডেটার জন্য বিল্ট-ইন Content Providers অন্তর্ভুক্ত রয়েছে — ContactsContract, MediaStore, CalendarContract, CallLog। তৃতীয়-পক্ষের অ্যাপ্লিকেশনও নিরাপদ ডেটা আদান-প্রদানের জন্য নিজস্ব প্রোভাইডার তৈরি করতে পারে। প্রতিটি প্রোভাইডার authority সহ AndroidManifest.xml-এ নিবন্ধিত হয় — একটি অনন্য স্ট্রিং যা URI-এর প্রথম অংশ গঠন করে।
Content Provider ক্লায়েন্ট-সার্ভার মডেলে কাজ করে। প্রোভাইডার একটি সার্ভার হিসেবে কাজ করে যা ছয়টি বাধ্যতামূলক পদ্ধতি বাস্তবায়ন করে: query, insert, update, delete, getType এবং onCreate। ক্লায়েন্ট (অন্য অ্যাপ্লিকেশন) ContentResolver-এর মাধ্যমে প্রোভাইডারে অ্যাক্সেস করে, যা Android-এর IPC প্রক্রিয়ার মাধ্যমে কলগুলিকে প্রোভাইডারের সংশ্লিষ্ট পদ্ধতিতে অনুবাদ করে।
প্রতিটি Content Provider content:// স্কিমের URI দ্বারা চিহ্নিত হয়। উদাহরণস্বরূপ, content://com.example.app.provider/items। প্রথম অংশ authority (com.example.app.provider) ম্যানিফেস্টে প্রোভাইডার ক্লাসের সাথে আবদ্ধ। পাথ /items একটি টেবিল নির্দেশ করে, যখন /items/5 ID=5 সহ একটি নির্দিষ্ট রেকর্ড নির্দেশ করে।
যখন একটি অ্যাপ্লিকেশন ContentResolver.query(URI) কল করে, Android কলিং প্যাকেজের অনুমতি পরীক্ষা করে, authority দ্বারা প্রোভাইডার খুঁজে পায় এবং যদি এটি ইতিমধ্যে চলমান না থাকে তবে তার প্রক্রিয়া শুরু করে। প্রোভাইডার কোয়েরি সম্পাদন করে এবং একটি Cursor ফেরত দেয় — একটি অবজেক্ট যা ফলাফল ধারণ করে এবং ক্লায়েন্টকে রেকর্ডের উপর পুনরাবৃত্তি করতে দেয়।
ContentProvider ক্লাসের জন্য ছয়টি অ্যাবস্ট্রাক্ট পদ্ধতি বাস্তবায়নের প্রয়োজন। প্রতিটি পদ্ধতি একটি URI গ্রহণ করে এবং অপারেশন প্রকারের সাথে সংশ্লিষ্ট ফলাফল ফেরত দেয়। সিস্টেম এই পদ্ধতিগুলি যে কোনও প্রক্রিয়া থেকে কল করে, তাই এগুলি থ্রেড-নিরাপদ হতে হবে এবং দীর্ঘ সময়ের জন্য এক্সিকিউশন ব্লক করবে না।
query পদ্ধতি একটি URI, কলামের projection অ্যারে, আর্গুমেন্ট সহ selection স্ট্রিং এবং সর্ট অর্ডার গ্রহণ করে। এটি ডেটা সহ একটি Cursor ফেরত দেয়। বাস্তবায়নে, আপনাকে UriMatcher ব্যবহার করে URI পার্স করতে হবে এবং ডেটাবেসে সংশ্লিষ্ট SQL কোয়েরি সম্পাদন করতে হবে।
এই পদ্ধতিগুলি স্টোরে ডেটা পরিবর্তন করে। insert ContentValues — কী-ভ্যালু জোড়া — গ্রহণ করে এবং নতুন রেকর্ডের URI ফেরত দেয়। update এবং delete রেকর্ড ফিল্টার করার জন্য selection গ্রহণ করে এবং প্রভাবিত সারির সংখ্যা ফেরত দেয়। ডেটা পরিবর্তনের পরে, প্রোভাইডারকে ContentResolver.notifyChange-এর মাধ্যমে এটি সম্পর্কে বিজ্ঞপ্তি দিতে হবে।
| পদ্ধতি | উদ্দেশ্য | ফেরত |
|---|---|---|
| query | URI দ্বারা ডেটা পাওয়া | Cursor বা null |
| insert | নতুন রেকর্ড যোগ করা | নতুন রেকর্ডের URI |
| update | বিদ্যমান রেকর্ড আপডেট করা | int (সারির সংখ্যা) |
| delete | রেকর্ড মুছে ফেলা | int (সারির সংখ্যা) |
| getType | URI-এর জন্য MIME প্রকার | String |
| onCreate | প্রোভাইডার আরম্ভ | boolean |
ContentResolver হল সিস্টেমের সমস্ত Content Providers-এর সাথে কাজ করার জন্য একটি একক অ্যাক্সেস পয়েন্ট। ক্লায়েন্ট অ্যাপ্লিকেশন কখনও সরাসরি প্রোভাইডার পদ্ধতি কল করে না — শুধুমাত্র ContentResolver-এর মাধ্যমে, যা Android কনটেক্সট থেকে পায়। ContentResolver-এ CRUD অপারেশনের নাম প্রোভাইডারের মতোই কিন্তু সরাসরি রেফারেন্সের পরিবর্তে URI গ্রহণ করে।
প্রোভাইডারের ভিতরে আগত URI পার্স করতে UriMatcher ব্যবহার করা হয়। এটি একটি URI-কে একটি সংখ্যামূলক কোডে ম্যাপ করার অনুমতি দেয় — উদাহরণস্বরূপ, URI content://authority/items কোড 1 দেয়, এবং content://authority/items/# কোড 2 দেয়। এটি প্রতিটি পদ্ধতিতে ম্যানুয়াল URI স্ট্রিং পার্সিংয়ের প্রয়োজনীয়তা দূর করে।
// কন্টাক্ট অ্যাক্সেস করতে ContentResolver ব্যবহার করা
val uri = ContactsContract.Contacts.CONTENT_URI
val cursor = contentResolver.query(
uri,
arrayOf(ContactsContract.Contacts.DISPLAY_NAME),
null, null, null
)
cursor?.use {
while (it.moveToNext()) {
val name = it.getString(it.getColumnIndexOrThrow(
ContactsContract.Contacts.DISPLAY_NAME
))
Log.d("কন্টাক্ট", "নাম: $name")
}
}
ব্যবহারের পরে Cursor সর্বদা বন্ধ করতে হবে — উপরের উদাহরণে, use ফাংশন (Kotlin এক্সটেনশন) এটি করে। Cursor বন্ধ না হলে, মেমরি লিক হয় কারণ এটি Binder পুলে ডেটার একটি রেফারেন্স ধারণ করে। UI পরিস্থিতির জন্য, LiveData/Flow-এর সাথে CursorLoader বা Room ব্যবহার করুন।
নিজস্ব Content Provider তৈরি করা ContentProvider ক্লাস এক্সটেন্ড করার মাধ্যমে শুরু হয়। প্রোভাইডার SQLiteOpenHelper-এর মাধ্যমে SQLite ডেটাবেসের সাথে কাজ করে এবং কোয়েরির প্রকার নির্ধারণ করতে UriMatcher ব্যবহার করে। নোটের তালিকা পরিচালনার জন্য একটি ন্যূনতম বাস্তবায়ন বিবেচনা করুন।
প্রোভাইডার AndroidManifest.xml-এ application ট্যাগের ভিতরে নিবন্ধিত হয়। authorities অ্যাট্রিবিউট একটি অনন্য আইডেন্টিফায়ার সেট করে, এবং exported নির্ধারণ করে যে অন্যান্য অ্যাপ্লিকেশন প্রোভাইডারে অ্যাক্সেস করতে পারে কিনা। exported=true ছাড়া, প্রোভাইডার শুধুমাত্র আপনার অ্যাপ্লিকেশনের মধ্যেই অ্যাক্সেসযোগ্য।
// নোটের জন্য Content Provider উদাহরণ
class NotesProvider : ContentProvider() {
companion object {
const val AUTHORITY = "com.example.app.notes"
const val NOTES_PATH = "notes"
const val NOTES_URI = "content://$AUTHORITY/$NOTES_PATH"
const val NOTES_ID = "content://$AUTHORITY/$NOTES_PATH/#"
private val uriMatcher = UriMatcher(UriMatcher.NO_MATCH).apply {
addURI(AUTHORITY, NOTES_PATH, 1)
addURI(AUTHORITY, "$NOTES_PATH/#", 2)
}
}
override fun query(uri: Uri, projection: Array<String>?,
selection: String?, args: Array<String>?, sort: String?): Cursor? {
return when (uriMatcher.match(uri)) {
1 -> dbHelper.readableDatabase.query(TABLE_NOTES,
projection, selection, args, null, null, sort)
2 -> dbHelper.readableDatabase.query(TABLE_NOTES,
projection, "_id=?", arrayOf(uri.lastPathSegment), null, null, null)
else -> throw IllegalArgumentException("Unknown URI: $uri")
}
}
override fun insert(uri: Uri, values: ContentValues?): Uri? {
val id = dbHelper.writableDatabase.insert(TABLE_NOTES, null, values)
context?.contentResolver?.notifyChange(uri, null)
return ContentUris.withAppendedId(uri, id)
}
override fun delete(uri: Uri, selection: String?, args: Array<String>?): Int {
val count = dbHelper.writableDatabase.delete(TABLE_NOTES, selection, args)
context?.contentResolver?.notifyChange(uri, null)
return count
}
// getType, update, onCreate সংক্ষিপ্ততার জন্য বাদ দেওয়া হয়েছে
}
প্রোভাইডার ক্লাস তৈরি করার পরে, এটি android:authorities এবং android:exported অ্যাট্রিবিউট সহ ম্যানিফেস্টে নিবন্ধিত হতে হবে (true যদি প্রোভাইডার পাবলিক হয়)। সিস্টেম প্রথম অ্যাক্সেসে প্রোভাইডারের একটি ইনস্ট্যান্স তৈরি করে — এটি UI থ্রেডে ঘটে, তাই onCreate দ্রুত সম্পাদন হতে হবে।
Content Provider দুটি স্তরে ডেটা অ্যাক্সেস পরিচালনা করার অনুমতি দেয়: পড়ার অনুমতি এবং লেখার অনুমতি। এগুলি ম্যানিফেস্টে android:readPermission এবং android:writePermission অ্যাট্রিবিউটের সাথে সেট করা হয়। যদি ক্লায়েন্ট অ্যাপ্লিকেশনের সংশ্লিষ্ট অনুমতি না থাকে, সিস্টেম SecurityException সহ কল প্রত্যাখ্যান করে।
Android FLAG_GRANT_READ_URI_PERMISSION এবং FLAG_GRANT_WRITE_URI_PERMISSION ফ্ল্যাগের মাধ্যমে অস্থায়ী অনুমতি সমর্থন করে। এটি কার্যকর যখন একটি অ্যাপ্লিকেশন Intent-এর মাধ্যমে অন্য অ্যাপ্লিকেশনে একটি ফাইল URI পাঠায় — প্রাপক শুধুমাত্র নির্দিষ্ট URI-তে সীমিত সময়ের জন্য অ্যাক্সেস পায়। গ্রহীতার অ্যাপ্লিকেশন শেষ হওয়ার পরে সিস্টেম অস্থায়ী অনুমতি প্রত্যাহার করে।
সিস্টেম প্রোভাইডারগুলির জন্য, Android অ্যাপ্লিকেশন ম্যানিফেস্টে নির্দিষ্ট অনুমতি উল্লেখ করতে প্রয়োজন। উদাহরণস্বরূপ, কন্টাক্ট অ্যাক্সেস করতে READ_CONTACTS প্রয়োজন, এবং ক্যালেন্ডার অ্যাক্সেস করতে READ_CALENDAR প্রয়োজন। Android 6 থেকে শুরু করে, এই অনুমতিগুলি ইনস্টলেশনের সময় নয় বরং রানটাইমে অনুরোধ করা হয়।
সচরাচর জিজ্ঞাসিত প্রশ্ন
Content Provider হল একটি Android কম্পোনেন্ট যা ContentResolver-এর মাধ্যমে অ্যাপ্লিকেশনের মধ্যে ডেটা আদান-প্রদানের জন্য একটি স্ট্যান্ডার্ড ইন্টারফেস প্রদান করে। এটি স্টোরেজ পদ্ধতি (SQLite, ফাইল, নেটওয়ার্ক) অ্যাবস্ট্রাক্ট করে এবং পড়া ও লেখার অনুমতি নিয়ন্ত্রণ সহ নিরাপদ ডেটা অ্যাক্সেস নিশ্চিত করে।
Authority হল প্রোভাইডারের একটি অনন্য শনাক্তকারী স্ট্রিং যা AndroidManifest.xml-এ নির্দিষ্ট করা হয়। এটি URI content://authority/path-এর প্রথম অংশ গঠন করে এবং সিস্টেম দ্বারা ContentResolver কলগুলিকে সঠিক প্রোভাইডারে রুট করার জন্য ব্যবহৃত হয়। Authority ডিভাইসের সমস্ত অ্যাপ্লিকেশনের মধ্যে অনন্য হতে হবে।
UriMatcher URI-কে সংখ্যাসূচক কোডে ম্যাপ করে। আপনি addURI-এর মাধ্যমে প্যাটার্ন যোগ করেন, তারপর আগত URI-র জন্য কোড পেতে match কল করেন। এটি query, insert, update, delete পদ্ধতিগুলিকে নির্ধারণ করতে দেয় কোন টেবিল বা রেকর্ড অনুরোধ করা হয়েছে এবং ডেটাবেসে সংশ্লিষ্ট অপারেশন সম্পাদন করে।
হ্যাঁ, ব্যবহারের পরে Cursor সর্বদা বন্ধ করতে হবে। Cursor বন্ধ না হলে, মেমরি লিক হয় কারণ এটি প্রোভাইডারের ডেটাতে Binder রেফারেন্স ধারণ করে। Kotlin-এ, স্বয়ংক্রিয় বন্ধের জন্য use ফাংশন ব্যবহার করুন, এবং Java-তে — try-with-resources বা finally ব্লকে cursor.close() ব্যবহার করুন।
Content Provider হল আন্তঃঅ্যাপ্লিকেশন ডেটা অ্যাক্সেসের জন্য একটি কম্পোনেন্ট, যেখানে SQLiteDatabase হল একটি একক অ্যাপ্লিকেশনের জন্য অভ্যন্তরীণ স্টোরেজ মেকানিজম। Content Provider URI ইন্টারফেস এবং অনুমতি নিয়ন্ত্রণ প্রদান করে, যেখানে SQLiteDatabase OS-স্তরের নিরাপত্তা প্রক্রিয়া ছাড়াই সরাসরি ডেটাবেসের সাথে কাজ করে।
সারসংক্ষেপ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন