Content Provider — είναι ένα component του Android που παρέχει μια ενοποιημένη διεπαφή για πρόσβαση σε δεδομένα μεταξύ εφαρμογών. Αφαιρεί τη φυσική αποθήκευση (SQLite, αρχεία, πηγές δικτύου) και εξασφαλίζει ασφαλή ανταλλαγή πληροφοριών μέσω του ContentResolver. Σύμφωνα με τον Android Developer Guide, 2026, το Content Provider είναι ένα από τα τέσσερα βασικά components μιας εφαρμογής Android, μαζί με τα Activity, Service και BroadcastReceiver. Καθήκον του είναι να καθιστά τα δεδομένα διαθέσιμα σε άλλες εφαρμογές με έλεγχο δικαιωμάτων ανάγνωσης και εγγραφής.
Κύρια σημεία
Content Provider — είναι ένα component Android που διαχειρίζεται την πρόσβαση σε μια κεντρική αποθήκη δεδομένων και τα παρέχει σε άλλες εφαρμογές μέσω μιας ενοποιημένης συμβατικής διεπαφής. Κρύβει τις λεπτομέρειες υλοποίησης της αποθήκευσης: τα δεδομένα μπορούν να αποθηκευτούν σε SQLite, στο σύστημα αρχείων, στο cloud ή να είναι αποτέλεσμα μιας αίτησης δικτύου.
Το Android περιλαμβάνει ενσωματωμένους Content Provider για δεδομένα συστήματος — ContactsContract, MediaStore, CalendarContract, CallLog. Οι εφαρμογές τρίτων μπορούν επίσης να δημιουργήσουν τους δικούς τους παρόχους για ασφαλή ανταλλαγή δεδομένων. Κάθε πάροχος καταχωρείται στο AndroidManifest.xml με καθορισμό του authority — μιας μοναδικής συμβολοσειράς που αποτελεί το πρώτο μέρος του URI.
Το Content Provider λειτουργεί σύμφωνα με το μοντέλο πελάτη-εξυπηρετητή. Ο πάροχος λειτουργεί ως εξυπηρετητής που υλοποιεί έξι υποχρεωτικές μεθόδους: query, insert, update, delete, getType και onCreate. Ο πελάτης (άλλη εφαρμογή) έχει πρόσβαση στον πάροχο μέσω του ContentResolver, ο οποίος μεταβιβάζει τις κλήσεις στις αντίστοιχες μεθόδους του παρόχου μέσω του μηχανισμού IPC του Android.
Κάθε Content Provider αναγνωρίζεται από ένα URI του σχήματος content://. Για παράδειγμα, content://com.example.app.provider/items. Το πρώτο μέρος authority (com.example.app.provider) συνδέεται με την κλάση του παρόχου στο manifest. Η διαδρομή /items υποδεικνύει έναν πίνακα, και /items/5 — μια συγκεκριμένη εγγραφή με ID=5.
Όταν μια εφαρμογή καλεί ContentResolver.query(URI), το Android ελέγχει τα δικαιώματα του καλούντος πακέτου, βρίσκει τον πάροχο μέσω του authority και εκκινεί τη διαδικασία του αν δεν είναι ήδη σε λειτουργία. Ο πάροχος εκτελεί το ερώτημα και επιστρέφει ένα Cursor — ένα αντικείμενο που περιέχει το αποτέλεσμα και επιτρέπει στον πελάτη να κάνει επανάληψη στις εγγραφές.
Η κλάση ContentProvider απαιτεί την υλοποίηση έξι αφηρημένων μεθόδων. Κάθε μέθοδος λαμβάνει ένα URI και επιστρέφει ένα αποτέλεσμα που αντιστοιχεί στον τύπο λειτουργίας. Το σύστημα καλεί αυτές τις μεθόδους από οποιαδήποτε διεργασία, επομένως πρέπει να είναι thread-safe και να μην μπλοκάρουν την εκτέλεση για μεγάλο χρονικό διάστημα.
Η μέθοδος query λαμβάνει ένα URI, έναν πίνακα στηλών projection, μια συμβολοσειρά selection με ορίσματα και τη σειρά ταξινόμησης. Επιστρέφει ένα Cursor με δεδομένα. Στην υλοποίηση, το URI πρέπει να αναλυθεί με το UriMatcher και να εκτελεστεί το αντίστοιχο ερώτημα SQL στη βάση δεδομένων.
Αυτές οι μέθοδοι τροποποιούν τα δεδομένα στην αποθήκη. Η insert λαμβάνει ContentValues — ζεύγη κλειδιού-τιμής — και επιστρέφει το URI της νέας εγγραφής. Οι update και delete λαμβάνουν selection για φιλτράρισμα εγγραφών και επιστρέφουν τον αριθμό των επηρεαζόμενων γραμμών. Μετά την τροποποίηση δεδομένων, ο πάροχος πρέπει να ειδοποιήσει μέσω του ContentResolver.notifyChange.
| Μέθοδος | Σκοπός | Επιστροφή |
|---|---|---|
| query | Λήψη δεδομένων βάσει URI | Cursor ή null |
| insert | Προσθήκη νέας εγγραφής | URI νέας εγγραφής |
| update | Ενημέρωση υπαρχουσών εγγραφών | int (αριθμός γραμμών) |
| delete | Διαγραφή εγγραφών | int (αριθμός γραμμών) |
| getType | Τύπος MIME για URI | String |
| onCreate | Αρχικοποίηση παρόχου | boolean |
ContentResolver — είναι ένα ενιαίο σημείο πρόσβασης για εργασία με όλους τους Content Provider στο σύστημα. Η εφαρμογή-πελάτης ποτέ δεν καλεί απευθείας τις μεθόδους του παρόχου — μόνο μέσω του ContentResolver, τον οποίο το Android λαμβάνει από το context. Οι CRUD λειτουργίες στο ContentResolver έχουν τα ίδια ονόματα όπως στον πάροχο, αλλά λαμβάνουν 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 pool. Για σενάρια UI, χρησιμοποιήστε CursorLoader ή Room με LiveData/Flow.
Η δημιουργία του δικού σας Content Provider ξεκινά με κληρονομικότητα από την κλάση ContentProvider. Ο πάροχος λειτουργεί με βάση δεδομένων SQLite μέσω του SQLiteOpenHelper και χρησιμοποιεί το UriMatcher για τον καθορισμό του τύπου ερωτήματος. Ας εξετάσουμε μια ελάχιστη υλοποίηση για τη διαχείριση μιας λίστας σημειώσεων.
Ο πάροχος καταχωρείται στο AndroidManifest.xml εντός του tag 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 παραλείπονται για συντομία
}
Μετά τη δημιουργία της κλάσης, ο πάροχος πρέπει να καταχωρηθεί στο manifest με τα χαρακτηριστικά android:authorities και android:exported (true εάν ο πάροχος είναι δημόσιος). Το σύστημα δημιουργεί ένα στιγμιότυπο του παρόχου κατά την πρώτη πρόσβαση — αυτό συμβαίνει στο νήμα UI, επομένως το onCreate πρέπει να εκτελείται γρήγορα.
Το Content Provider επιτρέπει τη διαχείριση πρόσβασης σε δεδομένα σε δύο επίπεδα: δικαιώματα ανάγνωσης και δικαιώματα εγγραφής. Αυτά ορίζονται στο manifest με τα χαρακτηριστικά android:readPermission και android:writePermission. Εάν η εφαρμογή-πελάτης δεν έχει το αντίστοιχο δικαίωμα, το σύστημα θα απορρίψει την κλήση με SecurityException.
Το Android υποστηρίζει προσωρινά δικαιώματα μέσω των σημαιών FLAG_GRANT_READ_URI_PERMISSION και FLAG_GRANT_WRITE_URI_PERMISSION. Αυτό είναι χρήσιμο όταν μια εφαρμογή μεταδίδει το URI ενός αρχείου σε άλλη εφαρμογή μέσω Intent — ο παραλήπτης αποκτά πρόσβαση μόνο στο συγκεκριμένο URI για περιορισμένο χρόνο. Το σύστημα ανακαλεί το προσωρινό δικαίωμα μετά την ολοκλήρωση της εφαρμογής παραλήπτη.
Για τους παρόχους συστήματος, το Android απαιτεί τον καθορισμό συγκεκριμένων δικαιωμάτων στο manifest της εφαρμογής. Για παράδειγμα, για πρόσβαση σε επαφές απαιτείται READ_CONTACTS, για ημερολόγιο — READ_CALENDAR. Από το Android 6, αυτά τα δικαιώματα ζητούνται κατά την εκτέλεση, όχι κατά την εγκατάσταση.
Συχνές Ερωτήσεις
Content Provider — είναι ένα component Android που παρέχει μια τυπική διεπαφή για ανταλλαγή δεδομένων μεταξύ εφαρμογών μέσω του ContentResolver. Αφαιρεί τον τρόπο αποθήκευσης (SQLite, αρχεία, δίκτυο) και παρέχει ασφαλή πρόσβαση σε δεδομένα με έλεγχο δικαιωμάτων ανάγνωσης και εγγραφής.
Authority — είναι μια μοναδική συμβολοσειρά αναγνωριστικού του παρόχου που ορίζεται στο AndroidManifest.xml. Αποτελεί το πρώτο μέρος του URI content://authority/path και χρησιμοποιείται από το σύστημα για τη δρομολόγηση κλήσεων του ContentResolver στον κατάλληλο πάροχο. Το authority πρέπει να είναι μοναδικό μεταξύ όλων των εφαρμογών στη συσκευή.
UriMatcher αντιστοιχίζει URI με αριθμητικούς κωδικούς. Προσθέτετε μοτίβα μέσω του addURI και στη συνέχεια καλείτε το match για να λάβετε τον κωδικό για ένα εισερχόμενο URI. Αυτό επιτρέπει στις μεθόδους query, insert, update, delete να καθορίζουν ποιος πίνακας ή εγγραφή ζητήθηκε και να εκτελούν την αντίστοιχη λειτουργία στη βάση δεδομένων.
Ναι, το Cursor πρέπει να κλείνεται μετά τη χρήση. Εάν το Cursor δεν κλείσει, θα προκύψει διαρροή μνήμης, καθώς διατηρεί μια αναφορά Binder στα δεδομένα του παρόχου. Στο Kotlin, χρησιμοποιήστε τη συνάρτηση use για αυτόματο κλείσιμο, και στην Java — try-with-resources ή κλήση cursor.close() σε finally.
Content Provider — είναι ένα component για πρόσβαση σε δεδομένα μεταξύ εφαρμογών, ενώ η SQLiteDatabase είναι εσωτερική αποθήκευση μιας εφαρμογής. Το Content Provider παρέχει διεπαφή URI και έλεγχο δικαιωμάτων, ενώ η SQLiteDatabase λειτουργεί απευθείας με τη βάση δεδομένων χωρίς μηχανισμούς ασφαλείας σε επίπεδο λειτουργικού συστήματος.
Σύνοψη
Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση
Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.
Διαβάστε επίσης