內容提供者(ContentProvider)和內容觀察者(ContentObserver)的使用(以應用鎖為例)
阿新 • • 發佈:2019-01-31
內容提供者(ContentProvider)
package com.songyan.applock; import android.content.ContentProvider; import android.content.ContentValues; import android.content.UriMatcher; import android.database.Cursor; import android.net.Uri; import android.support.annotation.Nullable; public class AppLockProvider extends ContentProvider { //分別定義兩個返回值 private static final int INSERT=1; private static final int DELETE=0; //先new一個UriMatcher出來,引數就是當沒有匹配到的時候,返回的值是什麼 private static UriMatcher matcher=new UriMatcher(UriMatcher.NO_MATCH); private static Uri URI=Uri.parse("content://com.songyan.applock.applockprovider"); private AppLockDao dao; static { matcher.addURI("com.songyan.applock.applockprovider","insert",INSERT); matcher.addURI("com.songyan.applock.applockprovider","delete",DELETE); } @Override public boolean onCreate() { dao=new AppLockDao(getContext()); return false; } @Nullable @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { return null; } @Nullable @Override public String getType(Uri uri) { return null; } @Nullable @Override public Uri insert(Uri uri, ContentValues values) { //上面定義的返回值 int result=matcher.match(uri); if(result==INSERT){ String packageName=values.getAsString("packageName"); dao.add(packageName); //如果資料發生了改變就通知 getContext().getContentResolver().notifyChange(URI,null); }else{ new IllegalArgumentException("URI地址不正確"); } return null; } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { //上面定義的返回值 int result=matcher.match(uri); if(result==DELETE){ String packageName=selectionArgs[0]; dao.delete(packageName); //如果資料發生了改變就通知 getContext().getContentResolver().notifyChange(URI,null); }else{ new IllegalArgumentException("URI地址不正確"); } return 0; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { return 0; } }
內容觀察者(ContentObserver)
package com.songyan.applock;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.KeyguardManager;
import android.app.Service;
import android.content.Intent;
import android.database.ContentObservable;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.provider.Settings;
import android.support.annotation.Nullable;
import android.util.Log;
import java.util.ArrayList;
import java.util.List;
public class WatchDogService extends Service{
private AppLockDao dao;
private List<String> apps;
//存放要停止保護的app
private List<String> stopApps;
private ActivityManager activityManager;
private Intent intent;
private boolean flag=true;
private MyBinder myBinder;
//鍵盤的管理器
private KeyguardManager keyguardManager;
//在服務中定義的具體方法,臨時開啟對某個應用的保護
private void invokeMethodStartApp(String packageName){
if(stopApps.contains(packageName)){
stopApps.remove(packageName);
}
}
//臨時停止對某個應用的保護
private void invokeMethodStopApp(String packageName){
stopApps.add(packageName);
}
private class MyBinder extends Binder implements IService{
@Override
public void startApp(String packageName) {
//在IService介面的方法中引用服務的具體方法
invokeMethodStartApp(packageName);
}
@Override
public void stopApp(String packageName) {
invokeMethodStopApp(packageName);
}
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
//返回在onCreate中初始化的MyBinder物件
return myBinder;
}
@Override
public void onCreate() {
super.onCreate();
keyguardManager=(KeyguardManager)getSystemService(Service.KEYGUARD_SERVICE);
Log.d("songyandebug","service start");
dao=new AppLockDao(this);
apps=dao.getAllPackageName();
stopApps=new ArrayList<>();
myBinder=new MyBinder();
activityManager=(ActivityManager)getSystemService(Service.ACTIVITY_SERVICE);
//註冊一個內容觀察者
getContentResolver().registerContentObserver(
Uri.parse("content://com.songyan.applock.applockprovider"),
true,new MyObserver(new Handler()));
//MyObserver就是資料庫發生變化以後會執行的內容
intent=new Intent(this,LockActivity.class);
//服務裡面是沒有任務棧的,所以要指定一個新的任務棧,不然是無法在服務裡面啟動activity的
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
new Thread()
{
public void run(){
while(flag){
try{
//得到當前執行的任務棧,引數就是得到多少個任務棧,1就是隻拿一個任務棧
//1對應的也就是正在執行的任務棧啦
Log.d("songyandebug","service run execute");
for(String app:apps){
Log.d("songyandebug","get packageName:"+app);
}
List<RunningTaskInfo> runningTaskInfos=activityManager.getRunningTasks(1);
//拿到當前執行的任務棧
RunningTaskInfo runningTaskInfo=runningTaskInfos.get(0);
//拿到要執行的Activity的包名
String packageName=runningTaskInfo.topActivity.getPackageName();
Log.d("songyandebug","top runningTask is:"+packageName);
if(apps.contains(packageName)){
Log.d("songyandebug","service run execute2");
intent.putExtra("packageName",packageName);
startActivity(intent);
//stopSelf();
}else{
}
sleep(1000);
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
}.start();
}
@Override
public void onDestroy() {
super.onDestroy();
flag=false;
}
private class MyObserver extends ContentObserver{
public MyObserver(Handler handler){
super(handler);
//重新更新apps裡面的內容
apps=dao.getAllPackageName();
Log.d("songyan","資料庫的內容發生了變化");
}
}
}
內容提供者也不要忘記在AndroidManifest.xml中註冊