Thursday, September 12, 2013

Android Studio 0.2.x 引入多模块 Eclipse 项目

!!!!太他妈的累人了!整整折腾了两天!!!!!!!


不知从那个版本开始 Import Module... Android StudioFile菜单中消失了,在0.2.0之前的版本作为library的模块可以像Eclipse里一样,绝对路径可以完全和主Applicaiton无关,比如如下的目录结构:

/AllProjects/androidProject/myApplication
/Libs/android/ActionbarSherlock

这里myApplication用到ActionbarSherlock这个库,但是到了0.2.x版本行不通了。首先你得把ActionbarSherlock 移成和myApplication 同级目录,但如果按照上面的目录结构,eclipse 引出Gradle后,用Android Studio 引入后,Project的名字叫andropidProject ,如果在androidProject 目录下还有其他项目,引出到Android Studio后显然会引起混乱,所以重新调整目录结构如下:

/AllProjects/androidProject/myAppProject/myApplication
/AllProjects/android/Project/myAppProject/ActionbarSherelock

然后从Eclipse Export Gradle...但是:别以为这样就OK了,后面的问题仍然是一连串的,下面我分步骤讲解下。

基本环境:
  • Ubuntu 13.04 64bit
  • Eclipse Standard 4.3 (KEPLER)
  • Android Studio 0.2.8 Build #AI-132.821530
  • JDK "1.7.0_25"
  • Android SDK Tools 22.0.5


项目:
myApplication

依赖库:
ActionbarSherlock
drag-sort-listview


第一步:
调整目录结构,并在Eclipse里正确编译。

/
├─ AllProjects
│  └─ androidProject
│  └─ myAppProject
│     ├─ myApplication
│     ├─ ActionbarSherlock
│     └─ drag-sort-listview
└─ android-sdk-linux


第二步:
导出gradle build 文件。

选择Eclipse->File->Export... ,在Export 对话框中选择Android->Generate Gradle build files .具体导出方法参看 Android 官方介绍Migrating from Eclipse 。选中所有要导出的项目,myApplication, actionbarsherlock, drag-sort-listview ,点下一步,确认Project root 是否是 /AllProjects/androidProject/myAppProject , (如果不是,说明你的项目目录结构不正确),最后向导会在Project root 目录中生成下列文件和目录:

gradle/
build.gradle
gradlew
gradlew.bat
settings.gradle

第三步:
运行Android Studio ,Welcome 窗口中选择 Import Project... File->Import Project... 选择导入 /AllProjects/androidProject/myAppProject/build.gradle .

接下来第一个问题来了,按照Android 官方站点的介绍,选择 use gradle wrapper , 出现如下错误:



这里有两个问题,第1个问题比较复杂,先解决第2个问题。
2个问题产生的原因可能是我在Android Studio 中将ADT目录 指向 /android-sdk-linux ,而不是Android Studio Bundle ADT (在Android Studio 目录下的SDK目录),我想通常同时用Eclipse Android Studio的都会这么配置吧,否则机器上保存两份ADT 不是有病嘛!

3.1 步:
Project root 目录中创建 local.properties 文件,文件中加上如下行:

sdk.dir=/home/royer/android-sdk-linux

(你也可用Android Studio new Project.. 生成一个Android Project ,让后从那里copy 一个 local.properties过来)。


现在回头看第一个问题,这个应该是Android Studio 或者 Intellij Bug... Anyway, 解决方法如下:

3.2步:
选择 Use local gradle distribution , Gradle home 里输入你本地的Gradle 路径,如下图:



Gradle 可以到 Gradle download 下载,我用了1.7 版,1.61.8应该也都可以。

到此时,导入是成功了,但编译通不过,碰到的第1个问题是:

Gradle: Execution failed for task ':myApplication:processDebugManifest'.
> Manifest merging failed. See console for more info.

按照提示,开console, 运行 ./gradlew build ,可以看到原因,是myApplication 指定的 android:targetSdkVersion 低于 actionbarsherlock 指定的版本。

第四步:
修改 AndroidManifest.xml确保 主项目和库项目的tagetSdkVersion 一致.

重新build,刚才错误消失了,但新出了19个错误,大致如下:

Gradle: Error while executing dx command
Gradle: UNEXPECTED TOP-LEVEL EXCEPTION:
Gradle: java.lang.IllegalArgumentException: already added: Landroid/support/v4/app/NotificationCompatIceCreamSandwich;

实际上是如何引用 supportv4 库的问题, Eclipse 里是copy 到个项目的libs 目录下,而Android Studio 是引用repositories 的方法。参考Android 官方文档 Support Library Setup,解决如下:

第五步:
修改每个项目的build.gradle 文件。
dependencies {
compile "com.android.support:support-v4:18.0.+"
compile fileTree(dir: 'libs', include: '*.jar', exclude: 'android-support-v4.jar')
.....
}
注:如果你的libs 目录里只有android-support-v4.jar ,则可以把 comile fileTree 整行删除。



OK, 到此为止,至少我成功的import了。

Friday, September 6, 2013

Linux 下 vmware 虚拟机中永久激活Windows 7

Linux vmware 虚拟机中永久激活Windows 7

  1. 简述

    vmware 可以指定一个外部文件作为其虚拟机的BIOS,那么就可以通过把品牌机的SLIC2.1的信息写到这个BIOS文件中来激活Windows 7. 只要能够生成这个BIOS文件,其余的步骤就和兼容机刷BIOS永久激活Windows 7的方法一样了,网上教程到处可见,比如这篇就是个不错的教程。

  2. 基本环境

    1. 主机操作系统:Ubuntu 13.04 64bit
    2. 虚拟机软件: vmware player for linux 64bit
    3. 目标虚拟机: Windows 7 64bit 旗舰版

  3. 所需工具

    1. SLIC Toolkit V3.2 (用来验证SLIC 是否成功写入)
    2. rw-everything
      下载地址:http://rweverything.com/
    3. PhoenixTool (需要 .Net Framework 2.0)

  4. 流程

    1. 第一步:提取vmwarebios

      Ubuntu, vmwarebios /usr/lib/vmware/bin/vmware-vmx 中。用objcopy 提取bios440 section

      objcopy vmware-vmx -O binary -j bios440 --set-section-flags bios440=a bios440.rom.z
      注:这里我先把/usr/lib/vmware/bin/vmware-vmx 拷贝到里临时目录下。

      如果不能提取,可以用objdump命令:
      objdump -h vmware-vmx | grep bios440 
      确认下 bios440 section是否存在或名称是否正确(有些版本的vmware section 名字是 .bios440)。得到结果如下:

      28 bios440 00033d47 0000000000000000 0000000000000000 00d6c0d0 2**0

      另外也可以根据objdump的信息用dd 命令把bios440 section dump 出来。
      dd skip=14074064 bs=1 count=212295 ibs=1 obs=1 if=vmware-vmx of=bios440.rom.z

      其中14074064 对应与objdump 00d6c0d0,bios440 seciton vmware-vmx 中起始位置,而212295是大小,对应objdump00033d47 段。

      用下面的命令对刚才提出的bios440.room.z 解压:
      perl -e 'use Compress::Zlib; my $v; read STDIN, $v, 212295; $v = uncompress($v); print $v;' < bios440.rom.z > bios440.rom
      这里212295 就是bios440.rom.z 的文件大小,vmware版本不同,大小可能略有不同。
      这样的的bios440.rom 就是vmware 512K 的虚拟机BIOS了。


    2. 第二步:用rw-everything 提取ACPI Tables

      启动虚拟机, 运行 rw.exe . Access菜单->ACPI Tables ,从ACPI Tables 的子窗口上选Save All 按钮(或Ctrl+F2), 保存文件名就用缺省的即可 AcpiTbls.rw 。如图:

    3. 第三步:用PhoenixTool 合并SLIC 生成bios

      vmware 虚拟机的BIOS是属于Phoenix类的。感谢PhoenixTool 的作者,有了这个工具,就不必再用Phoenix BIOS Editor WinHex 繁琐无比的操作来生成Phoenixbios了。
      1. Original 里输入从vmware-vmx里抽出的bios440.rom。 等待PhoenixTool完成分析。
      2. Manufacturer 里选择厂商,这个取决于你准备好的SLIC2.1 OEM证书文件是那个厂商的。
      3. SLIC File里输入你的SLIC2.1 的文件。
      4. RW File里输入刚才rw-everything生成的AcpiTbls.rw .



      5. 点击Advanced 按钮,出现可能会刷砖的警告,点“是”,出现advanced option对话框,确保”Only alter RSDT and XSDT tables” 选中,点Done按钮退出设置。



      6. Go按钮开始生成。
        成功生成的话,新的BIOS文件会在bios440.rom 所在的目录里,文件名是bios440_SLIC.rom

    4. 第四步修改 .vmx 文件

      虚拟机关机。用文本编辑软件打开要修改的虚拟机对应的.vmx文件,在文件尾加上:
      bios440.filename = “bios440_SLIC.rom”
      理论上bios440_SLIC.rom 可以放在任何目录,只要配置文件写上绝对路径即可。
      重新启动虚拟机。运行SLIC Toolkit V3.2 检查SLIC2.1 是否成功加入BIOS。如下图红框中字样表示成功提取到SLIC,厂商是LENOVO,型号TC-5K,版本2.1.



最后提供一个各品牌SLIC和证书的下载地址。http://www.360doc.com/content/12/0229/14/1309227_190545700.shtml


另外,如果需要序列号的话,请注意序列号要和你的windows版本匹配,比如你的BIOS烧的是联想的SLICWindows 7是旗舰版,则需要找个联想OEMWindows 7旗舰版的序列号,否则可能还是不能成功激活Windows

本文同步发布在我的CSDN Blog中。http://blog.csdn.net/royer/article/details/11313611

Saturday, August 17, 2013

bash中处理文件名有空格的问题 $(command ls) when file name with space

一个练习。遍历指定的目录,以树状结构显示包括子目录下的所有文件。
在bash中遍历文件用
for file in * ; do
...
done
很多教科书上用: for file in $(commmand ls *) ,但这种方法不能正确处理文件名中包含$IFS指定的分隔符,即便ls 用 --quoting-style=shell 限定也没有用。

for file in * ; 的缺点是不能处理隐藏文件或目录

完整源码如下:
#!/bin/bash

declare -r tab="---"
declare -r lead="|"

function recdir {

declare -i cbfiles=0
declare -a files 

local thistab="$2"$lead$tab
cd "$1"

# get how many files in this directory
for file in * ; do
 files[$(( cbfiles++ ))]="$file"
done

declare -i curr=0
for file in "${files[@]}" ; do
 curr=$((++curr))
 echo "$thistab$file"
 if [ -d "$file" ]; then
  space=${tab//-/' '}
  ll=""
  if [ $(( curr < cbfiles )) = 1 ]; then
   ll=$2$lead"${space}"
  else
   ll="$2 ${space}"
  fi
  recdir "$file" "$ll"
 fi
done

cd ".."
}

rootdir=${1:-.}
rootdir=${rootdir%/}

if [ -d "$rootdir" ]; then
 echo "$rootdir"
 recdir $rootdir
else
 echo "$rootdir is not a directory."
fi

unset rootdir

执行结果如下:
.
|---CRFSC_Manual.pdf
|---foo1
|---foo1~
|---p1_b.jpg
|---p1.jpg
|---p2.jpg
|---p3.jpg
|---studynote
|   |---Match Waveform Theory Notebook.odt
|   |---test.txt
|   |---whh
|       |---a.txt
|---SWIGDocumentation.pdf
|---科学和特异功能.odt

Wednesday, August 14, 2013

bash笔记(三)——条件测试

if 语句之后除了可以跟命令行之外,还可以用[...]结构,[...]结构和内部命令 test 是等效的,即 [ string1 = string2 ]test string1 = string2 的结果是相同的。另外在bash 2.05之后的版本还可以用[[...]] 结构,[[...]] 和[...]之间的不同可参考: http://stackoverflow.com/a/3427931/1036923 .

注意:在 “[” 之后和 “]” 之前空格是必须的。

通常代码形式如下:
if [ -n "$varname" ]; then
    echo "hello"
else
    echo '$varname' is null!
fi
在条件表达式里始终用双引号将变量引起,有以下两个原因:

  1. 将变量解释为一个单词。
  2. 如果变量是null, 没有双引号则上例中条件测试将变为[ -n ] ,它总是返回true; 用了双引号则表达式为[ -n "" ] ;

条件组合

if command && [ condition ] && [ condition ] || [ condition ]; then


if command && [ \( condition \) -a \( condition \) -o \( condition \) ]; then
...


-a 和 -o 只能用在测试条件表达式中

字符串比较

Operator True if...
str1 = str2 str1 matches str2
str1 != str2 str1 does not match str2
str1 < str2 str1 is less than str2
str1 > str2 str1 is greater than str2
-n str1 str1 is not null (has length greater than 0)
-z str1 str1 is null (has length 0)
注:bash 没有 >= 和 <= 比较符。

文件测试

下表列出常用的文件测试表达式。

Operator True if...
-a file file exists
-d file file exists and is a directory
-e file file exists; same as -a
-f file file exists and is a regular file(i.e., not a directory or other special type of file)
-r file You have read permission on file
-s file file exists and is not empty
-w file You have write permission on file
-x file You have execute permission on file, or directory search permission if it is a directroy
-N file file was modified since it was last read
-O file You own file
-G file file's group ID matchs yours (or one of yours, if you are in multiple groups)
file1 -nt file2 file1 is newer than file2
file1 -ot file2 file1 is older than file2


算术比较


Test Comparison
-lt Less than
-le Less than or equal
-eq Equal
-ge Greater than or equal
-gt Greater than
-ne Not equal
注:bash还有针对整数比较的独立语法,效率更高,所以要优先用它而不是上表列出的算术比较运算符。

Monday, August 12, 2013

bash 笔记(二)——字符串操作


一个常用的字符串操作是放在变量名的{}内的一些特定操作符,见下表。

Operator Substitution
${varname:-word} If varname exists and isn't null, return its value; otherwise return word.
Purpose: Returning a default value if the variable is undefined.
Example: ${count:-0} evaluates to 0 if count is undefined.
${varname:=word} If varname exists and isn't null, return its value; otherwise set it to word and then return its value. Positional and special parameters cannot be assigned this way.
Purpose: Setting a variable to a default value if it is undefined.
Example: ${count:=0} set count to 0 if it is undefined.
${varname:?message} If varname exists and isn't null, return its value; otherwise print varname:followed by message, and abort the current command or script(non-interactive shell only). Omitting message produces the default message parameter null or not set.
Purpose: Catching errors that result from variables being undefined.
Example: {count:?”undefined!”} prints “count: undefined!” and exits if count is undefined.
${varname:+word} If varname exists and isn't null, return word; otherwise return null.
Purpose: Testing for existence of a variable.
Example: ${count:+1} return 1 (which could mean “true”) if count is defined.
${varname:offset:length} Performs substring expansion. It returns the substring of $varname starting at offset and up to length characters. The first character in $varname is position 0. if length is omitted, the substring start at offset and continues to the end of $varname. If offset is less than 0 then the position is taken from the end of $varname. If varname is @, the length is number of positional parameters starting at parameter offset.
Purpose: Returning parts of a string(substrings or slices).
Example: if count is set to frogfootman, ${count:4} return footman. ${count:4:4} return foot.
表中除了最后一项,其余各项中的冒号(:)是可以省略的。如果没有冒号,则测试条件由“exists and isn't null" 变为 “exists",即仅仅测试变量是否存在。

模式匹配(Patterns and Pattern Matching)


Operator Substitution
${variable#pattern} If the pattern matches the beginning of the variable's value, delete the shortest part that matches and return the rest.
${variable##pattern} If the pattern matches the begginning of the variable's value, delete the longest part thar matches and return the rest.
${variable%pattern} If the pattern matches the end of the variable's value, delete the shortest part that matches and return the rest.
${variable%%pattern} If the parttern matches the end of the variable's value, delete the longest part the matches and return the rest.
${variable/parttern/string}
${variable//parttern/string}
The longest match to pattern in variable is replaced by string. In the first form, only the first match is replaced. In the second form, all matches are replaced. If the pattern begins with a #, it must match at the start of the variable. If it begins with a %, it must match with the end of the variable. If string is null, the matches are deleted. If variable is @ or *, the operation is applied to each positional parameter in turn and the expansion is the resultant list.
记忆小巧门:#是用在数字开头的,所以对应变量开始部分。%总是用在数字的后面,所以对应变量的结尾部分。

此类模式匹配比较经典的应用是对路径名的解析比如假设:

path=/home/david/document/long.file.name 

则:


${path##/*/}
                     long.file.name
${path#/*/}
      david/document/long.file.name
$path
/home/david/document/long.file.name
${path%.*}
/home/david/document/long.file
${path%%.*}
/home/david/document/long

最长和最短匹配只有在有通配符*存在的情况下才生效,否则他们的输出结果是一样的。比如:filename=alicece ,则${filename%ce} 和 ${filename%%ce} 两个输出的结果都是 alice .

长度操作符

 ${#varname}


*扩展的模式匹配

如果用shopt把extglob设置打开,则可以一次提供多个模式匹配,之间用|分隔。

Operator Meaning
*(patternlist) Matches zero or more occurrences of the given patterns.
+(patternlist) Matches one or more occurrences of the given patterns.
?(patternlist) Matches zero or one occurrences of the given patterns.
@(patternlist) Matches exactly one of the given patterns.
!(patternlist) Matches anything except one of the given patterns.
例子:

  • *(alice|hatter|hare) would match zero or more occurrences of alice, hatter, and hare. So it would match the null string, alice, alicehatter, etc.
  • +(alice|hatter|hare) would do the same except not match the null string.
  • ?(alice|hatter|hare) would only match the null string, alice, hatter, or hare.
  • @(alice|hatter|hare) would only match alice, hatter, and hare.
  • !(alice|hatter|hare) matches everything except alice, hatter and hare.

模式字串里可以包含shell的通配符,比如:+([0-9])可以匹配一位或多位的数字。模式还可以嵌套,比如 rm !(vt+([0-9])) 可以删除所有文件除了文件名由vt开始后跟一串数字的文件。

bash 笔记(一)——变量

1.变量的定义

varname=value
注意:等号两边不能有空格。如果变量(value)超过一个单词,则必须用引号引起。


2.变量和引号

$ fred='Four spaces between these    words.'
$ echo $fred 

Four spaces between these words. 
当使用不带双引号使用变量时,shell会把字符串切分成多个单词,在处理命令行参数时通常就这样做。如果用双引号引起,则shell把整个字符串作为一个单词处理。
$ echo "$fred"
Four spaces between these    words.
双引号和单引号的区别
双引号称为“弱引用”,单引号称为“强引用”。顾名思义,双引号会对引号里的内容进行转意,比如将变量里的内容引出;而单引号则完全拷贝单引号里的内容,对特殊字符不做转意处理。以上面$fred为例:
$ echo '$fred'
$fred

3.位置参数变量

3.1 $0, $1, $2, $3, ...

$1, $2, $3, ... 分别代表命令行中/函数第1, 2, 3, ...个参数。$0 是脚本名字。在函数中$0仍然是脚本名,而不是函数名(如果脚本是用 source 命令执行,则 $0=bash)

3.2 $* 和 $@


  • $* 把所有的参数作为一个单独的字符串,其中用环境变量IFS(internal field separator)中的第一个字符作为参数之间的分隔符。
  • $@ 等价于"$1" "$2" "$3"... "$N" ,就是N个独立的用双引号引起的字符串,它们之间用空格分开。


4.变量名通用写法

完整的变量名书写格式是${varname} 。比如你有超过9个以上的参数,你必须用${10}而不是$10 来引用第10个参数。另外当你想在输出的变量后跟一下划线,你必须用:
echo ${UID}_ 
如果使用 
echo $UID_ ,shell 会把UID_ 看作变量名。

5.变量的类型

用内建命令declare 定义变量的类型,比如 declare -i varname ,表示varname 是个整数变量。 用'-'定义,用'+'取消。常用的设置变量属性的 declare option 见下表。

Option Meaning
-a to make NAMEs indexed arrays (if supported)
-A to make NAMEs associative arrays (if supported)
-i to make NAMEs have the `integer' attribute
-l to convert NAMEs to lower case on assignment
-r to make NAMEs readonly
-t to make NAMEs have the `trace' attribute

当declare 作为命令使用时还有另外一些参数:

Option Meaning
-f restrict action or display to function names and definitions
-F restrict display to function names only (plus line number and source file when debugging)
-g create global variables when used in a shell function; otherwise ignored
-p display the attributes and value of each NAME

Friday, August 2, 2013

Android Audio Arduino: Cross compiling native audio libraries for Android...

Android Audio Arduino: Cross compiling native audio libraries for Android...: Update July, 31 2013: The latest git version of libsndfile builds fine without editing sndfile-play.c In  part 1 of this small series of ...

Search This Blog