在Android游戏开发中我们必须考虑背景音乐播放问题,在Android平台中提供了MediaPlayer类可以播放声音,但是游戏除了播放音乐外还需要考虑画面的流畅性,以及多种音效同时播放,所以必须用到Android多线程机制和异步音效播放。Android SDK从1.0开始就提供了AsyncPlayer类,这里我们为了根据我们自己的需要可以派生或修改出更灵活的播放类。 import android.content.Context;import android.net.Uri;import android.os.PowerManager;import android.os.SystemClock;import android.util.Log; import java.io.IOException;import java.lang.IllegalStateException;import java.util.LinkedList; public class AsyncPlayer { private static final int PLAY = 1; private static final int STOP = 2; private static final boolean mDebug = false; private static final class Command { int code; Context context; Uri uri; boolean looping; int stream; […]
图160S
Android游戏开发之旅17 图像渐变特效 Android开发技术
在Android游戏开发中我们不免要涉及到一些图形特效处理,今天主要看下Android平台下实现渐变效果。在android.graphics中我们可以找到有关Gradient字样的类,比如LinearGradient 线性渐变、RadialGradient径向渐变和 角度渐变SweepGradient 三种,他们的基类为android.graphics.Shader。为了显示出效果android123使用一个简单的例子来说明。 一、LinearGradient线性渐变 在android平台中提供了两种重载方式来实例化该类分别为,他们的不同之处为参数中第一种方法可以用颜色数组,和位置来实现更细腻的过渡效果,比如颜色采样int[] colors数组中存放20种颜色,则渐变将会逐一处理。而第二种方法参数仅为起初颜色color0和最终颜色color1。 LinearGradient(float x0, float y0, float x1, float y1, int[] colors, float[] positions, Shader.TileMode tile) LinearGradient(float x0, float y0, float x1, float y1, int color0, int color1, Shader.TileMode tile) 使用实例如下 Paint p=new Paint(); LinearGradient lg=new LinearGradient(0,0,100,100,Color.RED,Color.BLUE,Shader.TileMode.MIRROR); //参数一为渐变起初点坐标x位置,参数二为y轴位置,参数三和四分辨对应渐变终点,最后参数为平铺方式,这里设置为镜像 刚才Android开发网已经讲到Gradient是基于Shader类,所以我们通过Paint的setShader方法来设置这个渐变,代码如下: p.setShader(lg); canvas.drawCicle(0,0,200,p); //参数3为画圆的半径,类型为float型。 二、 […]
Android读写Txt文本文件代码 Android开发技术
在Android平台中经常要用到Txt文本文件的读写操作,Android平台中处理Text这样的文本MIME的文件可以使用Java虚拟机的FileWriter类比较简单方便。该类位于java.io.FileWriter,提供了多种重写方法 FileWriter(File file) //创建文件通过File对象 FileWriter(File file, boolean append) //如果文件存在,第二个参数设置为false则覆盖,为true则代表追加方式。 FileWriter(FileDescriptor fd) //通过FileDescriptor对象来生成文件 FileWriter(String filename) //写入文件,参数为完整的路径和文件名 FileWriter(String filename, boolean append) //第二个参数通第二种重载方式一样。 因为该类从java.io.OutputStreamWriter继承,具备void close() void flush() String getEncoding() void write(char[] buf, int offset, int count) void write(String str, int offset, int count) void write(int oneChar) 还可以使用java.io.Writer Writer append(CharSequence csq) Writer append(CharSequence csq, int start, int end) Writer append(char c) abstract […]
Android多线程下载远程图片 Android开发技术
很多时候我们需要在Android设备上下载远程服务器上的图片进行显示,今天Android123整理出两种比较好的方法来实现远程图片的下载。 方法一、直接通过Android提供的Http类访问远程服务器,这里AndroidHttpClient是SDK 2.2中新出的方法,API Level为8,大家需要注意下,静态访问可以直接调用,如果SDK版本较低可以考虑Apache的Http库,当然HttpURLConnection或URLConnection也可以。 static Bitmap downloadBitmapByCwj(String url) { final AndroidHttpClient client = AndroidHttpClient.newInstance("Android123"); final HttpGet getRequest = new HttpGet(url); try { HttpResponse response = client.execute(getRequest); final int statusCode = response.getStatusLine().getStatusCode(); if (statusCode != HttpStatus.SC_OK) { Log.e("cwjDebug", "Error " + statusCode + " while retrieving […]
Android游戏开发之旅18 SoundPool类 Android开发技术
对于Android的游戏音效播放,上次Android123已经告诉大家使用SoundPool类来实现,由于本次我们的游戏需要多种音效同时播放所以就选择了SoundPool类,它和Android提供常规的MediaPlayer类有哪些不同呢? 1. SoundPool载入音乐文件使用了独立的线程,不会阻塞UI主线程的操作。但是这里Android开发网提醒大家如果音效文件过大没有载入完成,我们调用play方法时可能产生严重的后果,这里Android SDK提供了一个SoundPool.OnLoadCompleteListener类来帮助我们了解媒体文件是否载入完成,我们重载onLoadComplete(SoundPool soundPool, int sampleId, int status) 方法即可获得。 2. 从上面的onLoadComplete方法可以看出该类有很多参数,比如类似id,是的SoundPool在load时可以处理多个媒体一次初始化并放入内存中,这里效率比MediaPlayer高了很多。 3. SoundPool类支持同时播放多个音效,这对于游戏来说是十分必要的,而MediaPlayer类是同步执行的只能一个文件一个文件的播放。 SoundPool类使用示例代码: SoundPool sp=new SoundPool(8, /*maxStreams*/, AudioManager.STREAM_MUSIC /*streamType*/, 100 /*srcQuality*/) ; 有关载入音效的方法,有以下几种方法 int load(Context context, int resId, int priority) //从APK资源载入 int load(FileDescriptor fd, long offset, long length, int priority) //从FileDescriptor对象载入 int load(AssetFileDescriptor afd, int priority) //从Asset对象载入 […]

Android开发工具-App Inventor Android开发技术
随着Android设备的普及为了让更多的人参与Android软件开发,这里Google官方提供了一个开发工具App Inventor可以让用户无需编写代码也能生成自己的APK软件。这里Android123也大家一个截图可以充分了解该工具的样子,可以看到整个IDE类似VB的样子,左边是控件工具箱,中间是界面布局视图,右边是组件和属性对话框,从左边提供的支持来看仍然更像儿童编程启蒙软件。不过对于入门级的Android软件开发来说的确可以试试这个相对更简单的工具,只需要点点鼠标就可以拥有自己的Android应用程序。 对于开发示例和代码,可以在 App Inventor for Android (英文) 上了解更多的使用方法和示例。

android调试工具monkey压力测试实战 Android开发技术
很多Android开发者可能因为没有充分测试自己的软件造成很容易出现FC(Force Close)的问题,这里我们可以通过使用Android固件中自带的monkey工具来做软件的压力测试,monkey工具可以模拟各种按键,触屏,轨迹球、activity等事件,这里Android123提示大家说白了monkey就是一个小猴子随机狂玩你的android软件,看看会不会产生异常。 具体的使用我们通过Android SDK给我们的adb调试桥链接设备或模拟器,进入Linux Shell状态,当然我们可以输入adb shell获取设备的shell,也可以直接通过adb命令执行,比如说adb shell monkey来查看monkey工具中的参数说明,如图: 我们要测试的apk文件要在android设备中已经安装,当然模拟器中也可以测试的。执行adb shell monkey -p cn.com.android123.cwj -v 100 我们执行这句的中包含了p参数,这里代表已安装软件的packageName,而v代表查看monkey生成的详细随机事件名,最后的数字100为我们测试的随机事件数量为100.有关更多的测试方法,请查看上图中的参数,整个测试比较简单单很有效,不妨试试。

保护你的Android付费软件-LVL全攻略 Android开发技术
Google近期开始打击盗版Android软件,为开发者提供了 License Verification Library (LVL) 方式来防止Android软件被盗版,通过Android Market Licensing服务,提交的软件可以自动通过Market安全验证来限制授权情况,这一特性从Android SDK 1.5即API Level 3开始支持。LVL的原理主要是通过网络检查你应用是否通过购买,当然了谷歌并没有直接连接服务器而是通过远程IPC方式检查,如果连通网络会尝试判断应用是否授权,当然Google设计时加入了无网络验证的最低执行次数验证,比如执行了多少次后不网络验证将无法运行。 Android反盗版保护LVL的实战具体使用,首先我们在Eclipse中打开Android SDK and AVD Manager,选择Available Packages这项,单击Refresh可以找到Market Licensing package,revision 1这项,我们单击Install Selected即可,如图 LVL使用了RSA公钥对比方式验证软件是否得到购买许可,所以在编译apk文件时就要加入整个反盗版机制的相关的代码和密钥,在License Verification Library (LVL) 中我们需要经历以下步骤,获取一个许可公钥在Android Market的发布账号中,然后调试程序,最终发布 1. 在Market发布页面可以找到Licensing这项,我们可以加入开发者的测试Gmail账户,下面生成的是你的公钥,当然从大小写和结尾的=来看是Base64编码的,如图 接下来,我们可以查看在AVD和SDK管理器中下载的库文件和示例,路径位置如下 <sdk>/market_licensing/library/ (the LVL library project)<sdk>/market_licensing/sample/ (the example application) 当然,开发Android程序有多种方式,比如Eclipse或Ants脚本编译,如果使用Eclipse方式,可以选择当前程序的属性,在左边Android这也中,添加引用库为我们下载的,一般在<sdk根目录>/market_licensing/library/ 文件夹中,如图 当然,如果使用ants方式可以通过在default.properties 文件中加入android.library.reference.1=path/to/library_project这句,或使用sdk工具下的android批处理或bash脚本执行 android update lib-project –target […]
保护你的Android付费软件-LVL全攻略(二) Android开发技术
昨天我们介绍了Android Market新的付费软件保护机制-LVL我们今天一起来看看如何集成密钥以及LVL库到Android项目中,这样做目前可以有效保证及时是Root权限的设备也无法正常的使用。 1. 在项目的androidmanifest.xml文件中加入<uses-permission android:name="com.android.vending.CHECK_LICENSE">权限,使其Market客户端可以检测授权状态。 2.制定一个策略Policy,本质上 Android Market licensing 服务并没有判断给用户赋予什么样的权限,在Policy接口中提供了两个方法分别为allowAccess() 和 processServerResponse() 他们均被 LicenseChecker 从服务器响应权限信息明确时被回调。 processServerResponse() 的原始定义 lets you preprocess the raw response data received from the licensing server, prior to determining whether to grant access. allowAccess() 的解释为determines whether to grant the user access to your application, based on any available license response data (from the […]
Android游戏开发之旅19 分辨率大全 Android开发技术
对于Android游戏开发我们不得不像iPhone那样思考兼容Android平板电脑,对于苹果要考虑iPad、iPhone 3GS和iPhone 4等屏幕之间的兼容性,对于几乎所有的分辨率Android123总结了大约超过20中粉笔阿女郎的大小和对应关系,对于开发Android游戏而言可以考虑到未来的3.0以及很多平板电脑的需要。 常规的我们可能只考虑QVGA,HVGA,WVGA,FWVGA和DVGA,但是抛去了手机不谈,可能平板使用类似 WSVGA的1024×576以及WXGA的1280×768等等。 QVGA = 320 * 240;WQVGA = 320 * 480;WQVGA2 = 400 * 240;WQVGA3 = 432 * 240;HVGA = 480 * 320;VGA = 640 * 480;WVGA = 800 * 480;WVGA2 = 768 * 480;FWVGA = 854 * 480;DVGA = 960 * 640;PAL = 576 * 520;NTSC = 486 * […]
Android游戏开发之旅20 双按事件捕获 Android开发技术
对于游戏开发中我们可能经常要用到双按屏幕,在Android 1.6以前并没有提供完善的手势识别类,在Android 1.5 SDK中我们可以找到android.view.GestureDetector.OnDoubleTapListener,但是经过测试仍然无法正常工作,不知道什么原因,如果您知道可以联系android123@163.com共享下。最终我们使用的解决方法如下 最终我们测试的如下: public class TouchLayout extends RelativeLayout { public Handler doubleTapHandler = null; protected long lastDown = -1; public final static long DOUBLE_TIME = 500; public TouchLayout(Context context) { super(context); } public TouchLayout(Context context, AttributeSet attrs) { super(context, attrs); } public TouchLayout(Context context, […]
Android Txt文本读写类源代码 Android开发技术
Android系统内部提供了一个不错的txt文本读写类,但目前并没有公开提供给标准的SDK,FileUtils类的源代码如下,可以很好的操作Linux下的文本文件。 public class FileUtils{ public static final int S_IRWXU = 00700; public static final int S_IRUSR = 00400; public static final int S_IWUSR = 00200; public static final int S_IXUSR = 00100; public static final int S_IRWXG = 00070; public static final int S_IRGRP = 00040; public static final int S_IWGRP = 00020; […]

Android调试技巧之Eclipse行号和Logcat Android开发技术
很多初入Android的开发者可能会发现经常遇到Force Close或ANR这样的问题,一般我们通过Android系统的错误日志打印工具Logcat可以看到出错的内容,今天一起来说下如何通过Eclipse行号和Logcat捕捉出错点,我们遇到错误可以首先在Eclipse的DDMS中自带的Logcat组件查看错误,一般错误原因是Caused by XXX引起的,如下面我们可以看到因为android.widget.TextView是系统的类,由于没有太大的问题所以向前找可以看到我们的onCreate (test.java 20)这句是我们创建的Android工程位置,所以应该在Java代码的第20行查找。如图 默认的Eclipse是不显示行号的,我们可以通过到Eclipse的菜单中找Window -> Prefences 在Preferences对话框中依次进入General -> Editors -> Text Editors 并勾选 show line numbers即可,如图 当然Android123告诉大家已经更简单的快捷方式,在Eclipse直接按下Ctrl+F10键,在弹出的菜单中选择Show Line Numbers也可以显示行号,这对于调试Android应用来说十分的方便,平时我们出错竟然可以报告出在代码的第几行,虽然Google使用APK的方式通过Dalvik字节码方式可以增加了一些反编译Java程序的难度,虽然没有像反编译.class文件那么复杂,也许你不会ida这样的调试工具,不过Android开发网将在近期讲下如何通过GDB和DEXDUMP以及android123开发的一个小工具来最大化的反编译apk文件中的dex,还原出程序的源代码。
Android通过Intent发送电子邮件含附件 Android开发技术
如何在Android系统中发送带附件的电子邮件呢? 其实通过Intent可以很方便的发送Email,只需要短短10行代码就可以处理,这里Android开发网就以在sdcard上的android123.cwj文件为例,通过Intent来发送电子邮件。完整代码如下 File file = new File("\sdcard\android123.cwj"); //附件文件地址 Intent intent = new Intent(Intent.ACTION_SEND); intent.putExtra("subject", file.getName()); // intent.putExtra("body", "android123 – email sender"); //正文 intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file)); //添加附件,附件为file对象 if (file.getName().endsWith(".gz")) { intent.setType("application/x-gzip"); //如果是gz使用gzip的mime } else if (file.getName().endsWith(".txt")) { intent.setType("text/plain"); //纯文本则用text/plain的mime } else { intent.setType("application/octet-stream"); //其他的均使用流当做二进制数据来发送 } startActivity(intent); //调用系统的mail客户端进行发送
WordPress 技巧:让分类和标签的描述支持 HTML 代码
默认 WordPress 后台分类和标签的编辑页面,分类和标签的描述是不支持 HTML 代码的,我们可以通过在当前主题的 functions.php 文件添加如下代码让分类和标签的描述支持 HTML 代码: remove_filter( 'pre_term_description', 'wp_filter_kses' ); remove_filter( 'pre_link_description', 'wp_filter_kses' ); remove_filter( 'pre_link_notes', 'wp_filter_kses' ); remove_filter( 'term_description', 'wp_kses_data' ); 标签:WordPress 技巧
WordPress 网站如何防范大规模暴力破解攻击
WordPress 网站遭遇大规模暴力破解攻击 WordPress 网站过去几天遭到了大规模的暴力破解攻击,攻击者首先扫描互联网上的 WordPress 网站,然后利用 Web 服务器组建的僵尸网络不断尝试用户名和密码试图登录管理后台。 一般的僵尸网络是利用普通 PC,而这次攻击者使用了超过 9万台 Web 服务器,服务器比 PC 有更大的带宽和连接速度,因此可以更快的发动攻击。攻击者暴力攻击WordPress 管理入口,使用默认的用户名 admin,并尝试数以千计的密码。 如果防止被扫描和攻击 从上面这则新闻,可以看出攻击者主要是首先扫描 WordPress 网站,然后通过穷举法攻击 WordPress 的默认用户名:admin,我们可以通过以下三个步骤来减少被攻击以及被攻陷的机会: 在当前 functions.php 添加以下代码去掉 WordPress 版本信息,减少被扫描到的机会。 remove_action( 'wp_head', 'wp_generator'); 默认的用户名不要为 admin,通过一下 SQL 修改 admin 的用户名: UPDATE wp_users SET user_login = 'newuser' WHERE user_login = 'admin'; 安装 Limit Login Attempts 插件,限制登陆尝试次数,防止通过穷举法获取后台密码。

WordPress 技巧:不通过登陆后台禁用插件
有时候会因为安装的插件有 Bug 导致直接连后台都登陆不进去的尴尬情况;也有时候安装了太多插件,在后台一一禁用,工作量太大。那么就可以参考本文介绍的两种方法。 使用 FTP 或空间管理面板 方法很简单,把插件的文件删掉或者改名,让 WordPress 找不到插件文件,自然就无法调用相关插件了。WordPress 插件文件放在 /wp-content/plugins 文件目录下面,一个插件一个文件夹。 这里可以使用 FTP 或者是你主机提供的后台管理面板中的文件管理器,建议对文件夹改名而不要删除,这样可以保留插件文件以便恢复。 通过修改数据库禁用 WordPress 插件 上面那种方法比较简单,但是插件的信息还被记录在 WordPress 数据库中,可能会发生一些意外情况。直接修改数据库中的关于插件的记录值,就可以比较安全的禁用插件。 但是,这需要你有修改数据库的权限和途径。一般来说,在主机空间控制面板都会提供诸如 PHPMyAdmin 之类的 MySQL 数据库修改软件,本文就以 PHPMyAdmin 为例。 记录 WordPress 插件信息的表位于:wp_options 表中的 active_plugins 字段,active_plugins 的值记录着插件使用情况。 就我个人网站来说,只使用了多说一个插件,所以就字段值如上图。如果禁用所有插件,你只需要用 a:0:{} 来代替 active_plugins 的值即可。如果你想禁用某个插件,就按照对应的格式,删掉相关信息即可。 标签:WordPress 技巧
WordPress 教程:为插件自定义数据表
当你写插件的时候,你可能需要写东西到数据库中去,一般来说,有两种数据要存储,第一种是安装数据,一般存储在 wp_options 表中,使用 WordPress 的 options 机制来实现。第二种是数据,可以存储到 postmeta 表或者 usermeta 表中。如果数据特别多,就需要单独创建数据表了。这篇文章就讲讲如何在写插件时候创建数据表。 一般在写插件时候创建数据库有如下三个步骤: 创建一个添加新数据表的 PHP 函数。 保证插件启动的时候调用这个函数。 如果新版本有不同的数据表结构,创建一个升级函数。 今天我就以微信机器人 WordPress 插件高级版的 新功能:自定义文本回复,来讲解下这个过程,其中的第三步,由于没有数据库的升级不涉及。 创建一个添加新数据表的 PHP 函数 我们这个插件的安装函数叫做:weixin_robot_texts_crate_table。 1. 数据库表前缀 默认 WordPress 数据库标签前缀都是 wp_,但是有人如果在一个数据库安装两个及以上 WordPress,就需要在 wp-config.php 设置 WordPress 数据库表前缀来区别,所以我们向 WordPress 数据库添加新表的时候,要先找找到数据库表前缀。我们可以在变量 $wpdb->prefix 找到。代码如下: global $wpdb; $table_name = $wpdb->prefix . "weixin_robot_texts"; 2. 判断表是否存在 可以通过一条 SHOW TABLES SQL 查询来判断。 if($wpdb->get_var("SHOW […]
WordPress 技巧:为评论模块增加更多 HTML 标签支持
WordPress 原生的评论模块内容,支持使用 HTML 标签来增强评论内容的格式和效果。但是这肯定会带来一些安全隐患,特别是评论这种随便一个浏览者都可以提交数据的地方,容易产生跨站攻击(XSS),所以 WordPress 系统严格的限制了评论模块可以使用的 HTML 标签。默认的情况下,只支持:a、abbr、acronym、b、blockquote、cite、code、del、em、i、q、strike、strong 这几个标签和对应的相关属性。 这些标签肯定是远远不够用的,如果是技术博客,评论往往需要包含代码,那么可能就需要添加 pre 标签的支持,如果想要评论中可以引用图片,那么需要 img 标签的支持。本文就是来讲解如何在评论模块中增加更多 HTML 标签的支持。 WordPress 允许的标签和属性 WordPress 出于安全考虑,严格的限制了文章和评论等可编辑内容支持的 HTML 标签类型和标签的属性。具体的内容可以看:wp-includes/kses.php 这个文件,里面有两个全局数组变量 $allowedposttags 和 $allowedtags ,这两个数组变量就包含了允许的 HTML 标签,每个标签的键值又是一个数组,记录了这个标签常用的属性。例如: $allowedtags = array( 'a' => array( 'href' => true, 'title' => true, )); 上面这个数组的含义就是支持 a 标签以及对应的 href、title 属性。 让 WordPress 评论支持更多标签的方法 思路很简单,先按照上面的格式,声明一个标签信息数组,然后 hook 勾到 WordPress 上面。例如想要增加 […]
Android自定义View以及layout属性全攻略 Android开发技术
对于Android系统的自定义View可能大家都熟悉了,对于自定义View的属性添加,以及Android的Layout的命名空间问题,很多网友还不是很清楚,今天Android123一起再带大家温习一下 CwjView myView=new CwjView(context); 如果用于游戏或整个窗体的界面,我们可能直接在onCreate中setContentView(myView); 当然如果是控件,我们可能会需要从Layout的xml中声明,比如 <cn.com.android123.CwjView android:layout_width="wrap_content" android:layout_height="wrap_content" /> 当然,我们也可以直接从父类声明比如 <View class="cn.com.android123.CwjView" android:layout_width="wrap_content" android:layout_height="wrap_content" /> 上面我们仅用了父类View的两个属性,均来自android命名空间,而名称为layout_width或layout_height,我们自定义的控件可能有更多的功能,比如 <cn.com.android123.CwjView android:layout_width="wrap_content" android:layout_height="wrap_content" cwj:age="22" cwj:university="sjtu" cwj:city="shanghai" /> 我们可以看到上面的三个属性,是我们自定义的。作为标准xml规范,可能还包含了类似 xmlns:android="http://schemas.android.com/apk/res/android" 这样的语句,对于定义完整的View,我们的命名空间为cwj,这里可以写为 xmlns:cwj=http://schemas.android.com/apk/res/cn.com.android123.cwjView 或 xmlns:cwj=http://schemas.android.com/apk/res/android 都可以。 对于定义的cwj命名空间和age、university以及city的三个属性我们如何定义呢? 在工程的res/values目录中我们新建一个cwj_attr.xml文件,编码方式为utf-8是一个好习惯,内容如下 <?xml version="1.0" encoding="utf-8" ?> <resources> <declare-styleable name="CwjView"> <attr name="age" format="integer" /> […]
Android Picture和PictureDrawable的用处 Android开发技术
在Android系统中图形类为我们提供了很多图形对象类,很多网友知道Drawable,了解Bitmap之类的,那么今天的Picture和PictureDrawable又是什么东西呢? Android123再次给大家说下,Picture在android.graphics.Picture包中,相对于Drawable和Bitmap而言,Picture对象就小巧的多,它并不存储实际的像素,仅仅记录了每个绘制的过程。整个类提供了两个重载形式,其中比较特别的是Picture(Picture src) 从一个Picture对象去实例化操作, Canvas beginRecording(int width, int height) //开始记录绘制过程 static Picture createFromStream(InputStream stream) //静态方法,从输入流创建一个Pictrue对象 void draw(Canvas canvas) //在canvas上画这个picture对象 void endRecording() //结束录制绘制过程 int getHeight() int getWidth() void writeToStream(OutputStream stream) //将绘制结果写到输出流中 我们可以看到整个类中方法不多,但主要的beginRecording和endRecording记录开始和结束,最终通过draw方法绘制到画布上去,而createFromStream和writeToStream可以帮助我们从流中读写这个Picture对象,我们可以将整个绘制过程通过FileInputStream或FileOutputStream放到文件中去。 PictureDrawable是什么呢? 这里Android123提示大家它位于android.graphics.drawable.PictureDrawable 是从Drawable类继承而来的,它的构造方法只有一个就是从Picture对象中实例化,PictureDrawable(Picture picture) void draw(Canvas canvas) // 绘制到Canvas int getIntrinsicHeight() int getIntrinsicWidth() int getOpacity() //获取透明度级别 Picture getPicture() //从PictureDrawable转为Picture void setAlpha(int alpha) //设置透明级别 void setColorFilter(ColorFilter colorFilter) void setDither(boolean […]

Android AIDL全攻略一 Android开发技术
Android的服务开发中我们可能都是Activity和Service同进程处理,但想象过系统提供的各种ServiceManager吗? 比如 SensorManager、SmsManager 这些服务可以提供给任意应用,对于这样的公共后台服务器开发类似我们在Win32的COM组件或Symbian的C/S框架,我们需要AIDL(Android Interface Definition Language即Android接口定义语言)来支持服务IPC(interprocess communication IPC)和各个进程的组件进行通讯。 我们将分5节完成以下几个问题 1. AIDL的概念 (本节) 2. Service绑定 3. AIDL基础框架 4. Parcelable 5. Android开源项目中的AIDL示例分析 使用Win32+Eclipse+ADT开发的网友可以通过在SDK的platform/android-x.y/tools文件夹中找到 aidl.exe 文件,这里android123提醒大家注意的是并不是sdk根目录下的tools文件一定要进入到platform中去,其中android-x.y是相应的sdk版本。我们首先执行无参数的aidl可以看到完整的帮助如图: 当然从目前的新版ADT插件来说可以自动的通过AIDL文件生成Java代码,如果使用Ants方式编译可以考虑上面的cmd命令行方式
Android开发之模拟按下Home键的效果 Android开发技术
有网友询问如何实现按下Home键的效果,Android设备在按下Home键会自动切换回桌面,其实实现的方法很简单,由于Launcher捕获了Home键的按下action,我们直接发送个Intent给Launcher即可, Intent i= new Intent(Intent.ACTION_MAIN); i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); //android123提示如果是服务里调用,必须加入new task标识 i.addCategory(Intent.CATEGORY_HOME); startActivity(i);
自定义Android主题风格theme.xml方法 Android开发技术
在Android中可以通过自定义主题风格方式来实现个性化以及复用,首先我们创建theme.xml主题文件,保存位置为工程的res/values/theme.xml ,这里我们可以可以为主题起一个名称,比如CWJ,这里去除了xml的文件头<?xml version="1.0" encoding="utf-8"?>这行,我们在工程中只需在androidmanifest.xml文件的Activity节点中加入android:theme="@style/Theme.CWJ" 属性,则这个Activity就使用了这种主题风格,整个xml的关键代码如下: <resources> <style name="Theme.CWJ" parent="android:Theme"> <item name="android:windowBackground">@drawable/android123</item> </style></resources> 其中上面的代码中,我们定义设置全局android:windowBackground即背景值为/res/drawable中的android123图片为背景,更多的属性定义可以参考view的layout xml属性设置,比如我们设置所有字体颜色、大体大小和样式,可以在style节点中加入 <item name="android:textColor">#fff</item> <item name="android:textSize">14sp</item> <item name="android:textStyle">bold</item> 当然我们可以将上面的android123的图片改进下,使用一个xml文件替代,比如使用bitmap对象,则/res/drawable/android123.xml的完整代码变为 <?xml version="1.0" encoding="utf-8"?> <bitmap xmlns:android="http://schemas.android.com/apk/res/android" android:src="@drawable/cwj_image" android:tileMode="repeat" /> 这里我们使用了一个bitmap对象来解析cwj_image图片,当然这里可以识别各种类型的图片,其中android:tileMode是bitmap的内部属性,其中tileMode设置为repeat代表重复,这样可以节省bitmap资源,比如我们的背景是一层楼,那么全屏可以显示同样的为5层效果,而图片仅是一层大小,对于资源利用相对更高。 当然bitmap的属性tileMode的值为repeat外还有其他的值比如clamp、mirror,这些值并没有在SDK中并没有找到定义,通过上次Android开发网的 Android自定义View以及layout属性全攻略 一文,我们可以联想到bitmap属于android.graphics.Bitmap 包,由于是android框架,所以下载git的base包,找到该类,类的实例化时android123已经在 Android自定义View以及layout属性全攻略 说的很清楚,所以我们定位到res\values中找到attr.xml有关bitmap的定义即可,有关bitmap的更多属性如 antialias、filter和dither都可以找到使用。
Android AIDL全攻略二 – Service绑定 Android开发技术
上次我们在 Android AIDL全攻略一 中讲到了AIDL的概念,由于AIDL属于服务相关内容,同时需要涉及到Service绑定问题,作为整个Android AIDL系列教程的第二节我们一起来看下Service绑定问题。我们过去使用一些轻量级的服务可能直接startService启动,通过Service中的onStart方法可以获取执行服务的命令行,其中参数Intent可以传递内容,当然作为低频度的传输也可以考虑Broadcast来交互Activity和Service,但是作为正常专业的长久的服务Android123还是推荐大家使用绑定机制来实现数据的传输。其中系统级别的跨进程服务AIDL就是基于Service绑定方式的。 作为Service必须重写一个方法就是onBind(),如果使用startService方式启动服务,则我们在onBind()中返回一个null的IBinder对象。今天使用bindService方法将如何写呢? 具体的步骤如下: 1. 使用bindService方法启动服务,bindService (Intent service, ServiceConnection conn, int flags) 有三个参数,这里大家可能会对第二个ServiceConnection和最后第三个参数的标识感到陌生,一般在我们调用bindService时需要一个ServiceConnection获取服务实例以及状态,代码如下 private ServiceConnection sc = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { Toast.makeText(ctx, "android123 service connected", Toast.LENGTH_LONG).show(); } @Override public void onServiceDisconnected(ComponentName name) { Toast.makeText(ctx, "android123 service disconnected", Toast.LENGTH_LONG).show(); } }; 这样,我们在服务的连接和断开时都会收到一个Toast的消息提示,而bindService最后的参数一般使用BIND_AUTO_CREATE 标识自动创建。所以一般我们绑定一个服务,使用下面的代码 bindService(intent, sc, Service.BIND_AUTO_CREATE); 来启动服务,而解除绑定可以用 unbindService(sc); 2. […]
Android AIDL全攻略三 – AIDL框架 Android开发技术
在Android AIDL全攻略的一和二中我们提到了相关的基础内容,本次我们将通过实例代码完成AIDL框架。这里Android123推荐大家使用Eclipse+ADT的开发方式以提高我们的效率,有关ants和aidl命令的编译方式不了解的可以来函至android123@163.com 我们会及时回复。 1. AIDL的语法和框架,Android IDL语言类似Java的接口,可以使用常规的String、Boolean等类型,但对于数值传递我们需要使用 Parcelable 接口,如果你不了解 Parcelable 的使用,Android123将在下节详细解释。 2. 在我们的工程中创建一个 xxx的.aidl文件,这时回到Eclipse重新构建工程可以发现在/res/gen的文件夹下会自动生成Ixxx.java文件,ADT帮我们实现这个接口的stub类,具体的AIDL文件内容比如为: package com.android123.cwj; interface IWeatherService { int getTemperature(in String city,out String temperature); int getTemperatureList(in String city, out String[] temperature);} 上面我们注意AIDL文件中的方法,参数类型前面有in和out关键字,类似Win32 COM中的IN或OUT,分别代表传入和输出,对于Java文件,ADT插件会在res/gen中生成一个java文件实现Stub子类。本文未完成,
Android中String资源文件的format方法 Android开发技术
很多时候我们感性Google在设计Android时遵守了大量MVC架构方式,可以让写公共代码、美工和具体逻辑开发人员独立出来。有关Android的资源文件values/strings.xml中如何实现格式化字符串呢? 这里Android123举个简单的例子,以及最终可能会用到哪些地方。 <?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">cwj_Demo</string> <string name="hello">android开发网</string> </resources> 上面是一段简单的字符串资源文件,没有用到格式化,因为比较简单直接描述了意思,当我们设计一个类似 Delete xxx File ? 的时候,我们可能需要在Java中动态获取 xxx 的名称,所以定义资源时使用格式化可以轻松解决,不需要一堆String去拼接或StringBuffer一个一个append这样的愚蠢方法,看例子 <string name="alert">Delete %1$s File</string> 这里%1$s代表这是一个字符串型的,如果是整数型可以写为%1$d,类似printf这样的格式化字符串函数,当然如果包含了多个需要格式化的内容,则第二个可以写为%2$s或%2$d了,那么最终在Java中如何调用呢? 看下面的例子: 例一: 整数型的 <string name="alert">I am %1$d years old</string> 定义的是这样的 当然,我们杜绝意外情况,比如冒出个secret这样的string类型的,注意上面是%1$d不是%1$s,所以默认标准的合并成为 int nAge=23; String sAgeFormat = getResources().getString(R.string.alert); String sFinalAge = String.format(sAgeFormat, […]
onRetainNonConfigurationInstance和getLastNonConfigurationInstance Android开发技术
很多网友可能知道Android横竖屏切换时会触发onSaveInstanceState,而还原时会产生onRestoreInstanceState,但是Android的Activity类还有一个方法名为onRetainNonConfigurationInstance和getLastNonConfigurationInstance这两个方法。 我们可以通过 onRetainNonConfigurationInstance 代替 onSaveInstanceState,比如距离2 @Override public Object onRetainNonConfigurationInstance() { //这里需要保存的内容,在切换时不是bundle了,我们可以直接通过Object来代替 return obj; } 在恢复窗口时,我们可以不使用 onRestoreInstanceState,而代替的是 getLastNonConfigurationInstance 方法。我们可以直接在onCreate中使用,比如 Object obj = getLastNonConfigurationInstance(); 最终obj的内容就是上次切换时的内容。 这里Android123提醒大家,每次Activity横竖屏切换时onCreate方法都会被触发。
inent调用代码总结,不断完善中 Android开发技术
来自网友整理的Intent,当然Android123将会加入更多内容不断完善Intent常见调用帮助网友方便查找。 显示Web网页: 1. Uri uri = Uri.parse("http://www.android123.com.cn"); 2. Intent it = new Intent(Intent.ACTION_VIEW,uri); 3. startActivity(it); 显示Google地图: 1. Uri uri = Uri.parse("geo:38.899533,-77.036476"); 2. Intent it = new Intent(Intent.Action_VIEW,uri); 3. startActivity(it); Maps路径规划: 1. Uri uri = Uri.parse("http://maps.google.com/maps?f=d&saddr=startLat%20startLng&daddr=endLat%20endLng&hl=en"); 2. Intent it = new Intent(Intent.ACTION_VIEW,URI); 3. startActivity(it); 拨打电话: 1. Uri uri = Uri.parse("tel:xxxxxx"); 2. […]
Android工程内嵌资源文件的两种方法 Android开发技术
Android软件一般处理大的资源通过sdcard比如在线下载资源到sdcard,而apk中内嵌资源或二进制文件时一般使用下面的两种方法: 方法一 res/raw目录下存放,比如cwj.dat一个二进制文件,我们可以读取可以直接 InputStream is=context.getResources().openRawResource(R.raw.cwj); 方法二 工程根目录下的assets文件夹中存放,比如assets/cwj.dat 这样我们使用下面的代码 AssetManager am = context.getAssets(); InputStream is = am.open(cwj.dat); 这里Android123提示大家Google的Android系统处理Assert有个bug,在AssertManager中不能处理单个超过1MB的文件,不然会报异常具体数值大家可以测试下传个稍大的文件,我们在两年前的文章中有提到,而第一种raw没这个限制可以放个4MB的Mp3文件没问题。
Android中String资源文件的format方法 Android开发技术
很多时候我们感性Google在设计Android时遵守了大量MVC架构方式,可以让写公共代码、美工和具体逻辑开发人员独立出来。有关Android的资源文件values/strings.xml中如何实现格式化字符串呢? 这里Android123举个简单的例子,以及最终可能会用到哪些地方。 <?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">cwj_Demo</string> <string name="hello">android开发网</string> </resources> 上面是一段简单的字符串资源文件,没有用到格式化,因为比较简单直接描述了意思,当我们设计一个类似 Delete xxx File ? 的时候,我们可能需要在Java中动态获取 xxx 的名称,所以定义资源时使用格式化可以轻松解决,不需要一堆String去拼接或StringBuffer一个一个append这样的愚蠢方法,看例子 <string name="alert">Delete %1$s File</string> 这里%1$s代表这是一个字符串型的,如果是整数型可以写为%1$d,类似printf这样的格式化字符串函数,当然如果包含了多个需要格式化的内容,则第二个可以写为%2$s或%2$d了,那么最终在Java中如何调用呢? 看下面的例子: 例一: 整数型的 <string name="alert">I am %1$d years old</string> 定义的是这样的 当然,我们杜绝意外情况,比如冒出个secret这样的string类型的,注意上面是%1$d不是%1$s,所以默认标准的合并成为 int nAge=23; String sAgeFormat = getResources().getString(R.string.alert); String sFinalAge = String.format(sAgeFormat, […]
onRetainNonConfigurationInstance和getLastNonConfigurationInstance Android开发技术
很多网友可能知道Android横竖屏切换时会触发onSaveInstanceState,而还原时会产生onRestoreInstanceState,但是Android的Activity类还有一个方法名为onRetainNonConfigurationInstance和getLastNonConfigurationInstance这两个方法。 我们可以通过 onRetainNonConfigurationInstance 代替 onSaveInstanceState,比如距离2 @Override public Object onRetainNonConfigurationInstance() { //这里需要保存的内容,在切换时不是bundle了,我们可以直接通过Object来代替 return obj; } 在恢复窗口时,我们可以不使用 onRestoreInstanceState,而代替的是 getLastNonConfigurationInstance 方法。我们可以直接在onCreate中使用,比如 Object obj = getLastNonConfigurationInstance(); 最终obj的内容就是上次切换时的内容。 这里Android123提醒大家,每次Activity横竖屏切换时onCreate方法都会被触发。
inent调用代码总结,不断完善中 Android开发技术
来自网友整理的Intent,当然Android123将会加入更多内容不断完善Intent常见调用帮助网友方便查找。 显示Web网页: 1. Uri uri = Uri.parse("http://www.android123.com.cn"); 2. Intent it = new Intent(Intent.ACTION_VIEW,uri); 3. startActivity(it); 显示Google地图: 1. Uri uri = Uri.parse("geo:38.899533,-77.036476"); 2. Intent it = new Intent(Intent.Action_VIEW,uri); 3. startActivity(it); Maps路径规划: 1. Uri uri = Uri.parse("http://maps.google.com/maps?f=d&saddr=startLat%20startLng&daddr=endLat%20endLng&hl=en"); 2. Intent it = new Intent(Intent.ACTION_VIEW,URI); 3. startActivity(it); 拨打电话: 1. Uri uri = Uri.parse("tel:xxxxxx"); 2. […]

