android开发小问题随记(附1)

一、android中dip、dp、px、sp和屏幕密度

1. dip: device independent pixels(设备独立像素). 不同设备有不同的显示效果,这个和设备硬件有关,一般我们为了支持WVGA、HVGA和QVGA 推荐使用这    这个,不依赖像素。     这里要特别注意dip与屏幕密度有关,而屏幕密度又与具体的硬件有关,硬件设置不正确,有可能导致dip不能正常显示。在屏幕密度为160的显示屏上,1dip=1px,有时候可能你的屏幕分辨率很大如480*800,但是屏幕密度没有正确设置比如说还是160,那么这个时候凡是使用dip的都会显示异常,基本都是显示过小。      dip的换算:            dip(value)=(int) (px(value)/1.5 + 0.5) 2. dp: 很简单,和dip是一样的。 3. px: pixels(像素),不同的设备不同的显示屏显示效果是相同的,这是绝对像素,是多少就永远是多少不会改变。 4.  sp: scaled pixels(放大像素). 主要用于字体显示best for textsize。

备注: 根据google的推荐,像素统一使用dip,字体统一使用sp 
举个例子区别px和dip:
px就是像素,如果用px,就会用实际像素画,比个如吧,用画一条长度为240px的横线,在480宽的模拟器上看就是一半的屏宽,而在320宽的模拟器上看就是2/3的屏宽了。
而dip,就是把屏幕的高分成480分,宽分成320分。比如你做一条160dip的横线,无论你在320还480的模拟器上,都是一半屏的长度。
public static int dip2px(Context context, float dipValue){                 final float scale = context.getResources().getDisplayMetrics().density;                 return (int)(dipValue * scale + 0.5f);         }             public static int px2dip(Context context, float pxValue){                 final float scale = context.getResources().getDisplayMetrics().density;                 return (int)(pxValue / scale + 0.5f);         }
 
 
在录音的过程中发现在最前面的1s中总是会有“噗”的一声的噪音。一直在跟踪查找,发现是Android源码中有一处溢出造成的。stagefright中的AudioSource的void rampVolume(int32_t startFrame, int32_t rampDurationFrames, uint8_t *data, size_t bytes);函数(raise the volume from mute to the actual level linearly)。在AudioSource的read()函数将从AudioRecord读入的数据经过计算

int32_t autoRampDurationFrames =                     (kAutoRampDurationUs * mSampleRate + 500000LL) / 1000000LL;

        int32_t autoRampStartFrames =                     (kAutoRampStartUs * mSampleRate + 500000LL) / 1000000LL;

int32_t nFrames = mNumFramesReceived - autoRampStartFrames;

rampVolume(nFrames, autoRampDurationFrames,                 (uint8_t *) buffer->data(), buffer->range_length());

其中nFrames和autoRampDurationFrames的计算存在溢出,kAutoRampDurationUs和kAutoRampDurationUs都是int64_t类型的值,计算结果直接强制转换为int32_t类型。于是修改后的代码为

int64_t autoRamp = kAutoRampDurationUs;     autoRamp *= mSampleRate;     int32_t autoRampDurationFrames = (autoRamp +500000LL) / 1000000LL;

    autoRamp = kAutoRampStartUs;     autoRamp *= mSampleRate;         int32_t autoRampStartFrames =                     (autoRamp + 500000LL) / 1000000LL;

int32_t nFrames = mNumFramesReceived - autoRampStartFrames;

rampVolume(nFrames, autoRampDurationFrames, (uint8_t *) buffer->data(), buffer->range_length());

这样就解决了rampVolume函数处理的nFrames帧的数据出现爆音的问题。

  举一反三,播放器的文件大小限制的问题也是由于溢出的问题引起的,文件大小使用int32_t类型的地方限制了大小只能支持到2G,因此需要将这些地方修改int64_t使得文件大小能够支持到fat32的存储文件的最大值4G。

三、Oracle迁移至SQLite

文章参考:http://blog.csdn.net/johnnycode/article/details/7413111#

1. 从PL/SQL 中查询你要的数据,然后导出成CSV格式文件;

clip_image002

也可以使用脚本进行导出CSV文件,具体如下:

--set colsep ' || ';
 set echo off;
 set feedback off; --禁止显示最后一行的计数反馈信息
 set heading off;  --禁止输出列标题
 set pagesize 0;   --设置显示多少行打印一次列名
 set linesize 1000;
 set numwidth 12;
 set termout off;
 set trimout on;   --清空多余的空格
 set trimspool on;
 set newpage none; --没有翻页,输出的文件没有空行
 spool e:\name.csv;
--select col1||','||col2 from table_name;
select t.type_code||','||t.type_name from t_b_op_type t;
spool off;

2. 用记事本打开CSV文件。首先需要将 CSV  文件处理下字符集的问题,众所周知

sqlite 默认字符集 UTF-8 ,涉及中文的地方如果不设置那么导入sqlite的数据将会乱码

右键选择 CSV 文件,打开方式为记事本,将会看到如下数据

clip_image002[1]

需要将第一行列去除,然后将分号 ” 同时去掉,最终结果为

clip_image004

下面这步最重要,将文件另存为,最下方编码选择 UTF-8 ,然后另存到E盘根目录即可。

clip_image006

2. 创建数据库

运行cmd命令,在CMD下进入到SQLite文件夹,输入sqlite3.exe mydata.db(数据库名称),

如不指定路径,那么 sqlite3 将会默认将数据库文件创建运行 sqlite3 的目录中。(此过程不会产生db文件)

sqlite3.exe mydata.db

3. 创建表

建表语句可以从 oracle 中复制即可。建表完毕,可以使用 .ta 命令查看新建表是否成功。(此过程完后产生db文件)

create table T_B_OP_TYPE…

.ta

4. csv 默认数据分割符为逗号 “,” 而 sqlite 默认数据分割符为 “|” ,先用 .show 命令确认下

.show

更改分隔符为”,” .separator “,”

再次确定 .show

.show

5. 导入数据(.import  //导入命令)

.import 数据库路径\mydata.db

6. 验证

select * from T_B_OP_TYPE; //分号不能少

OK,大功告成!

如果PC没有安装 sqlite ,这里将 sqlite 操作交给 Android 手机来处理

参考文章:http://blog.csdn.net/johnnycode/article/details/7413111#

SQL Server迁移至SQLite

貌似这个SQL_Server_To_SQLite_DB_Converter软件很强大,此工具可转换Sql Server数据库为Sqlite数据,包括结构和数据,可以直接搞定!

工具下载地址:https://files.cnblogs.com/huwei_good/SQL_Server_To_SQLite_DB_Converter_bin.zip

clip_image002[3]

SQL Server Address: 数据库地址

Select DB:选择数据库

Sqlite Database File Path:Sqlite数据库文件保存路径;

Password:设置数据库密码

填写好了,直接点击开始导出即可!

该软件是从老外的网站下载的,是用C#写的一个程序,是开源的,大家可以去此处下载:http://www.codeproject.com/KB/database/convsqlservertosqlite.aspx可以下载整个编译的程序,也可以下载编译完成的debug程序,功能十分强大.

SQLite 常用命令

入门系列:http://www.cnblogs.com/myqiao/archive/2011/07/10/2102465.html

sqlite常用命令和实例:http://huangjianming31.blog.163.com/blog/static/34740871201062121316395

sqlite常用命令和语法:http://blog.csdn.net/linchunhua/article/details/7184439

sqlite常用设置命令:http://www.cnblogs.com/caizhimin816/articles/1885349.html

在SQLite中,对大小写是敏感的。那么SQLite怎么区分大小写查询呢,以下是三种解决方案: 方案一:使用大小写转换函数LOWERUPPER 1.select * from test where UPPER(name) = 'ABC'; 2.select * from test where LOWER(name) = LOWER('ABC'); 方案二:在进行比较时强制声明不区分大小写 select * from test where name = 'ABC' COLLATE NOCASE; 方案三:创建表时声明该字段不区分大小写 create table test (_id Integer,name Text COLLATE NOCASE );

四、将SqlCe/sql server 转sqlite

之前做了一个Windows Mobile的项目,数据库用的是Sql CE。最近想移值到Android上,所以需要将数据库从SqlCE转成SQlite.

Google后,发现老外已经写了一个现在工具:Convert SQL Server DB to SQLite DB,非常好用,缺点是仅支持Sql Server 转Sqlite,没有支持SqlCe。现在问题就是如何将SqlCE转成Sql Server。

1. Sophisticated Database Conversion and Data Migration

    这是我用的第一个工具,用的是试用版本,转换时没有发现什么问题,以为成功了,也没有做检查。直到开发时,程序报错了,才发现第6个以后的字段名和50行后数据被修改了,不得以只能放弃。

image

 

2. Web Matrix

    2.1 创建一个Bekery站点

    image

    image

    image

2.2. 将数据库文件copy到站点目录的App_Data下

     image

2.3 转换数据库

      image

      image

      image

 

    Note:Matrix仅支持SqlCe 4.0,如果你的版本是3.5请先升级为4.0。升级可用 Tool to upgrade SQL CE database to SQL Server Compact 4.0

    还可参考 http://erikej.blogspot.se/2010/08/how-to-upgrade-version-3x-database-file.html

 

3. SQL Server Compact Toolbox强烈推荐

    这是一个Visual Studio的插件,Visual Studio 2010还需安装一下,Visual Studio 2012已经默认安装了,可以直接用了。

   3.1 先连接目标的Sql Server 数据库

   image

   image

   image

   3.2 连接Sql CE数据库

    image

    image

    image

    image

 

同时推荐一个SqlCE的管理插件:

http://exportsqlce.codeplex.com/

fig4.png

  参考:

http://erikej.blogspot.se/2012/02/migrating-databases-between-sql-server.html

http://erikej.blogspot.se/2010/02/how-to-use-exportsqlce-to-migrate-from.html

 

默认情况下,在SoftInput显示的时候,Back键会优先交给输入法处理,这时Back只会关闭输入法。需要再按Back,才能退出输入框所在的Activity, 如何能按一次Back就退出Activity呢?

方法是重载EditText的dispatchKeyEventPreIme函数:

[EditTextPreIme.java]

 

五、按Back键直接关闭activity,而不是关闭软键盘

import android.app.Activity; import android.content.Context; import android.util.AttributeSet; import android.view.KeyEvent; import android.widget.EditText;

 

public class EditTextPreIme extends EditText { public EditTextPreIme(Context context) { super(context); } public EditTextPreIme(Context context, AttributeSet attrs){ super(context, attrs); } public EditTextPreIme(Context context, AttributeSet attrs, int defStyle){ super(context, attrs, defStyle); } @Override public boolean dispatchKeyEventPreIme(KeyEvent event) { if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) { ((Activity)this.getContext()).onKeyDown(KeyEvent.KEYCODE_BACK, event);

或者粗鲁一点,直接在调用finish()关闭activity

(推荐第1种方式,由activity的onKeyDown统一处理):

((Activity)this.getContext()).finish(); return true; } else { return super.dispatchKeyEvent(event); } } }

posted @ 2013-02-26 10:21  crazywenza  阅读(380)  评论(0编辑  收藏  举报