تبادل داده و اطلاعات بین دو اپلیکیشن از طریق 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 دیدگاه