在应用之间共享数据
通过ContentProvider封装数据
ContentProvider使用的Uri语法结构如下:
content://authority/data_path/id
content:通用前缀,表示该uri用于ContentProvider定位资源
authority:是授权者名称,用来确定具体由哪一个ContentProvider提供资源。因此一般anthority都由类小写的全程组成,以保证唯一性。
data_path:是数据路径,用来确定请求的是哪一个数据集
id:是数据编号,用来请求单条数据。如果是多条,这个字段请忽略。
通过ContentResolver访问数据
使用内容组件获取通信信息
运行时,动态申请权限
利用ContentResolver读写联系人
利用ContentObserver监听短信
使用Servet和Client进行通信实例
server-UserDBHelper.java
package com.example.server.database;
import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class UserDBHelper extends SQLiteOpenHelper {
public static final String DB_NAME = "user.db";
public static final String TABLE_NAME = "user_info";
public static final int DB_VERSION = 1;
public static UserDBHelper mHelper = null;
private SQLiteDatabase mRDB = null;
private SQLiteDatabase mWDB = null;
public static UserDBHelper getInstance(Context context) {
if (mHelper == null) {
mHelper = new UserDBHelper(context);
}
return mHelper;
}
public UserDBHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
public SQLiteDatabase openReadLink() {
if (mRDB == null || !mRDB.isOpen()) {
mRDB = mHelper.getReadableDatabase();
}
return mRDB;
}
public SQLiteDatabase openWriteLink() {
if (mWDB == null || !mWDB.isOpen()) {
mWDB = mHelper.getWritableDatabase();
}
return mWDB;
}
public void closeDBLink() {
if (mRDB != null && mRDB.isOpen()) {
mRDB.close();
mRDB = null;
}
if (mWDB != null && mWDB.isOpen()) {
mWDB.close();
mWDB = null;
}
}
//创建数据库,执行建表语句
@Override
public void onCreate(SQLiteDatabase db) {
String sql = "CREATE TABLE IF NOT EXISTS " + TABLE_NAME + "(" +
"_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," +
"name VARCHAR NOT NULL," +
"age INTEGER NOT NULL," +
"height LONG NOT NULL," +
"weight FLOAT NOT NULL," +
"married INTEGER NOT NULL);";
db.execSQL(sql);
}
// public void insert(User user) {
// ContentValues values = new ContentValues();
// mWDB.insert(TABLE_NAME,null,values);
// }
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
server-UserContentProvider.java
package com.example.server.provider;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.net.Uri;
import android.util.Log;
import com.example.server.database.UserDBHelper;
public class UserContentProvider extends ContentProvider {
private UserDBHelper dbHelper;
private static String TAG = "pansd-UserContentProvider";
@Override
public boolean onCreate() {
Log.d(TAG, "onCreate: UserContentProvider");
dbHelper = UserDBHelper.getInstance(getContext());
return true;
}
public UserContentProvider() {
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
// Implement this to handle requests to delete one or more rows.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public String getType(Uri uri) {
// TODO: Implement this to handle requests for the MIME type of the data
// at the given URI.
throw new UnsupportedOperationException("Not yet implemented");
}
// content://com.example.server.provider.UserContentProvider/user
@Override
public Uri insert(Uri uri, ContentValues values) {
// TODO: Implement this to handle requests to insert a new row.
Log.d(TAG, "insert: 开始插入");
SQLiteDatabase writableDatabase = dbHelper.getWritableDatabase();
writableDatabase.insert(UserDBHelper.TABLE_NAME,null,values);
// throw new UnsupportedOperationException("Not yet implemented");
Log.d(TAG, "insert: 插入成功");
return uri;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
// TODO: Implement this to handle query requests from clients.
Log.d(TAG, "query: UserContentProvider");
SQLiteDatabase db = dbHelper.getReadableDatabase();
Cursor query = db.query(UserDBHelper.TABLE_NAME, projection, selection, selectionArgs, null, null, null);
// throw new UnsupportedOperationException("Not yet implemented");
return query;
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
// TODO: Implement this to handle requests to update one or more rows.
throw new UnsupportedOperationException("Not yet implemented");
}
}
server-清单文件
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.server">
<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/Theme.Demo1">
<provider
android:name=".provider.UserContentProvider"
android:authorities="com.example.server.provider.usercontentprovider"
android:enabled="true"
android:exported="true"></provider>
<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>
Client-avtivity
package com.example.client;
import androidx.appcompat.app.AppCompatActivity;
import android.content.ContentValues;
import android.database.Cursor;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
public class ContentWriteActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_content_write);
}
public void contentProviderWrite(View view) {
ContentValues values = new ContentValues();
values.put("name", "pshdhx");
values.put("age", 22);
values.put("height", 183);
values.put("weight", Float.parseFloat("164"));
values.put("married", true);
getContentResolver().insert(UserInfoContent.CONTENT_URI, values);
// Toast.makeText(this, "保存成功", Toast.LENGTH_SHORT).show();
System.out.println("values = " + values);
}
public void contentProviderQuery(View view) {
Cursor query = getContentResolver().query(UserInfoContent.CONTENT_URI, null, null, null, null);
int userId = 999;
String name = "";
if (query != null) {
while (query.moveToNext()) {
userId = query.getInt(query.getColumnIndex("_id"));
name = query.getString(query.getColumnIndex("name"));
}
query.close();
}
Toast.makeText(this, "userId="+userId+"=name="+name, Toast.LENGTH_SHORT).show();
// System.out.println("name = " + name);
}
}
Client-清单文件
<queries>
<package android:name="com.example.server"/>
<!-- <provider android:authorities="com.example.server.provider.UserContentProvider"/>-->
</queries>
使用内容组件获取通讯信息
运行时动态申请权限
当我需要短信权限的时候,我再提醒用户,给用户弹窗,说我要这个权限。
步骤:
1、检查App是否开启了指定权限:调用ContextCompat的checkSelfPermission方法
2、请求系统弹窗,以便用户选择是否开启权限
调用ActivityCompat的requestPermission方法,即可命令系统自动弹出权限申请窗口。
3、判断用户的权限选择结果
重写活动页面的权限请求回调方法onRequestPermissionResult,在该方法内部处理用户的权限选择结果
清单文件:
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.WRITE_CONTACTS"/>
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.SEND_SMS"/>