ContentProvider에 대한 예비 연구


이 섹션 소개:

이 섹션에서 제공하는 내용은 Android의 네 가지 주요 구성 요소 중 마지막인 ContentProvider(콘텐츠 제공자)입니다. 일부 독자는 "안드로이드에는 5가지 주요 구성요소가 있지 않나요? 인텐트는 어떻습니까?" 네, 인텐트도 매우 중요합니다. 이러한 구성요소 간의 연결을 유지하기만 하면 됩니다! Intent에 대해서는 다음 장에서 설명하겠습니다! 이 ContentProvider에 대해 이야기하면 언제쯤 될까요? 그 사람이 이용당할까요? 두 가지 유형이 있습니다:

  • 1.우리는 자체 애플리케이션에서 다른 애플리케이션에 액세스하거나 ContentProvider가 우리에게 노출한 일부 데이터에 액세스하려고 합니다. 휴대폰 연락처, 문자 메시지 등! 이 데이터를 읽거나 수정하고 싶으므로 ContentProvider를 사용해야 합니다!
  • 2.우리 애플리케이션은 다른 애플리케이션이 읽거나 작동할 수 있도록 일부 데이터를 노출하려고 합니다. ContentProvider에서는 노출할 데이터를 선택할 수도 있으므로 개인 데이터 유출을 피할 수 있습니다!

속이기 쉬운 것 같지만 실제로는 매우 간단하게 ContentProvider에 대해 알아봅시다~공식 문서: ContentProvider이 섹션에서는 ContentProvder의 개념을 설명하고 몇 가지 일반적인 용도를 적어보겠습니다. 당신을 위해 시스템 ContentProvider의 예, 그리고 맞춤형 ContentProvider!


ContentProvider 개념 설명:

1.jpg


2. 시스템에서 제공하는 ContentProvider를 사용하세요

실제로 우리는 ContentProvider를 사용할 때 자체 데이터를 직접 노출하지 않는 경우가 더 많습니다. ContentResolver를 통해 읽어보세요. 다른 애플리케이션에서 정보를 얻기 위해 가장 일반적으로 사용되는 방법은 시스템 앱, 정보, 연락처를 읽는 것입니다. 멀티미디어 정보 등! 이러한 ContentProvider를 호출하려면 관련 API 정보를 직접 확인해야 합니다! 또한, 다른 버전은 다른 URL에 해당할 수 있습니다! 해당 데이터베이스 테이블의 URL과 필드를 가져오는 방법은 다음과 같습니다. 여기서는 가장 일반적으로 사용되는 연락처를 예로 들어 보겠습니다. google~
①해당 API를 찾으려면 시스템 소스 코드 파일: all-src.rar -> AndroidManifest.xml로 이동하세요. 파일 탐색기/데이터 /data/com.android.providers.contacts/databases/contact2.db 내보낸 후 SQLite 그래픽 도구를 사용하여
raw_contact table, data table, mimetypes table이라는 세 가지 핵심 테이블을 확인하세요! 몇 가지 기본 작동 예는 다음과 같습니다.


1) 받은 편지함 정보 간단한 읽기:

핵심 코드: ㅋㅋㅋ (uri, new String[]{"address","date","type","body"}, null, null, null);

while(cursor.moveToNext())
{
문자열 주소 = 커서 getString. (0);
       문자열 날짜 =cursor.getString(1);
     문자열 유형 =cursor.getString(2);
     문자열 본문 =cursor.getString(3);
    System.out.println("주소:" + 주소 );
      System.out.println("시간:" + 날짜);
     System.out.println("유형:" + type);
     System.out.println("콘텐츠:" + body);
     시스템 . out.println("======================");
}
cursor.close();
}


잊지 말고 가세요 AndroidManifest.xml에 받은 편지함을 읽을 수 있는 권한을 추가합니다:


<uses-permission android:name="android.permission.READ_SMS"/>

실행 결과:

실행 결과의 일부는 다음과 같습니다.

2.png


2) 받은 편지함에 메시지를 삽입하기만 하면 됩니다.

핵심 코드:

private void insertMsg() {
ContentResolv er 확인자 = getContentResolver();
Uri uri = Uri.parse("content://sms/");
ContentValues ​​​​conValues ​​​​= new ContentValues();
conValues.put("address", "123456789" );
conValues.put ("type", 1);
conValues.put("date", System.currentTimeMillis());
conValues.put("body", "no zuo no die 왜 시도하는지!") ;
resolver.insert( uri, conValues);
Log.e("HeHe", "SMS 삽입 완료~");
}

실행 결과:

3.png

참고:

위 코드는 4.4 이하에서 문자 메시지 작성 기능을 구현할 수 있지만 5.0에서는 다음과 같은 이유로 작성할 수 없습니다. 5.0부터 기본 SMS 응용 프로그램이 아닌 소프트웨어는 SMS 데이터베이스에 작성하여 문자 메시지를 보낼 수 없습니다!


3) 휴대폰 연락처 단순 읽기

핵심 코드:

private void getContacts(){
  //①raw_contacts 테이블을 쿼리하여 연락처 ID 가져오기
ContentResolver 해결자 = getContentResolver()
Uri uri; = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
//연락처 데이터 쿼리
커서 = resolver.query(uri, null, null, null, null);
while(cursor.moveToNext())
{
//연락처 이름 가져오기 , 휴대폰 번호
  String cName =cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
  String cNum =cursor.getString(cursor.getColumnIndex(ContactsContract.CommonData) Kinds.Phone.NUMBER));
      System.out.println("이름:" + cName);
    System.out.println("번호:" + cNum);
     System.out.println("============ ==========");
}
cursor.close();
}

연락처 읽기 권한을 추가하는 것을 잊지 마세요:

<uses-permission android: name=" android.permission.READ_CONTACTS"/>

실행 결과:

실행 결과의 일부는 다음과 같습니다.

4.png


4) 지정된 전화번호의 연락처 정보를 쿼리합니다.

핵심 코드:

private void queryContact(문자열 번호 ){
Uri uri = Uri.parse("content://com.android.contacts/data/phones/filter/" + 숫자);
ContentResolver 확인자 = getContentResolver();
커서 커서 = 확인자.query(uri, new String[]{"display_name"}, null, null, null);
if (cursor.moveToFirst()) {
문자열 이름 =cursor.getString(0);
System.out.println(number + "해당 연락처 이름:" + 이름);
                                                                      이름);

실행 결과:

5.png


5) 새 연락처 추가

핵심 코드:

private void AddContact()는 RemoteException, OperationApplicationException을 발생시킵니다. {
    //使用事务添加联系人
    Uri uri = Uri.parse("content://com.android.contacts/raw_contacts");
    Uri dataUri =  Uri.parse ("content://com.android.contacts/data");

    ContentResolver resolver = getContentResolver();
    ArrayList<ContentProviderOperation> 작업 = new ArrayList<ContentProviderOperation>();
    ContentProviderOperation op1 = ContentProviderOperation.newInsert(uri)
           .withValue("account_name", null)
           .build();
    작업. add(op1);

    //依次是이름 ,号码,邮编
    ContentProviderOperation op2 = ContentProviderOperation.newInsert(dataUri)
           .withValueBackReference("raw_contact_id", 0)
           .withValue("mimetype", "vnd.and roid.cursor.item/name")
            .withValue(" data2", "Coder-pig")
            .build();
    options.add(op2);

    ContentProviderOperation op3 = ContentProviderOperation.newInsert(dataUri)
            .withValueBackReference("raw_contact_id ", 0)
            .withValue("mimetype ", "vnd.android.cursor.item/phone_v2")
            .withValue("data1", "1379898888")
           .withValue("data2", "2")
            .build();
    작업 s.추가(op3 );

    ContentProviderOperation op4 = ContentProviderOperation.newInsert(dataUri)
            .withValueBackReference("raw_contact_id", 0)
.withValue("mimetype", "vnd.android.cursor.item/email_v2")
.withValue("data1", "779878443@qq.com")
.withValue("data2", "2")
.build " 성공적으로 추가됨", Toast.LENGTH_SHORT).show();
}



실행 결과:

권한을 잊지 마세요:

6.gif

<uses-permission android:name="android. WRITE_CONTACTS"/><uses-permission android:name="android.permission.WRITE_PROFILE"/>


3. Custom ContentProvider

우리는 애플리케이션 데이터가 노출되는 것을 원하지 않기 때문에 ContentProvider를 직접 정의하는 경우가 거의 없습니다. 다른 응용프로그램의 경우에도 불구하고 ContentProvider를 사용하는 방법을 배워야 합니다. 데이터를 전송하는 방법이 한 가지 더 있습니다. 그렇죠~
이것은 제가 이전에 그린 흐름도입니다.

7.jpg

다음으로 구현하겠습니다. 단계별:

시작하기 전에 먼저 데이터베이스 생성 클래스를 생성해야 합니다(데이터베이스 내용은 나중에 논의됩니다~):

DBOpenHelper.java

public class DBOpenHelper는 SQLiteOpenHelper를 확장합니다. {

final String CREATE_SQL = "CREATE TABLE test(_id INTEGER PRIMARY KEY AUTOINCREMENT,name)";

public DBOpenHelper(Context context, String name, CursorFactory Factory,
int version) {
super(context, name, null, 1);
}


@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_SQL);
}

} @Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
                          자동 생성된 메소드 스텁

}

}

1단계: ContentProvider 클래스를 사용자 정의하고 onCreate(), getType()을 구현하고 필요에 따라 해당 추가, 삭제, 수정 및 검색 메서드를 다시 작성합니다.

NameContentProvider.java

public 클래스 NameContentProvider는 ContentProvider를 확장합니다. {

//일부 상수 초기화
private static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
private DBOpenHelper d bOpenHelper;
​​​​​​​// UriMatcher를 직접 사용하여 여기에 URI를 추가하고 Matcher match 아래에서 호출합니다.

static{
matcher.addURI("com.jay.example.providers.myprovider", "test", 1);
}
@Override
public boolean onCreate ( ) {
dbOpenHelper = new DBOpenHelper( this.getContext (), "test.db", null, 1)
Return true;
}@osomeride
Pursor 쿼리(Uri Uri, String [] Project, String Selection,
ST raining [] selectargs, string sortOrder) {d Return null;
}@v@v@Public String Gettype (Uri Uri) {
Return Null; ContentValues ​​​​Values) {

Switch (Matcher.match (uri)
{
// 데이터베이스를 여는 것은 Uri 일치
사례 1을 증명하기 위한 것입니다:
sqlitedatabase db = dbopenhelper.getreadabledatabase () Ull, value);
                                                 ~//기존 Uri 뒤에 ID를 추가합니다
                                                                                             Uri nameUri = ContentUris.withAppendedId(uri, rowId); ifyChange(nameUri, null);
              return nameU 리;             반환                                                                                                 ,,,,,,,,,,,,,,, , ContentValues ​​​​값, 문자열 선택,
                                                                                                      


<!--속성 순서: 정규화된 클래스 이름, 일치에 사용되는 URI, 데이터 공유 여부 -->
<provider android:name="com .jay.example.bean.NameContentProvider"
   android:authorities="com.jay.example .providers.myprovider"
                 android:exported="true"/>

좋아, ContentProvider 역할이 완료되었습니다!


다음으로 새 프로젝트를 만들고 ContentResolver 부분을 구현해 보겠습니다. 버튼을 클릭하여 직접 데이터 조각을 삽입합니다.

MainActivity.java

public class MainActivity extends Activity {

private Button btninsert;

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

btninsert = (버튼) findViewById(R.id.btninsert);

/ /ContentProvider 데이터 읽기
Final ContentResolver Resolver = this.getContentResolver ();










dei public void Onclick (view v) {
ContentValues ​​​​values ​​​​= New ContentValues ​​​​() ;
                values.put("name", "测试");
               Uri uri = Uri.parse("content://com.jay.example.providers.myprovider/test");
               해결자 .insert(uri, 값) ;
              Toast.makeText(getApplicationContext(), "데이터 삽입 성공", Toast.LENGTH_SHORT).show();                                                  

사용 방법은? 알겠습니다. 코드는 매우 간단합니다. 먼저 프로젝트를 ContentProvider로 실행한 다음 프로젝트를 ContentResolver로 실행하세요. 버튼을 클릭하여 데이터 조각을 삽입한 다음 파일 탐색기를 열어 ContentProvider의 db 데이터베이스를 꺼내고 그래픽 보기 도구를 사용합니다. 삽입된 데이터와 시간 관계는 결과를 보여드리지는 않겠습니다~


4. ContentObserver를 통해 ContentProvider의 데이터 변경 사항을 모니터링하세요

8.jpg사용 가이드

:

실행 후 프로그램을 따로 두고 받아보세요. 문자 메시지를 보낸 후 logcat에서 메시지 내용을 볼 수 있고 필요에 따라 맞춤 설정할 수 있습니다. Activtiy를 Service로 변경하고 백그라운드에서 이런 작업을 수행하세요~

이 섹션 요약:

자, ContentProvider에 대한 예비 탐색은 여기까지입니다. 시스템에서 제공하는 일부 ContentProvider를 사용하고 자신만의 ContentProvider를 사용자 정의하는 ContentProvider의 개념과 프로세스, 마지막으로 ContentObserver를 통해 ContentProvider의 데이터 변경 사항을 모니터링하는 방법도 설명했는데, ContentProvider의 콘텐츠가 거의 마스터되었습니다. 좋아요, 우리가 모르는 것을 알아보기 위해 다음 섹션의 문서를 살펴보겠습니다~ 감사합니다