Android定时任务相关

Android上定时运行任务常用的方法有2种,一种方法用Timer+TimerTask,另一种是AlarmManager。 Timer Android 的 Timer 类可以用来计划需要循环执行的任务,Timer 的问题是它需要用 WakeLock 让 CPU 保持唤醒状态,这样会大量消耗手机电量,大大减短手机待机时间。而一旦待机,任务可能就不会执行了。 Timer实现不是很准确,时间上是有误差的。 AlarmManager AlarmManager 是 Android 系统封装的用于管理 RTC 的模块,RTC (Real Time Clock) 是一个独立的硬件时钟,可以在 CPU 休眠时正常运行,在预设的时间到达时,通过中断唤醒 CPU。 这意味着,如果我们用 AlarmManager 来定时执行任务,CPU 可以正常的休眠,只有在需要运行任务时醒来一段很短的时间。 这种实现通常要选择RTC_WAKEUP才能达到这样的效果,这是需要注意的!...

一月 24, 2013

TextView自动跑马灯

TextView中的文本太多时,我们希望文本以跑马灯的形式展现。xml文件中对TextView做以下属性配置即可实现: <TextView android:id="@+id/TextView03" android:layout_width="wrap_content" android:layout_height="wrap_content" android:ellipsize="marquee" android:focusable="true" android:focusableInTouchMode="true" android:marqueeRepeatLimit="marquee_forever" android:padding="5dip" android:singleLine="true" android:text="Really Long Scrolling Text Goes HereReally Long Scrolling Text Goes Here" /> 每次用跑马灯都要写这些属性配置,太麻烦了点。简单方法? TextView的跑马灯效果只有在获得焦点的时候才开始滚动,以上这些属性就是配置marquee效果,并且自动获得焦点。那简单的方法就是:自定义View继承TextView,然后覆盖TextView的一些方法,使其自动完成跑马灯效果,而不是通过配置属性来完成。代码如下: package com.androidbears.components; import android.content.Context; import android.graphics.Rect; import android.util.AttributeSet; import android.widget.TextView; public class ScrollingTextView extends TextView { public ScrollingTextView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } public ScrollingTextView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public ScrollingTextView(Context context) { super(context); init(); } @Override protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) { if(focused) super....

一月 11, 2013

Android应用没有Activity是否可以接受广播?

一个应用没有activity,在API<3.1的版本是可以的接受广播,3.1以后就不可以了。 从3.1开始出于安全的考虑,一个应用必须至少运行一次才能接受广播,意思是说用户知道这个应用运行过,它才可以接受广播。如果非要试试没有activity的话,可以第一次安装有activity,然后,删除activity和xml对应的配置信息再次安装。不过这样实际意义不大。 普通的App如果没有启动默认都是停止状态的,停止状态的App默认是接受不到任何广播的。不过发送广播时如果添加指定标记,也可以使停止状态的应用接受这个的广播。 /** * If set, this intent will not match any components in packages that * are currently stopped. If this is not set, then the default behavior * is to include such applications in the result. */ public static final int FLAG_EXCLUDE_STOPPED_PACKAGES = 0x00000010; /** * If set, this intent will always match any components in packages that * are currently stopped. This is the default behavior when * {@link# FLAG_EXCLUDE_STOPPED_PACKAGES} is not set....

十二月 19, 2012

Android自定义相机功能模块

一个Android自定义相机功能模块,调用简单。提供拍照预览功能,支持从图库选择图片,仅支持竖屏拍照和预览。 项目地址:https://github.com/laomo/TakePhoto 调用方式: package com.laomo.takephoto; import android.app.Activity; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Bundle; import android.widget.ImageView; public class MainActivity extends Activity { private static final int CODE_TAKE_PHOTO = 1; private ImageView mImageView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Intent intent = new Intent(this,TakePhotoActivity.class); startActivityForResult(intent, CODE_TAKE_PHOTO); mImageView = (ImageView) findViewById(R.id.imageview); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { //取得拍照所得图片的byte数组 if(resultCode == RESULT_OK&&requestCode == CODE_TAKE_PHOTO){ byte[] _data = data....

十二月 10, 2012

Ant编译Android工程

一.Ant安装 Windows下安装Ant: ant 官网可下载 http://ant.apache.org ant 环境配置: 解压ant的包到本地目录。 在环境变量中设置ANT_HOME,值为你的安装目录。 把ANT_HOME/bin加到你系统环境的path。 Ubuntu下安装Ant sudo apt-get install ant即可,环境变量也会自动配置。 二.编译Anadroid工程 android本身是支持Ant编译的,这里要知道一些Android命令。配置好android sdk 环境,保证在任意目录下执行android 命令。 1.创建一个android项目 android create project -k tk.laomos.demo -a Demo -t 25 -p . 参数说明: -k /–package 为命名空间(包名) -a /–name 工程名 -p /–path 项目 -t 为目标平台的版本对应id编号 查看当前平台Api level对应的id:(列出不同版本平台的对应id编号) android list targets 2.更新一个android项目产生build.xml等ant配置文件 对已经存在的android工程,我们可以update下(修改平台的版本),这样会自动添加build.xml 等ant的配置文件. android update project --name Demo -t 25 -p . 然后直接执行ant可以查看相应的参数。 ant 参数如下: debug:带调试用签名的构建 release:构建应用程序,生成的apk必须签名才可以发布 install:安装调试构建的包到运行着的模拟器或者设备; 直接执行: ant debug install...

十月 12, 2012

通过adb启动手机应用

通过adb shell pm命令可以启动手机中已安装的应用,还可以发送广播,启动服务等等。 例如: //拨打电话 adb shell am start -a android.intent.action.CALL -d tel:10086 //启动浏览器打开网页 adb shell am -a android.intent.action.VIEW -d http://laomos.tk //发送广播 adb shell am broadcast -a tk.laomo.START //启动已经安装的应用 adb shell am start tk.laomo.demo/tk.laomo.demo.MainActivity 通过adb shell pm启动应用可以用于: 1.自动化测试 2.配合ant、maven使用,ant、maven打包安装,adb shell pm启动应用 等等。 Ps:android中通过包名启动应用可以这样调用: Intent mIntent = getPackageManager() .getLaunchIntentForPackage("com.laomo.demo"); startActivity(mIntent);

十月 12, 2012

判断手机是否已安装google map

需求是这样的:如果手机已安装google map,通过google map打开google地图;否则通过浏览器打开google地图(无论是否已安装其它地图程序)。 网上比较普遍的判断方法是通过Class.forName判断有没有这个类: try { Class.forName("com.google.android.maps.MapActivity"); } catch (Exception e) { return; } 例如这个如何在Android真机上检测是否有Google Map add-on 国外一位大牛指出:在标签中还包含了一个没有公布的属性"android:required",你可以将com.google.android.maps库的这个属性设置为false,即: 这代表如果在目标机器上内置了Google Map add-on,则可以正常使用应用;如果目标机器没有内置Google Map add-on,也可以成功安装应用。但是开发人员需要在代码中自行判断Google Map add-on是否可用。 try { Class.forName("com.google.android.maps.MapActivity"); } catch (Exception e) { Toast.makeText(MainActivity.this, "Oop! google地图不可用", Toast.LENGTH_SHORT).show(); return; } Intent intent = new Intent(); intent.setClass(MainActivity.this, MyMapActivity.class); startActivity(intent); 但是这种方法在有些版本的系统上不生效。后来一朋友说他们是这样实现的: 1.首先定义一个方法isIntentAvailable(Intent intent);用来判断有没有这个intent要”启动的“应用。 private boolean isIntentAvailable(Intent intent) { List<ResolveInfo> activities = getPackageManager().queryIntentActivities(intent, PackageManager.COMPONENT_ENABLED_STATE_DEFAULT); return activities.size() != 0; } 2.然后调用判断即可。 Intent intent = new Intent(Intent....

十月 6, 2012

Android SparseArray

Sparse array —稀疏数组 原型解释:http://hi.baidu.com/kxw102/item/9302f36ef2b9db106995e639" 所谓稀疏数组就是数组中大部分的内容值都未被使用(或都为零),在数组中仅有少部分的空间使用。因此造成内存空间的浪费,为了节省内存空间,并且不影响数组中原有的内容值,我们可以采用一种压缩的方式来表示稀疏数组的内容。 人性化的SparseArray:http://blog.sina.com.cn/s/blog_68d72c9b010131ug.html SparseArray是android里为<Interger,Object>这样的Hashmap而专门写的class,目的是提高效率,其核心是折半查找函数(binarySearch),今天在看这个class的实现时发现一个很好的设计: public void remove(int key) { delete(key); } remove和delete都实现了,功能当然是一样的,对用户来说,想用delete,和remove的都可以。 SparseArray<E>详解:http://blog.csdn.net/xyz_fly/article/details/7931943 最近编程时,发现一个针对HashMap<Integer, E>的一个提示: 翻译过来就是:用SparseArray<E>来代替会有更好性能。 那我们就来看看源码中SparseArray到底做了哪些事情: 一、构造 从构造方法我们可以看出,它和一般的List一样,可以预先设置容器大小,默认的大小是10: public SparseArray() { this(10); } public SparseArray(int initialCapacity) { ...... } 二、增 它有两个方法可以添加键值对: public void put(int key, E value) public void append(int key, E value) 在存储数据的时候,是采用了二分法方式,以下是它采用二分法的源码: private static int binarySearch(int[] a, int start, int len, int key) { int high = start + len; int low = start - 1; while (high - low > 1) { int guess = (high + low) / 2; if (a[guess] < key) { low = guess; continue; } high = guess; } if (high == start + len) return start + len ^ 0xFFFFFFFF; if (a[high] == key) { return high; } return high ^ 0xFFFFFFFF; } 所以,它存储的数值都是按键值从小到大的顺序排列好的。...

九月 15, 2012

This Handler class should be static or leaks might occur

更新到adt20的开发者们可能会在handler上发现这么一条警告: This Handler class should be static or leaks might occur 首先在ADT 20 Changes中我们可以找到这样一个变化New Lint Checks: Look for handler leaks: This check makes sure that a handler inner class does not hold an implicit reference to its outer class. 翻译过来就是,Lint会增加一个检查项目:确保class内部的handler不含有外部类的隐式引用 。 同一个线程下的handler共享一个looper对象,消息中保留了对handler的引用,只要有消息在队列中,那么handler便无法被回收, 如果handler不是static那么使用Handler的Service和Activity就也无法被回收。这就可能导致内存泄露。当然这通常不会发 生,除非你发送了一个延时很长的消息。 知道了原因我们在来看解决方法: 1.最不想动代码的同学,可以在Preference搜一下Lint,在Lint Error Checking里搜HandlerLeak,然后选择ignore,然后整个世界清净了。。。。(不推荐) 2.上面的方法虽然简单,但是肯定不好的。。。给这个检查肯定是有用的,那第二种方法,自然就是把Handler定义成static,然后用post方法把Runnable对象传送到主线程: private static Handler handler; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // Create a handler to update the UI handler = new Handler(); } void test() { handler....

九月 15, 2012

Android应用程序请求root权限

前提是手机已经破解获取root权限 只是简单的取得root权限: try { Runtime.getRuntime().exec("su"); } catch (Exception e) {} 取得root权限并在程序里获得root结果: private boolean hasRoot() { char[] arrayOfChar = new char[1024]; try { int j = new InputStreamReader(Runtime.getRuntime().exec("su -c ls") .getErrorStream()).read(arrayOfChar); if (j == -1) { return true; } } catch (IOException e) { } return false; } -c, ——commmand=COMMAND 执行一个命令,然后退出所切换到的用户环境; 执行"su -c ls"这样不会阻塞程序。

八月 30, 2012