گروه مقاله : اندروید
تاريخ انتشار : 1396/04/17 - 11:14
كد :7687

ذخیره محتوا در اندروید

در این آموزش به توضیح کامپوننت content provider خواهیم پرداخت ، هدف این آموزش ذخیره و بازیابی محتوا توسط این کامپوننت و استفاده از متد های کوئری برای فراخوانی داده از آن است

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

یک کامپوننت content provider هنگام درخواست، داده ها را از یک نرم افزار به نرم افزار دیگری ارائه میدهد. مانند درخواست های که توسط متد های کلاس ContentResolver  پاسخ داده میشود . یک content provider میتواند راه های مختلفی را بکار بگیرد تا داده ها را گرداوری کند ،این راهکارها مانند ذخیره در بانک داده، ذخیره در فایل و ذخیره در شبکه می باشند.

 

content provider :

برخی اوقات لازم است که داده ها را در میان نرم افزار ها به اشتراک بگزاریم. در این شرایط است که کامپوننت های content provider مفید خواهند بود.

content provider اجازه میدهند که محتوا را در یک مرکز قرار داده و در صورت نیاز به نرم افزار های مختلف اجازه دسترسی به آن را بدهیم. یک content provider خیلی شبیه بانک داده عمل می کند . مخصوصا اینکه شما میتوانید برای آن کوئری تعریف کنید ،شما میتوانید محتوای موجود را ویرایش ، محتوای جدید ایجاد و یا محتوای موجود را حذف کنید. اینکار ها با متد های مانند insert(), update(), delete(),   و  query()اجرا میشوند. در بیشتر مواقع این داده ها در بانک داده SQlite ذخیره شده اند.

یک کامپوننت content provider مانند یک زیر کلاس از کلاس  ContentProvider اجرا میشود و باید با یک استاندارد APIs اجرا شود تا انتقال میان برنامه ها را ممکن سازد.

public class My Application extends  ContentProvider {

}

آدرس محتوا

برای کوئری یک کامپوننت content provider ، شما رشته کوئری را در قالب آدرسی مانند زیر ایجاد خواهید کرد:

<pfix>://<authority>/<data_type>/<id>

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

شماره

قسمت ها و توضیحات

1

pfix

این قسمت همواره به محتوا اعمال میگردد://

2

Authority

این بخش نام content provider را تعیین می کند، برای مثال تماس ها، جستجوگر و غیره ، برای تهیه کنندگان محتوا third-party این بخش میتواند یک نام واجد شرایط مانند com.tutorialspoint.statusprovider باشد.

3

data_type

این بخش نشان دهنده نوع داده است که یک content provider بطور خاص ایجاد می کند. برای مثال ، اگر شما تمام مخاطبان خود را از Contacts content provider مخاطبان بدست بیاورید، سپس مسیر داده ها  شامل کاربران و آدرس صفحه خواهد بود، به این مثال نگاه کنید :  content://contacts/people.

4

Id

این بخش یک رکورد خاص را مشخص خواهد کرد . مثلا اگر شما بدنبال محتوای شماره 5 در Contacts content provider مخاطبین می گردید آدرس شبیه این خواهد بود: content://contacts/people/5

 

ایجاد یک content provider

در این بخش با چند گام ساده برای ایجاد یک content provider آشنا خواهیم شد.

  • اول از همه باید کلاس یک Content Provider را ایجاد کنیم که کلاس ContentProviderbaseclass را کسترش دهد.
  • دوم، شما باید آدرس Content Provider خود را معرفی کنید. این آدرس برای دسترسی به محتوا بکار خواهد رفت.
  • در گام بعد شما باید بانک داده ای را، برای نگهداری از محتوا ایجاد کنید. معمولا اندروید از بانک داده SQLite و فریم ورکی برای بازنویسی متد onCreate() که از متد SQLite Open Helper method برای ایجاد و یا بازکردن provider's database بکار میرود.

وقتی که نرم افزار شما اجرا میشود ، متد onCreate()  برای هر Content Providers  در بخش اصلی نرم افزار فراخواهنی خواهد شد.

 

  • بعد شما باید کوئری Content Providers را برای ایجاد عملگرهای خاص در بانک های داده مختلف اجرا کنید.

· در آخر Content Providers خود را در فایل activity با تگ <provider> ثبت کنید.

در تصویر زیر لیستی از متدهای که شما برای بازنویسی در کلاس Content Provider برای اینکه یک Content Providers بدرستی در نرم افزار شما کار کند را مشاهده می کنید.

 

توضیح جدول متدهای Content Providers

متد onCreate() : این متد زمان ایجاد یک Content Providers فراخوانی میشود.

متد query() : این متد درخواستی را از مشتری دریافت کرده و نتیجه بصورت یک شئی نشانگر Cursor object بازگردانی میشود.

متد insert() : این متد یک رکورد جدید در Content Providers درج می کند.

متد delete() : این متد رکورد موجود را از  Content Provider حذف خواهد کرد

متد update(): این متد رکورد موجود در  Content Provider را ویرایش خواهد کرد.

متد getType() : این متد نوع داده را بر اساس آدرس داده شده بازمیگرداند.

مثال

در این مثال ما توضیح خواهید داد که چگونه یک  Content Provider  را ایجاد کنید :

گام

توضیحات

1

شما اندروید استودیو برای ایجاد یک نرم افزار اندرویدی استفاده خواهید کرد. ما نام این نرم افزار را My Application قرار داده و آن را در زیر شاخه packagecom.example.MyApplication با اکتیویتی خالی قرار میدهیم

2

Activity اصلی فایل MainActivity.java را تغییر دهید تا دو متد جدید onClickAddName() و onClickRetrieveStudents() را اضافه کنید.

3

ایجاد یک فایل جاوا به نام StudentsProvider.java در زیرمجموعه پکیج com.example.MyApplication برای مشخص کردن Content Provider اصلی و متد مرتبط

4

ثبت Content Provider خود در فایل AndroidManifest.xml با استفاده از تگ <provider.../>

5

تغییر محتوای پیشفرض فایل res/layout/activity_main.xml برای اینکه شامل یک رابط گرافیکی کوچک برای افزودن رکورد دانش آموزان باشد.

6

نیازی به تغییر فایل متنی string.xml.Android نیست این فایل توسط خود اندروید استودیو تغییر خواهد کرد.

7

اجرای اپلیکیشن برای اتصال به شبیه ساز اندروید و تائید نتیجه در نرم افزار

 

کد های زیر محتوای تغییر یافته فایل main activity در src/com.example.MyApplication/MainActivity.java میباشند این فایل میتوانید شامل هریک از متد های ساختار چرخه حیات  life cycle  باشد. ما به این کد ها دو متد 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.../> را اضافه کرده ایم. اینکار برای افزودن  Content 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 را نصب کرده اید . برای اجرای نرم افزار یکی از فایل های activity پروژه را بازکرده و روی دکمه Run در نوار ابزار کلیک کنید . اندروید استودیو نرم افزار شما را روی شبیه ساز نصب خواهد کرد. اگر همه چیز هنگام نصب نرم افزار درست پیشرفت پنجره شبیه ساز زیر به نمایش در خواهد آمد . لطفا هنگام انجام اینکار عجله نکنید زیرا ممکن است براساس سرعت کامپیوتر اینکار مدتی زمان ببرد.

 

 

حالا ما یک  name  و یک Grade  را وارد و روی دکمه  Add Name کلیک می کنیم. اینکار یک رکورد مربوط به دانش آموزش را به بانک داده اضافه کرده و یک پیام در زیر شبیه ساز ایجاد خواهد کرد. این پیام آدرس  Content Provider  را با شماره رکورد اضافه شده به بانک داده نشان میدهد. در این عملیات از متد insert() برای افزودن فایل استفاده می شود. اجازه دهید که اینکار را برای افزودن لیستی از سایر دانش آموزان به بانک داده استفاده کنیم.

 

 

بعد از اینکه کار افزودن رکورد به بانک داده به پایان رسید میتوانیم از   Content Provider بخواهیم که این رکورد ها را به ما نشان دهد. برای اینکار روی دکمه Retrieve Students کلیک کنید. اینکار داده های تمام رکورد ها را یکی یکی دریافت کرده و نمایش میدهد ا. ینکار به روش پیاده سازی متد query() بستگی دارد.

شما میتوانید activities  هایی را برای ویرایش و حذف بنویسد. اینکار با فراخوانی عملگر ممکن میشود. این عملگرها در فایل MainActivity.java قرار دارند. سپس ظاهر رابط کاربری را تغییر دهید تا دکمه هایی برای ویرایش و حذف داشته باشید. درست مانند کاری که ما برای افزودن دکمه برای افزودن داده و خواندن داده ها انجام دادیم.

در این روش شما میتوانید از Content Provider استفاده کنید . درست مانند اینکه شما از دفترچه آدرس استفاده می کنید. شما همچنین میتوانید از مفهوم  Content Provider  در توسعه بانک داده استفاده کنید،  چرا که شما میتوانید تمام عملیات یک بانک داده مانند خواندن ، نوشتن ، ویرایش کردن ، حذف کردن را با  Content Provider  انجام دهید. مثال اینکار را در بالا خواندیم.

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

 

نظرات كاربران :