应用B访问应用A的数据库(两种方式):
1.Android下有Linux系统,用Linux系统的chmod命令把文件改成可访问(修改权限),应用B可直接访问应用A的数据库。
2.ContentProvider:在应用A中建一个中间联系人,应用B访问中间联系人,中间联系人去访问应用A的数据库(ContentProvider给其他应用提供一个本应用的数据访问接口).
ContentProvider内容提供者(只针对于数据库)
内容提供者(ContentProvider)把数据进行封装然后提供出来,其他应用可以通过内容解析者(ContentResolver)来访问。
ContentResolver内容解析者
内容解析者,该类提供了和ContentProvider(内容提供者)中同名同参的增、删、改、查的方法,通过URI采用对应的方法来操作ContentProvider提供的数据。
案例:访问Android系统中短信的数据库(打印出所有字段名)
1.在.xml中创建一个按钮
<Button
android:text="访问sms"
android:id="@+id/btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"></Button>
2.在后台获取按钮的点击事件
1)创建ContentResolver()内容解析者对象:获取–getContentResolver()
2)创建URI(URI:查询的数据库的名)Uri u = Uri.parse(“短信数据库的名(固定的):content://sms”);
3)contentResolver .query(URI:u, String[] projection(查询哪些字段):null, 查询条件:null, 条件的值:null,排序的条件:null);查询短信数据库的方法(null:查询所有字段,也可以new一个数组类型的字段–知道字段)
4)
//返回索引位置的数据
query.getString(0);
图解:
//让游标往下移动一行
query.moveToNext();
图解:一般写循环,返回true就继续走执行里面的方法体,返回false跳出循环。
//按照索引的方式返回字段下的内容
query.getColumnName(0);
图解:
//根据字段名称返回当前的字段索引
query.getColumnIndex("");
图解:
注:使用mysql创建数据库时,每一个表的每一个字段都得写字段的类型,但Android下的数据库中不管存的什么类型,在数据库中都是string类型。
//返回索引位置的数据
query.getString(0);
//返回字段的个数
query.getColumnCount();
//让游标往下移动一行
query.moveToNext();
//移动到具体的哪一行,容易索引越界,容易抛异常报错
query.move(2);
//把该表所有字段的名称以数组类型返回
query.getColumnNames();
//按照索引的方式返回字段下的内容
query.getColumnName(0);
//根据字段名称返回当前的字段索引
query.getColumnIndex("");
//是不是第一行,布尔类型
query.isFirst();
4)通过返回的结果集query,列出短信内容(遍历一下查了多少条短信)
String[] columnNames = query.getColumnNames();把该表所有字段的名称以数组类型返回
for循环–遍历字段:
for (int i=0;i<columnNames.length;i++){
Log.i("shit",columnNames[i]);
}
3.安全权限
1)在AndroidManifest.xml中(不用通过用户)
<uses-permission android:name="android.permission.READ_SMS"></uses-permission>
2)动态加载/动态申请 (代码是固定的)(Android6.0以后)
判断当前APP是否有权限:ContextCompat.checkSelfPermission(MainActivity.this, 和上面AndroidManifest.xml中对应上面是啥权限这里就是啥:Manifest.permission.READ_SMS) ;返回值是int
同意:PackageManager.PERMISSION_GRANTED代表用户同意(0)
不同意:PackageManager.PERMISSION_DENIED(-1){
动态申请权限:ActivityCompat.requestPermissions(MainActivity.this,数组类型的权限:new String[]{动态申请参数:Manifest.permission.READ_SMS},请求码:填啥都行只要是int类型就行100);
}
int checkSelf= ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_SMS) == PackageManager.PERMISSION_DENIED);
if (checkSelf ==PackageManager.PERMISSION_DENIED){
ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.READ_SMS},100);
}
//也可以写成
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_SMS) == PackageManager.PERMISSION_DENIED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_SMS}, 100);
}
3)使用动态申请权限会触发:onRequestPermissionsResult方法:判断用户是不是点击同意还是点击拒绝
requestCode等于自定义的请求码----权限就是读取信息的权限
@NonNull String[] permissions权限会通过数组类型传过来
@NonNull int[] grantResults结果码通过数组传过来
4)危险权限
效果图:同时打印出所有列的列名
MainActivity.java代码:
package com.example.myapplication;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.content.ContentResolver;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.util.Log;
import android.view.View;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_SMS) == PackageManager.PERMISSION_DENIED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_SMS}, 100);
}
findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ContentResolver contentResolver = getContentResolver();
Uri u = Uri.parse("content://sms");
Cursor query = contentResolver.query(u, null, null, null,null);
String[] columnNames = query.getColumnNames();
for (int i=0;i<columnNames.length;i++){
Log.i("shit",columnNames[i]);
}
}
});
}
}
案例:查询两个手机互相发短信的数据(每一个按字段打印出来)
//让游标往下移动一行,读每一行的数据
query.moveToNext();
while (query.moveToNext()) {
String line = "";
//从第0个开始遍历这一行中每个列
for (int i = 0; i < query.getColumnCount(); i++) {
line += query.getColumnName(i) + ":" + query.getString(i) + ",";
}
Log.i("shit", line);
}
运行新手机往旧手机发短信,再运行旧手机然后访问sms出现结果
效果图:
MainActivity.java代码:
package com.example.myapplication;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.content.ContentResolver;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.util.Log;
import android.view.View;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_SMS) == PackageManager.PERMISSION_DENIED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_SMS}, 100);
}
findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ContentResolver contentResolver = getContentResolver();
Uri u = Uri.parse("content://sms");
Cursor query = contentResolver.query(u, null, null, null, null);
while (query.moveToNext()) {
String line = "";
//从第0个开始遍历这一行中每个列
for (int i = 0; i < query.getColumnCount(); i++) {
line += query.getColumnName(i) + ":" + query.getString(i) + ",";
}
Log.i("shit", line);
}
}
});
}
}
案例:查询联系人(打印出所有字段名)
1.在.xml中创建一个按钮
<Button
android:text="访问联系人"
android:id="@+id/btn2"
android:layout_width="match_parent"
android:layout_height="wrap_content"></Button>
2.在后台获取按钮的点击事件
1)拿到内容解析者ContentResolver cr = getContentResolver();
2)Cursor cs = cr .query(这里的URI是常量(与上一个不一样):ContactsContract.Contacts.CONTENT_URI,查询哪些字段 :null, 查询条件:null, 条件的值:null,排序的条件:null);
3)遍历所有字段
String[] str=cs.getColumnNames();
for (int i=0;i<str.length;i++){
Log.i("shit",str[i]);
}
3.安全权限
1)在AndroidManifest.xml中(不用通过用户)
<uses-permission android:name="android.permission.READ_CONTACTS"></uses-permission>
2)动态申请联系人读取权限
判断当前APP是否有权限:ContextCompat.checkSelfPermission(MainActivity.this, 和上面AndroidManifest.xml中对应上面是啥权限这里就是啥:Manifest.permission.READ_CONTACTS) ;返回值是int
同意:PackageManager.PERMISSION_GRANTED代表用户同意(0)
不同意:PackageManager.PERMISSION_DENIED(-1){
动态申请权限:ActivityCompat.requestPermissions(MainActivity.this,数组类型的权限:new String[]{动态申请参数:Manifest.permission.READ_CONTACTS},请求码:填啥都行只要是int类型就行200);
}
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_DENIED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_CONTACTS}, 200);
}
效果图:
列出所有字段名:
MainActivity.java代码:
package com.example.myapplication;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.content.ContentResolver;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.util.Log;
import android.view.View;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_SMS) == PackageManager.PERMISSION_DENIED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_SMS}, 100);
}
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_DENIED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_CONTACTS}, 200);
}
findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ContentResolver contentResolver = getContentResolver();
Uri u = Uri.parse("content://sms");
Cursor query = contentResolver.query(u, null, null, null, null);
while (query.moveToNext()) {
String line = "";
//从第0个开始遍历这一行中每个列
for (int i = 0; i < query.getColumnCount(); i++) {
line += query.getColumnName(i) + ":" + query.getString(i) + ",";
}
Log.i("shit", line);
}
}
});
findViewById(R.id.btn2).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ContentResolver cr = getContentResolver();
Cursor cs = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
String[] str=cs.getColumnNames();
for (int i=0;i<str.length;i++){
Log.i("shit",str[i]);
}
}
});
}
}
案例:查询联系人(每一个按字段打印出来)
后台:
while (cs.moveToNext()) {
//拼字符串的形式
String a = "";
for (int i = 0; i < cs.getColumnCount(); i++) {
a += cs.getColumnName(i) + ":" + cs.getString(i) + ",";
}
Log.i("shit", a);
}
MainActivity.java代码:
package com.example.myapplication;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.content.ContentResolver;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.util.Log;
import android.view.View;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_SMS) == PackageManager.PERMISSION_DENIED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_SMS}, 100);
}
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_DENIED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_CONTACTS}, 200);
}
findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ContentResolver contentResolver = getContentResolver();
Uri u = Uri.parse("content://sms");
Cursor query = contentResolver.query(u, null, null, null, null);
while (query.moveToNext()) {
String line = "";
//从第0个开始遍历这一行中每个列
for (int i = 0; i < query.getColumnCount(); i++) {
line += query.getColumnName(i) + ":" + query.getString(i) + ",";
}
Log.i("shit", line);
}
}
});
findViewById(R.id.btn2).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ContentResolver cr = getContentResolver();
Cursor cs = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
while (cs.moveToNext()) {
//拼字符串的形式
String a = "";
for (int i = 0; i < cs.getColumnCount(); i++) {
a += cs.getColumnName(i) + ":" + cs.getString(i) + ",";
}
Log.i("shit", a);
}
}
});
}
}
效果图: