آموزش برنامه نویسی اندروید- ارائه دهنده ی محتوا

  • توسط king2
  • یکشنبه , ۲۳ مهر ۱۳۹۶
  • 229 بازدید
  • 0

ارائه دهنده ی محتوا

ارائه دهنده ی محتوا ، داده ها را از یک برنامه به دیگر برنامه ها در صورت درخواست عرضه می کند. این درخواست توسط کلاس ContentResolver انجام می شود. یک ارائه دهنده ی محتوا می تواند با استفاده از راه های مختلفی داده های خودش را ذخیره کند؛ و داده ها می توانند در یک پایگاه داده، یک فایل و حتی روی شبکه ذخیره شوند.

ارائه دهنده ی محتوا

گاهی لازم است که داده ها را در میان برنامه ها به اشتراک بگذاریم. که در این مواقع ارائه دهنده های محتوا بسیار مفید هستند.

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

یک ارائه دهنده ی محتوا برای این که بتواند با سایر برنامه ها تراکنش انجام دهد باید مطابق با مجموعه استاندارد های رابط برنامه های کاربردی (APIs)  و به عنوان یک زیر کلاس از ContentProvider پیاده سازی شود.

public class My Application extends  ContentProvider {
}

مطلب پیشنهادی: سازماندهی و دسترسی به منابع اندروید

 

Content URIs

برای جستجو در یک ارائه دهنده ی محتوا باید از یک دستور پرس و جوی رشته ای در فرم URI مطابق با ساختار زیر استفاده کنیم:

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

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

قسمت ها با توضیحات
۱ prefix

همیشه مقدار content//: می باشد.

۲ authority

مشخص کننده ی نام ارائه دهنده ی محتوا است. به عنوان مثال مخاطبین، مرورگر و …

۳ data_type

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

۴ id

مشخص کننده ی رکوردی (record) است که درخواست شده. به عنوان مثال اگر شما ارائه دهنده ی محتوای اطلاعات تماس را برای پیدا کردن مخاطبی که شناسه ی آن ۵ است ، مورد جستجو قرار دهید URI ی شما شبیه content://contacts/people/5 خواهد بود.

 

ساختن ارائه دهنده محتوا

مراحل زیر شامل گام های ساده، برای ایجاد یک ارائه دهنده ی محتوا می شود.

  • قبل از همه لازم است یک کلاس ارائه دهنده ی محتوا که برگرفته از کلاس ContentProviderbaseclass است را بسازیم.
  • در مرحله ی بعد شما باید آدرس URIی ارائه دهنده ی محتوا، که برای دسترسی به محتوا مورد استفاده قرار خواهد گرفت را تعریف کنید.
  • بعد از این ها لازم است پایگاه داده ی خودتان را برای نگهداری محتوا بسازید. معمولا اندروید از پایگاه داده ی SQLite استفاده می کند و با توجه به اینکه SQLite از متدهای Open Helper برای ساختن یا ارتباط با یک ارائه دهنده ی پایگاه داده استفاده می کند، لازم است فریم ورک متد onCreate() مورد استفاده قرار بگیرد. هنگامی که نرم افزار شما اجرا می شود متد onCreate() تمام ارائه دهنده های محتوایی را که در نخ اصلی برنامه فراخوانی کرده اید کنترل و اجرا می کند.
  • در گام بعد شما باید دستور های پرس و جوی ارائه دهنده ی محتوا را برای انجام عملیات های مختلف با پایگاه داده پیاده سازی کنید.
  • و در نهایت با استفاده از تگ <provider> ارائه دهنده ی محتوا را در فایل activity  ثبت کنید.

برای کار کردن ارائه دهنده ی محتوا، نیاز داریم در کلاس آن از چند متد استفاده کنیم که لیست آن ها در زیر آورده شده است:

ارائه دهنده ی محتوا

  • ()onCreate این متد زمانی شروع می شود که ارائه دهنده شروع می شود.
  • ()query یک دستور پرس و جو را از طرف کلاینت دریافت می کند و نتیجه به عنوان یک Cursorبرگشت داده خواهد شد.
  • ()insert این متد یک رکورد جدید را در ارائه دهنده محتوا قرار می دهد.
  • ()delete این متد یک رکورد موجود را از ارائه دهنده محتوا را حذف می کند.
  • ()update این متد یک رکورد موجود را از ارائه دهنده محتوا به روز رسانی می کند.
  • ()getType این متد نوع MIMEداده را در یک URIبر می گرداند.

مثال

این مثال نحوه ی ایجاد یک ContentProvider را توضیح میدهد. بنابراین مراحل زیر را دنبال کنید همانند آنچه در هنگام ایجاد مثال Hello World انجام دادیم.

مرحله توضیحات
۱ با استفاده از Android StudioIDE یک برنامه اندروید جدید با نام My Application تحت بسته com.example.MyApplication ایجاد کنید
۲ به فایل اکتیویتی اصلی MainActivity.java  دو متد onClickAddName() و onClickRetrieveStudents()  اضافه کنید.
۳ یک فایل جاوا جدید به نام StudentsProvider.java تحت بسته com.example.MyApplication برای تعریف ارائه دهنده و متدهای های ارتباطی آن ایجاد کنید.
۴ ارائه دهنده ی محتوا را با استفاده از تگ <provider…/> در فایل AndroidManifest.xml ثبت کنید.
۵ محتوای پیش فرض res/layout/activity_main.xml را  با اضافه کردن یک GUI کوچک برای افزودن سوابق دانش آموزان تغییر دهید.
۶ نیازی به تغییر string.xml نیست.
۷ برنامه را با شبیه ساز دستگاه اندروید اجرا کنید و تغییرات حاصل را بررسی نمایید.

در زیر محتوای تغییر یافته ی فایل src/com.example.MyApplication/MainActivity.java وجود دارد. این فایل می تواند در بر گیرنده ی هر کدام از متد های اساسی چرخه حیات باشد. ما دو متد onClickAddName() و onClickRetrieveStudents() را که مسئول رسیدگی به تعامل کاربر با نرم افزار هستند را به فایل افزوده ایم.

package com.example.MyApplication;
import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.content.ContentValues;
import android.content.CursorLoader;
import android.database.Cursor;
import android.view.Menu;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void onClickAddName(View view) {
// Add a new student record
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();
}
public void onClickRetrieveStudents(View view) {
// Retrieve student records
String URL = "content://com.example.MyApplication.StudentsProvider";
Uri students = Uri.parse(URL);
Cursor c = managedQuery(students, null, null, null, "name");
if (c.moveToFirst()) {
do{
Toast.makeText(this,
c.getString(c.getColumnIndex(StudentsProvider._ID)) +
", " +  c.getString(c.getColumnIndex( StudentsProvider.NAME)) +
", " + c.getString(c.getColumnIndex( StudentsProvider.GRADE)),
Toast.LENGTH_SHORT).show();
} while (c.moveToNext());
}
}
}

فایل جدید StudentsProvider.java در زیر شاخه com.example.MyApplication و زیر محتویات src/ com.example.MyApplication/StudentsProvider.java ایجاد کنید.

package com.example.MyApplication;
import java.util.HashMap;
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;
public class StudentsProvider extends ContentProvider {
static final String PROVIDER_NAME = "com.example.MyApplication.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);
}
/**
* Database specific constant declarations
*/
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);";
/**
* Helper class that actually creates and manages
* the provider's underlying data repository.
*/
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);
/**
* Create a write able database which will trigger its
* creation if it doesn't already exist.
*/
db = dbHelper.getWritableDatabase();
return (db == null)? false:true;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
/**
* Add a new student record
*/
long rowID = db.insert(	STUDENTS_TABLE_NAME, "", values);
/**
* If record is added successfully
*/
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 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 == ""){
/**
* By default sort on student names
*/
sortOrder = NAME;
}
Cursor c = qb.query(db,	projection,	selection, 
selectionArgs,null, null, sortOrder);
/**
* register to watch a content URI for changes
*/
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("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 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("Unknown URI " + uri );
}
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
@Override
public String getType(Uri uri) {
switch (uriMatcher.match(uri)){
/**
* Get all student records
*/
case STUDENTS:
return "vnd.android.cursor.dir/vnd.example.students";
/**
* Get a particular student
*/
case STUDENT_ID:
return "vnd.android.cursor.item/vnd.example.students";
default:
throw new IllegalArgumentException("Unsupported URI: " + uri);
}
}
}

محتویات تغییر یافته ی AndroidManifest.xml در زیر آمده است. که در آن با استفاده از تگ <provider…/> ارائه دهنده محتوا را ثبت کرده ایم.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.MyApplication">
<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">
<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.example.MyApplication.StudentsProvider"/>
</application>
</manifest>

و در ادامه محتویات فایل res/layout/activity_main.xml آمده است.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.MyApplication.MainActivity">
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Content provider"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:textSize="30dp" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Tutorials point "
android:textColor="#ff87ff09"
android:textSize="30dp"
android:layout_below="@+id/textView1"
android:layout_centerHorizontal="true" />
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/imageButton"
android:src="@drawable/abc"
android:layout_below="@+id/textView2"
android:layout_centerHorizontal="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/button2"
android:text="Add Name"
android:layout_below="@+id/editText3"
android:layout_alignRight="@+id/textView2"
android:layout_alignEnd="@+id/textView2"
android:layout_alignLeft="@+id/textView2"
android:layout_alignStart="@+id/textView2"
android:onClick="onClickAddName"/>
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/editText"
android:layout_below="@+id/imageButton"
android:layout_alignRight="@+id/imageButton"
android:layout_alignEnd="@+id/imageButton" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/editText2"
android:layout_alignTop="@+id/editText"
android:layout_alignLeft="@+id/textView1"
android:layout_alignStart="@+id/textView1"
android:layout_alignRight="@+id/textView1"
android:layout_alignEnd="@+id/textView1"
android:hint="Name"
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/editText"
android:layout_alignLeft="@+id/editText2"
android:layout_alignStart="@+id/editText2"
android:layout_alignRight="@+id/editText2"
android:layout_alignEnd="@+id/editText2"
android:hint="Grade"
android:textColorHint="@android:color/holo_blue_bright" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Retrive student"
android:id="@+id/button"
android:layout_below="@+id/button2"
android:layout_alignRight="@+id/editText3"
android:layout_alignEnd="@+id/editText3"
android:layout_alignLeft="@+id/button2"
android:layout_alignStart="@+id/button2"
android:onClick="onClickRetrieveStudents"/>
</RelativeLayout>

اطمینان حاصل کنید محتویات فایل res/values/strings.xml همانند زیر است:

<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">My Application</string>
</resources>;

حالا برنامه ی تغییر یافته ی My Application را که ایجاد کرده ایم را اجرا کنید. فرض می کنیم AVD را در حین انجام تنظیمات ایجاد کرده اید. برای اجرای برنامه از Android Studio IDE یکی از فایل های activity  پروژه را باز کنید و از نوار ابزار بر روی آیکون اجرا  کلیک کنید. Android Studioاین برنامه را در AVD خود نصب و اجرا می کند و اگر همه تنظیمات و برنامه شما بدون مشکل باشد، پنجره ی شبیه ساز را نشان می دهد. براساس قدرت سخت افزاری دستگاه شما مقداری طول می کشد.

ارائه دهنده ی محتوا

حالا نام دانش آموز و کلاس آن را وارد کنید و در نهایت بر روی دکمه Add Name کلیک کنید. این کار اطلاعات دانش آموز را در پایگاه داده اضافه می کند و یک پیام در پایین صفحه، URI  را به همراه شناسه ی رکورد ثبت شده در پایگاه داده را نمایش خواهد داد . این عملیات از متد insert() استفاده می کند. بگذارید این روند را برای اضافه کردن چند دانش آموز بیشتر در پایگاه داده تکرار کنیم.

ارائه دهنده ی محتوا

بعد از این که چند رکورد را در پایگاه داده ثبت کردید نوبت به آن می رسد تا فیلد ها را از ارائه دهنده ی محتوا مورد بازیابی قرار دهیم. برای این منظور روی دکمه ی Retrieve Students کلیک کنید. این فعالیت با توجه به آنچه ما در متد query() پیاده سازی کرده ایم انجام می شود.

شما می توانید activities حذف و بروز رسانی را با ارائه توابع در فایل MainActivity.java بنویسیدهمان گونه که ما اکتیویتی های افزودن و بازیابی رکورد را پیاده سازی کردیم.

همچنین شما با همین روش می توانید از ارائه دهنده های موجود محتوا، مانند Address Book استفاده کنید یا با به کار گیری مفاهیم ارائه دهنده ی محتوا یک پایگاه داده مطلوب بسازید و با استفاده از تمام عملیات های قابل اجرا روی یک پایگاه داده مانند خواندن و نوشتن، یک نرم افزار پویا ایجاد کنید.

منبع: tutorialspoint

  • facebook
  • googleplus
  • twitter
  • linkedin
  • linkedin
قبلی «
بعدی »

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

تازه های طراحی سایت

بهینه سازی وبسایت

دانستی های سایت