Latest web development tutorials

مزود المحتوى الروبوت (موفر المحتوى)

مزود المحتوى عن طريق طلب عنصر يوفر بيانات من تطبيق إلى تطبيق آخر. هذه الطلبات بالمناسبة الطبقة ContentResolver للتعامل معها. يمكن لمزودي المحتوى استخدام طرق مختلفة لتخزين البيانات. ويمكن تخزين البيانات في قاعدة بيانات، ملف، أو حتى شبكة.

صور

أحيانا الحاجة لتبادل البيانات بين التطبيقات. في هذه الحالة يصبح مزود محتوى مفيد جدا.

يمكن لمزودي المحتوى جعل تركيز المحتوى، يمكن أن يكون هناك عدد من التطبيقات المختلفة للوصول، إذا لزم الأمر. موفري المحتوى وأعمال مثل قاعدة بيانات. يمكنك الاستعلام، تعديل محتواه، استخدم إدراج ()، التحديث ()، حذف () والاستعلام () لإضافة أو حذف المحتوى. في معظم الحالات يتم تخزين البيانات في قاعدة بيانات SQLite.

ويتم تنفيذ مزود محتوى المقرر بناء على فئة فرعية من فئة فئة ContentProvider. نحن بحاجة إلى تنفيذ سلسلة من API القياسية، لذلك التطبيقات الأخرى لتنفيذ الصفقة.

public class MyApplication extends  ContentProvider {

}

المحتوى URI

الاستعلام عن مزود المحتوى، تحتاج إلى أن يكون في شكل الشكل التالي لتحديد سلسلة الاستعلام URI:

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

وفيما يلي وصفا محددا من كل جزء من URI:

قسم تفسير
بادئة بادئة: تم تعيين كمحتوى: //
سلطان إذن: تحديد اسم مزود المحتوى، مثل الأسماء، ومتصفح، الخ قد يكون موفري المحتوى طرف ثالث اسم كامل، مثل: cn.programmer.statusprovider
DATA_TYPE نوع البيانات: هذا يشير إلى أن هذا نوع معين من مزود محتوى البيانات. على سبيل المثال: أنت تريد أن تقدم من قبل مزود المحتوى للحصول على كل دفتر العناوين اتصالات، مسار البيانات هو الشعب، ثم سوف URI تبدو على النحو التالي: المحتوى: // اتصالات / الناس
الهوية هذا الطلب تحديد سجل معين. على سبيل المثال: يمكنك تقديم مزود محتوى اتصالات البحث عن رقم الاتصال هو 5، ثم URI يبدو مثل هذا: المحتوى: // اتصالات / الناس / 5

إنشاء مزود المحتوى

خطوات بسيطة وصفها هنا مقدمي الخدمات لخلق المحتوى الخاص بهم.

  • أولا، تحتاج إلى إنشاء فئة مشتقة ContentProviderbase الطبقة مزود المحتوى.
  • ثانيا، تحتاج إلى تعريف المحتوى الخاص بك للوصول إلى مزود المحتوى عنوان URI.
  • بعد ذلك، تحتاج إلى إنشاء قاعدة بيانات لتخزين المحتوى. عادة، يستخدم الروبوت قاعدة بيانات SQLite وتجاوز OnCreate الخاص () طريقة استخدامها في إطار طريقة SQLiteOpenHelper لإنشاء أو فتح مزود قاعدة البيانات. عند بدء التطبيق الخاص بك، وسوف يطلق منهجه كل موفر المحتوى OnCreate الخاص () في موضوع التطبيق الرئيسي.
  • وأخيرا، استخدم <مزود ... /> العلامة مسجلة في AndroidManifest.xml مزود المحتوى.

وفيما يلي موفر المحتوى للحصول على العمل الخاص بك، فإنك تحتاج إلى بعض الأسلوب في إعادة صياغة الطبقة ContentProvider:

صور

  • OnCreate الخاص (): دعا عند بدء الموفر.
  • الاستعلام (): هذه الطريقة يقبل الطلبات من العميل. والنتيجة هي عودة مؤشر (المؤشر) الكائن.
  • إدراج (): مقدمي هذا المحتوى طريقة لإدراج سجل جديد.
  • حذف (): يتم حذف هذا الأسلوب من مزود محتوى في السجل الحالي.
  • التحديث (): تحديث هذا الأسلوب مزود المحتوى في السجل الحالي.
  • getType (): هذا الأسلوب بإرجاع نظرا URI نوع الفوقية.

أمثلة

يوضح هذا المثال كيفية إنشاء مزود المحتوى الخاص بك. دعونا اتبع الخطوات التالية:

خطوة وصف
1 إنشاء تطبيقات الروبوت باستخدام الروبوت ستوديو اسمه مزود المحتوى، في حزمة cn.uprogrammer.contentprovider، وإقامة أنشطة الفضاء.
2 تعديل الأنشطة الرئيسية MainActivity.java ملف إضافة إلى اثنين من أساليب جديدة onClickAddName () وonClickRetrieveStudents ().
3 التي أنشئت في إطار حزمة Java جديدة cn.uprogrammer.contentprovider ملف StudentsProvider.java لتحديد مزود الفعلي، والأساليب المرتبطة بها.
4 استخدام <مزود ... /> العلامة في AndroidManifest.xml سجلت مزود المحتوى.
5 تعديل الدقة المحتوى الافتراضي / تخطيط / ملف activity_main.xml لإضافة سجل الطالب يحتوي على واجهة بسيطة.
6 دون تعديل strings.xml، والروبوت ستوديو دفع ملف strings.xml الاهتمام.
7 إطلاق محاكي أندرويد لتشغيل التطبيق والتحقق من نتائج التغييرات التي أدخلت على التطبيق.

هنا هو مضمون تعديل الرئيسية ملف النشاط SRC / cn.uprogrammer.contentprovider / MainActivity.java من. هذا الملف يحتوي على كل من النهج الأساسي لدورة الحياة. لقد أضفنا طريقتين جديدتين، onClickAddName () وonClickRetrieveStudents () للسماح للمستخدم التفاعل مقبض التطبيق.

package cn.uprogrammer.contentprovider;

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;
import cn.uprogrammer.contentprovider.R;

public class MainActivity extends Activity {

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

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    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.provider.College/students";

        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 cn.uprogrammer.contentprovider. ما يلي هو مضمون SRC / cn.uprogrammer.contentprovider / StudentsProvider.java من.

package cn.uprogrammer.contentprovider;

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.provider.College";
    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("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:
                throw new IllegalArgumentException("Unknown URI " + uri);
        }

        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("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)){
            /**
             * 获取所有学生记录
             */
            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("Unsupported URI: " + uri);
        }
    }
}

وفيما يلي التعديلات ملف AndroidManifest.xml على. وأضاف هنا <مزود ... /> العلامة لتشمل موفري المحتوى لدينا:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="cn.uprogrammer.contentprovider"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="22" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >

        <activity
            android:name="cn.uprogrammer.contentprovider.MainActivity"
            android:label="@string/app_name" >

            <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.provider.College" >
        </provider>

    </application>

</manifest>

هنا هو مضمون RES / تخطيط / ملف activity_main.xml:

<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:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="内容提供者实例"
        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="www.uprogrammer.cn"
        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/ic_launcher"
        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="添加"
        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="姓名"
        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="年级"
        android:textColorHint="@android:color/holo_blue_bright" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="查询"
        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>

ضمان الدقة / القيم / ملف strings.xml له المحتويات التالية:

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">Content Provider</string>
    <string name="action_settings">Settings</string>

</resources>

دعونا فقط تشغيل تطبيق مزود المحتوى تعديلها. أفترض أنك قمت بإنشائها AVD خلال بيئة التثبيت. فتح مشروعك في الملف النشط، انقر على شريط الأدوات صور رمز لتشغيل التطبيق في الروبوت الاستوديو. الروبوت ستوديو تثبيت التطبيق على AVD وبدء تشغيله. إذا سارت الامور بشكل جيد، وسوف يتم عرضها على نافذة المحاكي على النحو التالي:

صور

أدخل اسم والسنة، وانقر على زر "إضافة"، والتي سوف تضيف سجل الطالب في البيانات، وعلى الجزء السفلي لحذف رسالة. يعرض محتوى المعلومات عددا من السجلات التي تم إضافتها إلى مزود محتوى قاعدة البيانات URI. وتستخدم هذه العملية في طريقة إدراج (). كرر هذه العملية لإضافة المزيد من الطلاب في قاعدة البيانات الخاصة بنا موفر المحتوى.

صور

وبمجرد الانتهاء من إضافة سجل قاعدة البيانات، فقد حان الوقت لرد الجميل إلى موفر المحتوى يتطلب هذه السجلات. انقر على زر "بحث"، والتي سوف تأتي لاسترداد وعرض كافة البيانات المسجلة عن طريق تنفيذ طريقة الاستعلام ().

يمكنك توفير MainActivity.java طريقة الاستدعاء لإعداد وتحديث وحذف العمليات، وتعديل واجهة المستخدم لإضافة وتحديث وحذف العمليات.

يمكنك استخدام المحتوى الموجود المنصوص عليها في هذا الطريق من خلال هذه الاتصالات. يمكنك أيضا بهذه الطريقة لتطوير تطبيق المنحى قاعدة بيانات جيدة، وكنت لا يمكن أن يؤديها على النحو المبين أعلاه كما هو معروف مثيل من عمليات قاعدة البيانات، مثل القراءة والكتابة وتحديث وحذف.