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();
            }
        }
    }
}

猜你喜欢

转载自blog.csdn.net/cyyyy_da/article/details/82930863