1. 程式人生 > >Android學習筆記6-跨程式共享資料-ContentProvider

Android學習筆記6-跨程式共享資料-ContentProvider

1,內容提供器簡介

1,內容提供器(ContentProvider) 主要用於在不同的應用程式之間實現資料共享額功能,它提供了一套完整的機制,允許一個程式訪問另一個程式的資料,同時保證被訪問的資料的安全性。

2,使用內提供器是Android實現跨程式共享資料的標準形式。

2,執行時許可權

Android開發團隊在6.0系統中加入了執行時許可權,使用者可以不用在安裝軟體時一次性授權應用的所有申請的許可權,而是在軟體的使用過程中再對某一許可權進行授權。

Android中的危險許可權有9組24個許可權
分別是日曆、拍照、聯絡人、位置、麥克風、電話、感測器、簡訊及儲存。

注意 :24個許可權每個都屬於一個許可權組,我們在進行執行時許可權的處理時 使用的是許可權名
但是使用者一旦同意授權了,那麼該許可權所在的許可權組的其他許可權也會被授權。

下面我們做一個打電話的Demo

首先在AndroidManifest.xml檔案中宣告許可權

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.chen.runtimepermissiontest"
> //CALL_PHONE是打電話時所需要的許可權 <uses-permission android:name="android.permission.CALL_PHONE" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round"
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> </application> </manifest>

MainActivity.java

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button makeCall = (Button) findViewById(R.id.make_call);
        makeCall.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            
            
                if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest
                .permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
                    
                    ActivityCompat.requestPermissions(MainActivity.this,new String[]
                            {Manifest.permission.CALL_PHONE},1 );
                } else  {
                    call();
                }
            }
        });
    }

    
    //打電話
    private void call() {
        try {
            Intent intent = new Intent(Intent.ACTION_CALL);
            intent.setData(Uri.parse("tel:10086"));
            startActivity(intent);
        } catch (SecurityException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onRequestPermissionsResult (int requestCode,String [] permissions,int [] grantResults) {
        switch (requestCode) {
            case 1:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    call();
                } else {
                    Toast.makeText(this, "你沒許可權", Toast.LENGTH_SHORT).show();
                }
                break;
            default:
        }
    }
}

ContextCompat.checkSelfPermission(Context, 許可權名).
1,先呼叫checkSelfPermission方法判斷使用者是否已經授過權,此方法接受兩個引數,第一個是Context,第二個是具體的許可權名。

2,將checkSelfPermission方法的返回值與 PackageManager.PERMISSION_GRANTED 比對
若相等則說明使用者已經授權,不相等則表示使用者沒有授權.

3, 若使用者沒有授權,則呼叫ActivityCompat.requestPermissions(Activity例項,String陣列,請求碼)。
將申請的許可權名放入String陣列中,請求碼必須是唯一值。

4,呼叫了requestPermissions()方法後,系統會彈出一個許可權申請的對話方塊,可以選擇同意或者拒絕。
然後把申請許可權的結果回撥到onRequestPermissionsResult(nt requestCode(請求碼),String [] permissions,int [] grantResults))中,授權的結果被封裝到grantResults引數中。

3,訪問其他程式中的資料

內容提供器的用法有兩種

  • 使用現有的內容提供器來操作相應程式中的資料
  • 建立自己的內容提供器給我們的程式提供外部訪問介面

3-1 ContentResolver的基本用法

通過Context的getContentResolver()方法獲取該類的例項

  • insert() 新增資料
  • update() 更新資料
  • delete() 刪除資料
  • query() 查詢資料

Uri:

ContentResolver中的增刪改查的方法不接受資料庫表名的引數,而是使用Uri代替,稱為內容URI,內容URI給內容提供器中的資料建立了唯一的識別符號。

Uri = authority + path

  • authurity是為了區分不同的應用程式,一般為應用程式的包名. 如: com/example.app.provider
  • path是為了同一應用程式中的不同表 如:table1

則Uri = com/example.app.provider/table1

為了辨認某個字串是內容Uri,需要在字串的頭部加上協議宣告。

URI的標準寫法:

content://com/example.app.provider/table1

再把它解析成Uri物件

Uri uri = Uri.parse(“content://com/example.app.provider/table1”)

查詢資料

Cursor cursor = getContentResolver(uri, //指定查詢某個應用程式下的某一張表
projection, // 指定查詢的列名
selection, // 指定where的約束條件
selectionArgs, // 為where中的佔位符提供具體的值
sortOrder // 指定查詢結果的排序方式
);

插入資料

ContentValues values = new ContentValues();
values.put("column1","text");
values.put("column2",1);
getContentRresolver().insert(uri,values);

更改資料

ContentValues values = new ContentValues();
values.put("columns1", " ");
getContentResolver().update(uri,values ,"column1 = ? and column2 = ?" ,
new String[] {"text","1"});

刪除資料

getContentResolver().delete(uri,"column2 = ?" ,new String[] {"1"} );

讀取聯絡人的demo

public class MainActivity extends AppCompatActivity {

    ArrayAdapter<String> adapter;
    List<String> contactList = new ArrayList<>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ListView listView = (ListView) findViewById(R.id.contacts_id);
        adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,
                contactList);
        listView.setAdapter(adapter);

        //獲取聯絡人許可權
        if(ContextCompat.checkSelfPermission(this,
                Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this,new String[]
                    {Manifest.permission.READ_CONTACTS} ,1 );
        } else {
            readContact();
        }

    }

    @Override
    public void onRequestPermissionsResult(int requestCode,String[] permissions,int[] grantResults) {
        switch (requestCode) {
            case 1 :
                if (grantResults.length >0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    readContact();
                } else {
                    Toast.makeText(this, "你沒有讀取聯絡人許可權", Toast.LENGTH_SHORT).show();
                }
            default:break;
        }
    }




    private  void readContact() {
        Cursor cursor = null;
        try {
            //查詢聯絡人資料
            cursor = getContentResolver().query(ContactsContract.CommonDataKinds
                    .Phone.CONTENT_URI,null ,null ,null );
            if(cursor != null) {
                while (cursor.moveToNext()) {
                    //獲取聯絡人姓名
                    String displayName = cursor.getString(cursor.getColumnIndex
                            (ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
                    //獲取聯絡人號碼
                    String displayNumber = cursor.getString(cursor.getColumnIndex
                            (ContactsContract.CommonDataKinds.Phone.NUMBER));
                    contactList.add(displayName + "\n" + displayNumber);

                }
                adapter.notifyDataSetChanged();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if(cursor != null) {
                cursor.close();
            }
        }
    }
}