通过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

那一刻似曾相识?

你有没有这么样的经历,一刹那脑子里突然闪过一种感觉,此情此景曾在哪里见过或已经经历过?我是经历过好多次,有时就是一句话,一个场景,有时是一个对话,或长或短。还曾经试想改变下,比如说:我知道我接下来要说什么,我想控制自己不这么说,但是从来没用成功过。。。 前些天终于知道这是一种心理学现象,很普遍。一下就是“科学解释”: Deja-vu,原文为法语déjà vu,即视现象,似曾相识的感觉 这里有意思的是,“似曾相识”的科学解释:即视现象里提到的:有一首歌就叫deja-vu(Iron Maiden唱的),相当形象。以下是歌词: When you see familiar faces But you don’t remember where they’re from Could you be wrong? When you’ve been particular places That you know you’ve never seen before Can you be sure? ’Cause you know this has happened before And you know that this moment in time is for real And you know when you feel deja-vu [Chorus:] Feel like I’ve been here before Feel like I’ve been here before Feel like I’ve been here before Feel like I’ve been here before Ever had a conversation That you realise you’ve had before Isn’t it strange Have you ever talked to someone And you feel you know what’s coming next It feels pre-arranged ’Cause you know that you’ve heard it before And you feel that this moment in time is surreal ’Cause you know when you feel deja-vu [Chorus:]

九月 29, 2012

互联网就是新的鸦片

我们都有过这样的经历:你在约会或者和朋友们聚餐,但是心里总有想要查看一下邮件的冲动,或者是Facebook、 Twitter、Instagram或者G+,又或者是Yammer等等其他任何你喜欢的社交网络。你可能还有过“我去下洗手间”的时候,其实是为了去查看一下邮件或者用智能手机看看Twitter上有没有人@你? 是不是有似曾相识的感觉?因为抽烟的人离开桌子或会议大都会说去下洗手间。如果我在酒吧或者聚会上直接打开笔记本电脑,那感觉比喝酒还更有负罪感。 ...

九月 28, 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

Android应用程序不出现在最近打开程序列表里

在开发的过程中,我们肯定会遇到这样的问题:不希望或者不需要应用或者页面出现在最近打开程序列表中。比如: 应用: 一键锁屏应用,点击应用图标,锁屏,结束应用 一些比较私密的应用程序,这个你懂得 页面: 一些应用支持第三方授权登录,授权页不应该出现在最近打开程序列表中 应用通过浏览器打开地图或者是其他的网页,浏览器不应该出现在最近打开程序列表中 关于页面,其实就是那些“中间页面”,就是那些用户无法直接进入的页面,都应该考虑要不要出现在最近程序列表中。 其实Android本身对此有很好的支持,只是目前很多应用并没有用到,可以说很大部分的开发者也没注意到这个问题。 方法一 设置启动的flags /** * If set, the new activity is not kept in the list of recently launched * activities. */ public static final int FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS = 0x00800000; Intent intent = new Intent(this, WaitingFallBackDialog.class); intent.setFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); startActivity(intent); 方法二 AndroidManifest.xml中activity标签下加android:excludeFromRecents =“true"即可。 方法三 这个其实是方法一的延伸,以及对现状的改善。对于别人已经发布的应用,我们没有办法改变其内部行为。如果不想自己打开的应用出现在最近应用列表中的话,可以自己做一个app来启动那些应用,intent指定flag: intent.setFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 以下是我写一个实现:https://raw.github.com/laomo/Starter/650d1c06f5f8a35c7ec8ec2a45d0659d5e71c0b6/Starter.apk 源码:https://github.com/laomo/Starter

八月 29, 2012

WordPress博客站点统计代码[转]

相信很多博主喜欢在自己的博客上显示关于博客的一些信息,如:文章数量,评论数量,博客至今运行多少天等等,要实现它并不难,只需要把以下代码粘贴到适当的位置即可,至少格式,可以根据自己的需要再做调整。以下为代码: <h3>站点统计</h3> 文章数量:<?php $count_posts = wp_count_posts(); echo $published_posts = $count_posts->publish; ?> 评论数量:<?php $total_comments = get_comment_count(); echo $total_comments['approved'];?> 分类数量:<?php echo $count_categories = wp_count_terms('category'); ?> 页面数量:<?php $count_pages = wp_count_posts('page'); echo $page_posts = $count_pages->publish; ?> 链接数量:<?php $link = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->links WHERE link_visible = 'Y'"); echo $link; ?> 标签数量:<?php echo $count_tags = wp_count_terms('post_tag'); ?> 站点成立:某年某月某日(自己填写) 迄今运行:<?php echo floor((time()-strtotime("20xx-x-xx"))/86400); ?>天 最后更新:<?php $last = $wpdb->get_results("SELECT MAX(post_modified) AS MAX_m FROM $wpdb->posts WHERE (post_type = 'post' OR post_type = 'page') AND (post_status = 'publish' OR post_status = 'private')"); $last = date('Y年n月j日', strtotime($last[0]->MAX_m));echo $last; ?...

八月 29, 2012

Android SDK各版本源码

http://repository.grepcode.com/java/ext/com/google/android/android/ 以上地址有各个版本android sdk源代码,而且持续更新,相当不错。

八月 21, 2012