Latest web development tutorials

안드로이드 콘텐츠 제공자 (콘텐츠 공급자)

구성 요청하여 콘텐츠 제공자는 하나의 애플리케이션에서 다른 하나의 애플리케이션 데이터를 제공한다. 클래스 컨텐트 리졸버 ContentResolver 방법으로 이러한 요청을 처리합니다. 콘텐츠 제공 업체는 데이터를 저장하는 다양한 방법을 사용할 수 있습니다. 데이터는 데이터베이스, 파일, 또는 네트워크에 저장 될 수있다.

그림

때로는 필요가 응용 프로그램간에 데이터를 공유 할 수 있습니다. 이 경우에, 컨텐츠 제공자는 매우 유용하게된다.

콘텐츠 제공 업체는 필요한 경우, 액세스에 서로 다른 응용 프로그램의 번호를 가질 수 있습니다 콘텐츠 초점을 만들 수 있습니다. 콘텐츠 제공 업체 및 데이터베이스와 같은 역할을합니다. 당신은 삽입, 쿼리의 내용을 편집, 사용할 수 있습니다 (), 갱신 (), 삭제 () 및 쿼리 ()를 추가하거나 내용을 삭제합니다. 대부분의 데이터는 SQLite는 데이터베이스에 저장된다.

콘텐츠 제공자는 클래스 컨텐트 프로 클래스의 서브 클래스로 구현됩니다. 다른 애플리케이션이 트랜잭션을 실행하기 위해 우리는 표준 API의 시리즈를 구현해야한다.

public class MyApplication extends  ContentProvider {

}

콘텐츠 URI

콘텐츠 공급자를 조회하려면 URI 쿼리 문자열을 지정하는 형식은 다음의 형태로 할 필요가 :

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

다음은 URI의 각 부분의 구체적인 설명한다 :

섹션 설명
접두사 접두사 : 내용으로 설정되어 있습니다 : //
권위 승인 : 등 주소록, 브라우저와 같은 컨텐츠 제공자의 이름을 지정 cn.programmer.statusprovider : 제 3 자 콘텐츠 공급자는 같은 이름 일 수있다
DATA_TYPE 데이터 타입 :이 나타내는 데이터를 콘텐츠 제공자의 특정 유형의 것이다. 예를 들면 : 당신은 연락처 주소록을 모두 얻을 수있는 콘텐츠 제공자가 제공하고자 다음과 같이 데이터 경로는 사람들이 다음 URI는 모양입니다 : 내용 : // 연락처 / 인
신분증 이 요청은 특정 레코드를 지정했습니다. 예를 들어 : 내용 : 당신은 콘텐츠 공급자 연락처 연락처 ID 번호는 5 검색 제공은, 다음 URI는 다음과 같습니다 // 연락처 / 인 / 5

콘텐츠 공급자를 만들

제공 여기에 설명 된 간단한 단계는 자신의 콘텐츠를 만들 수 있습니다.

  • 첫째, 파생 클래스 ContentProviderbase 콘텐츠 프로 바이더 클래스를 작성해야합니다.
  • 둘째, 콘텐츠 제공 업체 URI 주소를 액세스하기위한 콘텐츠를 정의 할 필요가있다.
  • 다음으로, 매장 콘텐츠 데이터베이스를 작성해야합니다. 일반적으로 안드로이드 만들거나 데이터베이스 공급자를 엽니 다 SQLiteOpenHelper 방법의 프레임 워크에서 사용 () 메소드를 SQLite 데이터베이스를 사용에서 onCreate 우선합니다. 응용 프로그램이 시작될 때, 그 각각의 콘텐츠 공급자에서 onCreate () 메소드는 응용 프로그램의 주 스레드에서 호출됩니다.
  • 마지막으로, AndroidManifest.xml에 콘텐츠 제공자에 등록 된 <제공 ... /> 태그를 사용합니다.

당신의 작업을 얻을 수있는 콘텐츠 공급자입니다 다음, 당신은 클래스 컨텐트 프로의 재기에 몇 가지 방법이 필요합니다 :

그림

  • 에서 onCreate는 () : 공급자가 시작될 때 호출됩니다.
  • 쿼리는 () :이 메소드는 클라이언트의 요청을 받아들입니다. 결과는 리턴 포인터 (커서) 객체이다.
  • () 삽입 :이 방법은 콘텐츠 제공 업체를 새로운 레코드를 삽입 할 수 있습니다.
  • () 삭제 :이 방법은 기존의 레코드의 콘텐츠 공급자에서 삭제됩니다.
  • 업데이트 () :이 방법은 기존 레코드의 콘텐츠 공급자를 업데이트합니다.
  • getType로 () :이 메소드는 지정된 URI 메타 데이터 형식을 반환합니다.

이 예는 자신 만의 콘텐츠 공급자를 만드는 방법에 대해 설명합니다. 이제 다음 단계를 따르 보자

단계 기술
(1) 안드로이드 패키지 cn.uprogrammer.contentprovider 안드로이드 스튜디오라는 이름의 콘텐츠 공급자를 사용하는 응용 프로그램, 공간 활동의 설립을 만듭니다.
수정 주요 활동이 새로운 방법 onClickAddName ()와 onClickRetrieveStudents을 추가 할 파일 MainActivity.java ().
3 실제 공급자 및 관련 메소드를 정의하는 StudentsProvider.java 파일 cn.uprogrammer.contentprovider 새 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>

여기에 고해상도 / 레이아웃 / 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를 만든 가정합니다. 활성 파일에서 프로젝트를 열고 도구 모음에서 클릭 그림 아이콘은 안드로이드 Studio에서 응용 프로그램을 실행합니다. 안드로이드 Studio는 AVD에 응용 프로그램을 설치하고 시작합니다. 모두가 잘된다면 다음과 같이, 그것은 에뮬레이터 창에 표시됩니다 :

그림

이름과 연도를 입력하고 메시지를 삭제하기 위해 데이터의 학생 기록을 추가하고 하단에있는 것이다 "추가"버튼을 클릭합니다. 콘텐츠 정보는 데이터베이스 콘텐츠 제공자 URI에 추가 레코드의 개수를 표시. 이 작업은 삽입 () 메소드를 사용합니다. 콘텐츠 제공 업체의 데이터베이스에 더 많은 학생들을 추가하려면이 과정을 반복합니다.

그림

데이터베이스의 레코드를 추가 완료되면, 다시 콘텐츠 제공자에 제공 이러한 레코드를 요구하는 시간이다. 검색 와서 쿼리 () 메소드를 구현하여 기록 된 모든 데이터를 표시합니다 "검색"버튼을 클릭합니다.

당신은 작업을 업데이 트를 추가하고 삭제하는 업데이트를 준비하고 작업을 삭제하고 사용자 인터페이스를 수정하는 MainActivity.java 콜백 메소드를 제공 할 수 있습니다.

당신은 접촉에 의해이 방법으로 제공하는 기존의 컨텐츠를 사용할 수 있습니다. 상술 한 바와 같은 읽기, 쓰기, 갱신 및 삭제와 같은 데이터베이스 조작의 인스턴스로서 알려진 바와 같이, 또한 양호한 지향 데이터베이스 애플리케이션을 개발하는이 방법으로 수행 될 수있다.