Android-콘텐츠 제공 업체
컨텐츠 제공자 구성 요소는 요청시 한 애플리케이션에서 다른 애플리케이션으로 데이터를 제공합니다. 이러한 요청은 ContentResolver 클래스의 메서드에 의해 처리됩니다. 콘텐츠 제공자는 다양한 방법으로 데이터를 저장할 수 있으며 데이터는 데이터베이스, 파일 또는 네트워크를 통해 저장할 수 있습니다.
콘텐츠 제공자
sometimes it is required to share data across applications. This is where content providers become very useful.
콘텐츠 제공 업체를 통해 콘텐츠를 한 곳에서 중앙 집중화하고 필요에 따라 다양한 애플리케이션에서 콘텐츠에 액세스 할 수 있습니다. 콘텐츠 제공자는 insert (), update (), delete () 및 query () 메서드를 사용하여 콘텐츠를 추가하거나 삭제할뿐만 아니라 쿼리하고 콘텐츠를 편집 할 수있는 데이터베이스와 매우 유사하게 작동합니다. 대부분의 경우이 데이터는SQlite 데이터 베이스.
콘텐츠 제공자는 다음의 하위 클래스로 구현됩니다. ContentProvider 다른 애플리케이션이 트랜잭션을 수행 할 수 있도록하는 표준 API 세트를 구현해야합니다.
public class My Application extends ContentProvider {
}
콘텐츠 URI
콘텐츠 제공자를 쿼리하려면 다음과 같은 형식의 URI 형식으로 쿼리 문자열을 지정합니다.
<prefix>://<authority>/<data_type>/<id>
다음은 URI의 다양한 부분에 대한 세부 사항입니다.
Sr. 아니요 | 부품 및 설명 |
---|---|
1 | prefix 항상 content : //로 설정됩니다. |
2 | authority 콘텐츠 제공 업체의 이름 (예 : 연락처 , 브라우저 등 )을 지정 합니다 . 타사 콘텐츠 제공 업체의 경우 com.tutorialspoint.statusprovider 와 같은 정규화 된 이름이 될 수 있습니다. |
삼 | data_type 이 특정 공급자가 제공하는 데이터 유형을 나타냅니다. 예를 들어 연락처 콘텐츠 공급자 로부터 모든 연락처를 가져 오는 경우 데이터 경로는 사람 이고 URI는 다음과 같습니다. content : // contacts / people |
4 | id 요청 된 특정 레코드를 지정합니다. 예를 들어 연락처 콘텐츠 제공 업체에서 연락처 번호 5를 찾는 경우 URI는 다음과 같습니다. content : // contacts / people / 5 . |
컨텐츠 제공자 생성
여기에는 고유 한 콘텐츠 제공 업체를 만드는 여러 간단한 단계가 포함됩니다.
먼저 ContentProviderbaseclass 를 확장하는 Content Provider 클래스를 만들어야합니다 .
둘째, 콘텐츠에 액세스하는 데 사용할 콘텐츠 공급자 URI 주소를 정의해야합니다.
다음으로 콘텐츠를 유지하기 위해 자체 데이터베이스를 만들어야합니다. 일반적으로 Android는 SQLite 데이터베이스를 사용하고 프레임 워크는 SQLite Open Helper 메서드를 사용하여 공급자의 데이터베이스를 만들거나 여는 onCreate () 메서드 를 재정의해야 합니다. 애플리케이션이 시작되면 각 콘텐츠 제공자 의 onCreate () 핸들러가 기본 애플리케이션 스레드에서 호출됩니다.
다음으로 다른 데이터베이스 특정 작업을 수행하기 위해 콘텐츠 공급자 쿼리를 구현해야합니다.
마지막으로 <provider> 태그를 사용하여 활동 파일에 콘텐츠 제공자를 등록합니다.
다음은 콘텐츠 공급자가 작동하도록하기 위해 콘텐츠 공급자 클래스에서 재정의해야하는 메서드 목록입니다.
콘텐츠 제공자
onCreate() 이 메서드는 공급자가 시작될 때 호출됩니다.
query()이 메서드는 클라이언트로부터 요청을받습니다. 결과는 Cursor 객체로 반환됩니다.
insert()이 메서드는 콘텐츠 공급자에 새 레코드를 삽입합니다.
delete() 이 메서드는 콘텐츠 공급자에서 기존 레코드를 삭제합니다.
update() 이 메서드는 콘텐츠 공급자의 기존 레코드를 업데이트합니다.
getType() 이 메서드는 주어진 URI에있는 데이터의 MIME 유형을 반환합니다.
예
이 예제에서는 자신 만의 ContentProvider 를 만드는 방법을 설명합니다 . 그럼 우리가 만드는 동안 다음 것과 비슷한에 다음 단계를 수행 할 수 안녕하세요 예 -
단계 | 기술 |
---|---|
1 | Android StudioIDE를 사용하여 Android 애플리케이션을 만들고 com.example.MyApplication 패키지 아래에 빈 Activity가 있는 My Application 으로 이름을 지정합니다 . |
2 | 기본 활동 파일 MainActivity.java 를 수정 하여 두 개의 새 메소드 onClickAddName () 및 onClickRetrieveStudents () 를 추가하십시오 . |
삼 | com.example.MyApplication 패키지 아래에 StudentsProvider.java 라는 새 Java 파일을 만들어 실제 공급자 및 관련 메서드를 정의합니다. |
4 | <provider ... /> 태그를 사용 하여 AndroidManifest.xml 파일 에 콘텐츠 제공 업체를 등록합니다. |
5 | res / layout / activity_main.xml 파일 의 기본 컨텐츠를 수정하여 학생 레코드를 추가하기위한 작은 GUI를 포함하십시오. |
6 | string.xml.Android 스튜디오를 변경할 필요가 없습니다. |
7 | 애플리케이션을 실행하여 Android 에뮬레이터를 시작하고 애플리케이션에서 수행 한 변경 결과를 확인합니다. |
다음은 수정 된 주요 활동 파일의 내용입니다. 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());
}
}
}
com.example.MyApplication 패키지 아래에 새 파일 StudentsProvider.java를 생성 하고 다음 내용은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에서 앱을 실행하려면 프로젝트의 활동 파일 중 하나를 열고
이제 학생을 입력합시다 Name 과 Grade 마지막으로 Add Name버튼을 클릭하면 데이터베이스에 학생 레코드가 추가되고 데이터베이스에 추가 된 레코드 번호와 함께 ContentProvider URI를 보여주는 메시지가 하단에 깜박입니다. 이 작업은 우리의insert()방법. 이 과정을 반복하여 콘텐츠 제공 업체의 데이터베이스에 학생을 몇 명 더 추가해 보겠습니다.
데이터베이스에 레코드 추가를 완료했으면 이제 ContentProvider에 해당 레코드를 돌려달라고 요청할 때입니다. Retrieve Students 우리의 구현에 따라 하나씩 모든 레코드를 가져 와서 표시하는 버튼 query() 방법.
콜백 함수를 제공하여 업데이트 및 삭제 작업에 대한 활동을 작성할 수 있습니다. MainActivity.java 추가 및 읽기 작업과 동일한 방식으로 업데이트 및 삭제 작업을위한 버튼을 갖도록 사용자 인터페이스를 수정합니다.
이렇게하면 주소록과 같은 기존 콘텐츠 제공 업체를 사용하거나 위의 예에서 설명한대로 읽기, 쓰기, 업데이트 및 삭제와 같은 모든 종류의 데이터베이스 작업을 수행 할 수있는 멋진 데이터베이스 지향 애플리케이션을 개발할 때 콘텐츠 제공 업체 개념을 사용할 수 있습니다.