تبادل داده و اطلاعات بین دو اپلیکیشن از طریق Content Provider یا ارایه دهندگان محتوا در اندروید

منتشرشده توسط حامد قنبری در تاریخ

در پلت فرم آندروید، یک برنامه نمی تواند به طور مستقیم به داده های برنامه دیگر دسترسی داشته باشد و تمام اطلاعات یک برنامه  منحصر به خود آن برنامه است و هر برنامه دارای دایرکتوری ،داده های شناسه  دار  و دارای  منطقه حفاظت شده مختص به خود آن برنامه است. این به این معنی است که برنامه نمی تواند دادههای دیگری را از برنامه دیگری را جستجو و یا دستکاری کند. با این حال، اگر می خواهید  برنامه ای را  ایجاد کنید تا داده های برنامه دیگری را جستجو و یا دستکاری کند، باید از Content Providerاستفاده کنید.

 

Content Provider:

Content Providerمطابق با مجموعه استاندارد های رابط  برنامه کاربردی (API) پیاده سازی می شوند. بعبارت دیگر این عمل به عنوان یک رابط کاربری است که به شما امکان ذخیره و بازیابی اطلاعات از یک منبع داده را می دهد. و همچنین به شما امکان می دهد داده های برنامه را با برنامه های دیگر به اشتراک بگذارید.  ارائه دهندگان محتوا لایه برنامه را از لایه داده جدا می کند و با این کار اجازه کنترل کامل  آن را  به سایر برنامه ها می دهد البته به شرطی که  اجزای برنامه یا کاربران دیگر مجوز دسترسی آسان به داده ها را داشته باشند. در نتیجه، هر برنامه با مجوزهای مناسب می تواند داده ها را از برنامه دیگری، از جمله داده های موجود در بعضی پایگاه های بومی آندروید، اضافه، حذف، به روز رسانی و بازیابی کند. Content Provider در عمل بسیار شبیه یک پایگاه داده SQliteاست که در آن شما می توانید آن را فراخوانی کرده، محتوای آن را ویرایش کنید، و همچنین با اضافه کردن یا حذف محتویات با استفاده از متدهای inserter ()، update ()، delete () و query () عملیات مورد نظر خود را در آن اعمال کنید. ارائه دهنده محتوا به عنوان یک کلاس زیر کلاس ContentProvider اجرا می شود و باید یک مجموعه استاندارد از API ها را اجرا کند که سایر برنامه ها را قادر به انجام تبادل داده می کند.

قبل از اینکه مثالی برای عزیزان بزنیم لازم است دو نکته مهم در خصوص نحوه کار کردن با Content Provider  در اختیار دوستان قرار بدهیم:

اول اینکه منبع داده پردازی یا همان دیتابیس  Content Provider دارای آدرس مشخصی است و سایر اپلیکیشن ها بر اساس این آدرس امکان دستیابی به اطلاعات اپلیکیشن  را دارند .  این آدرس اصولاً بر مبنای نام پکیج و آدرس کلاس Provider   و با کلمه://content شروع می شود. برای مثال اجزای اصلی URL این مثال به شکل زیر است.:

String URL = "content://psrd.ir.example.MyProvider/cte";

دوم اینکه به منظور اعمال عملیات های مختلفی همچون inserter ، update ، delete  از کلاس ContentValues  استفاده می کنیم.

ContentValues values = new ContentValues();
values.put(MyProvider.name, YouRname.getText().toString());
values.put(MyProvider.email, emial.getText().toString());
Uri uri = getContentResolver().insert(MyProvider.CONTENT_URI, values);

برای آپدیت کردن نیز بر اساس Id  به شکل زیر عمل خواهیم کرد :

 

ContentValues values = new ContentValues();
values.put(MyProvider.name,name);
values.put(MyProvider.email,email);
int id = 2;
getContentResolver().update(MyProvider.CONTENT_URI,values,MyProvider.id+"=?",new String[] {String.valueOf(id)});

به منظور درک بهتر موضوع مثالی برای دوستان آماده کرده ایم که امیداوریم مفید واقع شده باشد.

اگر در داخل برنامه اکلیپس یا اندروید استودیو قرار دارید پروژه جدیدی را  ایجاد کنید

اکلیپس :File ⇒ New Android ⇒ Application Project

اندروید استودیو :File ⇒ New  ⇒ New Project

اما اگر هنوز برنامه خود را باز نکرده اید یکی از برنامه های فوق را باز نموده و بعد از تعیین مشخصات(نامگذاری) ، تعیین حداقل sdk  و نوع اکتیویتی (blank  یا Empty) ، نام اکتیویتی ابتدایی و اصلی خود  را همان MainActivity قرار دهید. بعد از لود کامل برنامه ، در مسیر res ⇒layout لایه متناظر اکتیوتی اصلی یعنی activity_main را پیدا نمود و کدهای مندرج و پیش فرض آن را پاک کرده و کدهای xml  زیر را به آن اضافه کنید:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


    <Button
        android:text="ذخیره داده ها "
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="232dp"
        android:id="@+id/Save" />

    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:inputType="textPersonName"
        android:ems="10"
        android:layout_alignParentTop="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true"
        android:layout_marginRight="67dp"
        android:layout_marginEnd="67dp"
        android:layout_marginTop="74dp"
        android:id="@+id/editText"
        android:hint="نام شما" />

    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:inputType="textPersonName"
        android:ems="10"
        android:layout_below="@+id/editText"
        android:layout_alignLeft="@+id/editText"
        android:layout_alignStart="@+id/editText"
        android:id="@+id/editText2"
        android:hint="ایمیل شما" />

    <Button
        android:text="فراخوانی داده ها"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/Save"
        android:layout_alignLeft="@+id/Save"
        android:layout_alignStart="@+id/Save"
        android:id="@+id/VerifyData" />
</RelativeLayout>

 

سپس کلاس جدیدی به نام MyProvider.java ایجاد می کنیم. این کلاس حاوی متدهای ساخت ، جایگزینی ، آپدیت ،حذف  داده های مورد نظر ما در اپلیکیش خواهد بود. همانطور که می بینیم نحوه برنامه نویسی این کلاس مشابه ساخت SQLLite  در اندروید است.

package psrd.ir.example;

/**
 * Created by h.ghanbari on 22/01/2018.
 */


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 java.util.HashMap;

public class MyProvider extends ContentProvider {

    static final String PROVIDER_NAME = "psrd.ir.example.MyProvider";
    static final String URL = "content://" + PROVIDER_NAME + "/cte";
    public static final Uri CONTENT_URI = Uri.parse(URL);
    public  static final String id = "id";
    public static final String name = "name";
    public static final String email = "email";
    static final int uriCode = 1;
    static final UriMatcher uriMatcher;
    private static HashMap<String, String> values;
    static {
        uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        uriMatcher.addURI(PROVIDER_NAME, "cte", uriCode);
        uriMatcher.addURI(PROVIDER_NAME, "cte/*", uriCode);
    }

    @Override
    public boolean onCreate() {
        Context context = getContext();
        DatabaseHelper dbHelper = new DatabaseHelper(context);
        db = dbHelper.getWritableDatabase();
        if (db != null) {
            return true;
        }
        return false;
    }

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

        switch (uriMatcher.match(uri)) {
            case uriCode:
                qb.setProjectionMap(values);
                break;
            default:
                throw new IllegalArgumentException("Unknown URI " + uri);
        }
        if (sortOrder == null || sortOrder == "") {
            sortOrder = name;
        }
        Cursor c = qb.query(db, projection, selection, selectionArgs, null,
                null, sortOrder);
        c.setNotificationUri(getContext().getContentResolver(), uri);
        return c;
    }

    @Override
    public String getType(Uri uri) {
        switch (uriMatcher.match(uri)) {
            case uriCode:
                return "vnd.android.cursor.dir/cte";

            default:
                throw new IllegalArgumentException("Unsupported URI: " + uri);
        }
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        long rowID = db.insert(TABLE_NAME, "", values);
        if (rowID > 0) {
            Uri _uri = ContentUris.withAppendedId(CONTENT_URI, rowID);
            getContext().getContentResolver().notifyChange(_uri, null);
            return _uri;
        }
        throw new SQLException("Failed to add a record into " + uri);
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        int count = 0;
        switch (uriMatcher.match(uri)) {
            case uriCode:
                count = db.delete(TABLE_NAME, selection, selectionArgs);
                break;
            default:
                throw new IllegalArgumentException("Unknown 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 uriCode:
                count = db.update(TABLE_NAME, values, selection, selectionArgs);
                break;
            default:
                throw new IllegalArgumentException("Unknown URI " + uri);
        }
        getContext().getContentResolver().notifyChange(uri, null);
        return count;
    }

    private SQLiteDatabase db;
    static final String DATABASE_NAME = "mydb";
    static final String TABLE_NAME = "names";
    static final int DATABASE_VERSION = 1;
    static final String CREATE_DB_TABLE = " CREATE TABLE " + TABLE_NAME
            + " (id INTEGER PRIMARY KEY AUTOINCREMENT, "
            + " name TEXT NOT NULL,"
            + " email 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 " + TABLE_NAME);
            onCreate(db);
        }
    }
}

 

سپس کلاس MainActivity.java  را باز کرده ابتدا ویوهای مورد نظر خود در لایوت را برای کلاس تعریف می کنیم و سپس براساس داده های ورودی قرار است عملیات مربوط به ذخیره داده ها و همچنین نحوه فراخوانی آنها را در صورت درخواست کاربر انجام دهیم.

package psrd.ir.example;

import android.app.AlertDialog;
import android.content.ContentValues;
import android.content.DialogInterface;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class Main2Activity extends AppCompatActivity {

    public String valuecontent;
    public String InputName , InputEmail;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

     final  EditText yourname = (EditText)findViewById(R.id.editText);
        final EditText youremial = (EditText)findViewById(R.id.editText2);
      final  Button save = (Button)findViewById(R.id.Save);
        Button verifydata = (Button)findViewById(R.id.VerifyData);
        save.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                InputName = yourname.getText().toString();
                InputEmail = youremial.getText().toString();

                if ( !InputEmail.isEmpty()&& !InputName.isEmpty()) {
                    ContentValues values = new ContentValues();
                    values.put(MyProvider.name, InputName);
                    values.put(MyProvider.email,InputEmail);
                    Uri uri = getContentResolver().insert(MyProvider.CONTENT_URI, values);
                    Toast.makeText(getApplicationContext(), "ذخیره شده",Toast.LENGTH_LONG).show();

                }else{
                    AlertDialog.Builder alertDialog = new AlertDialog.Builder(
                            Main2Activity.this);
                    alertDialog.setTitle("هشدار");
                    alertDialog.setMessage("لطفا نام و ایمیل خود را وارد کنید");
                    alertDialog.setPositiveButton("خوب",
                            new DialogInterface.OnClickListener() {
                                public void onClick(DialogInterface dialog, int which) {
                                    dialog.cancel();
                                }
                            });


                    alertDialog.show();

                }
            }
        });

        verifydata.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                try {
                    String URL = "content://psrd.ir.example.MyProvider/cte";
                    Uri students = Uri.parse(URL);
                    Cursor c = managedQuery(students, null, null, null, "name");

                    if (c.moveToFirst()) {
                        do {
                            valuecontent = c.getString(c.getColumnIndex(MyProvider.id)) +
                                    ", " + c.getString(c.getColumnIndex(MyProvider.name)) +
                                    ", " + c.getString(c.getColumnIndex(MyProvider.email));
                            Toast.makeText(Main2Activity.this, valuecontent, Toast.LENGTH_SHORT).show();
                        } while (c.moveToNext());
                    }
                    if (valuecontent == null){
                        Toast.makeText(getApplicationContext(), "داده ای ذخیره نشده است",Toast.LENGTH_LONG).show();

                    }

                }catch (Exception e){
                    e.printStackTrace();
                }



            }
        });

    }

}

لازم است به منظور میسر شدن ارتباط داده ها بین دو اپلیکیشن در قسمت مربوط به Androidmanfest.xml  مجوز لازم به اپلیکیشن تعریف شود. از این مجوز زیر در فایل مذکور به شکل زیر تعریف می کنیم:

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

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

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:label="@string/title_activity_main2"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <provider
            android:authorities="psrd.ir.example.MyProvider"
            android:name=".MyProvider"
            android:exported="true"
            android:multiprocess="true" >

        </provider>
    </application>

</manifest>

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

کپی برداری از محتوای سایت psrd، ممنوع بوده و پیگرد قانونی دارد. (تنها استفاده شخصی کاربران ، مجاز است) (کپی برداری توسط سایر وب سایت ها  غیرقانونی بوده و در صورت رویت به ستادسازماندهی اطلاع داده خواهد شد.

 


0 دیدگاه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

-- بارگیری کد امنیتی --