android运行时权限
在运行程序时动态的对程序的某一项权限申请做授权,避免了安装软件时不一次性授权不能安装的问题。
不是所有权限都需要在运行时申请授权,现在的权限归为两类一类是普通权限一类是危险权限,还有一类是特殊权限用的比较少。
对于普通权限系统为自行帮我们授权,如申请访问网络状态,而危险权限则需要得到用户的同意才能使用,每一个危险权限属于一个权限组,若权限组中任意一个权限被允许那么这个权限组的所有权限都会被允许。
在一个 需要用户授权的操作中基本流程应该是,在执行要执行的操作前先检查权限是否被允许,不被允许则申请用户的许可,允许则直接进行操作。
访问其他应用程序的数据
类容提供器的用法主要有两种一种是创建自己程序的内容提供器供外部访问,另一种是通过外部的内容提供器来访问其他程序中的数据。
对于每一个程序想要访问内容提供器中的数据,则必须借助ContentResolver类,通过Context类中的getContentResolver方法取得该类的实例,该类提供了一系列的方法对数据进行增删改查。不同于数据库的增删改查操作接受表名,内容提供器使用URI来唯一标识数据,他主要由两部分组成一部分是authority一部分是path,前者用于对不同应用程序做区分,后者用于对同一应用程序中的不同的表做区分。
authority:com.example.app.provider
path:table1 ,table2
uri:content://com.example.app.provider.table1
uri:content://com.example.app.provider.table2
uri可以清楚的表示出我们想要访问的哪个程序的哪个数据,若不这样按照数据库的那种模式我们无法让程序知道我们要访问的是哪一个程序中的表
得到uri字符串后要解析成uri对象才可以被作为参数传入
Uri uri = Uri.parse("content://com.example.databasetest.provider/book");
这时便可以通过这个uri对象来查询这张表了
常见的增删改查代码
package com.example.providertest;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
private String newId;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button addData = (Button) findViewById(R.id.add_data);
addData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 添加数据
Uri uri = Uri.parse("content://com.example.databasetest.provider/book");
ContentValues values = new ContentValues();
values.put("name", "A Clash of Kings");
values.put("author", "George Martin");
values.put("pages", 1040);
values.put("price", 55.55);
Uri newUri = getContentResolver().insert(uri, values);
newId = newUri.getPathSegments().get(1);
}
});
Button queryData = (Button) findViewById(R.id.query_data);
queryData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 查询数据
Uri uri = Uri.parse("content://com.example.databasetest.provider/book");
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
if (cursor != null) {
while (cursor.moveToNext()) {
String name = cursor.getString(cursor. getColumnIndex("name"));
String author = cursor.getString(cursor. getColumnIndex("author"));
int pages = cursor.getInt(cursor.getColumnIndex ("pages"));
double price = cursor.getDouble(cursor. getColumnIndex("price"));
Log.d("MainActivity", "book name is " + name);
Log.d("MainActivity", "book author is " + author);
Log.d("MainActivity", "book pages is " + pages);
Log.d("MainActivity", "book price is " + price);
}
cursor.close();
}
}
});
Button updateData = (Button) findViewById(R.id.update_data);
updateData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 更新数据
Uri uri = Uri.parse("content://com.example.databasetest.provider/book/" + newId);
ContentValues values = new ContentValues();
values.put("name", "A Storm of Swords");
values.put("pages", 1216);
values.put("price", 24.05);
getContentResolver().update(uri, values, null, null);
}
});
Button deleteData = (Button) findViewById(R.id.delete_data);
deleteData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 删除数据
Uri uri = Uri.parse("content://com.example.databasetest.provider/book/" + newId);
getContentResolver().delete(uri, null, null);
}
});
}
}
创建自己的内容提供器
新建一个类去集成contentProvider的方式来创建一个自己的内容提供器,覆写其中的
个抽象方法, oncreate(),增删改查,getType()
onCreate()初始化内容提供器的时候调用,通常完成对数据库的创建和升级等操作,返回true成功返回false失败
getType() 根据传入内容的URI来返回相应的MIME类型。
URI的格式主要有两种
URI以/结尾表示访问此表中的数据,而以id结尾则表示访问词表中为此ID值的数据,一般用通配符的方式来分别匹配这两种格式的内容URI
*表示任意长度的任意字符,#表示匹配任意长度的数字
再借助UriMatcher这个类就可以轻松实现匹配内容URI的功能,它提供了一个addURI的方法接受三个参数,再别分吧authrity path 和一个自定义代码传入,这样在调用urimatcher的match方法时就可以将一个uri对象传入,返回值是一个能够匹配此uri对象所对应的自定义代码,利用这个diamagnetic判断调用方期望访问的是哪一张表的哪一个数据。
通过匹配其他程序传入的url来判断要访问的数据,这时再在内容提供器内部调用数据库的操作去操作数据库,最后将得到的值返回给外部程序。
代码:
package com.example.databasetest;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
public class DatabaseProvider extends ContentProvider {
public static final int BOOK_DIR = 0;
public static final int BOOK_ITEM = 1;
public static final int CATEGORY_DIR = 2;
public static final int CATEGORY_ITEM = 3;
public static final String AUTHORITY = "com.example.databasetest.provider";
private static UriMatcher uriMatcher;
private MyDatabaseHelper dbHelper;
static {
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(AUTHORITY, "book", BOOK_DIR);
uriMatcher.addURI(AUTHORITY, "book/#", BOOK_ITEM);
uriMatcher.addURI(AUTHORITY, "category", CATEGORY_DIR);
uriMatcher.addURI(AUTHORITY, "category/#", CATEGORY_ITEM);
}
@Override
public boolean onCreate() {
dbHelper = 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 = dbHelper.getReadableDatabase();
Cursor cursor = null;
switch (uriMatcher.match(uri)) {
case BOOK_DIR:
cursor = db.query("Book", projection, selection, selectionArgs, null, null, sortOrder);
break;
case BOOK_ITEM:
String bookId = uri.getPathSegments().get(1);
cursor = db.query("Book", projection, "id = ?", new String[] { bookId }, null, null, sortOrder);
break;
case CATEGORY_DIR:
cursor = db.query("Category", projection, selection, selectionArgs, null, null, sortOrder);
break;
case CATEGORY_ITEM:
String categoryId = uri.getPathSegments().get(1);
cursor = db.query("Category", projection, "id = ?", new String[] { categoryId }, null, null, sortOrder);
break;
default:
break;
}
return cursor;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
// 添加数据
SQLiteDatabase db = dbHelper.getWritableDatabase();
Uri uriReturn = null;
switch (uriMatcher.match(uri)) {
case BOOK_DIR:
case BOOK_ITEM:
long newBookId = db.insert("Book", null, values);
uriReturn = Uri.parse("content://" + AUTHORITY + "/book/" + newBookId);
break;
case CATEGORY_DIR:
case CATEGORY_ITEM:
long newCategoryId = db.insert("Category", null, values);
uriReturn = Uri.parse("content://" + AUTHORITY + "/category/" + newCategoryId);
break;
default:
break;
}
return uriReturn;
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
// 更新数据
SQLiteDatabase db = dbHelper.getWritableDatabase();
int updatedRows = 0;
switch (uriMatcher.match(uri)) {
case BOOK_DIR:
updatedRows = db.update("Book", values, selection, selectionArgs);
break;
case BOOK_ITEM:
String bookId = uri.getPathSegments().get(1);
updatedRows = db.update("Book", values, "id = ?", new String[] { bookId });
break;
case CATEGORY_DIR:
updatedRows = db.update("Category", values, selection, selectionArgs);
break;
case CATEGORY_ITEM:
String categoryId = uri.getPathSegments().get(1);
updatedRows = db.update("Category", values, "id = ?", new String[] { categoryId });
break;
default:
break;
}
return updatedRows;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
// 删除数据
SQLiteDatabase db = dbHelper.getWritableDatabase();
int deletedRows = 0;
switch (uriMatcher.match(uri)) {
case BOOK_DIR:
deletedRows = db.delete("Book", selection, selectionArgs);
break;
case BOOK_ITEM:
String bookId = uri.getPathSegments().get(1);
deletedRows = db.delete("Book", "id = ?", new String[] { bookId });
break;
case CATEGORY_DIR:
deletedRows = db.delete("Category", selection, selectionArgs);
break;
case CATEGORY_ITEM:
String categoryId = uri.getPathSegments().get(1);
deletedRows = db.delete("Category", "id = ?", new String[] { categoryId });
break;
default:
break;
}
return deletedRows;
}
@Override
public String getType(Uri uri) {
switch (uriMatcher.match(uri)) {
case BOOK_DIR:
return "vnd.android.cursor.dir/vnd.com.example.databasetest. provider.book";
case BOOK_ITEM:
return "vnd.android.cursor.item/vnd.com.example.databasetest. provider.book";
case CATEGORY_DIR:
return "vnd.android.cursor.dir/vnd.com.example.databasetest. provider.category";
case CATEGORY_ITEM:
return "vnd.android.cursor.item/vnd.com.example.databasetest. provider.category";
}
return null;
}
}