9.内容提供者:Content Provider :不同应用程序间实现数据共享功能。
用法2种:
1.读取和操作相应程序中的数据
2.给jj程序的数据提供外部接口
11.android 的危险权限需要加入运行时权限处理,其它普通权限只需要在androidManifest中添加权限即可
1. URI写法:访问程序的table表:content://com.example.app.provider/table
2.访问table表中拥有对应id的数据:content://com.example.app.provider/table/10
3.使用通配符匹配:
* 代表任意长度的字符 : 可以匹配任意表内容的URI : content://com.example.app.provider/*
# 代表任意长度的数据 : 可以匹配table表中任意一行数据 : content://com.example.app.provider/table/#
14.Uri对象所对应的MIME类型 :主要由3部分组成
1.必须以vnd开头
2.如果URI以路径结尾:则后接android.cursor.dir/ 如果以id结尾:则后接android.cursor.item/
content://com.example.app.provider/table
MIME:vnd.android.cursor.dir/content://com.example.app.provider/table
content://com.example.app.provider/table/10
MIME: vnd.android.cursor.item/content://com.example.app.provider/table/10
15. jj完整的内容提供者
1.创建一个类继承ContentProvider,实现其6个方法
2.使用UriMatcher实现内容匹配URI的功能
用法2种:
1.读取和操作相应程序中的数据
2.给jj程序的数据提供外部接口
3.访问内容提供者 中的共享数据需要借助 ContentResolver类 进行共享数据的CURD
public class MainActivity extends AppCompatActivity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// content 协议 包名 表名
Uri uri = Uri.parse("content://com.example.a123.databasetext/table");
// 查询
Cursor cursor = getContentResolver().query(
uri, //查询应用程序下的某表
projection, // 指定查询的咧
selection, // 指定where 的约束条件
selectionAgrs, // where的占位符
sortOrder); // 查询结果排序
// 添加
ContentValues values = new ContentValues();
values.put("name1","haha");
values.put("name2","hehe");
getContentResolver().insert(uri,values);
// 更新
ContentValues values1 = new ContentValues();
values.put("name1","");
getContentResolver().update(uri,values,"name1 = ?",new String[]{"xxxx"});
// 删除
getContentResolver().delete(uri,"name1 = ? ",new String[]{"haha"});
}
}
10. android 运行时权限
11.android 的危险权限需要加入运行时权限处理,其它普通权限只需要在androidManifest中添加权限即可
12.拨打电话的运行时权限完整流程
public class MainActivity extends AppCompatActivity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 拨打电话的运行时权限完整流程
// 表示用户未授权Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
// 弹出让用户选择是否授权,选择后执行回调onRequestPermissionsResult
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 (Exception e) {
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)
{
switch (requestCode) {
case 1:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
call();
}
break;
default:
break;
}
}
}
13. 创建jj的内容提供者
1. URI写法:访问程序的table表:content://com.example.app.provider/table
2.访问table表中拥有对应id的数据:content://com.example.app.provider/table/10
3.使用通配符匹配:
* 代表任意长度的字符 : 可以匹配任意表内容的URI : content://com.example.app.provider/*
# 代表任意长度的数据 : 可以匹配table表中任意一行数据 : content://com.example.app.provider/table/#
14.Uri对象所对应的MIME类型 :主要由3部分组成
1.必须以vnd开头
2.如果URI以路径结尾:则后接android.cursor.dir/ 如果以id结尾:则后接android.cursor.item/
content://com.example.app.provider/table
MIME:vnd.android.cursor.dir/content://com.example.app.provider/table
content://com.example.app.provider/table/10
MIME: vnd.android.cursor.item/content://com.example.app.provider/table/10
15. jj完整的内容提供者
1.创建一个类继承ContentProvider,实现其6个方法
2.使用UriMatcher实现内容匹配URI的功能
3.当调用UriMatcher的match时,传入一个Uri对象,返回值就是能够匹配这个Uri对象对应的自定义代码,就可以知道调用方希望访问哪张表数据
public class MyProvider extends ContentProvider
{
private static final int TABLE_DIR = 0;
private static final int TABLE_ITEM = 1;
private static final int TABLE1_DIR = 2;
private static final int TABLE1_ITEM = 3;
private static UriMatcher mUriMatcher;
static {
mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
mUriMatcher.addURI("com.example.app.provider", "table", TABLE_DIR);
mUriMatcher.addURI("com.example.app.provider", "table", TABLE_ITEM);
mUriMatcher.addURI("com.example.app.provider", "table1", TABLE_DIR);
mUriMatcher.addURI("com.example.app.provider", "table1", TABLE1_ITEM);
}
// ContentResolver 尝试访问程序数据时候 内容提供者才会初始化,返回true代表成功
@Override
public boolean onCreate()
{
return false;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
{
switch (mUriMatcher.match(uri)) {
case TABLE_DIR:
// 查询table表中所有数据
break;
case TABLE_ITEM:
// 查询table表中单条数据
break;
}
return null;
}
// 根据传入的Uri来返回相应的MIME类型
@Override
public String getType(Uri uri)
{
switch (mUriMatcher.match(uri))
{
case TABLE_DIR:
return "vnd.android.cursor.dir/content://com.example.app.provider/table";
case TABLE_ITEM:
return "vnd.android.cursor.item/content://com.example.app.provider/table";
}
return null;
}
@Override
public Uri insert(Uri uri, ContentValues values)
{
return null;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs)
{
return 0;
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)
{
return 0;
}
}
16.创建jj的内容提供者 MyProvider
public class MyProvider extends ContentProvider
{
// 定义常量 分别访问不同表中的所有数据和单条数据
public static final int BOOK_DIR = 0;
public static final int BOOK_ITEM = 1;
public static final int TABLE_DIR = 2;
public static final int TABLE_ITEM = 3;
public static final String AUTHORITY = "com.example.app.provider";
private static UriMatcher mUriMatcher;
private MyDatabaseHelper mMyDatabaseHelper;
// UriMatcher初始化
static {
mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
mUriMatcher.addURI(AUTHORITY, "book", BOOK_DIR);
mUriMatcher.addURI(AUTHORITY, "book", BOOK_ITEM);
mUriMatcher.addURI(AUTHORITY, "table", TABLE_DIR);
mUriMatcher.addURI(AUTHORITY, "table", TABLE_ITEM);
}
// ContentResolver 尝试访问程序数据时候 内容提供者才会初始化,返回true代表成功
@Override
public boolean onCreate()
{
mMyDatabaseHelper = new MyDatabaseHelper(getContext(), "BookStore.db", null, 2);
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
{
// 查询数据
SQLiteDatabase db = mMyDatabaseHelper.getReadableDatabase();
Cursor cursor = null;
switch (mUriMatcher.match(uri)) {
case BOOK_DIR:
// 查询table表中所有数据
cursor = db.query("Book", null, null, null, null, null, null);
break;
case BOOK_ITEM:
// 查询table表中单条数据 通过uri的getPathSegments获取1位置存放的id,0位置存放路径
String booId = uri.getPathSegments().get(1);
cursor = db.query("Book", projection, "id = ?", new String[] { booId }, null, null, sortOrder);
break;
}
return cursor;
}
// 根据传入的Uri来返回相应的MIME类型
@Override
public String getType(Uri uri)
{
switch (mUriMatcher.match(uri)) {
case BOOK_DIR:
return "vnd.android.cursor.dir/content://com.example.app.provider/book";
case BOOK_ITEM:
return "vnd.android.cursor.item/content://com.example.app.provider/book";
}
return null;
}
@Override
public Uri insert(Uri uri, ContentValues values)
{
// 添加数据
SQLiteDatabase db = mMyDatabaseHelper.getWritableDatabase();
Uri uriReturn = null;
switch (mUriMatcher.match(uri)) {
case BOOK_DIR:
case BOOK_ITEM:
long newBookId = db.insert("Book", null, values);
// Uri.parse 将uri内容解析为对象
uriReturn = Uri.parse("content://" + AUTHORITY + "/book/" + newBookId);
break;
}
return uriReturn;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs)
{
// 删除数据
SQLiteDatabase db = mMyDatabaseHelper.getWritableDatabase();
int deleteRows = 0;
switch (mUriMatcher.match(uri)) {
case BOOK_DIR:
deleteRows = db.delete("Book", selection, selectionArgs);
break;
case BOOK_ITEM:
String bookId = uri.getPathSegments().get(1);
deleteRows = db.delete("Book", "id = ?", new String[] { bookId });
break;
}
return deleteRows;
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)
{
// 更新数据
SQLiteDatabase db = mMyDatabaseHelper.getWritableDatabase();
int updateRows = 0;
switch (mUriMatcher.match(uri)) {
case BOOK_DIR:
updateRows = db.update("Book", values, selection, selectionArgs);
break;
case BOOK_ITEM:
String bookId = uri.getPathSegments().get(1);
updateRows = db.update("Book", values, "id = ?", new String[] { bookId });
}
return updateRows;
}
需要在androidManifest中注册
<application
android:name="org.litepal.LitePalApplication"
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>
// 注册内容提供者
<provider
android:authorities="com.example.a123.databasetext"
android:name=".MyProvider"
android:enabled="true"
android:exported="true">
</provider>
</application>
</manifest>
使用jj创建的内容提供者
public class MainActivity extends AppCompatActivity
{
private String newId;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 内容提供者添加数据
Uri uri = Uri.parse("content://com.example.a123.database.provider/book");
ContentValues values = new ContentValues();
values.put("name","haha");
values.put("price",12.99);
Uri newUri = getContentResolver().insert(uri,values);
newId = newUri.getPathSegments().get(1);
// 查询
Cursor cursor = getContentResolver().query(uri,null,null,null,null);
while (cursor.moveToNext())
{
String name = cursor.getString(cursor.getColumnIndex("name"));
}
cursor.close();
// 更新数据
Uri uri1 = Uri.parse("content://com.example.a123.database.provider/"+newId);
ContentValues values1 = new ContentValues();
values1.put("name","hehe");
getContentResolver().update(uri,values,null,null);
// 删除
getContentResolver().delete(uri1,null,null);
}
}