Facebook Twitter LinkedIn E-mail
magnify
Home 2012 三月

如何使Android应用开机时自动启动

如果需要在Android开机时自动启动应用程序,可以通过响应android.intent.action.BOOT_COMPLETED广播消息来实现, Android系统启动结束时,会发出 android.intent.action.BOOT_COMPLETED 消息。 具体步骤如下:

1. 定义一个Broadcast Receiver ,比如:BootupReceiver

public class BootupReceiver extends BroadcastReceiver{

 @Override
 public void onReceive(Context context, Intent intent) {

 //better delay some time.
 try {
 Thread.sleep(2000);
 } catch (InterruptedException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
 }
 Intent i = new Intent(context, BootupDemoActivity.class);
 i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
 context.startActivity(i);

 }

}

用于响应android.intent.action.BOOT_COMPLETED。

2. 在Manifest文件中定义该Broadcast Receiver

<receiver android:name=”.BootupReceiver” android:enabled=”true”
android:permission=”android.permission.RECEIVE_BOOT_COMPLETED”>
<intent-filter>
<action android:name=”android.intent.action.BOOT_COMPLETED”></action>
<category android:name=”android.intent.category.DEFAULT” />
</intent-filter>

</receiver>

3. 加上所需权限

<uses-permission android:name=”android.permission.RECEIVE_BOOT_COMPLETED” />

这些,但手机重启示会自动运行你的应用。 不过此时你的应用可能会被屏幕锁定挡住。解除屏幕锁定后可以看到你运行的应用。

如果想用户一开机就看到你的应用,可以使用代码就屏幕锁去除,方法如下:

1. 在Activity的onCreate事件处理中添加下面代码

 KeyguardManager keyguardManager
 = (KeyguardManager)getSystemService(KEYGUARD_SERVICE);
 KeyguardLock lock = keyguardManager.newKeyguardLock(KEYGUARD_SERVICE);

 lock.disableKeyguard();

2. 在Manifest文件中添加所需权限

<uses-permission android:name=”android.permission.DISABLE_KEYGUARD” />

本例代码下载

 

Android NDK 开发教程二:概述

注意:在Windows上运行NDK需要有Cygwin支持,个人建议使用Ubuntu为好 。

介绍:

Android SDK是一个允许Android应用开发人员使用C或C++源文件编译并嵌入到本机源代码中的应用程序包的一组工 具。

重要说明:

Android NDK只能用于android 1.5以上版本

1 Android NDK的目的:

Android虚拟机允许你的应用程序源代码通过JNI调用在本地实现的源代码,简单的说,这就意味着:

—-你的应用程序将声明一个或多个用’native’关键字的方法用来指明它们是通过本地代码实现的

例如:native byte[] loadFile(String filePath)

—-你必须提供包含实现这些方法的共享库(就是.so),将共享库打包到你的应用程序包apk中,这些库文件必须根据 标准的Unix约定来命名为 lib<something>.so,并且是需要包含一个标准的JNI的接口,例如

libFileLoader.so

—-你的应用程序必须明确的装载这些库文件(.so文件),比如,在程序的开始装载它,只需要简单的添加几句源代码:

static {

System.loadLibrary(“FileLoader”);

}

注意:这里你不必再将前缀lib和后缀.so写入。

Android NDK对于Android SDK只是个组件,它可以帮你:

—-生成的JNI兼容的共享库可以在大于Android1.5平台的ARM CPU上运行

—-将生成的共享库拷贝到合适的程序工程路径的位置上,以保证它们自动的添加到你的apk包中(并且签名的)

—-在以后的版本中,我们将提供来帮助你的源代码通过远程gdb连接和尽可能多的源代码的信息。

而且,Android NDK还提供:

—-一组交叉编译链(编译器、链接器等)来生成可以在Linux,OS X和Windows(用Cygwin)运行的二进制文件

—-一组与由Android平台提供的稳定的本地API列表的头文件

它们在docs/STABLE-APIS.html中有说明

重要提示:

记住,在以后的更新和发布平台中,Android系统镜像中的大多数本地系统库并不是一成不变的,而是可以彻底改变, 甚至删除的

—-一个编译系统(build system)可以允许开发者写一个非常短的编译文件(build files)去描述哪个源代码需要编 译,并且怎样编译。编译系统可以解决所有的toolchain/platform/CPU/ABI细节的问题。并且,较晚的NDK版 本中还添加了更多的可以不用改变开发者的编译文件的情况下的toolchains,platforms,系统接口

2Android NDK的缺点

NDK并不是一个可以编写通用的源代码并且可以在Android设备上运行的方法,你的应用程序还是需要使用JAVA程序,适当的处理系统事件来避免“应用程序没有反应”的对话框或者处理Android应用程序的生命周期

注意:可以适当的在源代码中写一个复杂的应用程序,用于启动/停止一个小型的“应用程序包”

强烈建议很好地理解的 JNI,因为许多操作在这种环境要求的开发人员,都采取具体的行动,不一定在常见典型的本机代码。这些措施包括:

—-不能通过指针直接访问VM的对象。比如:你不能安全的得到一个指向String对象的16位char数组的循环遍历

—-需要显示引用管理本机代码时候要保持处理JNI调用之间的VM对象

NDK在Android平台仅仅提供了有限的本地API和库文件的支持的系统头文件,然而一个标准的Android系统镜像包括许多本地共享库,这些都应该被考虑在更新和发行版本的可以彻底改变的实现细节

如果Android系统库没有明确的被NDK明确的支持,然后应用程序不应该依赖于它提供的,或者打破了将来在各种设备上的无线系统更新

选定的系统库将逐渐被添加到稳定的NDK API中

3NDK开发实践

下面将给出一个怎样用Android NDK开发本地代码的粗略的概述

(1) 把本地代码放在$PROJECT/jni/…下,比如将hello.c放到apps/hello/jni/目录下

(2) 在你的NDK编译系统中在$PROJECT/jni/Android.mk来描述你的源代码

(3) 可选:在$PROJECT/jni/Application.mk到你的编译系统中来详细描述你的项目,尽管你开始的话不一定需要它, 但是它允许你使用更多的CPU或者覆盖编译器/链接器的标记(看docs/APPLICATION-MK.html了解更多细节)

(4) 从你的项目的目录开始通过运行”$NDK/ndk-build”来编译你的代码,或者从子目录开始

(5) 最后一步可以copy,万一成功,剥离共享库的应用层序需要你的应用程序的项目根目录。然后你通过通常的方法来 生成最终的apk

现在,开始一些更 的细节

① 配置N DK

以前的发行版本需要你运行“build/host-setup.sh”脚本来配置你的NDK。从release 4(NDK r)以后就完全去除了这一步

② 放置C/C++代码

假如我们创建的是test目录,创建的代码hello.c

把hello.c放到test/jni目录下

这个项目的位置相当于你的Android应用程序项目的路径

这样你就很轻松的组织起来了你想要的jni的目录,这里项目目录的名字和结构不会影响到最终生成的apk,所以 你不必用类似于com.<mycompany>.<myproject>作为应用程序包名

注意,NDK是支持C和C++的,NDK支持的C++文件扩展名是’.cpp’,但是其他的扩展名也是可以被处理的     (看docs/ANDROID-MK.html了解更多)

它可以通过调整你的Android.mk文件来将源代码放在不同的位置

③ 创建一个Android.mk编译脚本

Android.mk文件是一个小型的编译脚本,你可以在NDK编译系统中用它来描述你的源代码。更详细的描述在docs/ANDROID-MK.html中

总而言之,NDK将你的源代码聚合到模块(modules)中,每个模块可以执行下列之一

—-一个静态库(lib<project>.a)

—-一个动态库(lib<project>.so)

你可以在Android.mk中定义多个模块,或者你可以编写多个Android.mk文件,每一个定义一个单独的模块

注意,单独的Android.mk也行被编译系统多次解析,以确定哪些变量没有被定义。

默认地,NDK会通过如下的编译脚本去寻找

test/jni/Android.mk(存放位置)

如果你想定义Android.mk到子目录中,你需要在最高层的Android.mk中明确的包含它们,下面是一个帮助的方法可以实现这个功能。

include $(call all-subdir-makefiles)

它会将所有的在子目录中的Android.mk文件加入到当前编译文件的路径中

④ 写一个Application.mk编译文件(可选)

在你的编译系统中有一个Android.mk文件描述模块的同时,Application.mk文件藐视你的应用程序本身。请看docs/APPLICATION-MK.html文档来理解这个文件允许我们做什么。这包括

—-你的应用程序需要模块的准确清单

—-CPU架构生成机器代码

—-可选信息,你是否需要一个release或者debug build,特殊的C/C++编译器标志和其他适用于所有模块的build

这个文件是可选文件:默认地,NDK会提供一个对于所有的在你的Android.mk(所有的makefiles都在里面)中的所有模块的简单编译并且指定默认的CPU ABI

使用Application.mk有两种方法:

—-把它放到 test/jni/Application.mk,它就会自动的被’ndk-build’脚本找出来

—-把它放在NDK/<name>/Application.mk,也就是NDK安装的路径下,然后从NDK目录下执行”make APP=<name>”

这个方法是Android NDK r4以前的。现在仍然兼容。但是我们强烈建议你使用第一种方法,因为它更简单并且不用修改NDK安装树的目录。

再次看看docs/APPLICATION-MK.html对于它的完整说明

⑤ 调用NDK编译系统

用NDK编译成机器码的最好方法是使用”ndk-build”脚本,你还可以使用第二个,这取决于你早起常见的”$NDK/apps”子目录

在两种情况下,成功构建将copy应用程序所需的最终的已经剥离的二进制模块(即共享库)到应用程序的项目路径中(注意,未剥离的版本主要是用于调试目的,无需拷贝未剥离的二进制文件到设备中)

[1]:使用’ndk-build’命令

‘ndk-build’脚本位于NDK安装目录最顶层,可以直接被应用程序项目目录(你的AndroidManifest.xml文件所在位置)或者其他任何子目录

$ cd $PROJECT

$ $NDK/ndk-build(注意是$NDK/ndkbuild,这是个命令)
将启动NDK的build脚本,它会自动探测您开发的系统和应用程序项目文件,以确定build设么

例如:

$ndk-build

$ndk-build clean à清理生成的二进制文件

$ndk-build –B V=1 à强制完全重新build,显示命令

默认的,它期望的是可选文件$PROJECT/jni/Application.mk和必须的文件$PROJECT/jni/Android.mk

成功的话,它讲话就复制生成的二进制模块(即共享库.so文件)到你的项目树中的适当位置。您可以在以后重新build完整的Android应用程序包或者通过“ant”命令,或者ADT插件。

可以看docs/NDK-BUILD.html来了解更多的信息

[2]:使用$NDK/apps/<name>/Application.mk

这种build方法是在Android NDK r4版本之前的,不过依然兼容现在的。我们强烈建议您尽可能的使用’ndk-build’,因为我们可能会删除在以后的NDK发行版本中的支持

① 创建一个子目录为$NDK/apps/<name>/

② 在$NDK/apps/<name>/目录下写一个Application.mk文件,然后需要定义一个APP_PROJECT_PATH来 执行你的应用程序项目的目录。

③ 进入到NDK安装目录,然后再输入如下的命令

$cd $NDK
注意:输入cd $NDK后,会自动跳到你设置的ndk的目录中

$make APP=<name>

$make APP=<name> -B 表示重新编译

结果跟第一种方法一样,除了中间文件被放置到了$NDK/out/apps/<name>/

4.从新build你的应用程序包

在NDK生成的二进制文件后,你需要使用一般的方法来重新build你的Android应用程序包文件(apk),或者用“ant”命令或者ADT插件

有关详细信息,请参阅Android SDK的文档,新的.apk会嵌入到您的共享库中,他们将自动提取安装时由系统安装的软件包到你的Android设备上

5 调试支持

NDK提供了一个服务脚本,名字叫”ndk-gdb”,很容易推出一个应用程序的本地调试会话。

本机调试仅仅能运行在Android 2.2或者更高版本,并且不需要root权限或者特权访问,所以可以随意调试你的应用程序。

有关详细信息,请阅读DOCS / NDK- GDB.html。总括而言,本机调试
遵循这个简单的计划:
(1)确保您的应用程序调试(如设置机器人:调试“真”,在您的AndroidManifest.xml)

(2) “NDK构建”构建您的应用程序,然后安装在您的 设备/模拟器

(3)启动应用程序。

(4)运行“ndk-gdb”从你的应用程序项目目录。

你会得到一个gdb提示符。一个有用的列表,请参阅GDB用户手册命令。

 

Android NDK 开发教程一:安装NDK

Android OS 的基本框架为Linux-Java ,在介绍Android开发时用到的Android结构图:

android 体系底层为Linux内核,之上提供一些C/C++函数库,因此Android 应用开发也可以使用C /C++开发,这就是Android NDK开发包,但Android提供NDK开发包的主要目的并不是推荐开发人员使用C(Native 代码)来编写一般的Android应用,而是要使用Java代码来编写Android应用来更好的处理Android应用生命周期(Life-cycle)相关的事件以避免出现“应用程序不响应(ANR)”的对话框。

使用NDK主要是通过JNI 使用从Java代码调用C代码,也就是使用Native编程主要是为上层Java代码提供库函数(动态库或是静态库的形式)而不是全部使用Native C代码编写整个Android应用(尽管借助于少量Java代码也是可以大部分使用C代码来实现的)。使用NDK大部分情况是需要将一些已有的C函数库移植到Android平台的所选择的快捷方法,而不是作为提高代码效率的手段。

安装Android NDK的方法非常简单:打开网页http://developer.android.com/sdk/ndk/index.html

选择合适的NDK开发包,下载解压即可。注:安装NDK之前需先安装SDK开发包,参见Android简明开发教程二:安装开发环境

Android NDK 的前两级目录如下:

.
├── build
│   ├── awk
│   ├── core
│   ├── gmsl
│   └── tools
├── docs
│   ├── ANDROID-ATOMICS.html
│   ├── ANDROID-MK.html
│   ├── APPLICATION-MK.html
│   ├── CHANGES.html
│   ├── CPLUSPLUS-SUPPORT.html
│   ├── CPU-ARCH-ABIS.html
│   ├── CPU-ARM-NEON.html
│   ├── CPU-FEATURES.html
│   ├── CPU-X86.html
│   ├── DEVELOPMENT.html
│   ├── HOWTO.html
│   ├── IMPORT-MODULE.html
│   ├── INSTALL.html
│   ├── LICENSES.html
│   ├── NATIVE-ACTIVITY.HTML
│   ├── NDK-BUILD.html
│   ├── NDK-GDB.html
│   ├── NDK-STACK.html
│   ├── openmaxal
│   ├── opensles
│   ├── OVERVIEW.html
│   ├── PREBUILTS.html
│   ├── sidenav.html
│   ├── STABLE-APIS.html
│   ├── STANDALONE-TOOLCHAIN.html
│   ├── system
│   └── SYSTEM-ISSUES.html
├── documentation.html
├── GNUmakefile
├── ndk-build
├── ndk-build.cmd
├── ndk-gdb
├── ndk-stack
├── ndk.txt
├── platforms
│   ├── android-14
│   ├── android-3
│   ├── android-4
│   ├── android-5
│   ├── android-8
│   └── android-9
├── prebuilt
│   └── linux-x86
├── README.TXT
├── RELEASE.TXT
├── samples
│   ├── bitmap-plasma
│   ├── hello-gl2
│   ├── hello-jni
│   ├── hello-neon
│   ├── module-exports
│   ├── native-activity
│   ├── native-audio
│   ├── native-media
│   ├── native-plasma
│   ├── san-angeles
│   ├── test-libstdc++
│   └── two-libs
├── sources
│   ├── android
│   ├── cpufeatures
│   └── cxx-stl
├── tests
│   ├── awk
│   ├── build
│   ├── device
│   ├── README
│   ├── run-standalone-tests.sh
│   ├── run-tests.sh
│   └── standalone
└── toolchains
    ├── arm-linux-androideabi-4.4.3
    └── x86-4.4.3

在开发NDK之前,建议先看一下doc 子目录下的文档,后面的博客也会有所介绍。

 

Android NFC 门票系统手机端程序简介

在开发Android NFC 门票系统手机端程序过程中也碰到一些技术问题, 比如:

  • 离线工作方式

      Android NFC 门票系统开发的一个实际要求,是要求系统可以工作在离线和在线两种方式。这是很多大型的游乐活动都远离城区,缺乏可靠的网络支持,临时架设的网络总可能出现这样那样的问题,有些区域可能网络无法覆盖到。因此手机端程序在设计时考虑到这种离线工作方式。解决方法是通过腕带时芯片时内存以及Message queue来实现。

  • 数据同步

     手机端采用SQL Lite 作为数据存储,如何和后台mysql 数据同步,目前市场没有现成的有效的Android 平台上SQL Lite 和mysql 数据库同步的解决方案。解决方法是通过查询后台数据库有无变化,比如Hash值有无变化,手机端保留两个数据库,一个为工作数据库,一个为同步数据库,同步数据库完成和后台数据同步后,两个数据库完成切换(毫秒级),这样手机用户感觉不到下载数据的延迟。

  • 使Home键,Power键等按钮失效

     通常情况下,用户按Home键,Power键,Search 键,会退出当前应用的运行,这对于工作人员Scan 会用户腕带时会造成问题,这个手机端程序需要一旦运行后,只有管理员或是用户登出时,才可以主动退出运行,其它情况不能退出运行,也就是除了运行门票系统手机端程序外,普通工作人员无法退出程序运行(即使时重启后)。解决方法是重写一个Dummy的Home Screen activity ,用户按Home键时,还是回到门票系统手机端程序。再有是相应Boot 完成消息,手机通电启动后自动运行这个门票系统手机端程序等。

  • Nexsus S Gingerbread NFC 不稳定

      在开发过程中,发现Sumsung 出厂时的版本NFC用两个问题,一个很容易就将NFC服务“搞死”,手机扫描一个支持paypass 的信用卡,NFC功能立马失效,再有随手机出厂的ROM中带有一个内置的NFC Tag原因,即使应用设置成前台方式工作参见Android NFC 开发教程(2): ApiDemos->NFC->ForegoundDispatch 。这个应用也时不时的突然冒出来捣乱。解决方法是编译自定义的ROM,去掉这个内置应用,并升级到ICS。ICS版本下NFC可靠性大大提高。

等等,此外这里不便于描述一下实现的技术细节,发一些应用的截图,可以大致知道手机端应用目前提供的一些功能(这个列表在后面的时间将会不断扩充:-))

启动时数据同步操作,之后的同步为后台自动运行,支持3G,Wifi 网络(internet 可选)。

选择工作位置,可以扫描或是人工选择,工作位置可以是入口,出口,酒吧,工作地点的类型决定了系统手机端程序的工作方法:门禁或是POS机

工作人员登录,系统支持Staff, super user ,admin user 不同用户类别,支持权限管理。

选择门禁工作地点后菜单选择

选择POS工作地点后菜单选择

管理用户,支持白名单,黑名单,短消息,消费记录,扫描记录等。

门禁,扫描用户腕带(门票),读取芯片上信息,校验后决定是否允许该客人进入指定区域(如是否可以进入VIP区等),并显示该区域容量指示。

POS终端

付费,可以修改客人的order ,确定后,直接扫描客人腕带完成交易。

 

在Android手机上安装完整版Ubuntu

目前市场的Android手机性能越来越高,完全可以安装Ubuntu桌面操作系统。在Android手机安装Ubuntu有两种方法,

对上述两种方法进行实测之后,发现目前都有局限性,第一种方法,目前对触摸屏缺乏支持,因此在Nexus S手机上安装之后,基本无法操作,只启动显示Ubuntu桌面,后面无法响应按键(触摸屏)事件。

第二种方法,可以安装Ubuntu9.x 到Nexus S手机上,同时也保留原先的Android系统,但操作系统比较老,使用apt-get update 有问题,很多链接出现404 问题,需要修改/etc/apt/sources.list 指向旧的ubuntu 版本,勉强可以更新,但致命的一个问题是原文提供的ubuntu.img 只有2G,ubuntu操作系统基本占据的2G的空间,留给用户使用的空余空间不到100M,无法安装一些常用软件如apache,mysql 等,实用性不高。

这里给出一个综合的方法,首先根据第一种中提供的rootfs.ext2 ,使用dd ,mkfs.ext2 创建一个新的my4gimage.ext2 文件(4G 左右,SD卡能支持的单个文件最大为4G)。这个文件映像文件包含了Ubuntu 10.0 版本和ssh server. 文件下载(900M ,tar.gz格式

基本步骤可以参考上面第二种方法的步骤,概述如下:

1.  对于需要安装Ubuntu系统的手机,首先需要获得root 权限,简单的方法是使用fastboot 重新刷机,如CyanogenMod 提供的ROM。

2. 将ubuntu.tar.gz 解压到手机sd卡的ubuntu 目录下。

3. 使用数据线把手机连接到PC,使用adb shell ,或者直接运行手机上terminal Emulator

然后,输入su ,进入超级用户模式,然后 键入

  • cd /sdcard
  • cd ubuntu
  • sh ubuntu.sh (只需运行一次)
  • bootubuntu

下面就可以使用apt-get update 进行升级,可以升级到最新的Ubuntu 11.x 。

升级可以使用SSH 客户端,或是使用vnc 客户端,

  • 如果使用ssh ,需要先启动 ssh 服务,  /etc/init.d/ssh start

  • 如果使用vnc ,需先安装vnc server ,   apt-get install tightvncserver

下面就可以使用do-release-upgrade 升级Ubuntu 或是安装apache2 ,php, mysql 。

注:mysql 安装中可能或出现/com/ubuntu/upstart 无法连接的错误,从而无法使用service mysql start 来启动mysql ,可以直接在命令行执行mysqld & 绕过。

这样安装好的Ubuntu和桌面系统一样使用,性能相当不错,作为一般的Web 服务器用于开发,或是作为Web 服务器临时替代(手机本身可以作为Access Point)都是一个不错的选择。

 

基于Android NFC的门票系统

很久没有更新博客了,前段时间一直在忙基于Android NFC的应用,经过几个月的努力,世界上第一个基于Google Nexsus S 的NFC 门票系统终于从实现概念到成功商业运行的转变:-)。今年的二月和三月在澳洲的Perth成功的举行了三次音乐会,最近的一次为Future Music 2012 ,规模在近四万人左右,高峰期每分钟通过300-400人,系统运行良好。

手机通过内置NFC读写器读取用户门票上的Mifare芯片(腕带)。腕带既可以作为门禁(普通区或贵宾区)也可以作为电子钱包等功能,后台提供各种报表,如吞吐量,及时销售,短信等。