1. 程式人生 > >內容提供者(ContentProvider)和內容觀察者(ContentObserver)的使用(以應用鎖為例)

內容提供者(ContentProvider)和內容觀察者(ContentObserver)的使用(以應用鎖為例)

內容提供者(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中註冊