Android小技巧集合

 

合并apk和odex的方法

       有时候发现别人手机里有一款 apk 挺好,想弄出来装自己手机上,可是却发现那个 apk 是残缺的,里面没有 classes.dex 文件,却有个跟 apk 同名的 odex 文件。残缺的 apk 是装不了的,只能把这个 apkodex 合并成一个完整的 apk 才能安装。

       需要的工具:

1 smali-1.2.2.jar baksmali-1.2.2.jar

       2 . 还需要这个 apk 所在的 rom 里面的一些 jar 文件,都在 /system/framework 里面: core.jar, ext. jar, framework. jar, android.policy. jar, services. Jar 。当然,这五个是最基本的,有可能还不够,这种情况下面会讲到。

       总共分四步:

       1 . 把下载好的 smali-1.2.2.jar baksmali-1.2.2.jar ,还有 rom 里面抠出来的 5jar ,放到工作目录,然后 apkodex 也放到一起。

2 . 分解 odex 文件为 class 文件。

命令: java -jar baksmali-1.2.2.jar -x <a.odex>

<a.odex> 处是你要分解的 odex 文件的名字,命令完成之后,会生成一个 out 文件夹,里面就是所有的 class 文件。如果出现问题,比如什么异常,缺少包什么的,就更到 rom 里面把出错信息里面要求的包拿出来,放到当前目录下。

       3.  class 生成为 classes.dex 文件。

命令: java -Xmx512M -jar smali-1.2.2.jar out -o classes.dex

这一步应该不会有什么问题,然后会生成 classes.dex 文件。

       4.  classes.dex 放入 apk 里面,把盖子盖上。

最后这一步最简单了,用解压缩软件打开 apk ,然后把千辛万苦生成的 classes.dex 塞进去,就 ok 了。这个 apk 就能用了。如果想给他重新签个名的话,去找个 Auto Sign 签名工具签署一下就行。

===========================================================

ScaleAnimation代码实现的pivot问题

用hardcode写动画遇到一个问题,pivot的值怎么设置。我一开始以为是相对于整个屏幕的,后来才发现,原来是相对于要实现动画的这个view的左上角的坐标。         在这个pivot上浪费了很长时间,在这里记一笔
===========================================================

Android系统常用Intent大全

1.从google搜索内容
Intent intent = new Intent();
intent.setAction(Intent.ACTION_WEB_SEARCH);
intent.putExtra(SearchManager.QUERY,"searchString")
startActivity(intent);

2.浏览网页
Uri uri = Uri.parse("http://www.google.com");
Intent it  = new Intent(Intent.ACTION_VIEW,uri);
startActivity(it);

3.显示地图
Uri uri = Uri.parse("geo:38.899533,-77.036476");
Intent it = new Intent(Intent.Action_VIEW,uri);
startActivity(it);

4.路径规划
Uri uri = Uri.parse("http://maps.google.com/maps?f=dsaddr=startLat%20startLng&daddr=endLat%20endLng&hl=en");
Intent it = new Intent(Intent.ACTION_VIEW,URI);
startActivity(it);

5.拨打电话
Uri uri = Uri.parse("tel:xxxxxx");
Intent it = new Intent(Intent.ACTION_DIAL, uri); 
startActivity(it);
6.调用发短信的程序
Intent it = new Intent(Intent.ACTION_VIEW);  
it.putExtra("sms_body", "The SMS text");  
it.setType("vnd.android-dir/mms-sms");  
startActivity(it);
7.发送短信
Uri uri = Uri.parse("smsto:0800000123");  
Intent it = new Intent(Intent.ACTION_SENDTO, uri);  
it.putExtra("sms_body", "The SMS text");  
startActivity(it);

String body="this is sms demo";
Intent mmsintent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts("smsto", number, null));
mmsintent.putExtra(Messaging.KEY_ACTION_SENDTO_MESSAGE_BODY, body);
mmsintent.putExtra(Messaging.KEY_ACTION_SENDTO_COMPOSE_MODE, true);
mmsintent.putExtra(Messaging.KEY_ACTION_SENDTO_EXIT_ON_SENT, true);
startActivity(mmsintent);
 
8.发送彩信
Uri uri = Uri.parse("content://media/external/images/media/23");  
Intent it = new Intent(Intent.ACTION_SEND);  
it.putExtra("sms_body", "some text");  
it.putExtra(Intent.EXTRA_STREAM, uri);  
it.setType("image/png");  
startActivity(it);

StringBuilder sb = new StringBuilder();
sb.append("file://");
sb.append(fd.getAbsoluteFile());
Intent intent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts("mmsto", number, null));
// Below extra datas are all optional.
intent.putExtra(Messaging.KEY_ACTION_SENDTO_MESSAGE_SUBJECT, subject);
intent.putExtra(Messaging.KEY_ACTION_SENDTO_MESSAGE_BODY, body);
intent.putExtra(Messaging.KEY_ACTION_SENDTO_CONTENT_URI, sb.toString());
intent.putExtra(Messaging.KEY_ACTION_SENDTO_COMPOSE_MODE, composeMode);
intent.putExtra(Messaging.KEY_ACTION_SENDTO_EXIT_ON_SENT, exitOnSent);
startActivity(intent);


9.发送Email
Uri uri = Uri.parse("mailto:xxx@abc.com");
Intent it = new Intent(Intent.ACTION_SENDTO, uri);
startActivity(it);

Intent it = new Intent(Intent.ACTION_SEND);  
it.putExtra(Intent.EXTRA_EMAIL, "me@abc.com");  
it.putExtra(Intent.EXTRA_TEXT, "The email body text");  
it.setType("text/plain");  
startActivity(Intent.createChooser(it, "Choose Email Client")); 

Intent it=new Intent(Intent.ACTION_SEND);    
String[] tos={"me@abc.com"};    
String[] ccs={"you@abc.com"};    
it.putExtra(Intent.EXTRA_EMAIL, tos);    
it.putExtra(Intent.EXTRA_CC, ccs);    
it.putExtra(Intent.EXTRA_TEXT, "The email body text");    
it.putExtra(Intent.EXTRA_SUBJECT, "The email subject text");    
it.setType("message/rfc822");    
startActivity(Intent.createChooser(it, "Choose Email Client"));  
 
Intent it = new Intent(Intent.ACTION_SEND);  
it.putExtra(Intent.EXTRA_SUBJECT, "The email subject text");  
it.putExtra(Intent.EXTRA_STREAM, "file:///sdcard/mysong.mp3");  
sendIntent.setType("audio/mp3");  
startActivity(Intent.createChooser(it, "Choose Email Client"));

10.播放多媒体 
Intent it = new Intent(Intent.ACTION_VIEW);
Uri uri = Uri.parse("file:///sdcard/song.mp3");
it.setDataAndType(uri, "audio/mp3");
startActivity(it);

Uri uri = Uri.withAppendedPath(MediaStore.Audio.Media.INTERNAL_CONTENT_URI, "1");  
Intent it = new Intent(Intent.ACTION_VIEW, uri);  
startActivity(it); 

11.uninstall apk
Uri uri = Uri.fromParts("package", strPackageName, null);  
Intent it = new Intent(Intent.ACTION_DELETE, uri);  
startActivity(it);

12.install apk
Uri installUri = Uri.fromParts("package", "xxx", null);
returnIt = new Intent(Intent.ACTION_PACKAGE_ADDED, installUri);

===========================================================

startActivity的requires new task异常解析

    很多人使用startActivity时候,会碰到如下的异常:

Caused by: android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity  context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?

    我曾经也遇到过,不过后来研究了一下之后,明白了原理,记下来,以为碰到同样困扰的兄弟们解惑。

    都知道,Context中有一个startActivity方法,Activity继承自Context,重载了startActivity方法。如果使用Activity的startActivity方法,不会有任何限制,而如果使用Context的startActivity方法的话,就需要开启一个新的task,遇到上面那个异常的,都是因为使用了Context的startActivity方法。解决办法是,加一个flag。

===========================================================

获取屏幕上正在显示的activity

 

        用过ActivityManager的童鞋估计都知道,可以从ActivityManager里面可以获取到当前运行的所有任务,所有进程和所有服务,这是任务管理器的核心。


    
    那么,从里面我们可以发掘点什么出来吗?


    
    仔细看getRunningTasks的文档,里面说获取的是系统中"running"的所有task,"running"状态包括已经被系统冻结的task。而且返回的这个列表是按照顺序排列的,也就是说第一个肯定比第二个后运行。


    
     getRunningTasks有个整型参数,表示返回列表的最大个数。那么,我们如果把1作为参数给进去,那么他返回的task就是当前运行的那个task,然后从task中获取到最顶层的activity,这个activity就是当前显示给用户的那个activity了。

 

Java代码
  1. ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);  
  2. ComponentName cn = am.getRunningTasks(1 ).get( 0 ).topActivity;  
  3. Log.d("" ,  "pkg:" +cn.getPackageName());  
  4. Log.d("" ,  "cls:" +cn.getClassName());   
ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE); ComponentName cn = am.getRunningTasks(1).get(0).topActivity; Log.d("", "pkg:"+cn.getPackageName()); Log.d("", "cls:"+cn.getClassName());

          至于这个能做什么,嘿嘿,我相信你知道的。

===========================================================

判断一个activity是否存在于系统中

 

已知包名和类名,如何判断这个activity是否在系统中存在呢?很简单,通过intent就行。

Java代码
  1. Intent intent =  new  Intent();  
  2. intent.setClassName("包名" ,  "类名" );        
  3. if (getPackageManager().resolveActivity(intent,  0 ) ==  null ) {  
  4.     //说明系统中不存在这个activity   

===========================================================

Android获取外部和内部存储空间总大小和可用大小

 

      android.os下的StatFs类主要用来获取文件系统的状态,能够获取sd卡的大小和剩余空间,获取系统内部空间也就是/system的大小和剩余空间等等。

      看下读取sd卡的:

Java代码
  1. void  readSDCard() {  
  2.         String state = Environment.getExternalStorageState();  
  3.         if (Environment.MEDIA_MOUNTED.equals(state)) {  
  4.             File sdcardDir = Environment.getExternalStorageDirectory();  
  5.             StatFs sf = new  StatFs(sdcardDir.getPath());  
  6.             long  blockSize = sf.getBlockSize();  
  7.             long  blockCount = sf.getBlockCount();  
  8.             long  availCount = sf.getAvailableBlocks();  
  9.             Log.d("" ,  "block大小:" + blockSize+ ",block数目:" + blockCount+ ",总大小:" +blockSize*blockCount/ 1024 + "KB" );  
  10.             Log.d("" ,  "可用的block数目::" + availCount+ ",剩余空间:" + availCount*blockSize/ 1024 + "KB" );  
  11.         }     
  12.     }  
void readSDCard() { String state = Environment.getExternalStorageState(); if(Environment.MEDIA_MOUNTED.equals(state)) { File sdcardDir = Environment.getExternalStorageDirectory(); StatFs sf = new StatFs(sdcardDir.getPath()); long blockSize = sf.getBlockSize(); long blockCount = sf.getBlockCount(); long availCount = sf.getAvailableBlocks(); Log.d("", "block大小:"+ blockSize+",block数目:"+ blockCount+",总大小:"+blockSize*blockCount/1024+"KB"); Log.d("", "可用的block数目::"+ availCount+",剩余空间:"+ availCount*blockSize/1024+"KB"); }   }

       然后看下读取系统内部空间的:

Java代码
  1. void  readSystem() {  
  2.         File root = Environment.getRootDirectory();  
  3.         StatFs sf = new  StatFs(root.getPath());  
  4.         long  blockSize = sf.getBlockSize();  
  5.         long  blockCount = sf.getBlockCount();  
  6.         long  availCount = sf.getAvailableBlocks();  
  7.         Log.d("" ,  "block大小:" + blockSize+ ",block数目:" + blockCount+ ",总大小:" +blockSize*blockCount/ 1024 + "KB" );  
  8.         Log.d("" ,  "可用的block数目::" + availCount+ ",可用大小:" + availCount*blockSize/ 1024 + "KB" );  
  9.     }  
void readSystem() { File root = Environment.getRootDirectory(); StatFs sf = new StatFs(root.getPath()); long blockSize = sf.getBlockSize(); long blockCount = sf.getBlockCount(); long availCount = sf.getAvailableBlocks(); Log.d("", "block大小:"+ blockSize+",block数目:"+ blockCount+",总大小:"+blockSize*blockCount/1024+"KB"); Log.d("", "可用的block数目::"+ availCount+",可用大小:"+ availCount*blockSize/1024+"KB"); }

       StatFs获取的都是以block为单位的,这里我解释一下block的概念:

1.硬件上的 block size, 应该是"sector size",linux的扇区大小是512byte
2.有文件系统的分区的block size, 是"block size",大小不一,可以用工具查看
3.没有文件系统的分区的block size,也叫“block size”,大小指的是1024 byte
4.Kernel buffer cache 的block size, 就是"block size",大部分PC是1024
5.磁盘分区的"cylinder size",用fdisk 可以查看。

      我们这里的block size是第二种情况,一般SD卡都是fat32的文件系统,block size是4096.

      这样就可以知道手机的内部存储空间和sd卡存储空间的总大小和可用大小了。

===========================================================

解决Android的ListView控件滚动时背景变黑

      如果大家在非黑色背景下使用ListView控件时,Android默认可能在滚动ListView时这个列表控件的背景突然变成黑色。这样可能导致程序的黑色的背景和主程序的主题既不协调。解决的方法Google在设计Android时也考虑了,在Layout的ListView中加入 android:cacheColorHint="#00000000" 的属性即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android 控件集合是指在Android开发中,用于构建用户界面的一组预定义控件的集合Android提供了丰富的控件可供开发者使用,包括文本框、按钮、图像视图、列表视图、下拉框等。这些控件可以通过XML布局文件或者Java代码动态创建和配置。 Android 控件集合具有以下特点: 1. 多样性:Android控件集合中包含了丰富的控件种类,满足了不同应用场景下的需求。开发者可以根据具体的界面设计要求选择合适的控件进行使用。 2. 可定制性:Android控件集合提供了丰富的配置属性,开发者可以通过设置这些属性来满足自己的设计需求。同时还可以通过自定义控件继承或覆盖Android原生控件,实现更加个性化的效果。 3. 事件监听:Android控件集合支持事件监听机制,开发者可以为控件添加相应的事件处理器,对用户的交互行为做出响应。比如,可以为按钮控件添加点击事件监听器,实现点击按钮后执行相应的操作。 4. 布局管理:Android控件集合中的控件可以通过各种布局管理器进行灵活的排列和组合。比如,线性布局、相对布局、帧布局等。开发者可以根据需求选择合适的布局管理器,实现想要的页面布局效果。 综上所述,Android控件集合提供了丰富多样的控件供开发者使用,具备较高的可定制性和灵活性,方便开发者构建出各种各样的用户界面。通过合理运用和配置控件集合,可以实现强大的Android应用程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值