工作,学习,生活,这里将会有一些记录. 备用域名:http://meisw.wdlinux.cn 注册 | 登陆
浏览模式: 标准 | 列表2011年06月的文章

jpgraph

<?php
include ("../jpgraph.php");
include ("../jpgraph_line.php");//将要用于图表创建的数据存放在数组中
$data =array(19,23,34,38,45,67,71,78,85,90,96,145);
$graph = new Graph(500,300);                                                    //创建新的Graph对象
$graph->SetScale("textlin");                                                   //设置刻度样式
$graph->img->SetMargin(30,30,80,30);                    //设置图表边界
$graph->title->Set("CDN TrafficTotal");        //设置图表标题
$graph->title->SetColor("blue");
$graph->title->SetMargin(20); // Create the linear plot
$lineplot=new LinePlot($data);              // 创建新的LinePlot对象
$lineplot->SetLegend("Line(Mbits)");   //设置图例文字
$lineplot->SetColor("red");                 // 设置曲线的颜色 // Add the plot to the graph
$graph->Add($lineplot);                     //在统计图上绘制曲线 // Display the graph
$graph->Stroke();                         //输出图像
?>

 

-----------

$graph = new Graph(300,200,"auto");    
$graph->img->SetMargin(40,30,20,40);
$graph->SetScale("textlin");
$graph->SetShadow();

// Create a bar pot
$bplot = new BarPlot($datay);
$bplot->SetFillColor("orange");
$graph->Add($bplot);

// Display the graph
$graph->Stroke();

 

-------------

JPGRAPH生成统计图

JpGRAPHP下载地址: http://www.aditus.nu/jpgraph/ 有两个版本, 一个适用PHP 4.0, 还有一个适用PHP 5.1 以上的,如果刚好是PHP 5.0.X 的需要升到5.1以上. (我有试过5.0的运行不起来的).

如果你要用到中文, 需要修改一下配置文件 /src/jpgraph.php
替换 $font_family=FF_FONT1 为 $font_family=FF_SIMSUN

如果你设置的文件编码是UTF-8, 就需要修改掉一些文件里面的代码,不然就会乱码
方法1 在文件 /src/jpgraph_ttf.inc.php
注释掉下面这段代码
//    elseif( $aFF === FF_SIMSUN ) {
//        // Do Chinese conversion
//        if( $this->g2312 == null ) {
//        include_once 'jpgraph_gb2312.php' ;
//        $this->g2312 = new GB2312toUTF8();
//        }
//        return $this->g2312->gb2utf8($aTxt);
//    }

方法2 文件jpgraph_gb2312.php
function gb2utf8($gb) { //在此之后直接加上下面这句代码
return $gb

语言包:
windows系统在C:/WINDOWS/Fonts/下有所有的语言包
LINUX系统,是要自己指定路径的 如果出现语言包找不到的情况,可以自己新建一个目录并且把语言文件上传上去,并且修改下 /src/jpgraph.php 文件里定义的语言包路径
if (!defined('TTF_DIR')) {
    if (strstr( PHP_OS, 'WIN') ) {
    $sroot = getenv('SystemRoot');
        if( empty($sroot) ) {
        $t = new ErrMsgText();
        $msg = $t->Get(12,$file,$lineno);
        die($msg);
        }
    else {
      define('TTF_DIR', $sroot.'/fonts/');
        }
    } else {
    define('TTF_DIR','/usr/share/fonts/truetype/');
    //修改这个路径
    }
}

/src/Examples目录下有很多例子,我只画了一个线状图。

 

require_once('include/jpgraph.php'); //Graph类
require_once('include/jpgraph_line.php'); //LinePlot 类
$aAxisType = 'intlin'//第一个int是X轴类型第2个lin是Y轴类型
$yScaleMin = 0//Y轴最小值, 如果不需要设置,可以为空,或者NULL,下同
$yScaleMax = 11//Y轴最大值
$xScaleMin = 1//X轴最大值
$xScaleMax = 24//X轴最大值

$unitType = '月份';

  
$chartDataTmpArr = array('1' => '1', '2' => '0', '3' => '4', '4' => '5', '5' => '7', '6' => '8', '7' => '4', '8' => '6', '9' => '8', '10' => '7', '11' => '4', '12' => '5', '13' => '4', '14' => '6', '15' => '4', '16' => '2', '17' => '2', '18' => '2', '19' => '2', '20' => '7', '21' => '6', '22' => '1', '23' => '4', '24' => '4');

$chartDataTmpArr2 = array('1' => '2', '2' => '0', '3' => '2', '4' => '2', '5' => '8', '6' => '9', '7' => '5', '8' => '7', '9' => '9', '10' => '7', '11' => '4', '12' => '7', '13' => '2', '14' => '4', '15' => '5', '16' => '6', '17' => '0', '18' => '3', '19' => '6', '20' => '5', '21' => '8', '22' => '9', '23' => '4', '24' => '4');
$graph = new Graph($width = 780 , $height = 400); //创建新的Graph对象
$graph->SetScale($aAxisType, $yScaleMin, $yScaleMax, $xScaleMin, $xScaleMax); //设置刻度模式SetScale($aAxisType,$aYMin=1,$aYMax=1,$aXMin=1,$aXMax=1)

$graph->img->SetMargin(40, 20, 50, 50) ; //设置图表边界
$title = date("Y-m-d H:i:s")."统计图";
$graph->title->SetFont(FF_SIMSUN,FS_BOLD); //设置图表标题的字体类型
$graph->title->Set($wholeTitle);
$graph->title->SetMargin (20);

$graph->xaxis->title->SetFont(FF_SIMSUN);
$graph->xaxis->title->Set($unitType);
$graph->xaxis->title->SetMargin(14);

$graph->legend->SetLineWeight(2); //设置图例文字的字体 

$lineplot = new LinePlot($chartDataTmpArr); //创建要画的一地条曲线的对象
$lineplot->SetWeight(2); //曲线的线宽

$lineplot->SetLegend("进入");//设置图例文字
$graph->legend->Pos0.025, 0.08, "right","center" ); //图例文字框的位置 0.025,0.08 是以右上角为基准的,0.025是距左右距离,0.08是上下距离。
$graph->legend->SetLayout('1'); //如果有两条曲线,他们的图例文字并排放置。
$graph->legend->SetFrameWeight(0); //图例文字外框边框border设置为0
$graph->legend->SetFillColor('#C8C8C8'); //图例文字框内的填充颜色
$graph->legend->SetShadow('#C8C8C8', 0); //设置图例文字框的阴影部分颜色和border
$lineplot->SetColor("orange"); //设置曲线颜色
$graph->Add($lineplot); //在统计图上绘制曲线
    
$lineplot2 = new LinePlot($chartDataTmpArr2); //创建一条新的曲线对象
$lineplot2->SetLegend("出去");
$lineplot2->SetWeight(2);
$lineplot2->SetColor("blue"); 
$graph->Add($lineplot2);

$filename = 'images/strock/'.time().'.png';
$graph->Stroke($filename);

/*如果这里直接调用Stroke()函数,图片会从cache里直接输出,但是有个问题,网页上只能为这个曲线图输出,

别的内容在这个曲线图之前输出就会出错。别的内容放在这个曲线图之后都没输出了。

所以需要传递一个文件名,这样在本地就会存储内容。*/

echo '<img src="'.$filename.'" />';

/* 存放图片的文件夹会有比较多的图片,如果是LINUX服务器的话可以设置一个cronjob,定时清空下图片。

还有另一种方法 比如画图文件为 drawImage.php 可以用另一个文件viewImage.php以内容<img src ="drawImage.php" /> 的方法把图片载入进来,这样可以不用生成图片文件, 

而且图片显示位置可以随便放. 不过这样做是有问题的,比如说他要载入的数据是动态的, 

那就没办法把那么一大串的数组也都穿进去. 或许可以用serialize 函数来处理一堆的数据,

再在drawImage.php中用unserialize函数还原数据.没试过. */

再谈关于ubuntu的root密码问题

如何设定/改变/启用 root 使用者的密码?

  sudo passwd root

  为了启用 root 帐号 (也就是 设置一个口令) 使用:

  sudo passwd root

  当你使用完毕后屏蔽 root 帐号 使用:

  sudo passwd -l root

  这个将锁住 root 帐号. 


  如何在终端机模式下切换到 root 身份?

  sudo -s -H

  Password: <在这注明您的密码>缺省禁止 root 的好处包括了以下内容.

  起初 Ubuntu 团队希望安装尽可能的简单. 不使用 root , 在安装期间的两个用户交互步骤可以省略. (科林·沃森)

  更进一步, 如果在安装中使用 root, 用户将被要求永远记住他们选择的密码--即使他们很少使用到它. Root 密码经常被对 Unix 安全模型不熟悉的用户忘记. (马特·齐默曼)

  它防止了缺省登录时 "我能做任何事情" --在较大的变化发生之前,你将被提示输入口令,这可以使你考虑你这样做的结果. 如果你作为 root 登录, 你可以删除一些 "没用的文件夹" 并且不会意识到你正处于错误的目录,那时已经太晚了. 它是在 Unix 下长时间使用 "su-command-^D" 练习的情况下,代替一直呆在 root shell--除非你做严重的系统维护 (那时你仍然可以使用 "sudo su"). (吉姆·奇塔姆 和 安德鲁·索巴拉)

  Sudo 增加了运行命令的日志记录 (在 /var/log/auth.log). 如果你陷入困境, 你总是可以返回并看见那些运行的命令.

  安全

  与传统的 superuser 模型相比,这种方法有不同的利弊,两者都不总是显示优良的.

  在鼓励使用 root 权限执行一个单独的命令, sudo 好过打开一个 shell:

  减少使用 root 权限的时间总耗用, 降低了不注意使用 root 执行命令的风险

  提供了有用的审核痕迹

  有一个单独的 root 密码 (传统模型) 提供了一层额外的保护,当如果一个管理员的密码被侵害时。

  无论怎样, 如果管理员 (使用 sudo 或 su 变成 root) 被侵害, 攻击者一般可以通过一次间接的攻击来获得 root。

-----------------------

Ubuntu在默认情况下是不启用root用户的,所以这对于一下对于linux命令不熟悉的用户在进行文件系统管理时不是很方便,例如要在主目录下粘贴一下东西,新建一些文件,当然用命令是很简单的,但也有例外,这就需要启用root用户来进行可视化管理,首先要建立root用户
sudo passwd
Password: <--- 输入安装时那个用户的密码(新建用户的时候千万不能跳过)
Enter new UNIX password: <--- 新的Root用户密码
Retype new UNIX password: <--- 重复新的Root用户密码
passwd:已成功更新密码
这样就建立一root用户,在只执行这一步时笔者测试就可以用root登录,但有的文章称还要允许root登录,下面就介绍怎样允许root登录允许root登录,
如果要允许root登录(不推荐),则这样操作:
gksu /usr/sbin/gdmsetup
(或者使用桌面菜单:系统>系统管理>登录窗口)
点“安全”选项页,选择“允许本地管理员登录”。
注:这一步依赖上一步

不输入密码直接登录
在论坛上也看见有人抱怨,家中的Ubuntu不能像Window$那样──不用输入密码就能登录。其实同样能做到:
就在上一步的“安全”选项页中,勾选:
“启用自动登录”,“用户”选择

----------------------------

刚入Ubuntu的人(base on debian),大多会因为安装中没有提示root密码而不太清楚为什么会这样。根据Ubuntu的中文文档,总结了本文。

关键词:

如何设定/改变/启用 root 使用者的密码?

sudo passwd root

为了启用 root 帐号 (也就是 设置一个口令) 使用:

sudo passwd root
 

当你使用完毕后屏蔽 root 帐号 使用:

sudo passwd -l root

这个将锁住 root 帐号.

如何在终端机模式下切换到 root 身份?

sudo -s -H

Password: <在这注明您的密码>缺省禁止 root 的好处包括了以下内容.

起初 Ubuntu 团队希望安装尽可能的简单. 不使用 root , 在安装期间的两个用户交互步骤可以省略. (科林·沃森)

更进一步, 如果在安装中使用 root, 用户将被要求永远记住他们选择的密码–即使他们很少使用到它. Root 密码经常被对 Unix 安全模型不熟悉的用户忘记. (马特·齐默曼)

它防止了缺省登录时 "我能做任何事情" –在较大的变化发生之前,你将被提示输入口令,这可以使你考虑你这样做的结果. 如果你作为 root 登录, 你可以删除一些 "没用的文件夹" 并且不会意识到你正处于错误的目录,那时已经太晚了. 它是在 Unix 下长时间使用 "su-command-^D" 练习的情况下,代替一直呆在 root shell–除非你做严重的系统维护 (那时你仍然可以使用 "sudo su"). (吉姆·奇塔姆 和 安德鲁·索巴拉)

Sudo 增加了运行命令的日志记录 (在 /var/log/auth.log). 如果你陷入困境, 你总是可以返回并看见那些运行的命令. (安德鲁·Zbikowski)

安全

与传统的 superuser 模型相比,这种方法有不同的利弊,两者都不总是显示优良的.

在鼓励使用 root 权限执行一个单独的命令, sudo 好过打开一个 shell:

减少使用 root 权限的时间总耗用, 降低了不注意使用 root 执行命令的风险

提供了有用的审核痕迹

有一个单独的 root 密码 (传统模型) 提供了一层额外的保护,当如果一个管理员的密码被侵害时。

无论怎样, 如果管理员 (使用 sudo 或 su 变成 root) 被侵害, 攻击者一般可以通过一次间接的攻击来获得 root

pureftpd-mysql.conf

MYSQLSocket     /tmp/mysql.sock
MYSQLServer     localhost
MYSQLPort       3306
MYSQLUser       ftp
MYSQLPassword   123456
MYSQLDatabase   ftpusers
MYSQLCrypt      md5
MYSQLGetPW      SELECT Password FROM users WHERE User="\L" AND Status="1" AND (Ipaddress = "*" OR Ipaddress LIKE "\R")
MYSQLGetUID     SELECT Uid FROM users WHERE User="\L" AND Status="1" AND (Ipaddress = "*" OR Ipaddress LIKE "\R")
MYSQLGetGID     SELECT Gid FROM users WHERE User="\L" AND Status="1" AND (Ipaddress = "*" OR Ipaddress LIKE "\R")
MYSQLGetDir     SELECT Dir FROM users WHERE User="\L" AND Status="1" AND (Ipaddress = "*" OR Ipaddress LIKE "\R")
MySQLGetQTASZ   SELECT QuotaSize FROM users WHERE User="\L"
MySQLGetBandwidthUL SELECT ULBandwidth FROM users WHERE User="\L" AND Status="1" AND (Ipaddress = "*" OR Ipaddress LIKE "\R")
MySQLGetBandwidthDL SELECT DLBandwidth FROM users WHERE User="\L" AND Status="1" AND (Ipaddress = "*" OR Ipaddress LIKE "\R")

 

--------------------------------------------

# If you want to use the Socket connect methode comment out the
# Lines with MMYSQLServer and MYSQLPort.
# If you want to use the Port methode comment out the MYSQLSocket line
#//IMPORTENT!!!If display 530 error,please check the following MYSQL parameter!!
MYSQLSocket     /tmp/mysql.sock
MYSQLServer     localhost
MYSQLPort       3306
MYSQLUser       ftp
MYSQLPassword   123456
MYSQLDatabase   ftpusers
MYSQLCrypt      md5

# In the following directives, parts of the strings are replaced at
# run-time before performing queries :
#
# \L is replaced by the login of the user trying to authenticate.
# \I is replaced by the IP address the user connected to.
# \P is replaced by the port number the user connected to.
# \R is replaced by the IP address the user connected from.
# \D is replaced by the remote IP address, as a long decimal number.
#
# Very complex queries can be performed using these substitution strings,
# especially for virtual hosting.


# Query to execute in order to fetch the password

MYSQLGetPW      SELECT Password FROM users WHERE User="\L" AND Status="1" AND (Ipaddress = "*" OR Ipaddress LIKE "\R")


# Query to execute in order to fetch the system user name or uid

MYSQLGetUID     SELECT Uid FROM users WHERE User="\L" AND Status="1" AND (Ipaddress = "*" OR Ipaddress LIKE "\R")


# Optional : default UID - if set this overrides MYSQLGetUID

#MYSQLDefaultUID 1000


# Query to execute in order to fetch the system user group or gid

MYSQLGetGID     SELECT Gid FROM users WHERE User="\L" AND Status="1" AND (Ipaddress = "*" OR Ipaddress LIKE "\R")

# Optional : default GID - if set this overrides MYSQLGetGID

#MYSQLDefaultGID 1000


# Query to execute in order to fetch the home directory

MYSQLGetDir     SELECT Dir FROM users WHERE User="\L" AND Status="1" AND (Ipaddress = "*" OR Ipaddress LIKE "\R")

# Optional : query to get the maximal number of files
# Pure-FTPd must have been compiled with virtual quotas support.

# MySQLGetQTAFS  SELECT QuotaFiles FROM users WHERE User="\L"

# Optional : query to get the maximal disk usage (virtual quotas)
# The number should be in Megabytes.
# Pure-FTPd must have been compiled with virtual quotas support.

# MySQLGetQTASZ  SELECT QuotaSize FROM users WHERE User="\L"


# Optional : ratios. The server has to be compiled with ratio support.

# MySQLGetRatioUL SELECT ULRatio FROM users WHERE User="\L"
# MySQLGetRatioDL SELECT DLRatio FROM users WHERE User="\L"


# Optional : bandwidth throttling.
# The server has to be compiled with throttling support.
# Values are in KB/s .

MySQLGetBandwidthUL SELECT ULBandwidth FROM users WHERE User="\L" AND Status="1" AND (Ipaddress = "*" OR Ipaddress LIKE "\R")
MySQLGetBandwidthDL SELECT DLBandwidth FROM users WHERE User="\L" AND Status="1" AND (Ipaddress = "*" OR Ipaddress LIKE "\R")

# Enable ~ expansion. NEVER ENABLE THIS BLINDLY UNLESS :
# 1) You know what you are doing.
# 2) Real and virtual users match.

# MySQLForceTildeExpansion 1


# If you upgraded your tables to transactionnal tables (Gemini,
# BerkeleyDB, Innobase...), you can enable SQL transactions to
# avoid races. Leave this commented if you are using the
# traditionnal MyIsam databases or old (< 3.23.x) MySQL versions.

# MySQLTransactions On

查看/修改Linux时区和时间

查看/修改Linux时区和时间

  一、时区

  1. 查看当前时区

  date -R

  2. 修改设置时区

  方法(1)

  tzselect

  方法(2) 仅限于RedHat Linux 和 CentOS

  timeconfig

  方法(3) 适用于Debian

  dpkg-reconfigure tzdata

  3. 复制相应的时区文件,替换系统时区文件;或者创建链接文件

  cp /usr/share/zoneinfo/$主时区/$次时区 /etc/localtime

  在中国可以使用:

  cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

  二、时间

  1、查看时间和日期

  date

  2、设置时间和日期

  将系统日期设定成1996年6月10日的命令

  date -s 06/22/96

  将系统时间设定成下午1点52分0秒的命令

  date -s 13:52:00

  3. 将当前时间和日期写入BIOS,避免重启后失效

  hwclock -w

  三、定时同步时间

  * * * * * /usr/sbin/ntpdate 210.72.145.44 > /dev/null 2>&1

 

------

发现用tzselect改的似乎不生效,重起也不行

Linux修改时区不用重启的方法

安装虚拟机的时候,没太注意时区,装好后发现时区比中国上海的慢了16个小时,寻得一些方法,分享给大家:

  

  时区的配置文件是/etc/sysconfig/clock。用tzselect命令就可以修改这个配置文件,根据命令的提示进行修改就好了。

  但是在实际工作中,发现这种方式是不能够使得服务器上的时间设置马上生效的,而且使用ntpdate去同步时间服务器也不能够更改时间。即使你使用了 date命令手工设置了时间的话,如果使用ntpdate去进行时间同步的话,时间又会被改动到原来的错误时区的时间。而生产的机器往往是非常重要的,不能够进行重启等操作。

  如果要修改时区并且马上生效,可以更换/etc/localtime 文件来实现。比如修改时区为中国上海,那么就可以使用如下的命令来使得时区的更改生效。

  cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

  然后最好使用下面的命令将更改写入bios。

  hwclock

  --------------------------------

  具体操作:

  [root@localhost ~]# cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

  cp: overwrite `/etc/localtime'? y

  [root@localhost ~]# date

  Sat Feb 20 16:04:43 CST 2010

  [root@localhost ~]# hwclock

  Sat 20 Feb 2010 04:05:12 PM CST -0.474966 seconds

Android 开发中使用 SQLite 数据库

SQLite 介绍

SQLite 一个非常流行的嵌入式数据库,它支持 SQL 语言,并且只利用很少的内存就有很好的性能。此外它还是开源的,任何人都可以使用它。许多开源项目((Mozilla, PHP, Python)都使用了 SQLite.

SQLite 由以下几个组件组成:SQL 编译器、内核、后端以及附件。SQLite 通过利用虚拟机和虚拟数据库引擎(VDBE),使调试、修改和扩展 SQLite 的内核变得更加方便。


图 1. SQLite 内部结构
图 1. SQLite 内部结构

SQLite 基本上符合 SQL-92 标准,和其他的主要 SQL 数据库没什么区别。它的优点就是高效,Android 运行时环境包含了完整的 SQLite。

SQLite 和其他数据库最大的不同就是对数据类型的支持,创建一个表时,可以在 CREATE TABLE 语句中指定某列的数据类型,但是你可以把任何数据类型放入任何列中。当某个值插入数据库时,SQLite 将检查它的类型。如果该类型与关联的列不匹配,则 SQLite 会尝试将该值转换成该列的类型。如果不能转换,则该值将作为其本身具有的类型存储。比如可以把一个字符串(String)放入 INTEGER 列。SQLite 称这为“弱类型”(manifest typing.)。

此外,SQLite 不支持一些标准的 SQL 功能,特别是外键约束(FOREIGN KEY constrains),嵌套 transcaction 和 RIGHT OUTER JOIN 和 FULL OUTER JOIN, 还有一些 ALTER TABLE 功能。

除了上述功能外,SQLite 是一个完整的 SQL 系统,拥有完整的触发器,交易等等。


Android 集成了 SQLite 数据库

Android 在运行时(run-time)集成了 SQLite,所以每个 Android 应用程序都可以使用 SQLite 数据库。对于熟悉 SQL 的开发人员来时,在 Android 开发中使用 SQLite 相当简单。但是,由于 JDBC 会消耗太多的系统资源,所以 JDBC 对于手机这种内存受限设备来说并不合适。因此,Android 提供了一些新的 API 来使用 SQLite 数据库,Android 开发中,程序员需要学使用这些 API。

数据库存储在 data/< 项目文件夹 >/databases/ 下。


Android 开发中使用 SQLite 数据库

Activites 可以通过 Content Provider 或者 Service 访问一个数据库。下面会详细讲解如果创建数据库,添加数据和查询数据库。

创建数据库

Android 不自动提供数据库。在 Android 应用程序中使用 SQLite,必须自己创建数据库,然后创建表、索引,填充数据。Android 提供了 SQLiteOpenHelper 帮助你创建一个数据库,你只要继承 SQLiteOpenHelper 类,就可以轻松的创建数据库。SQLiteOpenHelper 类根据开发应用程序的需要,封装了创建和更新数据库使用的逻辑。SQLiteOpenHelper 的子类,至少需要实现三个方法:

  • 构造函数,调用父类 SQLiteOpenHelper 的构造函数。这个方法需要四个参数:上下文环境(例如,一个 Activity),数据库名字,一个可选的游标工厂(通常是 Null),一个代表你正在使用的数据库模型版本的整数。
  • onCreate()方法,它需要一个 SQLiteDatabase 对象作为参数,根据需要对这个对象填充表和初始化数据。
  • onUpgrage() 方法,它需要三个参数,一个 SQLiteDatabase 对象,一个旧的版本号和一个新的版本号,这样你就可以清楚如何把一个数据库从旧的模型转变到新的模型。

下面示例代码展示了如何继承 SQLiteOpenHelper 创建数据库:

public class DatabaseHelper extends SQLiteOpenHelper {     
  DatabaseHelper(Context context, String name, CursorFactory cursorFactory, int version) 
  {     
    super(context, name, cursorFactory, version);     
     }     
     
     @Override    
     public void onCreate(SQLiteDatabase db) {     
         // TODO 创建数据库后,对数据库的操作     
     }     
     
     @Override    
 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {     
         // TODO 更改数据库版本的操作     
     }     
     
 @Override    
 public void onOpen(SQLiteDatabase db) {     
         super.onOpen(db);       
         // TODO 每次成功打开数据库后首先被执行     
     }     
 }

 

接下来讨论具体如何创建表、插入数据、删除表等等。调用 getReadableDatabase() 或 getWriteableDatabase() 方法,你可以得到 SQLiteDatabase 实例,具体调用那个方法,取决于你是否需要改变数据库的内容:

db=(new DatabaseHelper(getContext())).getWritableDatabase(); 
 return (db == null) ? false : true;

 

上面这段代码会返回一个 SQLiteDatabase 类的实例,使用这个对象,你就可以查询或者修改数据库。

当你完成了对数据库的操作(例如你的 Activity 已经关闭),需要调用 SQLiteDatabase 的 Close() 方法来释放掉数据库连接。

创建表和索引

为了创建表和索引,需要调用 SQLiteDatabase 的 execSQL() 方法来执行 DDL 语句。如果没有异常,这个方法没有返回值。

例如,你可以执行如下代码:

db.execSQL("CREATE TABLE mytable (_id INTEGER PRIMARY KEY   
        AUTOINCREMENT, title TEXT, value REAL);");

 

这条语句会创建一个名为 mytable 的表,表有一个列名为 _id,并且是主键,这列的值是会自动增长的整数(例如,当你插入一行时,SQLite 会给这列自动赋值),另外还有两列:title( 字符 ) 和 value( 浮点数 )。 SQLite 会自动为主键列创建索引。

通常情况下,第一次创建数据库时创建了表和索引。如果你不需要改变表的 schema,不需要删除表和索引 . 删除表和索引,需要使用 execSQL() 方法调用 DROP INDEX 和 DROP TABLE 语句。

给表添加数据

上面的代码,已经创建了数据库和表,现在需要给表添加数据。有两种方法可以给表添加数据。

像上面创建表一样,你可以使用 execSQL() 方法执行 INSERT, UPDATE, DELETE 等语句来更新表的数据。execSQL() 方法适用于所有不返回结果的 SQL 语句。例如:

db.execSQL("INSERT INTO widgets (name, inventory)"+ 
"VALUES ('Sprocket', 5)");

 

另一种方法是使用 SQLiteDatabase 对象的 insert(), update(), delete() 方法。这些方法把 SQL 语句的一部分作为参数。示例如下:

ContentValues cv=new ContentValues(); 
 cv.put(Constants.TITLE, "example title"); 
 cv.put(Constants.VALUE, SensorManager.GRAVITY_DEATH_STAR_I); 
 db.insert("mytable", getNullColumnHack(), cv);

 

update()方法有四个参数,分别是表名,表示列名和值的 ContentValues 对象,可选的 WHERE 条件和可选的填充 WHERE 语句的字符串,这些字符串会替换 WHERE 条件中的“?”标记。update() 根据条件,更新指定列的值,所以用 execSQL() 方法可以达到同样的目的。

WHERE 条件和其参数和用过的其他 SQL APIs 类似。例如:

String[] parms=new String[] {"this is a string"}; 
 db.update("widgets", replacements, "name=?", parms);

 

delete() 方法的使用和 update() 类似,使用表名,可选的 WHERE 条件和相应的填充 WHERE 条件的字符串。

查询数据库

类似 INSERT, UPDATE, DELETE,有两种方法使用 SELECT 从 SQLite 数据库检索数据。

1 .使用 rawQuery() 直接调用 SELECT 语句;

使用 query() 方法构建一个查询。

  • Raw Queries

    正如 API 名字,rawQuery() 是最简单的解决方法。通过这个方法你就可以调用 SQL SELECT 语句。例如:

    Cursor c=db.rawQuery( 
         "SELECT name FROM sqlite_master WHERE type='table' AND name='mytable'", null);

    在上面例子中,我们查询 SQLite 系统表(sqlite_master)检查 table 表是否存在。返回值是一个 cursor 对象,这个对象的方法可以迭代查询结果。

    如果查询是动态的,使用这个方法就会非常复杂。例如,当你需要查询的列在程序编译的时候不能确定,这时候使用 query() 方法会方便很多。

  • Regular Queries

    query() 方法用 SELECT 语句段构建查询。SELECT 语句内容作为 query() 方法的参数,比如:要查询的表名,要获取的字段名,WHERE 条件,包含可选的位置参数,去替代 WHERE 条件中位置参数的值,GROUP BY 条件,HAVING 条件。

    除了表名,其他参数可以是 null。所以,以前的代码段可以可写成:

    String[] columns={"ID", "inventory"}; 
     String[] parms={"snicklefritz"}; 
     Cursor result=db.query("widgets", columns, "name=?",parms, null, null, null);

使用游标

不管你如何执行查询,都会返回一个 Cursor,这是 Android 的 SQLite 数据库游标,使用游标,你可以:

通过使用 getCount() 方法得到结果集中有多少记录;

通过 moveToFirst(), moveToNext(), 和 isAfterLast() 方法遍历所有记录;

通过 getColumnNames() 得到字段名;

通过 getColumnIndex() 转换成字段号;

通过 getString(),getInt() 等方法得到给定字段当前记录的值;

通过 requery() 方法重新执行查询得到游标;

通过 close() 方法释放游标资源;

例如,下面代码遍历 mytable 表

Cursor result=db.rawQuery("SELECT ID, name, inventory FROM mytable"); 
    result.moveToFirst(); 
    while (!result.isAfterLast()) { 
        int id=result.getInt(0); 
        String name=result.getString(1); 
        int inventory=result.getInt(2); 
        // do something useful with these 
        result.moveToNext(); 
      } 
      result.close();

 


在 Android 中使用 SQLite 数据库管理工具

在其他数据库上作开发,一般都使用工具来检查和处理数据库的内容,而不是仅仅使用数据库的 API。使用 Android 模拟器,有两种可供选择的方法来管理数据库。

首先,模拟器绑定了 sqlite3 控制台程序,可以使用 adb shell 命令来调用他。只要你进入了模拟器的 shell,在数据库的路径执行 sqlite3 命令就可以了。数据库文件一般存放在:

/data/data/your.app.package/databases/your-db-name

如果你喜欢使用更友好的工具,你可以把数据库拷贝到你的开发机上,使用 SQLite-aware 客户端来操作它。这样的话,你在一个数据库的拷贝上操作,如果你想要你的修改能反映到设备上,你需要把数据库备份回去。

把数据库从设备上考出来,你可以使用 adb pull 命令(或者在 IDE 上做相应操作)。存储一个修改过的数据库到设备上,使用 adb push 命令。

一个最方便的 SQLite 客户端是 FireFox SQLite Manager 扩展,它可以跨所有平台使用。


图 2. SQLite Manager
图 2. SQLite Manager


结束语

如果你想要开发 Android 应用程序,一定需要在 Android 上存储数据,使用 SQLite 数据库是一种非常好的选择。本文介绍了如何在 Android 应用程序中使用 SQLite 数据库 ,主要介绍了在 Android 应用程序中使用 SQLite 创建数据库和表、添加数据、更新和检索数据,还介绍了比较常用的 SQLite 管理工具,通过阅读本文,你可以在 Android 中轻松操作 SQLite 数据库。

 

原文 http://www.ibm.com/developerworks/cn/opensource/os-cn-sqlite/index.html

Android平板电脑刷机包简单解释

本文将对android刷机包的刷机步骤进行简单的解释,本人用的设备是7寸山寨的flytouchCPU为威盛8505,本次用的固件包为VIA8505的1.7.2,之所以用这个是因为这个固件包的scriptcmd比较完善,在2.0.88scriptcmd被封装到prepare.bin中了,其实效果应该是一样的。

 

在此想先提一下Android的启动方式:1.u-boot启动2.加载linux内核3.linux内核进行系统初始化4.在内核的start_kernel()函数的kernel_init()中设定ramdisk_execute_command = "/init";最终在init_post()函数中调用init程序,而这个init程序就是Android编译好的在根目录下的init程序。明白了这个过程,对于理解刷机的原理就方便多了。

 

下面用红框圈起来的是本刷机包中主要用到的几个文件:

各文件用途:

Android_fs.tgz 整个Android的文件系统,里面文件虽然多,但主要的就是根目录下的文件和System文件夹里的文件,System文件夹里的文件又和Android编译出来的System.img里面的文件类似,所以这里推测,如果修改自己的刷机包,把自己修改好的System文件夹进行一下替换即可,当然要注意驱动的问题。

Ramdisk.gz        应该是linux的根文件系统镜像

Data.tgz            用户数据的部分,里面主要是各种用户程序和安装包,对应编译好的Data.img

uzImage.bin   linux内核镜像

u-boot.bin      u-boot启动文件

wload.bin              不知道

pre_****_disk文件夹 是可用这里面的文件来替代android_fs.tgz data.tgz里面的文件的,因为在后面判断若存在这几个文件夹,会进行相同目录的合并工作,这时肯定要发生替换了。

 

 

常用命令格式:

fatload <interface> <dev[:part]>  <addr(目的地址)> <filename> [bytes] 仅限内存中

cp source target   count

nand write addr off size Nand Flash烧写命令,将SDRAM addr地址处的size 字节的数据烧写到Nand off 偏移地址。

 

Scriptcmd中的文件拷贝地址:

nandrw erase all

1.fatload mmc 0 0 script/wload.binu-boot

erase ffff0000 +10000

cp.b 0 ffff0000 10000

cp source target   count

即将wload.bin拷贝到内存ffff0000的位置,count=10000

2.fatload mmc 0 0 script/u-boot.bin

erase fff80000 +50000

cp.b 0 fff80000 50000    

3.fatload mmc 0 0 script/ramdisk.gz

nand write 0 C00000 $(filesize)

4.fatload mmc 0 0 script/uzImage.bin(这个是linux内核的镜像,u代表是u-boot模式)

nand write 0 0 $(filesize)

5. 设置环境变量:setenv bootargs mem=237M root=/dev/ram rw initrd=0x01000000,32M console=ttyS0,115200n8 init=/linuxrc lcdid=1

fatload mmc 0 1000000 script/mvl5_v5t_ramdisk_WM8505.090922.loop.gz(这个类似linux启动时的initrd文件,mmc代表接口(类似usb)),就是从设备0拷贝,拷到内存地址0x01000000处,不是和以前一样拷到内存地址0处。

6.bootm 0 bootm [addr [arg ...]] addr是地址,arg是传递给内核的参数bootm命令可以引导启动存储在内存中的程序映像。这些内存包括RAM和可以永久保存的Flash。作用是从内存地址0处启动,在上面第四点中把uzImage.bin拷贝在内存地址0处,所以这里bootm 0就是执行uzImage.bin,在bootargs中还设置了initrd,所以刷机时第一次加载时是需要initrd来执行的,这里initrd就是mvl5_v5t_ramdisk_WM8505.090922.loop.gz这个文件,先用gzip解压再挂载,就可以看出它其实就是个临时的linux文件系统。

 

可以看出scriptcmd只负责文件拷贝,文件拷贝完打印"Please wait...",之后就bootm,所以这里出错的可能性很小,有一点是这个刷机包只是支持nand flash的,还有一种是udisk的,所以进行nand write时可能会不行。

 

之后就要执行update.sh文件了

 

Update.sh解释:

常用命令格式:

if [ -f /mnt/mmcblk0p1/script/android_fs.tgz ] ; then

-f 表示判断该文件名是否存在且为文件,-d表示directory,文件夹)

    string="Update filesystem Start ......"

    echo $string

    gui-echo $pointX $pointY "$string" 这里显示字符串要用两个echo

else

    exit 0 退出

fi  : 结束if条件   if反过来写

 

if [ $? -ne 0 ] ; then ……else……: $?是上一个操作的返回值,-nenot equal 的意思,因为linux中返回0代表出错,所以上面的操作就是若不出错,就执行else中的内容。

 

猜测:

/dev/mtdblock9nand flash闪存,因为根文件系统在此处

 

1.       if [ -f /mnt/mmcblk0p1/script/android_fs.tgz ] ; 先判断这个压缩文件是否存在,因为这个文件时超重要的,没有肯定要退出了~~ 这里不知何故sd卡已经自动挂载     到/mnt/mmcblk0p1/了,又是看不见的操作…………,我的猜想是这样的,在scriptcmd中,已经把ramdisk加载到sd卡了,这是个可以运行的linux根文件目录,这里肯定     有/mnt/这个目录的

2.       flash_eraseall /dev/mtd9 不解释

3.       mount -t yaffs2 /dev/mtdblock9 /mnt/mtd    -t只是表示我这次挂载要制定文件类型,文件类型自然为yaffs2了,把/dev/mtdblock9挂载到/mnt/mtd

4.       tar zxvf /mnt/mmcblk0p1/script/android_fs.tgz -C /mnt/mtd 解压到/mnt/mtd上,实际上是解压到/dev/mtdblock9上了,算是耗时最长的一步了。

5.       if [ -d /mnt/mmcblk0p1/script/driver ] ; cp -a /mnt/mmcblk0p1/script/driver/* /mnt/mtd    实际还是把驱动拷到设备里

6.       tar zxvf /mnt/mmcblk0p1/script/busybox_1.16.tgz -C /mnt/mtd

       if [ -x /mnt/mtd/busybox/bin/ash ] ; then mv /mnt/mtd/system/bin/sh    /mnt/mtd/system/bin/sh-org

       ln -s /busybox/bin/busybox /mnt/mtd/system/bin/sh busybox(不是busyboxsh)system原来的sh替换掉,不知何故

       if [ -d /mnt/mmcblk0p1/script/pre_root_disk ] ; then

7.      cp -a /mnt/mmcblk0p1/script/pre_root_disk/* /mnt/mtd   /pre_root_disk下的文件和andorid根目录的文件合并(其实没几个文件的,但可以自己添加定制了)

8.       cp /mnt/mmcblk0p1/script/data.tgz /mnt/mtd/restore cp /mnt/mmcblk0p1/script/cache.tgz /mnt/mtd/restore 本来还有后面这句的,但自己的刷机包里没  有cache.tgz,也无伤大雅了

9.       chmod 777 -R /mnt/mtd     chown root:0 /mnt/mtd/system/bin/preboot             umount /mnt/mtd   改变根文件系统的权限,改变preboot的拥有者和权限,    最后卸载/mnt/mtd,终于完成使命了?

10.    flash_eraseall /dev/mtd10   从哪又冒出来个mtd10   可能都是临时的吧。

11.    mount -t yaffs2 /dev/mtdblock10 /mnt/mtd  这是Data部分的挂载点。

12.    tar zxvf /mnt/mmcblk0p1/script/data.tgz -C /mnt/mtd       cp -a /mnt/mmcblk0p1/script/etc/* /mnt/mtd/wmtpref      cp -a    /mnt/mmcblk0p1/script/pre_data_disk/* /mnt/mtd             chmod 777 -R /mnt/mtd sync   umount /mnt/mtd 修改权限,再卸载掉

13.    flash_eraseall /dev/mtd12    mount -t yaffs2 /dev/mtdblock12 /mnt/mtd  

14.    create_loopfile mtd12 /mnt/mtd/vfat.bin bs=524288 

15.    mkdosfs /mnt/mtd/vfat.bin   格式化这个loop文件

16.     losetup /dev/loop/0 /mnt/mtd/vfat.bin          

mount -o iocharset=gb2312 -t vfat /dev/loop/0 /LocalDisk                                         

        cp -a /mnt/mmcblk0p1/script/pre_local_disk/* /LocalDisk            

  losetup -d /dev/loop/0                                                                        

        chmod 777 -R /mnt/mtd        sync      umount /mnt/mtd

17.   flash_eraseall /dev/mtd12

18.   mount -t yaffs2 /dev/mtdblock12 /mnt/mtd

19.   cp -a /mnt/mmcblk0p1/script/pre_local_disk/* /mnt/mtd

20.   echo 0 > /proc/boot-splash

21.   if [ -x /mnt/mmcblk0p1/script/update.sh ] ; then 通过判断update.sh文件还在不在来判断是否移除了SD

22.   reboot

 

代码部分写的有点乱,但基本原理还是清晰的, update.sh所作的工作无非还是解压,复制,合并这类的工作,和scriptcmd的工作本质上一样的,不过这也像是启动过程的两层引导,stage1stage2stage1先把内核加载进来,之后stage2linux内核下工作就容易多了。

 

看到这里,相信读者会明白刷机时怎么样会刷坏?而怎么样又不会刷坏?

在刷机的过程中只是文件的解压和复制,所以除非flash不支持或是其他硬件原因,刷机的过程一般是不会出问题的,关键是刷完之后的启动过程。

如果刷的u-boot的版本不对,连u-boot都启动不起来的话,那以后再刷也不行了;如果u-bootlinux内核的版本都正确,只是Android相关的文件运行不正确,虽然机器不能正常启动,但还是可以再刷的;如果u-boot正确,linux内核镜像有问题,那可能刷机过程只执行完scriptcmd就结束了,update.sh无法正确执行,但只要u-boot正确,还是可以再刷的,直到刷回好用的版本。

Records:70123456789