‘壹’ android源码问题,拨打完电话会更新通话记录列表,通过一个监听来实现查询CallLogProvider,有了解的吗
能否将详细log贴上
这个是2.3 系统还是 4.0 的 还是?
05-09 18:18:36.519: E/DatabaseUtils(393): at android.database.sqlite.SQLiteQueryBuilder.computeProjection(SQLiteQueryBuilder.java:588)
05-09 18:18:36.519: E/DatabaseUtils(393): at android.database.sqlite.SQLiteQueryBuilder.buildQuery(SQLiteQueryBuilder.java:403)
后面的log也多贴一些。
‘贰’ Android开发怎么查看和管理sqlite数据库
在Android中可以使用Eclipse插件DDMS来查看,也可以使用Android工具包中的adb工具来查看。android项目中的sqlite数据库位于/data/data/项目包/databases中。
使用DDMS导出sqlite数据库。
1、首先打开android项目的调试模式,然后找到显示DDMS:
选择DDMS
2、切换到DDMS,显示FileExplorer窗口,找到/data/data/
然后找到程序包的文件夹,打开databases,就能看到sqlite数据库文件了。选择将其导出。
这样就把sqlite数据库文件以文件的方式导出来了,然后使用sqlite界面管理工具如sqliteadministrator、sqliteman或者firefox插件sqlitemanager等打开就可以了。
使用adb工具访问sqlite数据库
AndroidDebugBridge(ADB)是Android的一个通用调试工具,它可以更新设备或模拟器中的代码,可以管理预定端口,可以在设备上运行shell命令,我们知道android是基于linux内核,它的内部文件结构也是采用linux文件组织方式,因此访问它的文件结构需要使用shell。这次我们就会用shell来访问android应用中的sqlite数据库文件。
1、运行cmd,切换到android-sdk目录,运行adb.exe,加上参数shell,出现#号就代表进入了shell命令模式,注意adb要在Android模拟器运行时才能进入shell:
2、shell命令记住两个基本命令ls和cd,类似windows命令提示行中的dir和cd,代表列出当前目录下文件列表和进入到指定目录。了解闭手昌这两个命令之后,就可以找到data/data/项目包名/databases:
找到数据库文件:
接下来就是使用sqlite管理工具来进行轿扒操作了。键入sqlite3数据库名就进入了sqlite管理模式了。
在android的sdk中自带了sqlite3.exe,这是sqlite的官方管理工具,它是一个命令行工具。为了使用方便,将其路径注册到系统环境变量path中,即将;%Android_Home%加在Path中,这样只样运行sqlite3,就能直接打开sqlite管理工具了。
sqlite管理数据库篇
sqlite命令行工具默认是以;结束语句的。所以如果只是一行语句,要在末尾加;,或者在下一行中键入;,这样sqlite命令才会被执行。
sqlite常薯李用命令:
.tables--查看数据库的表列表
.exit--退出sqlite命令行
‘叁’ 如何使用SQLite,Android上SQLite的最佳实践
SQLite3是目前最新的SQLite版本。可以从网站上下载SQLite3的源代码(本书使用的版本是sqlite-3.6.12.tar.gz)。
解压缩后进入sqlite-3.6.12的根目录,首先命令“./configure”生成Makefile文件,接着运行命令“make”对源代码进行编译,最后运行命令“make install”安装SQLite3。安装完毕后,可以运行命令sqlite3查看SQLite3是否能正常运行,如下所示:
[root@localhost ~]# sqlite3
SQLite version 3.6.12
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite>
可以看到,SQLite3启动后会停留在提示符sqlite>处,等待用户输入SQL语句。
在使用SQLite3前需要先了解下SQLite3支持的数据类型。SQLite3支持的基本数据类型主要有以下几类:
NULL
NUMERIC
INTEGER
REAL
TEXT
SQLite3会自动把其他数据类型转换成以上5类基本数据类型,转换规则如下所示:
char、clob、test、varchar—> TEXT
integer—>INTEGER
real、double、float—> REAL
blob—>NULL
其余数据类型都转变成NUMERIC
下面通过一个实例来演示SQLite3的使用方法。
新建一个数据库
新建数据库test.db(使用.db后缀是为了标识数据库文件)。在test.db中新建一个表test_table,该表具有name,、sex、age三列。SQLite3的具体操作如下所示:
[root@localhost home]# sqlite3 test.db
SQLite version 3.6.12
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> create table test_table(name, sex, age);
如果数据库test.db已经存在,则命令“sqlite3 test.db”会在当前目录下打开test.db。如果数据库test.db不存在,则命令“sqlite3 test.db”会在当前目录下新建数据库test.db。为了提高效率,SQLite3并不会马上创建test.db,而是等到第一个表创建完成后才会在物理上创建数据库。
由于SQLite3能根据插入数据的实际类型动态改变列的类型,所以在create语句中并不要求给出列的类型。
创建索引
为了加快表的查询速度,往往在主键上添加索引。如下所示的是在name列上添加索引的过程。
sqlite> create index test_index on test_table(name);
操作数据
如下所示的是在test_table中进行数据的插入、更新、删除操作:
sqlite> insert into test_table values ('xiaoming', 'male', 20);
sqlite> insert into test_table values ('xiaohong', 'female', 18);
sqlite> select * from test_table;
xiaoming|male|20
xiaohong|female|18
sqlite> update test_table set age=19 where name = 'xiaohong';
sqlite> select * from test_table;
xiaoming|male|20
xiaohong|female|19
sqlite> delete from test_table where name = 'xiaoming';
sqlite> select * from test_table;
xiaohong|female|19
批量操作数据库
如下所示的是在test_table中连续插入两条记录:
sqlite> begin;
sqlite> insert into test_table values ('xiaoxue', 'female', 18);
sqlite> insert into test_table values ('xiaoliu', 'male', 20);
sqlite> commit;
sqlite> select * from test_table;
xiaohong|female|19
xiaoxue|male|18
xiaoliu|male|20
运行命令commit后,才会把插入的数据写入数据库中。
数据库的导入导出
如下所示的是把test.db导出到sql文件中:
[root@localhost home]# sqlite3 test.db ".mp" > test.sql;
test.sql文件的内容如下所示:
BEGIN TRANSACTION;
CREATE TABLE test_table(name, sex, age);
INSERT INTO "test_table" VALUES('xiaohong','female',19);
CREATE INDEX test_index on test_table(name);
COMMIT;
如下所示的是导入test.sql文件(导入前删除原有的test.db):
[root@localhost home]# sqlite3 test.db < test.sql;
通过对test.sql文件的导入导出,可以实现数据库文件的备份。
11.2.2 SQLite3的C接口
以上介绍的是SQLite3数据库的命令操作方式。在实际使用中,一般都是应用程序需要对数据库进行访问。为此,SQLite3提供了各种编程语言的使用接口(本书介绍C语言接口)。SQLite3具有几十个C接口,下面介绍一些常用的C接口。
sqlite_open
作用:打开SQLite3数据库
原型:int sqlite3_open(const char *dbname, sqlite3 **db)
参数:
dbname:数据库的名称;
db:数据库的句柄;
sqlite_colse
作用:关闭SQLite3数据库
原型:int sqlite_close(sqlite3 *db)
例如:
test.c:
#include <stdio.h>
#include <sqlite3.h>
static sqlite3 *db=NULL;
int main()
{
int rc;
rc= sqlite3_open("test.db", &db);
if(rc)
{
printf("can't open database!\n");
}
else
{
printf("open database success!\n");
}
sqlite3_close(db);
return 0;
}
运行命令“gcc –o test test.c –lsqlite3”进行编译,运行test的结果如下所示:
[root@localhost home]# open database success!
sqlite_exec
作用:执行SQL语句
原型:int sqlite3_exec(sqlite3 *db, const char *sql, int (*callback)(void*,int,char**,char**), void *, char **errmsg)
参数:
db:数据库;
sql:SQL语句;
callback:回滚;
errmsg:错误信息
例如:
test.c:
#include <stdio.h>
#include <sqlite3.h>
static sqlite3 *db=NULL;
static char *errmsg=NULL;
int main()
{
int rc;
rc = sqlite3_open("test.db", &db);
rc = sqlite3_exec(db,"insert into test_table values('bao', 'male', 24)", 0, 0, &errmsg);
if(rc)
{
printf("exec fail!\n");
}
else
{
printf("exec success!\n");
}
sqlite3_close(db);
return 0;
}
编译完成后,运行test的结果如下所示:
[root@localhost home]# ./test
exec success!
[root@localhost home]# sqlite3 test.db
SQLite version 3.6.11
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> select * from test_table;
bao|male|24
sqlite3_get_table
作用:执行SQL查询
原型:int sqlite3_get_table(sqlite3 *db, const char *zSql, char ***pazResult, int *pnRow, int *pnColumn, char **pzErrmsg)
参数:
db:数据库;
zSql:SQL语句;
pazResult:查询结果集;
pnRow:结果集的行数;
pnColumn:结果集的列数;
errmsg:错误信息;
sqlite3_free_table
作用:注销结果集
原型:void sqlite3_free_table(char **result)
参数:
result:结果集;
例如:
test.c:
#include <stdio.h>
#include <sqlite3.h>
static sqlite3 *db=NULL;
static char **Result=NULL;
static char *errmsg=NULL;
int main()
{
int rc, i, j;
int nrow;
int ncolumn;
rc= sqlite3_open("test.db", &db);
rc= sqlite3_get_table(db, "select * from test_table", &Result, &nrow, &ncolumn,
&errmsg);
if(rc)
{
printf("query fail!\n");
}
else
{
printf("query success!\n");
for(i = 1; i <= nrow; i++)
{
for(j = 0; j < ncolumn; j++)
{
printf("%s | ", Result[i * ncolumn + j]);
}
printf("\n");
}
}
sqlite3_free_table(Result);
sqlite3_close(db);
return 0;
}
编译完成后,运行test的结果如下所示:
[root@localhost home]# ./test
query success!
xiaohong | female | 19 |
xiaoxue | female | 18 |
xiaoliu | male | 20 |
bao | male | 24 |
sqlite3_prepare
作用:把SQL语句编译成字节码,由后面的执行函数去执行
原型:int sqlite3_prepare(sqlite3 *db, const char *zSql, int nByte, sqlite3_stmt **stmt, const char **pTail)
参数:
db:数据库;
zSql:SQL语句;
nByte:SQL语句的最大字节数;
stmt:Statement句柄;
pTail:SQL语句无用部分的指针;
sqlite3_step
作用:步步执行SQL语句字节码
原型:int sqlite3_step (sqlite3_stmt *)
例如:
test.c:
#include <stdio.h>
#include <sqlite3.h>
static sqlite3 *db=NULL;
static sqlite3_stmt *stmt=NULL;
int main()
{
int rc, i, j;
int ncolumn;
rc= sqlite3_open("test.db", &db);
rc=sqlite3_prepare(db,"select * from test_table",-1,&stmt,0);
if(rc)
{
printf("query fail!\n");
}
else
{
printf("query success!\n");
rc=sqlite3_step(stmt);
ncolumn=sqlite3_column_count(stmt);
while(rc==SQLITE_ROW)
{
for(i=0; i<2; i++)
{
printf("%s | ", sqlite3_column_text(stmt,i));
}
printf("\n");
rc=sqlite3_step(stmt);
}
}
sqlite3_finalize(stmt);
sqlite3_close(db);
return 0;
}
编译完成后,运行test的结果如下所示:
[root@localhost home]# ./test
query success!
xiaohong | female | 19 |
xiaoxue | female | 18 |
xiaoliu | male | 20 |
bao | male | 24 |
在程序中访问SQLite3数据库时,要注意C API的接口定义和数据类型是否正确,否则会得到错误的访问结果。
‘肆’ 如何监听一个程序
监听一个程序的数据库操作可以通过多种方式进行,具体取决于你所处的环境和你具体想要监听什么。如果你想监听一个程序对SQLite数据库的操作,你可以使用以下几种方法:
1. 日志记录(Logging):你可以开启SQLite的日志功能来记录所有发生的数据库操作。然而,SQLite本皮指身不直接支持详细的日志记录,所以你可能需要使用一些SQLite的封装库,如Python的sqlite3模块,或者其他语言的类似库,来捕捉并记录操作。
2. 数据库触发器(Database Triggers):在SQLite数据库中,你可以使用触发器来监听数据库的某燃判配些操作。触发器是一种特殊类型的存储过程,它会在数据库上的特定事件(如INSERT、UPDATE或DELETE)发生时自动执行。
3. 代理或中间件(Proxies or Middleware):你可以在应用程序和数据库之间插入一层代理或中间件,所有的数据库会通过这个中间层。这样,你就可以在这个中间层捕获、记录甚至修改所有的数据库请求和响应。这种方法需要一些编程技巧和对网络编程的理解。
4. SQLite监控工具:有一些专门用于监控SQLite数据库的工具,如DB Browser for SQLite、SQLite Inspector等。这些工具可以让你查看数据库的实时状冲伏态,包括正在执行的查询、改变的表格等。
5. 系统调用跟踪(System Call Tracing):如果你有足够的系统编程知识,你可以使用如strace(Linux)、DTrace(BSD)或ProcMon(Windows)等工具来跟踪程序对SQLite数据库文件的系统调用。这样可以让你看到程序在什么时候读取或写入数据库文件,以及读写的具体内容。这种方法相对复杂,需要对操作系统和系统编程有深入的理解。
‘伍’ 有哪些比较好的AndroidSQLite开源工具类(android中的sqlite数据库具有哪些特点)
是一个免费的开源的、简易的、遵循Apache2开源协议发布的Android开发框架,其开发宗旨是简单、快速的进行Android应用程序的开发,包含Androidmvc、简易sqliteorm、ioc模块、封装Androidhttpclitent的http模块,具有快速构建文件缓存功能,无需考虑缓存文件的格式,都可以非常轻松的实现缓存,它还基于文件缓存模块实现了图片缓存功能,在android中加载的图片的时候,对oom的问题,和对加载图片错位的问题都轻易解决。他还包括了一个手机开发中经常应用的实用工具类,如日志管理,配置文件管理,android下载器模块,网络切换检测等等工具。
目前主要有以下模块:
MVC模块:实现视图与模型的分离。
ioc模块:android中的ioc模块,完全注解方式就可以进行UI绑定、res中的资源的读取、以及对象的初始化。
数据库模块:android中的orm框架,使用了线程池对sqlite进行操作。
http模块:通过httpclient进行封装http数据请求,支持异步及同步方式加载。
缓存模块:通过简单的配置及设计可以很好的实现缓存,对缓存可以随意的配置
图片缓存模块:imageview加载图片的时候无需考虑图片加载过程中出现的oom和android容器快速滑动时候出现的图片错位等现象。
配迅扰颂置器模块:可以对简易的实现配对配置的操作,目前配置文件可以支持Preference、Properties对配置进行存取。
日志打印模块:可以较快的轻易的是实现日志打印,支持日志打印的扩展,目前支持对sdcard写入本地打印、以及控制台打印
下载器模块:可以简单的实现多线程下载、后台下载、断点续传、对下载进李肆行控制、如开始、暂停、删除等亩郑等。
网络状态检测模块:当网络状态改变时,对网络状态进行检测。
‘陆’ 如何使用SQLite,Android上SQLite的最佳实践
按照我的认识,SQLite工作的方式,基本上不可能会破坏你的数据库,除非代码里有bug或者有硬件问题。
因伍圆模此,腔缓我推荐这样使用:创建一个SQLiteOpenHelper静腔掘态对象。什么时候去close它呢?不需要。当app关闭,它会自动释放文件引用。
‘柒’ 如何使用SQLite,Android上SQLite的最佳实践
前些时候看到兴趣小组里有人问“Android上SQLite的最佳实践”是什么,好奇地搜了一下,确实没有一个好一点的指导文档,平时的使用也只是简单的拷贝code,并没有深入的研究过。以下是我看到的Kevin关于其使用的心得,原文的大体的意思是:
Android例子涵盖了一些Sqlite的基本用法,但它们并没有深入地给出合理的使用方法,更重要的是,不合理的使用方法。大多数例子和文档只是涉及最基本的数据库查询,或者教你如何创建一个ContentProvider。从来不提及的地方像:
· 什么地方创建和保存SQLiteOpenHelper实例?
· 可以有多少个实例?
· 多线程同时访问数据库有没有什么要担心的?
基本的内容是,你可以历宏哗任意次数地连接Sqlite数据库,而且Android系统也支持你这样做。Sqlite拥有文件级别的锁,用来同步访问和防止错误。如果你只知道这些,那么,将会给你带来很大的痛苦。开源的一个好处是,你可以深入代码一探究竟。从代码和一些测试中,我了解到以下事实:
· Sqlite拥有文件级别的锁。许多线程可以同时读,但只有一个可以写。锁阻止多个同时写入。
· Android在SQLiteDatabase中实现了一些java锁来确保动作是同步进行。
· 如果你用多个线程疯狂地访问数据库,你的数据库不会(或不应该)崩溃。
没提到的是,如果你通过多个不同的真实连接同时写数据库,其中的某个会失败,它不会等到前一个完成后继续写入。简单地,不会写入你的改变,更糟糕的是,你也得不到一个异常,只是在LogCat中输出一些message,仅此而已。
SQLiteOpenHelper类做了一些有趣的事。尽管它有方法可以获得一个只读的连接和可读写的连接,但实质上它们是同一个连接。假设没有文件写错误的话,只读的连接实质上就是一个可读写的连接。有趣吧。因此,如果你的app中使用一个helper的话,即便从多线程中使用,你也从未使用多个连接。
同样,一个helper中只有一个SQLiteDatabase的实例,这个实例中实现了一些java锁。因此,当你绝喊正在执行数据库的操作时,其它db的操作都将锁定。即便是你使用多个线程来做这些事以便优化数据库的性能,坏消息,没有什么用。
按照我的认识,SQLite工作的方式,基本上不可能会破坏你的数据库,除非代码里有bug或者有硬件问题。
因此,我推荐这样使用:创建一个SQLiteOpenHelper静态对象。什么时候去close它呢?不需要。当app关闭,它会自动释放文件引用。
但是,会不会有“close() was never explicitly called on database”异常呢?
如果你注意的话,当连接挂在那里的时候,你没有得到那个异常。你只是在连接已经建立,而你又尝试打开另一个时才会有异常。因此,你只需要打开一次连接。
像这样来使用:
public class DatabaseHelper extends OrmLiteSqliteOpenHelper
{
private static DatabaseHelper instance;public static synchronized DatabaseHelper getHelper(Context context)
{
if (instance == null)
instance = new DatabaseHelper(context);
肢行
return instance;
}
//Other stuff...
}
‘捌’ android怎么做到断电瞬间将数据存到数据库中,我的adroid机器是没电池的,所以写了个监听拔电广播但不行
断电瞬间配早就1s,Android用的数行卖颂据库是SQLite,1s之档郑内你把手机所有数据存到你创建的数据库,你在和我开玩笑嘛?每个APP都有数据库有数据表,而且是加密的,你第一步读取加密数据库都不行,还怎么复制出来