近期出现在Google Android开发路线图的动作来看,对于QVGA和WVGA的表现的比较重要,最终随着Android手机不同品牌的推出,使用的屏幕大小和分辨率可能将会出现一些分歧。比如目前使用的是480×320的HVGA,而很多市面上常规的机型使用了320×240的QVGA屏,不过趋势逐渐向宽屏和高分辨率发展。800×480的WVGA已经出现了很多样板机型了。 下面是roadmap原文 Beyond Q1 2009 Support for WVGA and QVGA, in addition to the currently supported HVGA display. 在多国语言以及资源文件分配上,android平台可以很好的通过layout的布局文件来实现本地化问题,这里可以参考本站以前的文章。 Support for additional types of displays:
图160S
剖析Android自带Widget – Clock指针钟表 Android开发技术
我们都知道Android操作系统自带了几个Widget组件,比如带指针的钟表,一般在Home Screen上的那个表盘,它在哪里呢? 我们其实在alarmclock这个包中可以看到,下面就来一起分析一下实现的方法。其实有关内部的更新在AnalogClock类已经完成了,这里仅仅分析Widgets部分。 首先看下alarmclock中有关widgets的AndroidManifest.xml描述内容如下: <receiver android:name="AnalogAppWidgetProvider" android:label="@string/analog_gadget-android123"> <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> </intent-filter> <meta-data android:name="android.appwidget.provider" android:resource="@xml/analog_appwidget" /> </receiver> xml/analog_appwidget.xml的内容如下 <?xml version="1.0" encoding="utf-8"?> <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:minWidth="146dip" //widget最小宽度 android:minHeight="146dip" //widget最小高度 android:updatePeriodMillis="0" //更新频率,单位为毫秒 android:initialLayout="@layout/analog_appwidget" > </appwidget-provider> layout/analog_appwidget.xml的内容如下 <AnalogClock xmlns:android="http://schemas.android.com/apk/res/android" android:dial="@drawable/appwidget_clock_dial" //表盘背景图片 android:hand_hour="@drawable/appwidget_clock_hour" //时针图片 android:hand_minute="@drawable/appwidget_clock_minute" //分针图片 android:layout_width="fill_parent" android:layout_height="fill_parent" /> 最后我们看下androidmanifest.xml中的receiver是如何触发的,AnalogAppWidgetProvider.java的内容如下 public class AnalogAppWidgetProvider extends BroadcastReceiver { public void […]
剖析Android自带Widget – Music播放器 Android开发技术
昨天的带指针时钟比较简单,今天我们继续android自带widget剖析,相对于alarmclock而言music程序稍微复杂些,主要是涉及到众多事件的处理,不过可以看出如何是和服务进行交互的。继续按照昨天的分析步骤和过程,首先我们看下music程序中AndroidManifest.xml中有关widgets的定义。 <receiver android:name="MediaAppWidgetProvider"> <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> </intent-filter> <meta-data android:name="android.appwidget.provider" android:resource="@xml/appwidget_info" /></receiver> 下面是xml/appwidget_info的内容,里面包含了这个widget程序的基本定义。 <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:minWidth="294dip" //最小宽度 android:minHeight="72dip" //最小高度 android:updatePeriodMillis="0" //更新频率 android:initialLayout="@layout/album_appwidget"> //widget界面布局文件</appwidget-provider> 整个设计还是十分清晰,这里我们就不再做过多的赘述。 public class MediaAppWidgetProvider extends AppWidgetProvider { public static final String CMDAPPWIDGETUPDATE = "appwidgetupdate"; static final ComponentName THIS_APPWIDGET = new ComponentName("com.android.music", "com.android.music.MediaAppWidgetProvider"); private static […]

APK签名导出向导 – Use the Export Wizard Android开发技术
以前我们介绍过试用Android签名用keytool和jarsigner制作apk文件 的方法来对一个APK文件进行签名,今天我们主要讲解下如何通过Android 1.5 SDK以后ADT 0.9.1版自带的Use the Export Wizard。首先我们在Package Explorer中选择工程的androidmanifest.xml文件,可以看到右边默认的manifest模式中有个exporting功能,选择Use the Export Wizard,如图所示: 第二步在Project Checks中,选择需要导出的工程, 一般默认的是当前工程,这里我们使用默认的android123即可,如下图: 接下来在Keystore selection中选择Create new keystore这项,默认的Location为keystore文件的保存位置,这里我们随便选择一个路径即可,然后输入密码和确认密码,这里可以随便填写,如图: 在Key Creation这项中,我们简单输入一些信息,比如Alias别名,这里我就写自己的名字CWJ, 密码要和刚才keystore中输入的一样才行,整个签名过程其实是一个RSA加密过程,最后的Validity(years)是有效期,这里输入推荐的25年即可,其他的内容为选填,如图 最后在Destination and Key/certificate checks中选择只有Destination APK file,这是保存的最终APK文件的路径,最后签名后的apk文件就保存到这个位置中,同时下面有一些描述信息,如图:
ApiDemos中的Android Widget例子解析 Android开发技术
今天继续我们的Android Widget开发之旅,看看Android SDK中ApiDemos上的Widget例子,下面的代码分为3个文件可以清楚的看到整个框架,主要是AppWidgetProvider类中的onUpdate、onDeleted、 onEnabled、onDisabled和updateAppWidget方法之间的状态改变,使用Logcat仔细分析一个widget的生命周期。 package com.example.android.apis.appwidget; import android.appwidget.AppWidgetManager;import android.appwidget.AppWidgetProvider;import android.content.ComponentName;import android.content.Context;import android.content.Intent;import android.content.pm.PackageManager;import android.os.SystemClock;import android.util.Log;import android.widget.RemoteViews; import java.util.ArrayList;import com.example.android.apis.R; 涉及到的文件有 ExampleAppWidgetConfigure.javaExampleBroadcastReceiver.javares/layout/appwidget_configure.xmlres/layout/appwidget_provider.xmlres/xml/appwidget_provider.xml public class ExampleAppWidgetProvider extends AppWidgetProvider { private static final String TAG = "ExampleAppWidgetProvider"; //logcat调试信息 public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { Log.d(TAG, "onUpdate"); // – 创建一个RemoteViews 对象 // – […]
APK文件格式分析,Android反编译入门(一) Android开发技术
对于软件开发人员来说,保护代码安全也是比较重要的因素之一,不过目前来说Google Android平台选择了Java Dalvik VM的方式使其程序很容易破解和被修改,首先APK文件其实就是一个MIME为ZIP的压缩包,我们修改ZIP后缀名方式可以看到内部的文件结构,类似Sun JavaMe的Jar压缩格式一样,不过比较去别的是Android上的二进制代码被编译成为Dex的字节码,所有的Java文件最终会编译进该文件中去,作为托管代码既然虚拟机可以识别,那么我们就可以很轻松的反编译。所有的类调用、涉及到的方法都在里面体现到,至于逻辑的执行可以通过实时调试的方法来查看,当然这需要借助一些我们自己编写的跟踪程序。模拟器自带了一个dexdump,有兴趣的网友可以先了解下,同时以及有关APK文件的汉化,我们将在下一次做详细的分析,因为这里主要是修改的不是dex而是资源文件,使用类似UltraEdit这样的工具以字节对齐的方式逐个替换即可,最终再签名下即可使用,这样的行为可以算作是非法修改,不过目前这样的方法在国内很流行,Google最然在Android Market上设置了权限保护app-private文件夹的安全,但是最终我们使用修改定值的系统仍然可以获取到需要的文件。

APK汉化原理及方法 Android开发技术
我们继续上次的APK格式文件分析,本次探讨下有关APK汉化技术,其实对于软件汉化一直都属于比较简单的范畴,对于传统Win32程序或者说PE文件而言,代码被编译成为一个二进制的文件中,通过类似section的方式来区分资源,android平台中将代码逻辑和资源文件进行了分离,字符串被放在了一个名为resources.arsc的文件中,我们将一个apk文件修改后缀名为zip,然后解压缩可以看到如下文件。其中高亮部分就是我们需要的文件如图: 相对于传统软件汉化而言,android apk文件的汉化我们不需要脱壳,不需要修改API导入表,几乎仅仅是字符串替换的体力活,这里我们使用winhex这个十六进制的查看工具来作分析,可以看到加载后显示的文件字符集为ansi,每个偏移十六进制对应的正是原始的字符串,如下图,我们只需要替换即可做到汉化,不过这样看起来还很麻烦,android123会在近期推出一个汉化工具自动包含词库替换英文到中文,相关技术参考 APK文件格式分析,Android反编译入门(一) 文件描述。

Android导出一个JAR库 Android开发技术
很早以前,我们说过如何导入一个JAR库,的方法可以参考 Android使用第三方外部JAR库文件 一文。那么如果将自己的代码封装成一个jar库供其他程序复用呢? 首先创建一个Android工程,确定可以编译通过,移除androidmanifest.xml文件,和相关的程序资源图片,比如res/drawable/icon.png。在Eclipse中我们找到Package Explorer,选择export,如图: 接下来在导出对话框中选择Java,JAR file,如下图所示: 在JAR File Specification这里选择我们需要到处的资源等等,在JAR file:路径选择我们导出后文件的存放位置,在下面的Compress the contents of the JAR file勾选可以压缩生成文件的体积。最后单击Next或Finish即可完成导出,这样可以在以后的工程中导入这个库,起到了代码复用的效果类似Windows 32开发的Dll文件一样。
Android安全模型导致开发时功能受限 Android开发技术
经过近2两年对Android整个平台的实测和开发,可以总结出一些系统设计问题: 1. Android选择Dalvik VM导致了系统运行效率的降低,硬件配置要求更高。似乎运行内存在128MB和CPU在400MHz是流畅运行的极限-导致虽然Android是免授权费用,但是硬件成本过高也是一大问题。 2. 虽然推出了Android NDK,但是使用C/C++开发仍然是一个重要的问题,Java可以保证更高的安全性、开发效率以及更低的开发门槛,但是对于设计一些优良的程序来说Java VM和GC的效率真是低的惊人。 3. Root权限限制,导致任务管理器、模拟按键、屏幕截图、短信防火墙类似的实现都遇到了问题,似乎这些仅仅是ADP开发机才能拥有的特性,虽然SDK版本的提高功能更多,但是底层的控制反而更少。 4..Google为了平台的安全性似乎并没有太大的改进,反倒是重演微软Windows Vista UAC带来的问题,重要的是虽然有许可权限但限制仍然是几个智能平台中最大的。
Android过后Chrome OS又是如何开发? Android开发技术
很多网友不知道对于目前Android SDK是否满意,但是如果Google操作系统 Chrome OS 真的上市后留给第三方开发人员的又是什么呢? Dalvik运行在PC Linux绝对是不太可能的,Linux PC平台的运算能力还是很强的,甚至是未来的Server考虑,可能又回到了Linux卡发难的老路。除非Google推出自己的OS API,类似Win32 API那样在应用层面上有一个统一。 Chrome OS最终运行Sun Java这样的方式开发出来的程序和Windows相比优势不是很明显,至少我们仍然看到Dot Net这样的东西仅仅适合数据库和Web应用,在桌面应用上的效率和稳定性十分低,反倒P/Invoke增加了开发难度以及运行效率。如果Linux平台上还是用GCC那样的去写最终仍然还是拍拖不了OOP这样的设计方式,可以想象没有Visual Studio这样稳定的IDE后,Eclipse也仅仅是Java或Ruby、Python这样的玩具脚本,比过去的Sun Applet先进不到哪里? 值得我们考虑的是Chrome OS和Android不同,会不会有一个Win32 API和DDK提供给大家。

Android开发工具-motoDEV studio介绍 Android开发技术
摩托罗拉自家的MOTODEV Studio for Android Beta版已经完成,他将会有更高智能度和全新的开发体验,相比目前的Eclipse+ADT来说可能更方便一用,不过目前并没有相关的运行界面,这款全新的IDE使用什么语言编写成了我们关心的问题,毕竟运行在Java VM上的Eclipse假死和不稳定十分明显,和微软的Visual Studio相比有着先天的不足,希望Motorola IDE能够有些改进。 MotoDev Studio 将帮助Android开发人员优化程序针对各种硬件,比如3D图形使用OpenGL, 以及更好的挂你了开发程序对于不同的设备和雇员,对于维护性和团队开发将有大幅改进,最终这款集成开发环境到底授权方式以及易用性如何还需要进一步了解。

Simple让BASIC语言编写Android程序 Android开发技术
比较有意思的是Google发布了BASIC语言编译针对Android平台的开发工具-Simple (Simple Compiler And Runtime),如果用户有VB基础的话相信使用Basic(Beginner’s All-purpose Symbolic Instruction Code)可以很好的编写一些简单的逻辑类程序。虽然Android主要使用Java来开发,但是虽然NDK的发布兼容C/C++目前Simple将帮助它支持Basic可以说基本上“全”了。下面我们给出一个简单的Simple编译器例子,看看下图Test.Initialize中的变量声明方式,Dim xxx As type是不是很熟悉,的确这是Basic。 本地下载Simple编译器源代码 http://down.android123.com/simple.zip
安装MOTODEV Studio for Android版方法 Android开发技术
安装MOTODEV Studio 来自摩托罗拉的Android开发IDE已经提供了下载,相关的安装方法如何呢? 下面是发布文档中有关Mac和Windows x86桌面系统的安装说明 。MOTODEV Studio for Android installation process depends upon your underlying operating system. Once you have installed MOTODEV Studio, the process of installing or configuring the Android SDK (documented under "Installing the Android SDK”) is the same regardless of your operating system. Microsoft Windows If you already have a previous version […]

MOTODev试用报告- Android开发效率之源 Android开发技术
如果使用Eclipse+ADT的网友感觉写代码仍然很不顺手可以试试来自摩托罗拉的集成开发环境,这款MOTODEV Studio for Android给我们带来了更高的开发效率。在安装过程中看到了Eclipse的授权许可信息就知道它的设计仍然逃不过Java VM,虽然IDE中似乎除了Xcode、Platform Builder外都是Eclipse,即使是Carbide C++等等都是开源的开发环境。 不做过多的抱怨,毕竟IDE仅仅是提高效率的工具,安装时首先弹出了命令行参数脚本错误,不过还是按照Setup向导直接安装,第一次运行还是设置workspace,接下来会提示设置Android SDK,这里第一个选项是下载SDK,不过这需要首先手动安装ADT插件,看来比较鸡肋。我们的PC上已经有了SDK,这里选择Use an existing SDK from the file system.设置SDK location即可,感觉就是比ADT需要设置的改成了向导模式。如图: 接下来,我们还是选择Workbench进入开发视图,整个界面和过去的大同小异,可以看到Motorola内部的工程管理工具也是自定义的,如图: 最后还是看看好用不好用,首先我们在不创建工程的情况下观察下,可以看到工具栏上多出了一些发布选项,比如Android Market以及Motorola自己的Marketplace,在右边我们不选择DDMS,加入MOTODEV Studio for Android这项,看到多出了Snappies代码段,可以比智能感知更方便的添加常规代码,有点类似.Net的常规控件添加,不过这里是代码段。下方可以看到多出了Appliacation Signing签名工具,不过这里在ADT 0.9.1插件中已经支持了。具体实际使用还需要测试才能作出评论。 经过Android开发网简单的试用,可以看到比常规的ADT是方便了一些,摩托罗拉近些年虽然在手机硬件方便一直处于下滑,但本次能提供一款免费的IDE还是可圈可点的。更多的使用经验我们会在以后的文章里提到。 详细的安装方法参考 安装MOTODEV Studio for Android版方法

MOTODEV初体验,高效Android开发工具 Android开发技术
摩托罗拉公司内部的Android开发工具-MOTODEV Studio到底比Eclipse + ADT方便到哪里呢? 这里我们来简单对比下,其实Motorola的IDE和Google官方的方案相比仅仅是二次开发改进。因为Eclipse是开源的,ADT插件也是开源的,整体上来说做了一些基础性的效率改进,要说恨神奇的地方没有发现,代码还是要人写的。下面是MOTODEV的启动Logo。 除了上次我们简单介绍的内容外可以看到Motodev studio for Android在创建新文件时,多出了不少选项,比如Android Activity、Broadcast Receiver、Service、Content Provider,几乎Android平台的主要框架都包含在内了。不过仅仅是基础代码的生成,从另一个侧面可以看到这点Google毕竟是从Web起家的,对于开发人员来说微软这方面作为软件帝国想的就十分周到。Motodev只是做了小幅的补充。经过简单的试用可以看到对于标准的Android开发来说,试用Motodev还合适,不过考虑到目前moto的经济状况,长久考虑还是推荐使用Eclipse+ADT的方式稳当,总体而言和Google官方的开发工具相比没有太大的改进,至少工作在Java VM上的产物稳定性仍然是一个问题。
AndroidManifest.xml文件剖析 (一) Android开发技术
很多网友对于Android全局配置文件AndroidManifest.xml不是很熟悉,今天我们就一起看下它完整的结构以及每个节点的作用。在我们日常的开发中都少不了下面的配置,每创建一个Activity、Service都离不开这个全局配置文件,深入的了解可以简化程序代码以及提高程序的维护性。 在最外层包含了包名如 package="cn.android123.demo" 、软件的版本号 android:versionCode="1" 以及 android:versionName="1.0" ,里面一层的application分支中将可能包含Android程序的四种对象 Activity、Service、Content Provider以及Receiver。我们每添加上面四个类型中的任一新对象都需要在androidmanifest.xml文件中添加相应节点。 其中Activity的属性常用的可能为android:name和android:label但我们需要了解所有的属性以帮助解决复杂的问题,完整的如下: android:allowTaskReparenting=["true" | "false"] android:alwaysRetainTaskState=["true" | "false"] android:clearTaskOnLaunch=["true"" | "false"] android:configChanges=[one or more of: "mcc" "mnc" "locale" "touchscreen" "keyboard" "keyboardHidden" "navigation" "orientation" "fontScale"] android:enabled=["true" | "false"] android:excludeFromRecents=["true" | "false"] android:exported=["true" | "false"] android:finishOnTaskLaunch=["true" | "false"] android:icon="drawable resource" android:label="string resource" android:launchMode=["multiple" | "singleTop" […]
AndroidManifest.xml文件剖析 (二) Android开发技术
有关AndroidManifest.xml文件的application分支我们有必要了解一些常见的属性,这里可以看到一些我们实用的选项,比如允许调试android:debuggable、任务关系android:taskAffinity,比如我们常见的方式创建一个新的任务实用标记FLAG_ACTIVITY_NEW_TASK,为程序制定一个主题,可以使用android:theme指向一个主题文件。 平时我们创建的程序使用一些安全敏感项,会需要请求系统许可权限,这里可以使用android:permission来制定相关的许可,每个程序的service、activity、content provider、receiver都需要在application的节点内实现。有关完整的属性可以查看: <application android:allowClearUserData=["true" | "false"] android:allowTaskReparenting=["true" | "false"] android:debuggable=["true" | "false"] android:description="string resource" android:enabled=["true" | "false"] android:hasCode=["true" | "false"] android:icon="drawable resource" android:label="string resource" android:manageSpaceActivity="string" android:name="string" android:permission="string" android:persistent=["true" | "false"] android:process="string" android:taskAffinity="string" android:theme="resource or theme" > . . .</application>
AndroidManifest.xml文件剖析 (三) Android开发技术
有关Androidmanifest.xml文件中的数据提供,我们来看下Provider节点中用到的定义,可以看到包含了权限控制、排序方式完整的如下: <provider android:authorities="list" android:enabled=["true" | "false"] android:exported=["true" | "false"] android:grantUriPermissions=["true" | "false"] android:icon="drawable resource" android:initOrder="integer" android:label="string resource" android:multiprocess=["true" | "false"] android:name="string" android:permission="string" android:process="string" android:readPermission="string" android:syncable=["true" | "false"] android:writePermission="string" ></provider> 而对于服务相关定义如下: <service android:enabled=["true" | "false"] android:exported[="true" | "false"] android:icon="drawable resource" android:label="string resource" android:name="string" android:permission="string" android:process="string" ></service> 最后是Broadcast使用的Receiver定义,一般配合<intent-filer> 和<meta-data>隐式处理。 <receiver android:enabled=["true" | […]

Android蓝牙API之BluetoothAdapter类(2) Android开发技术
从Android 2.0开始提供最全面的蓝牙开发接口,API Level为5的系统才能调用,目前Android Bluetooth API包含了主要以下几类:BluetoothAdapter BluetoothDevice、BluetoothSocket 、BluetoothServerSocket 和BluetoothClass 它们均在android.bluetooth这个包中出现。 我们调用时除了需要考虑API Level至少为5外,还需注意添加相应的权限,比如使用通讯需要在androidmanifest.xml加入<uses-permission android:name="android.permission.BLUETOOTH" />,而开关蓝牙需要android.permission.BLUETOOTH_ADMIN权限。 三、建立通讯 establishing 对于建立一个蓝牙通讯,必须经过以下四个步骤:获取本地蓝牙设备、查找远程设备、配对(已配对设备将会忽略这步的细节)、连接设备和传输数据. 在Android平台中首先我们需要查找本地活动的蓝牙适配器,通过BluetoothAdapter类的getDefaultAdapter() 方法获得一个系统默认可用的蓝牙设备,示例代码如下 BluetoothAdapter cwjBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); if (cwjBluetoothAdapter == null) { // Android开发网提示大家本机没有找到蓝牙硬件或驱动存在问题 } 当然有了这步仍然不能建立连接,因为我们还不知道手机中的蓝牙功能是否被开启,可以通过cwjBluetoothAdapter的.isEnabled方法来判断,如果没有开启,我们可以通过下面的代码提醒用户启用: if (!cwjBluetoothAdapter.isEnabled()) { Intent TurnOnBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(TurnOnBtIntent, REQUEST_ENABLE_BT);}这时用户会收到类似下面的窗口: 我们通过startActivityForResult()方法发起的Intent将会在onActivityResult()回调方法中获取用户的选择,比如用户单击了Yes开启,那么将会收到RESULT_OK 的结果,如果RESULT_CANCELED则代表用户不愿意开启蓝牙,当然android123提醒大家还可以通过其他方式来开启,比如说用BluetoothDevice获取蓝牙服务接口对象,是用enable()方法来开启,无需询问用户,这时就需要用到android.permission.BLUETOOTH_ADMIN权限。 如何判断系统蓝牙的状态呢? 建立BroadcastReceiver对象,接收ACTION_STATE_CHANGED动作,在EXTRA_STATE和EXTRA_PREVIOUS_STATE包含了现在状态和过去的状态,最终的结果定义是STATE_TURNING_ON正在开启, STATE_ON已经开启, STATE_TURNING_OFF正在关闭和 STATE_OFF已经关闭,如果有什么不明白的可以在我们的论坛中交流。 […]

Android蓝牙API之BluetoothAdapter类(1) Android开发技术
使用BluetoothAdapter类,你能够在Android设备上查找周边的蓝牙设备然后配对(绑定),蓝牙通讯是基于唯一地址MAC来相互传输的,考虑到安全问题Bluetooth通讯时需要先配对。然后开始相互连接,连接后设备将会共享同一个RFCOMM通道以便相互传输数据,目前这些实现在Android 2.0或更高版本SDK上实现。 一、查找发现 findding/discovering devices 对于Android查找发现蓝牙设备使用BluetoothAdapter类的startDiscovery()方法就可以执行一个异步方式获取周边的蓝牙设备,因为是一个异步的方法所以我们不需要考虑线程被阻塞问题,整个过程大约需要12秒时间,这时我们紧接着注册一个BroadcastReceiver 对象来接收查找到的蓝牙设备信息,我们过滤ACTION_FOUND这个 Intent动作来获取每个远程设备的详细信息,通过附加参数在Intent字段EXTRA_DEVICE 和 EXTRA_CLASS, 中包含了每个BluetoothDevice 对象和对象的该设备类型 BluetoothClass ,示例代码 private final BroadcastReceiver cwjReceiver = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (BluetoothDevice.ACTION_FOUND.equals(action)) { BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); myArrayAdapter.add(device.getName() + " android123 " + device.getAddress()); //获取设备名称和mac地址 } […]
Android UI开发专题(一) 之界面设计 Android开发技术
近期很多网友对Android用户界面的设计表示很感兴趣,对于Android UI开发自绘控件和游戏制作而言掌握好绘图基础是必不可少的。本次专题分10节来讲述,有关OpenGL ES相关的可能将放到以后再透露。本次主要涉及以下四个包的相关内容: android.content.res 资源类 android.graphics 底层图形类 android.view 显示类 android.widget 控件类 一、android.content.res.Resources 对于Android平台的资源类android.content.res.Resources可能很多网友比较陌生,一起来看看SDK上是怎么介绍的吧,Contains classes for accessing application resources, such as raw asset files, colors, drawables, media or other other files in the package, plus important device configuration details (orientation, input types, etc.) that affect how the application may behave.平时用到的二进制源文件raw、颜色colors、图形drawables和多媒体文件media的相关资源均通过该类来管理。 int […]
Android蓝牙API之BluetoothSocket类 Android开发技术
前面两篇文章中我们提到了有关Android平台蓝牙的配对、发现、启用等操作,本文开始通过BluetoothSocket类建立有关蓝牙通讯的套接字。从Android 2.0开始支持这一特性,蓝牙和LAN一样通过MAC地址来识别远程设备,建立完通讯连接RFCOMM通道后以输入、输出流方式通讯。 一、连接设备 蓝牙通讯分为server服务器端和client客户端,它们之间使用BluetoothSocket 类的不同方法来获取数据, 1. 作为服务器 如果一个设备需要和两个或多个设备连接时,就需要作为一个server来传输,在android中提供了BluetoothServerSocket类来处理用户发来的信息,服务器端套接字在接受(accepted) 一个客户发来的BluetoothSocket时作出相应的响应。示例代码如下: private class AcceptThread extends Thread { private final BluetoothServerSocket cwjServerSocket; public AcceptThread() { BluetoothServerSocket tmp = null; //使用一个临时对象代替,因为cwjServerSocket定义为final try { tmp = myAdapter.listenUsingRfcommWithServiceRecord(NAME, CWJ_UUID); //服务仅监听 } catch (IOException e) { } cwjServerSocket = tmp; } […]
Android蓝牙API之BluetoothSocket类(2) Android开发技术
通过前几次的讲解,很多网友相信对Android蓝牙相关开发可以很好的掌握了,通过BluetoothServerSocket可以方便的创建一个蓝牙服务器,使用BluetoothSocket类可以很好的处理连接,今天我们继续上次的内容说下Android下如何管理蓝牙套接字的连接,今天仍然使用BluetoothSocket类,处理具体的数据流。 在Java上处理数据流很简单,提供了InputSream、OutputSream和字节数组的之间的转化。今天android123将和大家一起说下处理上次遗留的manageConnectedSocket方法的细节,由于蓝牙传输中可能存在中断,所以为了防止阻塞需要开一个工作者线程,相关的示例代码 private class ConnectedThread extends Thread { private final BluetoothSocket cwjSocket; private final InputStream cwjInStream; private final OutputStream cwjOutStream; public ConnectedThread(BluetoothSocket socket) { cwjSocket = socket; InputStream tmpIn = null; //上面定义的为final这是使用temp临时对象 OutputStream tmpOut = null; try { tmpIn = socket.getInputStream(); //使用getInputStream作为一个流处理 tmpOut = socket.getOutputStream(); […]
Android上的Back键事件捕获 Android开发技术
很多网友不明白如何在Android平台上捕获Back键的事件,Back键是手机上的后退键,一般的软件不捕获相关信息可能导致你的程序被切换到后台,而回到桌面的尴尬情况,在Android上有两种方法来获取该按钮的事件。 1.直接获取按钮按下事件,此方法兼容Android 1.0到Android 2.1 也是常规方法,直接重写Activity的onKeyDown方法即可,代码如下: @Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) { //按下的如果是BACK,同时没有重复 Toast.makeText(android123.this,"Android开发网Back键测试",1).show(); return true; } return super.onKeyDown(keyCode, event);} 而对于Android 2.0开始又多出了一种新的方法,对于Activity 可以单独获取Back键的按下事件,直接重写onBackPressed方法即可,代码如下 @Overridepublic void onBackPressed() {// 这里处理逻辑代码,cwj提示大家注意该方法仅适用于2.0或更新版的sdkreturn;}
Only the original thread that created a view hierarchy can touch its views的相关 Android开发技术
很多网友在Android中使用多线程处理UI相关内容时可能会发现Logcat提示Only the original thread that created a view hierarchy can touch its views这样的错误,这主要是Android的相关View和控件不是线程安全的,我们必须做独立的处理这点比J2ME麻烦一些,这里Android给我们提供了很多方法,有关线程的,我们需要了解下J2ME中一些传统的线程创建方法,比如Runnable或直接new Thread(),大家需要了解UI线程、worker线程以及一些概念。今天android开发网说一种简单的方法除了异步任务AsyncTask外使用Handler可以很好的处理,和Win32的消息很像。 首先我们需要明白,主线程或者这里说的原始线程original thread 一般情况下是UI线程,当然UI线程并不一定是主线程,我们不能长时间的阻塞该应用,在Android平台上可能会产生类似Force close或Wait这样的对话框这里我们成为ANR,这里除了使用ProgressDialog方式给用一个动态的进度代表当前处理并没有中断可能需要一些时间,所以android123告诉大家相关的网络处理可以使用工作者线程,但是worker 线程不能处理显示元素即UI相关的View或Widget包中的高层的控件,所以通过一个Handler对象可以很好的传递Runnable或Message ,下面我们用一个简单的例子来描述 final Handler cwjHandler = new Handler(); final Runnable mUpdateResults = new Runnable() { public void run() { updateUI(); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); NetworkOperation();//一个很费时间的I/O操作,比如网络或文件读写等等。 } […]
Android UI开发专题(一) 之界面设计 Android开发技术
近期很多网友对Android用户界面的设计表示很感兴趣,对于Android UI开发自绘控件和游戏制作而言掌握好绘图基础是必不可少的。本次专题分10节来讲述,有关OpenGL ES相关的可能将放到以后再透露。本次主要涉及以下四个包的相关内容: android.content.res 资源类 android.graphics 底层图形类 android.view 显示类 android.widget 控件类 一、android.content.res.Resources 对于Android平台的资源类android.content.res.Resources可能很多网友比较陌生,一起来看看SDK上是怎么介绍的吧,Contains classes for accessing application resources, such as raw asset files, colors, drawables, media or other other files in the package, plus important device configuration details (orientation, input types, etc.) that affect how the application may behave.平时用到的二进制源文件raw、颜色colors、图形drawables和多媒体文件media的相关资源均通过该类来管理。 int […]
Android UI开发专题(二) 之绘图基础 Android开发技术
今天我们继续介绍Android平台底层绘图类的相关内容,在Android UI开发专题(一) 之界面设计中我们介绍了有关Android平台资源使用以及Bitmap相关类的操作,接下来将会以实例的方式给大家演示各种类的用处以及注意点。今天我们继续了解android.graphics包中比较重要的绘图类。 一、 android.graphics.Matrix 有关图形的变换、缩放等相关操作常用的方法有: void reset() // 重置一个matrix对象。 void set(Matrix src) //复制一个源矩阵,和本类的构造方法 Matrix(Matrix src) 一样 boolean isIdentity() //返回这个矩阵是否定义(已经有意义) void setRotate(float degrees) //指定一个角度以0,0为坐标进行旋转 void setRotate(float degrees, float px, float py) //指定一个角度以px,py为坐标进行旋转 void setScale(float sx, float sy) // 缩放 void setScale(float sx, float sy, float px, float py) //以坐标px,py进行缩放 […]

提高Android开发效率-Eclipse快捷键大全 Android开发技术
很多过去使用Visual Studio开发软件的网友可能不熟悉Java开发环境,今天Android开发网告诉大家一些提高Android开发效率的Eclipse快捷键,可以有效率的帮助我们管理代码和减少键盘输入。Eclipse相对于Visual Studio而言使用Java开发,响应速度和稳定性上有很大的欠缺,这些我们目前只能容忍下。 比较常用的Android123整理如下: 自动补充import Package Ctrl+Shift+O,这里O代表Organize Import的意思。 格式化代码缩进 Ctrl+Shift+F,这里面我们可以记忆F为Format格式化的意思。 快速查找代码 Ctrl+F,撤消到上一次Ctrl+Z 智能内容感知 Alt+/ ,该快捷键可以方便的匹配我们使用的类信息,/ 在键盘上和?是同一个按键,效果如图所示: 调用运行Run As对话框可以使用Ctrl+F11,如果为Debug调试方式可以直接使用F11。 生成一个板块注释Alt+Shift+J ,单行注释为Ctrl+/键
Android UI开发专题(三) 各种Drawable Android开发技术
本次我们主要讲解Android平台下的各种Drawable,这里在SDK的android.graphics.drawable包下面可以看到有各种Drawable类多达十几种,它们到底之间有什么关系和区别呢? 一、AnimationDrawable 顾名思义该类主要表示动画的图形类,可以实现逐帧播放的效果,下面代码示例如下 1. 定义一个cwj_animation.xml 放到res/drawable 目录下,其中定义的属性duration为延时,单位为毫秒,而oneshot属性表示是否仅播放一次,内容为: <animation-list android:id="selected" android:oneshot="false"><item android:drawable="@drawable/cwj0" android:duration="30" /><item android:drawable="@drawable/cwj1" android:duration="30" /><item android:drawable="@drawable/cwj2" android:duration="30" /><item android:drawable="@drawable/cwj3" android:duration="30" /><item android:drawable="@drawable/cwj4" android:duration="30" /><item android:drawable="@drawable/cwj5" android:duration="30" /></animation-list> 2.在java中调用也很简单 ImageView img = (ImageView)findViewById(R.id.cwj_image); //首先声明一个ImageView对象在xml布局文件中 img.setBackgroundResource(R.drawable.cwj_animation); //我们刚才的animation定义的xml文件 AnimationDrawable frameAnimation = (AnimationDrawable) img.getBackground(); //构造AnimationDrawable对象 frameAnimation.start() //开始播放动画 3. AnimationDrawable类还提供了一些常用的方法如下: void stop() 停止 void addFrame(Drawable frame, int duration) 添加一帧,类似xml中的布局 Drawable getFrame(int index) […]
Android UI开发专题(四) View自绘控件 Android开发技术
很多时候想要设计漂亮的Android UI,使用Android自带的控件无法满足我们的需要就要考虑自绘控件,在Android界面显示类View,可以通过继承扩展重写相关方法来实现我们的图形绘制。 首先我们需要了解下View类的底层实现,在SDK中我们可以看到View直接继承于Java的基类Object,实现了图形绘制和按键事件Drawable.Callback KeyEvent.Callback的相关方法,我们自绘时主要实现其内部的onDraw方法,相关的界面计算可以重写onMeasure方法,对于相关的按键可以重载onKeyDown、onKeyUp以及onTouchEvent等,下面android开发网就以一个实例来表示。 public class cwjView extendsView{ public cwjView(Context context) { this(context,null); } public cwjView(Context context,AttributeSet attrs) { this(context,attrs,0); } public cwjView(Context context,AttributeSet attrs,int defStyle) { super(context,attrs,defStyle); //这里是本类的构造,相关初始化可以在这里添加代码 } @Override protectd void onDraw(Canvas canvas) { super(canvas); //绘图的关键,可以看到已经包含了一个canvas句柄,可以直接通过我们前面讲到的Canvas类进行相关的操作,完整的例子,大家可以参考Android SDK中例子Snake贪食蛇游戏的实现。 } } 有关View类的更新,我们直接通过调用invalidate(int l,int r,int r,int b)来更新一个Rect矩形区域,或更新全部,同时在线程中我们使用需要调用postInvalidate来更新界面。
Android UI开发专题(五) Bitmap和Canvas实例 Android开发技术
在Android UI开发专题的前五节我们讲到的东西主要是基础和理论内容,从本次Android123将通过实例代码来演示,本次主要是Bitmap和Canvas类的使用,根据要求缩放Bitmap对象并返回新的Bitmap对象。centerToFit方法一共有4个参数,返回一个Bitmap类型,第一个参数为原始的位图对象,width和height分别为新的宽和高,而Context是用来加载资源的上下文实例。 Bitmap centerToFit(Bitmap bitmap, int width, int height, Context context) { final int bitmapWidth = bitmap.getWidth(); //获取原始bitmap的宽度 final int bitmapHeight = bitmap.getHeight(); if (bitmapWidth < width || bitmapHeight < height) { int color = context.getResources().getColor(R.color.window_background); //从资源读取背景色 Bitmap centered = Bitmap.createBitmap(bitmapWidth < width ? width : bitmapWidth, bitmapHeight < height ? height […]
Android自定义View实例AnalogClock源码 Android开发技术
针对Android底层View的直接构造很多网友没有实战经验,本次Android开发网结合目前平台开源代码一起通过AnalogClock类来理解View的直接继承。AnalogClock就是Home Screen上的那个带有两根指针的表盘类。它的实现我们直接从开源代码可以了解到: public class AnalogClock extends View { private Time mCalendar; private Drawable mHourHand; //时针 private Drawable mMinuteHand; //分针 private Drawable mDial; //表盘背景 private int mDialWidth; //表盘宽度 private int mDialHeight; //表盘高度 private boolean mAttached; //附着状态 private final Handler mHandler = new Handler(); //定一个Handler类实现更新时间 private float mMinutes; private float mHour; private boolean mChanged; […]
AsyncTask解决Android UI堵塞问题 Android开发技术
平时我们在开发Android程序时遇到较耗时任务的处理,如I/O访问的数据库操作、网络访问等情况时造成UI假死等问题,通过AsyncTask可以很好的解决这个问题,就今天以在Android中执行Downloader.downloadFile(url),可能会堵塞整个界面。显然这会影响用户体验,我们如何解决这个问题呢? 方法一、 创建一个新的线程执行我们的任务,使用Thread类,在 run(){}中写入任务代码,比如: new Thread(new Runnable() { public void run() { Downloader.downloadFile(url); } }).start(); 但使用Thread会产生一些意想不到的问题,需要程序员用更多的代码手动的维护它。 方法二: Android SDK为我们提供了一个后台任务的处理工具AsyncTask。AsyncTask就是一个封装过的后台任务类顾名思义就是异步任务,方便我们维护,Android开发网提示这样的好处可以解决一些线程安全问题,AsyncTask直接继承于Object类,位置为android.os.AsyncTask<Params, Progress, Result>。要使用AsyncTask工作我们要提供三个泛型参数,并重载四个方法(至少重载一个)。 三个泛型:Param ,任务执行器需要的数据类型Progress 后台计算中使用的进度单位数据类型Result 后台计算返回结果的数据类型有些参数是可以设置为不使用的,只要传递为Void型即可,比如AsyncTask<Void, Void, Void> 四个步骤:onPreExecute(),执行预处理,它运行于UI线程,可以为后台任务做一些准备工作,比如绘制一个进度条控件。doInBackground(Params…),后台进程执行的具体计算在这里实现,doInBackground(Params…)是AsyncTask的关键,此方法必须重载。在这个方法内可以使用publishProgress(Progress…)改变当前的进度值。onProgressUpdate(Progress…),运行于UI线程。如果在doInBackground(Params…)中使用了publishProgress(Progress…),就会触发这个方法。在这里可以对进度条控件根据进度值做出具体的响应。onPostExecute(Result),运行于UI线程,可以对后台任务的结果做出处理,结果就是doInBackground(Params…)的返回值。此方法也要经常重载,如果Result为null表明后台任务没有完成(被取消或者出现异常)。 AsyncTask实例代码: private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> { protected Long doInBackground(URL… urls) { int count = urls.length; long totalSize = 0; […]

