首页 > 代码库 > 最近整理的Android学习笔记

最近整理的Android学习笔记

今天记录一下这段时期学习android的笔记,这些笔记比较凌乱,但总归是有用的,以后什么时候有用,可以直接查询来使用。

通过命令操作contentprovider

adb shell content insert --uri 的使用
在命令行下输入adb shell content会提示相关的使用说明

ubuntu sqlite3可视化

sudo apt-get install sqlite3
sqlite3 -version
sudo apt-get install sqlitebrowser
sqlitebrowser

查看某一条提交记录

git show 9bc2f472e9cf204c737025b5d7101ba16c43b356
git log --pretty=oneline ./src/com/android/providers/settings/SettingsBackupAgent.java

google浏览器下载安装
sudo apt-get install chromium-browser chromium-browser-l10n

查询修改Settings数据库中的字段值

adb shell settings get namespace key
adb shell settings put namespace key value
adb shell settings delete namespace key
adb shell settings list namespace 

android studio原码导入

mmm development/tools/idegen/
development/tools/idegen/idegen.sh

反编译遇到的问题

apktool.jar下载
https://bitbucket.org/iBotPeaches/apktool/downloads
将apktool和apktool.jar放置到usr/local/bin目录下,并且设置其为可执行文件
sudo chmod +x apktool
sudo chmod +x apktool.jar
apktool d xxx.apk

反编译的时候可能会出现这样的错误:
com.googlecode.dex2jar.DexException
这是因为当前是odex文件,需要执行下面的操作:
java -jar baksmali-2.0.3.jar -d system/framework -x xxx.odex
-d 参数就是指定到那个目录下寻找那些所需的jar文件,如果所需的jar包就在当前目录,那么就不需要指定该目录了。
命令执行完成之后就会在当前目录下生成一个out目录,该目录里面就是对应的smali文件 

这里out目录下存放的是smail文件,我们也可是通过apktool反编译出资源,然后将out替换成我们自己的smaily目录
java -jar smali-2.0.3.jar  -o classes.dex out

Ubuntu 使用dpkg安装软件遇到的问题

使用sudo dpkg -i  **.deb安装的时候,可能会提示有依赖
dpkg -i 包名 (结果遇到依赖性问题,需要安装其他的包)
apt-get -f install (使用它就可以自动下载上面所需要的包了)

android固定手机屏幕

$ adb shell content insert --uri content://settings/system --bind name:s:accelerometer_rotation --bind value:i:0

Step2
从竖屏转到横屏
$ adb shell content insert --uri content://settings/system --bind name:s:user_rotation --bind value:i:1
由横屏转到竖屏
$ adb shell content insert --uri content://settings/system --bind name:s:user_rotation --bind value:i:0

git提交patch

git apply --reject xxx.patch
git apply xx.patch
git am xx.patch

adb无线连接手机

为避免使用数据线,可通过wifi通信,前提是手机与PC处于同一局域网

启动方法:

adb tcpip 5555  //这一步,必须通过数据线把手机与PC连接后再执行
adb connect <手机IP>

停止方法:

adb disconnect //断开wifi连接
adb usb //切换到usb模式

android模拟用户事件

文本输入: adb shell input text <string> 例手机端输出demo字符串,相应指令:adb shell input "demo".

键盘事件: input keyevent <KEYCODE>,其中KEYCODE见本文结尾的附表 例点击返回键,相应指令: input keyevent 4.

点击事件: input tap <x> <y> 例点击坐标(500,500),相应指令: input tap 500 500.

滑动事件: input swipe <x1> <y1> <x2> <y2> <time> 例从坐标(300,500)滑动到(100,500),相应指令: input swipe 300 500 100 500. 例200ms时间从坐标(300,500)滑动到(100,500),相应指令: input swipe 300 500 100 500 200.

Android沉浸式状态栏

如果想要我们的应用打开以后和状态栏的颜色保持一致,或者是我们自己定义的颜色,可以这样来做:

布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffffff"
    android:orientation="vertical"
    tools:context=".MainActivity" >

    <TextView
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:background="#009959"
        android:clipToPadding="true"
        android:fitsSystemWindows="true" />

    <Button
        android:layout_width="100dp"
        android:layout_height="50dp"
        android:background="#ff669d" />

</LinearLayout>

这里为textView设置了如下两个属性:
android:clipToPadding=”true”
android:fitsSystemWindows=”true”
之所以设置textview是因为我们在改textview中指定了颜色,即状态栏显示的颜色。

引用布局:

this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);

这样就完成了一个沉浸式的状态栏。

android实现截屏的效果

//构建Bitmap  

WindowManager windowManager = getWindowManager();  

Display display = windowManager.getDefaultDisplay();  

int w = display.getWidth();  

int h = display.getHeight();  

Bitmap Bmp = Bitmap.createBitmap( w, h, Config.ARGB_8888 );      

//获取屏幕  

View decorview = this.getWindow().getDecorView();   

decorview.setDrawingCacheEnabled(true);   

Bmp = decorview.getDrawingCache();   

SpannableString美化文字

SpannableString string = new SpannableString("test百度");
string.setSpan(new AbsoluteSizeSpan(50),3,5, Spannable.SPAN_POINT_POINT);
textView.setText(string);

SpannableString string = new SpannableString("test百度9465fhghfjhg");
string.setSpan(new StyleSpan(Typeface.ITALIC),3,9, Spannable.SPAN_POINT_POINT);
textView.setText(string);

SpannableString string = new SpannableString("test百度9465fhghfjhg");
string.setSpan(new BackgroundColorSpan(Color.argb(187,200,155,200)),3,9, Spannable.SPAN_POINT_POINT);
textView.setText(string);

SpannableString string = new SpannableString("test百度9465fhghfjhg");
string.setSpan(new ForegroundColorSpan(Color.argb(187,200,155,200)),3,9, Spannable.SPAN_POINT_POINT);

SpannableString string = new SpannableString("test百度9465fhghfjhg");
string.setSpan(new URLSpan("百度"),3,9, Spannable.SPAN_POINT_POINT);

SpannableString string = new SpannableString("test百度9465fhghfjhg");
string.setSpan(new ScaleXSpan(0.618f),3,9, Spannable.SPAN_POINT_POINT);

SpannableString string = new SpannableString("test百度9465fhghfjhg");
string.setSpan(new QuoteSpan(),3,9, Spannable.SPAN_POINT_POINT);

SpannableString string = new SpannableString("test百度9465fhghfjhg");
string.setSpan(new StrikethroughSpan(),3,9, Spannable.SPAN_POINT_POINT);

string.setSpan(new RelativeSizeSpan((float) Math.PI),3,9, Spannable.SPAN_POINT_POINT);

android.media.ExifInterface使用

android 2.0开始 加入的 android.media.ExifInterface 包中如下方法读取多媒体文件相关信息:

/**
  *
  * 目前Android SDK定义的Tag有:
  * TAG_DATETIME 时间日期
  * TAG_FLASH 闪光灯
  * TAG_GPS_LATITUDE 纬度
  * TAG_GPS_LATITUDE_REF 纬度参考
  * TAG_GPS_LONGITUDE 经度
  * TAG_GPS_LONGITUDE_REF 经度参考
  * TAG_IMAGE_LENGTH 图片长
  * TAG_IMAGE_WIDTH 图片宽
  * TAG_MAKE 设备制造商
  * TAG_MODEL 设备型号
  * TAG_ORIENTATION 方向
  * TAG_WHITE_BALANCE 白平衡
  */
String path = "/storage/extSdCard/mayi/fault_images/" + filename;//图片完整路径
System.out.println(path);
ExifInterface ext = new ExifInterface(path);//获取图片信息
int image_length = Integer.parseInt(ext.getAttribute(ExifInterface.TAG_IMAGE_LENGTH));
int image_width = Integer.parseInt(ext.getAttribute(ExifInterface.TAG_IMAGE_WIDTH));

manifest的一些属性

当给某一个activity设置android:excludeFromRecents=”true”的时候,就不会在最近使用的应用里边看到该activity

android:alwaysRetainTaskState
是否保留状态不变, 比如切换回home, 再从新打开, activity处于最后的状态

android:clearTaskOnLanunch
比如 P 是 activity, Q 是被P 触发的 activity, 然后返回Home, 从新启动 P, 是否显示 Q
android:finishOnTaskLaunch
是否关闭已打开的activity当用户重新启动这个任务的时候

android:onHistory
是否需要移除这个activity当用户切换到其他屏幕时。 这个属性是 API level 3 中引入的

android:screenOrientation
activity显示的模式, “unspecified” 默认值 “landscape” 风景画模式,宽度比高度大一些 “portrait” 肖像模式, 高度比宽度大。 “user” 用户的设置 “behind” “sensor” “nosensor”

android:allowTaskReparenting(‘true’ or ‘false’)
是否允许activity更换从属的任务,比如从短信息任务切换到浏览器任务

创建和删除app快捷方式

/**    
 * 为程序创建桌面快捷方式    
 */    
private void addShortcut(){     
        Intent shortcut = new Intent("com.android.launcher.action.INSTALL_SHORTCUT");     

    //快捷方式的名称     
    shortcut.putExtra(Intent.EXTRA_SHORTCUT_NAME, getString(R.string.app_name));     
    shortcut.putExtra("duplicate", false); //不允许重复创建     

    //指定当前的Activity为快捷方式启动的对象: 如 com.everest.video.VideoPlayer     
    //注意: ComponentName的第二个参数必须加上点号(.),否则快捷方式无法启动相应程序     
        ComponentName comp = new ComponentName(this.getPackageName(), "."+this.getLocalClassName());     
        shortcut.putExtra(Intent.EXTRA_SHORTCUT_INTENT, new Intent(Intent.ACTION_MAIN).setComponent(comp));     

    //快捷方式的图标     
    ShortcutIconResource iconRes = Intent.ShortcutIconResource.fromContext(this, R.drawable.icon);     
    shortcut.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, iconRes);     
    sendBroadcast(shortcut);     
 }  


/**    
 * 删除程序的快捷方式    
 */    
private void delShortcut(){     
      Intent shortcut = new Intent("com.android.launcher.action.UNINSTALL_SHORTCUT");     

        //快捷方式的名称     
        shortcut.putExtra(Intent.EXTRA_SHORTCUT_NAME, getString(R.string.app_name));     

        //指定当前的Activity为快捷方式启动的对象: 如 com.everest.video.VideoPlayer     
        //注意: ComponentName的第二个参数必须是完整的类名(包名+类名),否则无法删除快捷方式     
        String appClass = this.getPackageName() + "." +this.getLocalClassName();     
        ComponentName comp = new ComponentName(this.getPackageName(), appClass);     
        shortcut.putExtra(Intent.EXTRA_SHORTCUT_INTENT, new Intent(Intent.ACTION_MAIN).setComponent(comp));     

        sendBroadcast(shortcut);     

    }   

另外记得添加以下权限:

<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />     
<uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT" /> 

pm命令的使用

adb shell pm list package -e  列出手机上可用的所有应用
pm list packages -d    列出手机上不可用的所有应用、
pm list packages -s    列出手机上的系统应用
pm enable com.tct.note   使应用可用
pm disable com.tct.note   是应用不可用
pm path com.tct.note   打印出该包名所对应的apk的完整路径
pm list packages    查看手机上所有的应用的包名
pm list permission-groups   列出手机上的所有的权限组
pm list permissions  列出手机上所有的权限
pm list features   列出手机上的硬件功能
pm dump com.tct.note > storage/sdcard0/temp/dump.txt  将该应用的相关信息输出到文件
pm get-install-location com.tct.note  得到应用安装的路径  0:自动  1:内部存储   2:外部存储
aapt dump badging /local/pertest.apk  列出  中的详细信息
aapt dump permissions /local/pertest.apk  列出 中使用的权限

adb shell am start –n activityName
adb shell am kill +package
adb shell am force-stop +package

dumpsys命令的使用

adb shell dumpsys notification
adb shell dumpsys activity---------------查看ActvityManagerService 所有信息
adb shell dumpsys activity activities----------查看Activity组件信息
adb shell dumpsys activity services-----------查看Service组件信息
adb shell dumpsys activity providers----------产看ContentProvider组件信息
adb shell dumpsys activity broadcasts--------查看BraodcastReceiver信息
adb shell dumpsys activity intents--------------查看Intent信息
adb shell dumpsys activity processes---------查看进程信息

adb shell dumpsys battery
adb shell dumpsys cpuinfo
adb shell dumpsys meminfo
adb shell dumpsys activity
adb shell dumpsys activity top  获取当前界面的ui信息
adb shell dumpsys package   获取包的信息
adb shell dumpsys package com.android.mms 获取某一个包的信息
adb shell dumpsys notification  获取notification的信息
adb shell dumpsys power
adb shell dumpsys wifi
获取电话信息:
adb shell dumpsys telephony.registry
可以获取到电话状态,例如
mCallState值为0,表示待机状态、1表示来电未接听状态、2表示电话占线状态
mCallForwarding=false #是否启用呼叫转移
mDataConnectionState=2 #0:无数据连接 1:正在创建数据连接 2:已连接
mDataConnectionPossible=true  #是否有数据连接
mDataConnectionApn=   #APN名称

onTrimMemory学习

onTrimMemory()是Android 4.0之后提供的API,系统会根据不同的内存状态来回调。根据不同的内存状态,来响应不同的内存释放策略。

OnTrimMemory的参数是一个int数值,代表不同的内存状态:

TRIM_MEMORY_COMPLETE:内存不足,并且该进程在后台进程列表最后一个,马上就要被清理

TRIM_MEMORY_MODERATE:内存不足,并且该进程在后台进程列表的中部。
TRIM_MEMORY_BACKGROUND:内存不足,并且该进程是后台进程。
TRIM_MEMORY_UI_HIDDEN:内存不足,并且该进程的UI已经不可见了。
以上4个是4.0增加

TRIM_MEMORY_RUNNING_CRITICAL:内存不足(后台进程不足3个),并且该进程优先级比较高,需要清理内存

TRIM_MEMORY_RUNNING_LOW:内存不足(后台进程不足5个),并且该进程优先级比较高,需要清理内存

TRIM_MEMORY_RUNNING_MODERATE:内存不足(后台进程超过5个),并且该进程优先级比较高,需要清理内存

setContentView之后获得空间宽和高

如果在setContentView之后就尝试获得空间的宽和高,此时会得到0,因为此时还没有执行onMeasure方法,可以尝试如下两种解决方案:


 方法一:
        int w = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);
        int h = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);
        ssidtext.measure(w, h);
        int width =ssidtext.getMeasuredWidth();
        int height =ssidtext.getMeasuredHeight();

方法二:
        ViewTreeObserver vto = ssidtext.getViewTreeObserver();
        vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
            public boolean onPreDraw() {
                int height = ssidtext.getMeasuredHeight();
                int width = ssidtext.getMeasuredWidth();
                return true;
            }
        });

手机root之后

android中锁屏密码都是存在:/data/system/ 目录下的
我们可以查看后缀名是.key的文件,因为有很多种锁屏方案:手势密码,文本密码,PIN密码等,所以会有相对应的文件,我们只要找到对应的文件,然后将其删除即可。

其实每次连接上的wifi之后,系统会将这些wifi信息存储到指定文件中,在/data/misc/wifi/ 目录下面,然后查看wpa_supplicant.conf文件内容即可

设置屏幕显示方向

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);//通过程序改变屏幕显示的方向 

    1.landscape:横屏(风景照) ,显示时宽度大于高度;  

     2.portrait:竖屏 (肖像照) , 显示时 高 度大于 宽 度 ;  

     3.user:用户当前的首选方向;  

     4.behind:继承Activity堆栈中当前Activity下面的那个Activity的方向;  

     5.sensor:由物理感应器决定显示方向,它取决于用户如何持有设备,当 设备 被旋转时方向会随之变化——在横屏与竖屏之间;  

     6.nosensor:忽略物理感应器——即显示方向与物理感应器无关,不管用户如何旋转设备显示方向都不会随着改变("unspecified"设置除外);  

     7.unspecified :未指定,此为默认值,由Android系统自己选择适当的方向,选择策略视具体设备的配置情况而定,因此不同的设备会有不同的方向选择;

screenrecord的使用

adb shell screenrecord /sdcard/demo.mp4
限制录制时间:
adb shell screenrecord –time-limit 10 /sdcard/demo.mp4
指定视频分辨率的大小
adb shell screenrecord –size 1280*720 /sdcard/demo.mp4
指定视频比特率:比特率越大,视频质量越好
adb shell screenrecord –bit-rate 6000000 /sdcard/demo.mp4

scrollView滚动到屏幕底部

scrollView.fullScroll(ScrollView.FOCUS_DOWN);滚动到底部
scrollView.fullScroll(ScrollView.FOCUS_UP);滚动到顶部
需要注意的是,该方法不能直接被调用,因为Android很多函数都是基于消息队列来同步,所以需要一部操作,addView完之后,不等于马上就会显示,而是在队列中等待处理,虽然很快,但是如果立即调用fullScroll, view可能还没有显示出来,所以会失败,应该通过handler在新线程中更新

handler.post(new Runnable() {  
        @Override  
        public void run() {  
            scrollView.fullScroll(ScrollView.FOCUS_DOWN);  
        }  
    });  
<script type="text/javascript"> $(function () { $(‘pre.prettyprint code‘).each(function () { var lines = $(this).text().split(‘\n‘).length; var $numbering = $(‘
    ‘).addClass(‘pre-numbering‘).hide(); $(this).addClass(‘has-numbering‘).parent().append($numbering); for (i = 1; i <= lines; i++) { $numbering.append($(‘
  • ‘).text(i)); }; $numbering.fadeIn(1700); }); }); </script>

    最近整理的Android学习笔记