定制化ROM采坑之路(4):从Framework层去调用App中的数据库

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011195398/article/details/88251819

前言

最近在做一个实验,从Framework层去调用应用层的数据库,可以开启服务我们开发的App数据库进行一些管理,下面来讲解下我的开发流程。

准备工作

首先,我们准备一个数据库项目,主要就是基础的CRUD操作,我这里准备了一个SqliteDemo可以去下载,下面的内容我使用了项目中的java文件。

修改Framework层代码

我们准备Hook的点是在Application的onCreate()方法进行Hook,预想只要创建进程的时候就打印数据库的信息。
修改的文件路径:frameworks/base/core/java/android/app/Application.java

...
import android.util.Slog;
import android.app.DBHelper;
public class Application{
    private static final String PACKAGE_NAME = "com.martin.jetmo";
	private static final String TAG = "JetmoApplication";
    @CallSuper
    public void onCreate() {
        if (mLoadedApk.getPackageName().toLowerCase().equals(PACKAGE_NAME)) {
			mDBHelper = new DBHelper(this);     
			ArrayList<String> array_list = mDBHelper.getAllCotacts();//这里需要写String   
			for (String item : array_list) {        
				Slog.i(TAG, item);                   
			}                                       
        }
    }
    ...
}    

接下来,我们将前面项目的DBHelper.java文件拷贝到和Application的同级目录下。
放入文件的路径:frameworks/base/core/java/android/app/DBHelper.java

package android.app;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

import java.util.ArrayList;
import java.util.HashMap;

public class DBHelper extends SQLiteOpenHelper {

    public static final String DATABASE_NAME = "MyDBName.db";
    public static final String CONTACTS_TABLE_NAME = "contacts";
    public static final String CONTACTS_COLUMN_ID = "id";
    public static final String CONTACTS_COLUMN_NAME = "name";
    public static final String CONTACTS_COLUMN_EMAIL = "email";
    public static final String CONTACTS_COLUMN_STREET = "street";
    public static final String CONTACTS_COLUMN_CITY = "place";
    public static final String CONTACTS_COLUMN_PHONE = "phone";
    private HashMap hp;

    public DBHelper(Context context) {
        super(context, DATABASE_NAME , null, 1);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        // TODO Auto-generated method stub
        db.execSQL(
                "create table contacts " +
                        "(id integer primary key, name text,phone text,email text, street text,place text)"
        );
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // TODO Auto-generated method stub
        db.execSQL("DROP TABLE IF EXISTS contacts");
        onCreate(db);
    }

    public boolean insertContact (String name, String phone, String email, String street,String place) {
        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues contentValues = new ContentValues();
        contentValues.put("name", name);
        contentValues.put("phone", phone);
        contentValues.put("email", email);
        contentValues.put("street", street);
        contentValues.put("place", place);
        db.insert("contacts", null, contentValues);
        return true;
    }

    public Cursor getData(int id) {
        SQLiteDatabase db = this.getReadableDatabase();
        Cursor res =  db.rawQuery( "select * from contacts where id="+id+"", null );
        return res;
    }

    public int numberOfRows(){
        SQLiteDatabase db = this.getReadableDatabase();
        int numRows = (int) DatabaseUtils.queryNumEntries(db, CONTACTS_TABLE_NAME);
        return numRows;
    }

    public boolean updateContact (Integer id, String name, String phone, String email, String street,String place) {
        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues contentValues = new ContentValues();
        contentValues.put("name", name);
        contentValues.put("phone", phone);
        contentValues.put("email", email);
        contentValues.put("street", street);
        contentValues.put("place", place);
        db.update("contacts", contentValues, "id = ? ", new String[] { Integer.toString(id) } );
        return true;
    }

    public Integer deleteContact (Integer id) {
        SQLiteDatabase db = this.getWritableDatabase();
        return db.delete("contacts",
                "id = ? ",
                new String[] { Integer.toString(id) });
    }

    public ArrayList<String> getAllCotacts() {
        ArrayList<String> array_list = new ArrayList<String>();
        //hp = new HashMap();
        SQLiteDatabase db = this.getReadableDatabase();
        Cursor res =  db.rawQuery( "select * from contacts", null );
        res.moveToFirst();
        while(res.isAfterLast() == false){
            array_list.add(res.getString(res.getColumnIndex(CONTACTS_COLUMN_NAME)));
            res.moveToNext();
        }
        return array_list;
    }
}

注意,我们的java文件第一行需要修改为package android.app;;做好了准备工作接下来就是编译我们的源码。在我们修改好以后,这里有一个小技巧,使用git命令去检查我们的内容。

git命令

  • git log:查看提交的记录
    在这里插入图片描述
  • git diff : 代表修改后的差异命令,这里使用键盘的J按键进行向下翻页。
    在这里插入图片描述

上面显示的是我们刚才添加的java文件。

编译Framework模块

make命令的作用

在我们每次修改了源码后,我们都需要将命令make -j8 update-api,下面是命令的解释:

在这里插入图片描述
更多的解释可以看这篇文章《理解 Android Build 系统》

执行编译命令

在这里,我们需要执行编译命令

source build/envsetup.sh
lunch  mk_rolex-userdebug
make -j8 framework
  • 这里的-j8代表的是我们CPU的核数,这里的数字一般是核数的两倍。
  • framework代表的是我们需要编译的模块,指定为framwork模块。

拷贝文件到手机中

当我们执行了编译完成以后,我们需要将<源码目录>/out/target/product/rolex/system/framework路径下的文件夹arm64framework.jar文件拷贝到我们的手机上。

adb remount             								 	//挂载数据库
adb push arm64 /system/framework     						//arm64文件夹
adb push  framework.jar /system/framework   		 	 //framework.jar文件推送到制定目录
adb reboot												//重启手机

验证结果

接下来,我们通过logcat去验证下我们的结果adb logcat -s [tag]

扫描二维码关注公众号,回复: 5597161 查看本文章
adb logcat -s JetmoApplication

在这里插入图片描述
到这里我们成功的从framework层的东西去调用应用的数据库了。

小结

这篇文章我们验证了,可以从framework层去调用应用层App的数据库,需要注意的几个点。

  • 查找关键的Hook点,这里我们选择了Application的onCreate()方法。
  • 添加Java文件时,需要注意文件中需要导入的类库是否存在。
  • 将编译的文件,推送到手机的指定目录下。

总体来说文章内容还是比较简单,细心就可以完成了。

参考链接

https://developer.android.com/training/data-storage/sqlite#java

猜你喜欢

转载自blog.csdn.net/u011195398/article/details/88251819