آموزش Content Provider ها - در برنامه نویسی اندروید

یک مؤلفه Content Providerها، داده‌های یک برنامه را در صورت درخواست به برنامه‌های دیگر ارائه می‌کند. چنین درخواست هایی توسط متدهای کلاس ContentResolver رسیدگی می شود. یک Content Provider می‌تواند از روش‌های مختلفی برای ذخیره داده‌های خود استفاده کند و داده‌ها را می‌توان در یک پایگاه داده، در فایل‌ها یا حتی از طریق شبکه ذخیره کرد.

Android Content Providers

گاهی اوقات لازم است داده ها را در بین برنامه ها به اشتراک بگذارید. اینجاست که Content Providerها بسیار مفید می شوند.

Content Providerها به شما این امکان را می دهند که محتوا را در یک مکان متمرکز کنید و برنامه های مختلفی در صورت نیاز به آن دسترسی داشته باشند. یک Content Providers بسیار شبیه به یک پایگاه داده عمل می‌کند که می‌توانید آن را جستجو کنید، محتوای آن را ویرایش کنید، و همچنین با استفاده از متدهای insert()، update()، delete() و query() محتوا را اضافه یا حذف کنید. در بیشتر موارد این داده ها در پایگاه داده SQlite ذخیره می شوند.

یک Content Providers به‌عنوان یک زیر کلاس از کلاس ContentProvider پیاده‌سازی می‌شود و باید مجموعه استانداردی از APIها را پیاده‌سازی کند که سایر برنامه‌ها را قادر به انجام تراکنش‌ها کند.

public class My Application extends  ContentProvider {
}

Content URIs

برای جستجو در یک Content Provider، متن جستجو را به شکل یک URI مشخص می کنید که فرمت زیر را دارد:

<prefix>://<authority>/<data_type>/<id>

در ادامه جزئیات بخش های مختلف URI را آورده ایم :

قسمت و توضیحات ردیف
prefix

این همیشه روی content:// تنظیم شده است.

1
authority

این نام Content Provider، برای مثال مخاطبین، مرورگر و غیره را مشخص می‌کند. برای Content Providerها شخص ثالث، این نام می‌تواند نام کاملاً واجد شرایط باشد، مانند com.7cloner.statusprovider

2
data_type

این نشان دهنده نوع داده ای است که این Provider خاص ارائه می دهد. برای مثال، اگر همه مخاطبین را از Content Provider مخاطبین دریافت می‌کنید، مسیر داده افراد خواهد بود و URI شبیه به thiscontent://contacts/people خواهد بود.

3
id

این رکورد خاص درخواست شده را مشخص می کند. به عنوان مثال، اگر به دنبال شماره تماس 5 در Content Provider مخاطبین هستید، URI شبیه به این شکل است:

content://contacts/people/5

4

ایجاد Content Provider

این کار شامل چندین مرحله ساده برای ایجاد Content Provider است.

  • اول از همه باید یک کلاس Content Provider ایجاد کنید که کلاس پایه ContentProvider را ارث بری کرده است.
  • دوم، شما باید آدرس URI ارائه دهنده محتوای خود را که برای دسترسی به محتوا استفاده می شود، تعریف کنید.
  • در مرحله بعد باید پایگاه داده خود را برای حفظ محتوا ایجاد کنید. معمولاً اندروید از پایگاه داده SQLite استفاده می کند و فریمورک باید متد onCreate() را override کند که بتواند از متدهای SQLite Open Helper برای ایجاد یا باز کردن پایگاه داده Provider استفاده کند. هنگامی که برنامه شما راه اندازی می شود، کنترل کننده, متد ()onCreate هر یک از ContentProviderها را در Thread اصلی برنامه فراخوانی می کند.
  • حالا باید queryهای Content Provider را برای انجام عملیات های مختلف دیتابیس خاص طراحی کنید.
  • در نهایت با استفاده از تگ <provider>، میتوانید ContentProvider خود را در فایل اکتیویتی خود ثبت کنید.

در اینجا لیستی از متدهایی که باید در کلاس Content Provider بازنویسی (override) کنید تا Content Provider شما کار کند:

  1. onCreate() این متد زمانی فراخوانی می شود که Provider راه اندازی شود.
  2. query() این متد یک درخواست از مشتری دریافت می کند. نتیجه به عنوان یک شی Cursor است.
  3. insert() این متد یک رکورد جدید را در Content Provider وارد می کند.
  4. delete() این متد یک رکورد موجود را از Content Provider حذف می کند.
  5. update() این متد یک رکورد موجود را از Content Provider بروزرسانی می کند.
  6. getType() این متد نوع MIME دادها را در URI اعلامی برمی گرداند.

مثال

این مثال کامل نشان میدهد که چگونه ContentProvider خود را ایجاد کنیم. برای انجام اینکار مراحل زیر را دنبال کنید و اقدام به اجرای برنامه کنید :

توضیحات ردیف
یک پروژه جدید با پکیج نیم دلخواه در اندروید استودیو ایجاد کنید. 1
کدهای فایل MainActivity.java را مطابق کدهای زیر تغییر بدهید. 2
یک فایل جدید بنام StudentsProvider.java ایجاد کنید و کدهای آن را مطابق کدهایی زیر تغییر بدهید. 3
با استفاده از تگ <provider…/>، کلاس ContentProvider خود را در فایل AndroidManifest.xml خود ثبت کنید. 4
کد های فایل activity_main.xml را مطابق کدهای زیر تغییر بدهید. 5
برنامه خود را میتوانید روی یک شبیه ساز و تلفن واقعی تست کنید. 6

فایل MainActivity.java

package com.foray.articlelib;

import android.annotation.SuppressLint;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    public void onClickAddName(View view) {
        // ایجاد یک رکورد دانش آموز جدید
        try {
            ContentValues values = new ContentValues();
            values.put(StudentsProvider.NAME,
                    ((EditText)findViewById(R.id.editText2)).getText().toString());

            values.put(StudentsProvider.GRADE,
                    ((EditText)findViewById(R.id.editText3)).getText().toString());

            Uri uri = getContentResolver().insert(StudentsProvider.CONTENT_URI, values);

            Toast.makeText(getBaseContext(),
                    uri.toString(), Toast.LENGTH_LONG).show();
        }catch (Exception e){
            Log.e("7cloner", e.getMessage());
        }
    }
    @SuppressLint("Range")
    public void onClickRetrieveStudents(View view) {
        // بازیابی یک دانش آموز
        String URL = "content://com.foray.articlelib.StudentsProvider";

        Uri students = Uri.parse(URL);
        Cursor c = getContentResolver().query(students, null, null, null, null);
        if (c.moveToFirst()) {
            do{
                String data = c.getString(c.getColumnIndex(StudentsProvider._ID)) +
                        ", " +  c.getString(c.getColumnIndex( StudentsProvider.NAME)) +
                        ", " + c.getString(c.getColumnIndex( StudentsProvider.GRADE));
                Toast.makeText(this, data, Toast.LENGTH_SHORT).show();
                ((EditText)findViewById(R.id.editText)).setText(data);
            } while (c.moveToNext());
        }
        c.close();
    }


}

کلاس StudentsProvider.java

package com.foray.articlelib;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.text.TextUtils;

import java.util.HashMap;

public class StudentsProvider extends ContentProvider {

    static final String PROVIDER_NAME = "com.foray.articlelib.StudentsProvider";
    static final String URL = "content://" + PROVIDER_NAME + "/students";
    static final Uri CONTENT_URI = Uri.parse(URL);

    static final String _ID = "_id";
    static final String NAME = "name";
    static final String GRADE = "grade";

    private static HashMap<String, String> STUDENTS_PROJECTION_MAP;

    static final int STUDENTS = 1;
    static final int STUDENT_ID = 2;

    static final UriMatcher uriMatcher;
    static{
        uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        uriMatcher.addURI(PROVIDER_NAME, "students", STUDENTS);
        uriMatcher.addURI(PROVIDER_NAME, "students/#", STUDENT_ID);
    }

    /**
     * اعلان های ثابت خاص پایگاه داده
     */

    private SQLiteDatabase db;
    static final String DATABASE_NAME = "College";
    static final String STUDENTS_TABLE_NAME = "students";
    static final int DATABASE_VERSION = 1;
    static final String CREATE_DB_TABLE =
            " CREATE TABLE " + STUDENTS_TABLE_NAME +
                    " (_id INTEGER PRIMARY KEY AUTOINCREMENT, " +
                    " name TEXT NOT NULL, " +
                    " grade TEXT NOT NULL);";

    /**
     * کلاس کمکی که در واقع ایجاد و مدیریت می کند
     * مخزن داده های اساسی ارائه دهنده.
     */

    private static class DatabaseHelper extends SQLiteOpenHelper {
        DatabaseHelper(Context context){
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            db.execSQL(CREATE_DB_TABLE);
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            db.execSQL("DROP TABLE IF EXISTS " +  STUDENTS_TABLE_NAME);
            onCreate(db);
        }
    }

    @Override
    public boolean onCreate() {
        Context context = getContext();
        DatabaseHelper dbHelper = new DatabaseHelper(context);

        /**
         * یک پایگاه داده قادر به نوشتن ایجاد کنید که آن را فعال کند
         * ایجاد اگر از قبل وجود نداشته باشد.
         */

        db = dbHelper.getWritableDatabase();
        return (db == null)? false:true;
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        /**
         * ایجاد یک دانش آموز جدید
         */
        long rowID = db.insert(	STUDENTS_TABLE_NAME, "", values);

        /**
         * اگر رکورد با موفقیت اضافه شود
         */
        if (rowID > 0) {
            Uri _uri = ContentUris.withAppendedId(CONTENT_URI, rowID);
            getContext().getContentResolver().notifyChange(_uri, null);
            return _uri;
        }

        throw new SQLException("خطا در اضافه کردن رکورد : " + uri);
    }

    @Override
    public Cursor query(Uri uri, String[] projection,
                        String selection, String[] selectionArgs, String sortOrder) {
        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
        qb.setTables(STUDENTS_TABLE_NAME);

        switch (uriMatcher.match(uri)) {
            case STUDENTS:
                qb.setProjectionMap(STUDENTS_PROJECTION_MAP);
                break;

            case STUDENT_ID:
                qb.appendWhere( _ID + "=" + uri.getPathSegments().get(1));
                break;

            default:
        }

        if (sortOrder == null || sortOrder == ""){
            /**
             * به طور پیش فرض نام دانش آموزان را مرتب کنید
             */
            sortOrder = NAME;
        }

        Cursor c = qb.query(db,	projection,	selection,
                selectionArgs,null, null, sortOrder);
        /**
         * برای مشاهده URI محتوا برای تغییرات ثبت نام کنید
         */
        c.setNotificationUri(getContext().getContentResolver(), uri);
        return c;
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        int count = 0;
        switch (uriMatcher.match(uri)){
            case STUDENTS:
                count = db.delete(STUDENTS_TABLE_NAME, selection, selectionArgs);
                break;

            case STUDENT_ID:
                String id = uri.getPathSegments().get(1);
                count = db.delete( STUDENTS_TABLE_NAME, _ID +  " = " + id +
                                (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : ""), selectionArgs);
                break;
            default:
                throw new IllegalArgumentException("ناشناس URI " + uri);
        }

        getContext().getContentResolver().notifyChange(uri, null);
        return count;
    }

    @Override
    public int update(Uri uri, ContentValues values,
                      String selection, String[] selectionArgs) {
        int count = 0;
        switch (uriMatcher.match(uri)) {
            case STUDENTS:
                count = db.update(STUDENTS_TABLE_NAME, values, selection, selectionArgs);
                break;

            case STUDENT_ID:
                count = db.update(STUDENTS_TABLE_NAME, values,
                        _ID + " = " + uri.getPathSegments().get(1) +
                                (!TextUtils.isEmpty(selection) ? " AND (" +selection + ')' : ""), selectionArgs);
                break;
            default:
                throw new IllegalArgumentException("ناشناس URI " + uri );
        }

        getContext().getContentResolver().notifyChange(uri, null);
        return count;
    }

    @Override
    public String getType(Uri uri) {
        switch (uriMatcher.match(uri)){
            /**
             * دریافت تمامی رکورد های دانش آموزان
             */
            case STUDENTS:
                return "vnd.android.cursor.dir/vnd.example.students";
            /**
             * دریافت یک دانش آموزش خاص
             */
            case STUDENT_ID:
                return "vnd.android.cursor.item/vnd.example.students";
            default:
                throw new IllegalArgumentException("پشتیبانی نمی شود URI: " + uri);
        }
    }


}

گرافیک فایل activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="32dp">

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:text="Content provider"
        android:textSize="30dp" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/textView1"
        android:layout_centerHorizontal="true"
        android:text="7Cloner.com"
        android:textColor="#009688"
        android:textSize="30dp" />

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="150dp"
        android:id="@+id/imageButton"
        android:src="@drawable/abc"
        android:layout_below="@+id/textView2"
        android:layout_centerHorizontal="true" />

    <EditText
        android:id="@+id/editText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:enabled="false"
        android:layout_below="@id/imageButton"
        android:layout_alignStart="@id/imageButton"
        android:layout_alignEnd="@id/imageButton" />

    <EditText
        android:id="@+id/editText2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/editText"
        android:layout_alignStart="@id/editText"
        android:layout_alignEnd="@id/editText"
        android:hint="نام"
        android:textColorHint="@android:color/holo_blue_light" />

    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/editText3"
        android:layout_below="@id/editText2"
        android:layout_alignStart="@id/editText2"
        android:layout_alignEnd="@id/editText2"
        android:hint="مقطع تحصیلی"
        android:textColorHint="@android:color/holo_blue_bright" />


    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/button2"
        android:text="افزودن دانش آموز"
        android:layout_below="@+id/editText3"
        android:layout_alignEnd="@+id/editText3"
        android:layout_alignStart="@+id/editText3"
        android:onClick="onClickAddName"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="بازیابی دانش آموز"
        android:id="@+id/button"
        android:layout_below="@+id/button2"
        android:layout_alignEnd="@+id/button2"
        android:layout_alignStart="@+id/button2"
        android:onClick="onClickRetrieveStudents"/>
</RelativeLayout>

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.foray.articlelib">

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

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.ArticleLib">

        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <provider android:name=".StudentsProvider"
            android:authorities="com.foray.articlelib.StudentsProvider"
            android:exported="false" />
    </application>

</manifest>

سر آخر بعد از ثبت تمامی تغییرات بالا میتوانید برنامه را اجرا کنید و نتیجه به این صورت خواهد بود :

Android Content Providers Result

در تصویر بالا میتوانید نتیجه کار را ببینید و حالا هر برنامه ای با اجرا دستور بازیابی میتواند اطلاعات مربوط به یک یا چند دانش آموز را از برنامه شما دریافت کند.

دیدگاه‌ها و پرسش‌ها

برای ارسال نظر نیاز است تا ابتدا وارد سایت شوید.

هیچ نظری ارسال نشده است.

قیمت آموزش
رایگان
نوع دسترسی
رایگان

این مقاله در حال حاضر تنها به روش رایگان در دسترس می باشد.

ناصر خالدی
مدرس دوره

ناصر خالدی

مهندس شبکه, امنیت, برنامه نویسی تلفن های هوشمند, طراح وب سایت و متخصص هوش مصنوعی

گفتگوی برنامه نویسان

بخشی برای حل مشکلات برنامه‌نویسی و مباحث پیرامون آن

مقالات پیشنهادی

هک و امنیت

در تعریف کلی این واژه می توان گفت که به پیدا کردن راه های نفوذ به یک حریم شخصی و استفاده غیر مجاز از آن را هک می نامیم. هدف از هک می تواند ...


۹۷۷
۰
۱۳ آذر ۱۳۹۹

نود جی اس

توسعه دهندگان نود جی اس, زبان جاوا اسکریپت را از یک زبان قابل اجرا در مرورگر خارج کرده و به زبانی تبدیل کردن که بتوان آن را بصورت یه اپلیکیشن مستفل اجرا کرد و ...


۹۴۰
۰
۱۲ آذر ۱۳۹۹

وردپرس

وردپرس یک سیستم مدیریت محتوای قوی می باشد که با استفاده از آن می توان وب سایت ها و وبلاگ های گوناگونی با هر شرایطی را طراحی کرد چرا که این سیستم و ...


۸۲۲
۰
۱۳ آذر ۱۳۹۹

پی اچ پی - PHP

با استفاده از این زبان می توان وب سایت های پویا طراحی کرد, این زبان می تواند با HTML ادغام شود, در حقیقت یک زبان اسکریپتی متن باز و رایگان است. یعنی زمانی که سرور درخواست ...


۹۶۶
۰
۱۳ آذر ۱۳۹۹