相关文章推荐
还单身的弓箭  ·  MOF-阿里云开发者社区·  6 月前    · 
长情的山羊  ·  9个小技巧让你的 if ...·  1 年前    · 
android 零星调试笔记

android 零星调试笔记

adb使用:

连接不上手机

C:\Users\Administrator\.android\adb_usb.ini 增加一行内容: 0x1782


安装第三方应用

$ adb install apk文件名

2.安装系统应用

$ adb remount

$ adb push apk文件名 /system/app

// apk文件名形如testme.apk

卸载应用程序

1.$ adb uninstall 包名 例如:adb uninstall lee.study

2. 在终端上找到:Home->设置->应用程序->管理应用程序->选择某应用程序->卸载

设置属性值

使用adb shell: 改成中文 setprop persist.sys.language zh;setprop persist.sys.country cn;stop;sleep 5;start

注解: setprop persist.sys.language zh(MCC: mobile country code);setprop persist.sys.country cn(MNC: mobile network code);

stop;sleep 5;start 延时5秒重启机器

查看系统定义所有权限列表:

adb shell pm list permissions

拨打电话: am start -a Android .intent.action.CALL -d tel:10086 这里-a表示动作,-d表述传入的数据,还有-t表示传入的类型

打开网页: am start -a android.intent.action.VIEW -d 百度一下,你就知道 (这里-d表示传入的data)

打开音乐播放器: am start -a android.intent.action.MUSIC_PLAYER 或者 am start -n com.android.music/om.android.music.MusicBrowserActivity

启动服务: am startservice <服务名称>

例: am startservice -n com.android.music/com.android.music.MediaPlaybackService (这里-n表示组件)

am startservice -a com.smz.myservice (这里-a表示动作,就是你在Androidmanifest里定义的)

发送广播: am broadcast -a <广播动作> am broadcast -a android.intent.action.BOOT_COMPLETED

恢复出厂设置(手机必须拥有root权限): adb shell am broadcast -a android.intent.action.MASTER_CLEAR

模拟按键

adb shell input keyevent 3 :模拟home键 3 = KeyEvent.KEYCODE_HOME

利用adb命令查看apk文件包名

在控制台输入命令$adb shell pm
可以看到adb shell pm的相关用法

要看一个apk文件的相关信息最简单实用的方法是:
aapt dump badging [app.apk]
如果只是想查看手机上应用的packageName,则输入命令:
adb shell pm list packages
如果想知道应用对应的apk文件在手机上的安装位置则可以在上面的命令后加-f参数
adb shell pm list packages -f
查看所有安装的apk包名:
adb shell 'pm list packages -f' | sed -e 's/.*=//' | sort

adb server is out of date. killing... 解决措施:

描述:adb server is out of date. killing...
ADB server didn't ACK
* failed to start daemon *
error: unknown host service

究其源就是adb server没启动 解决过程分析整理如下:
E:\>adb nodaemon server
cannot bind 'tcp:5037'
原来adb server 端口绑定失败
继续查看到底是哪个端口给占用了
E:\>netstat -ano | findstr "5037"
TCP 127.0.0.1:4112 127.0.0.1:5037 CLOSE_WAIT 2960
TCP 127.0.0.1:5037 0.0.0.0:0 LISTENING 4596
TCP 127.0.0.1:5037 127.0.0.1:3006 ESTABLISHED 4596
TCP 127.0.0.1:6149 127.0.0.1:5037 CLOSE_WAIT 2960
打开任务管理器kill掉4596 这个进程。ok

解决读取权限问题

例如 使用adb push init.rc / 命令时报错:Unable to chmod init.rc: Read-only file system

在shell命令行中输入
adb root
切换到root用户
然后执行如下命令:(注意,/表示的是根目录,因此这个不仅仅是对sdcard,其他文件也可以读写。rw表示读写权限,mount重挂载文件系统)
adb shell mount -o remount rw /
执行完后,
可以用mount命令查看,当前挂载的文件系统权限如何,可以看出都有读写权限了(rw

代码中安装apk


需要在manifest.xml文件中,加上INSTALL_PACKAGES的权限,可以用 Package install的receiver来处理安装成功后的操作

或者:

Andoird判断某个APK是否已经安装


//Just call the method by passing the package name of the application you need to check.

if(isAppInstalled("com.yourpackage.package")){

//app installed

}else{

//app not installed

}

Logcat命令选项列表 选项 描述

[adb] logcat [<option>] ... [<filter-spec>] ...

options:

-b <buffer> 加载一个指定的LOG Buffer供查看,比如events 或radio。默认值是main 。具体参考查看指定的Log Buffers.
-c 清除整个 log并退出。
-d 输出LOG到屏幕上并退出。
-f <filename> 写LOG信息到 <filename>。默认是stdout.
-g 打印指定LOG Buffer的大小并退出。
-n <count> 设置日志的最大数目<count>,默认值是4,需要和选项-r一起使用。
-r <kbytes> Rotates每输出<kbytes> 写LOG文件,默认值为16,需要和选项-f一起使用。
-s 设置默认的过滤级别为silent。
-v <format> Sets 设置LOG的输出格式,默认的是brief 格式,要知道更多的支持的格式,参看控制LOG输出格式.

举例:

adb logcat ActivityManager:I MyApp:D *:S
只显示那些标签为“ActivityManager”且优先级为“Info”以上的和标签为“ MyApp”且优先级为“ Debug”以上的信息,其他标签的信息都不显示
表达式最后的元素 *:S,,是设置所有标签的优先级为“silent”,这样保证只有“ActivityManager”和“MyApp”的LOG才会显示

adb logcat -b <system,radio,events,main(default)>

main.log : adb logcat -v time >main.log

radio.log : adb logcat -b radio -v time>radio.log

net and routerinfo : adb shell ifconfig eth0>ifconfig.txt adb shell busybox route -n >route_info.txt

property value: adb shell getprop> no_services_sysprop.txt

iplog: adb shell tcpdump -i any -w /data/iplog.cap&adb pull data/iplog.cap


转: Android中调试获取Log(转

log文件分为实时打印的,还有状态信息的两种
实时打印的主要有:logcat main,logcat radio,logcat events,tcpdump, QXDM Log
状态信息的有:adb shell dmesg,adb shell dumpstate,adb shell dumpsys,adb bugreport
实时log:
adb logcat -b events -v time 打印系统事件的日志,比如触屏事件
tcpdump 是很有用的,对于TCP/IP协议相关的都可以使用这个来抓,
adb shell tcpdump -s 10000 -w /sdcard/capture.pcap,
比如抓mms下载的时候的UA profile,browser上网的时候,使用proxy的APN下载,streaming的相关内容包括UA profile等。
状态log:
其实一个就够了,那就是bugreport(命令adb bugreport>bugreport.log)。
里面包含有dmesg,dumpstate和dumpsys;
dmesg(命令adb shell dmesg > ldmesg_kernel.log)是kernel的log,凡是跟kernel相关的,比如driver出了问题(相机,蓝牙,usb,启动,等等)
dumpstate是系统状态信息,里面比较全,包括手机当前的内存信息、cpu信息、logcat缓存,kernel缓存等等;
dumpsys这个是关于系统所有进程Process的内容都在这个里面,adb shell dumpsys 这个命令还有更详尽的用法,
比如adb shell dumpsys meminfo system是查看system这个process的内存信息。
dumpsys [options]
meminfo 显示内存信息
cpuinfo 显示CPU信息
account 显示accounts信息
activity 显示所有的activities的信息
window 显示键盘,窗口和它们的关系
wifi 显示wifi信息
通过adb logcat/bugreport可以实时的查看系统的log,以及系统的状态信息;
如何将Log存储下来,保存当时系统运行的情况呢?
可以通过一些脚本或者执行可执行程序来保存log信息,以便分析问题

命令参数:

名字 功能
account 显示accounts信息
activity 显示所有的activities的信息
cpuinfo 显示CPU信息
window 显示键盘,窗口和它们的关系
wifi 显示wifi信息
batteryinfo $package_name 电量信息及CPU 使用时长
package packagename 获取安装包信息
usagestats 每个界面启动的时间
statusbar 显示状态栏相关的信息
meminfo
内存信息(meminfo $package_name or $pid
使用程序的包名或者进程id显示内存信息)
diskstats 磁盘相关信息
battery 电池信息
alarm 显示Alarm信息

资源layout加载出错:

郁闷好久的问题: Android Error:main cannot be resolved or is not a field

R.layout.main总是在layout上有错误提示波浪线。

解决方法:

(1) 删除"import android.R;".

(2) 勾选上Eclipse中的"Project->Build Automatically";

原因是:

添加文件,比如xml文件或者资源文件时,系统自动添加了import android.R;android.R是系统提供的资源,R是应用程序的资源。删除"import android.R"之后工程就是从/res文件夹下自动生成的资源文件里去解析了,否则它会从Android的资源类里去找。

Intent.ACTION_BOOT_COMPLETED 开机完成

模拟器启动不了

错误如 : Starting emulator for AVD '4.2.2' PANIC: Could not open: 4.2.2

解决:

1、把模拟器avd所在位置的.android文件夹直接复制C:\Documents and Settings\Administrator\
(模拟器avd所在位置 -- 选择 VIRTUAL... 选择 安卓 机,DETAILS...path:就是这个路径。把.android文件夹COPY到C:\Documents and Settings\Administrator\)

2、我的电脑-属性-高级 环境变量。
新建系统环境变量,
名字:ANDROID_SDK_HOME
变量值:X:\
X为android文件夹所在
(文件夹放在根目录)
然后新建一个,就能开机了

android彩蛋代码

DeviceInfoSettings. Java ->onPreferenceTreeClick->

Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setClassName("android", com.android.internal.app.PlatLogoActivity.class.getName());

startActivity(intent);

packages\apps\Crome\src\com\crome\test\PlatLogoActivity.java

取得屏幕大小:

1、在非activity类中

WindowManager windowManager = (WindowManager)(mContext.getSystemService(Context.WINDOW_SERVICE));

int screenWidth = windowManager.getDefaultDisplay().getWidth();

int screenHeight = windowManager.getDefaultDisplay().getHeight();

2、在activity类中

int screenWidth = getWindowManager().getDefaultDisplay().getWidth(); // 屏幕宽(像素,如:480px)

int screenHeight = getWindowManager().getDefaultDisplay().getHeight(); // 屏幕高(像素,如:800px)

eclipse出现 Some characters cannot be mapped using "GBK" character encoding 错误代码的解决办法

今天在使用eclipse调试腾讯空间API时,在我更改APP key后,点击保存按钮时,出现了Some characters cannot be mapped using "GBK" character encoding 这样的错误代码,根据提示看,应该是说一些文字无法用GBK编码映射。应该是有些地方的文字编码设置成了GBK造成的。

马上google了一番,终于找到了解决的办法,依次点击Window->Profermance->General->Content Type->Text看目录下面的每个文件,包括子目录里面 Default encoding的值是否为utf-8,如果为别的值或为空,则全部改为utf-8,每一项改完,别忘了点一下update.全部改完后推出菜单,再点一下保存,终于成功了。

获得 LayoutInflater 实例的三种方式

1.LayoutInflater inflater = getLayoutInflater(); //调用Activity的getLayoutInflater()

2.LayoutInflater localinflater =(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

3. LayoutInflater inflater = LayoutInflater.from(context);

示意代码:

LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);

View view = inflater.inflate(R.layout.custom, (ViewGroup)findViewById(R.id.test));

对于上面代码,指定了第二个参数 ViewGroup root,当然你也可以设置为 null 值。

ContentResolver.query(),以及 Activity.managedQuery异同:

参数、返回值相同:都返回 Cursor 对象

参数:

URI: Content Provider 需要返回的资源索引

Projection: 用于标识有哪些columns需要包含在返回数据中。

Selection: 作为查询符合条件的过滤参数,类似于SQL语句中Where之后的条件判断。

SelectionArgs: 同上。

SortOrder: 用于对返回信息进行排序。

不同:

mContext.getContentResolver().query

ContentResolver.query(),以及 Activity.managedQuery()所以,我们看到一个是ContentResolver提供的查询方法,位于android.content.ContextWrapper.getContentResolver(),另一个则为Activity。 Activity.managedQuery() 方法导致活动管理 Cursor 的生命周期

硬件灭屏功能:写文件

"/sys/class/leds/lcd-backlight/brightness"

./devices/platform/lcd-backlight/leds/lcd-backlight/brightness

0 :灭 255 : 亮

解锁功能

KeyguardManager keyguardManager = (KeyguardManager)getSystemService(KEYGUARD_SERVICE);

KeyguardLock keyguardLock = keyguardManager.newKeyguardLock("");

keyguardLock.disableKeyguard();

PowerManager pm = (PowerManager)getSystemService(POWER_SERVICE);

点亮屏幕

PowerManager pm = (PowerManager)getSystemService(POWER_SERVICE);

WakeLock mWakelock = pm.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP|PowerManager.SCREEN_DIM_WAKE_LOCK,"SimpleTimer");

mWakeLock.acquire();//点亮

mWakeLock.release();//关闭

activity全屏显示:

getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

requestWindowFeature(Window.FEATURE_NO_TITLE);

//注意;要在setContentView(R.layout.layout)语句之前调用才行

在最新SDK中随时可以改变改属性,做到随时隐藏、显示状态栏



取得build.prop中的值:

property_get()[c/c++] 、 SystemProperties_get*()[Java域]读取这些属性值 getBoolean、getInt、getLong、get

android 按键定义:

kernal\include\linux\input.h

设置默认动态墙纸:

在frameworks/base/core/res/res/values目录找到Config.xml文件

<string name="default_wallpaper_component">@null</string>

将其修改为对应的live wallpaper的启动component即可,如要把默认壁纸设置为2.1自带的galaxy,这样写即可:<string name="default_wallpaper_component">com.android.wallpaper/com.android.wallpaper.galaxy.GalaxyWallpaper</string>

这里的com.android.wallpaper/com.android.wallpaper.galaxy.GalaxyWallpaper 是动态壁纸的service的名字。

eclipse出现 Some characters cannot be mapped using "GBK" character encoding 错误代码的解决办法

今天在使用eclipse调试腾讯空间API时,在我更改APP key后,点击保存按钮时,出现了Some characters cannot be mapped using "GBK" character encoding 这样的错误代码,根据提示看,应该是说一些文字无法用GBK编码映射。应该是有些地方的文字编码设置成了GBK造成的。

马上google了一番,终于找到了解决的办法,依次点击Window->Profermance->General->Content Type->Text看目录下面的每个文件,包括子目录里面 Default encoding的值是否为utf-8,如果为别的值或为空,则全部改为utf-8,每一项改完,别忘了点一下update.全部改完后推出菜单,再点一下保存,终于成功了。

在Android源码下如何对APK手动签名呢?需要如下几个步骤:

1、编译signapk JAR包:

在Android源码目录下执行make signapk命令,即可在out/host/linux-x86/framework/目录下生成signapk.jar文件。

2、对已编译好的普通APK进行签名:

java -jar out/host/linux-x86/framework/signapk.jar build/target/product/security/platform.x509.pem build/target/product/security/platform.pk8 xinu.apk xinu_new.apk

以上都是在Android源码目录下执行,对xinu.apk进行签名,签名后名为xinu_new.apk,其中pem和pk8是签名时要用到的key文件,使用Android源码下的key可在编译出来系统上运行时获取System权限等。

-----------------------------------------------------

需要先打一个未签名的APK包,然后用系统签名对其进行签名。使用platform密钥对apk进行签名
1.1.进入<Android_Source_Path>/build/target/product/security,找到【platform.pk8】和【platform.x509.pem】系统密钥。
1.2.进入<Android_Source_Path>/build/tools/signapk找到SignApk.java,运行javac编译成SignApk.class
1.3.执行命令 Java com.android.signapk.SignApk platform.x509.pem platform.pk8 input.apk output.apk
至此,完成。
在运行1.3的命令前,请在你当前的工作目录下新建如下结构的文件夹:com.android.signapk,然后将第二步编译生成的SignApk放入该目录下。或者也可以将SignApk.java的package声明删除后再运行javac编译。
命令java com.android.signapk.SignApk platform.x509.pem platform.pk8 input.apk output.apk
不单可以对apk文件进行重签名,也可以对所有的zip文件进行重签名,包括ROM文件。
以上这方法在AndroidManifest中声明android.permission.INSTALL_PACKAGES,有一点比较奇怪的是执行“ int result = checkCallingOrSelfPermission(Intent.ACTION_PACKAGE_INSTALL) ”,result的值为android.content.pm.PackageManager.PERMISSION_DENIED而不是PERMISSION_GRANTED。

取得某个文件夹下特定格式文件列表

屏常亮代码:

getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);//屏常亮

自定义组合控件加载layout:

LayoutInflater.from(context).inflate(R.layout.cam_control_bar, this, true);

自定义控件不调用onDraw函数:

android默认不调用onDraw函数,在自定义view里如需手动绘制,需要在构造函数调用this.setWillNotDraw(false);来告诉ui线程此自定义layout有需要绘制的内容

实现序列图切换 就是一张图有几张小图组成 按时间切换 (java实现)

int currImage=0;
Handler handler=new Handler(){
		@Override
		public void handleMessage(Message msg) {
			if (msg.what==0x123) {
			currImage++;
			invalidate();
dukeImage=new Bitmap[]{	
				BitmapFactory.decodeResource(context.getResources(),R.drawable.qt10001),
				BitmapFactory.decodeResource(context.getResources(),R.drawable.qt10002),
				BitmapFactory.decodeResource(context.getResources(),R.drawable.qt10003),
				BitmapFactory.decodeResource(context.getResources(),R.drawable.qt10004),
				BitmapFactory.decodeResource(context.getResources(),R.drawable.qt10005),
new Timer().schedule(new TimerTask(){
			@Override
			public void run() {
				handler.sendEmptyMessage(0x123);
		}, 0,200);
public void onDraw(Canvas canvas) {	
canvas.drawBitmap(dukeImage[currImage], 
	LEFTMART,
		screenHeight-ImageHeight-BOTTOM, 
			paint);		
		}

转自: Android中动画学习


/**
*
* 简单实现了一个方法来判断动画的状态。CustomAnimDrawable是自己写的继承于AnimationDrawable的
*
* 一个类,用来根据播放第几帧来判断,避免了根据时间来判断时,理论时间和实际时间不一致造成的影响。
*
* 用到了Java的反射机制。
*
*/
public class CustomAnimDrawable extends AnimationDrawable {
private final String TAG = "xmp";
private AnimationDrawable mOriAnim;
private AnimationDrawable mSelf;
private Handler mHandler;
private boolean mStarted;
private AnimEndListenerRunnable mEndRunnable;
private AnimationDrawableListener mListener;

public CustomAnimDrawable(AnimationDrawable anim) {
mOriAnim = anim;
initialize();
}
private void initialize() {
mSelf = this;
mStarted = false;
mHandler = new Handler();
mEndRunnable = new AnimEndListenerRunnable();
for (int i = 0; i < mOriAnim.getNumberOfFrames(); i++) {
mSelf.addFrame(mOriAnim.getFrame(i), mOriAnim.getDuration(i));
}
}

@Override
public void start() {
mOriAnim.start();
mStarted = true;
mHandler.post(mEndRunnable);
if (mListener != null) {
mListener.onAnimationStart(mSelf);
}
Log.v(TAG, "------CustomAnimDrawable------>start");
}

/**
* 循环检测 动画的状态
*/
class AnimEndListenerRunnable implements Runnable {
@Override
public void run() {
// 动画已开始
if (!mStarted) {
return;
}
// 未停止继续监听
if (!isEnd()) {
// 这里的延迟时间是跟你的每一帧动画时间有关,基本保持一致就可以,最后一帧也会完整播放
// 上面动画时间为每一帧1000ms,所以这里设为了1000ms
mHandler.postDelayed(mEndRunnable,1000);
return;
}
Log.v(TAG, "----------->over");
// 动画已结束
if (mListener != null) {
mStarted = false;
mListener.onAnimationEnd(mSelf);
}
}
}
/**
* 判断动画是否结束 采用反射机制
* @return
*/
private boolean isEnd(){
Class<AnimationDrawable> animClass = AnimationDrawable.class;
try{
//利用Java反射方法判断是否结束
//获得私有方法 例如
//Method method = animClass.getDeclaredMethod("nextFrame",boolean.class);

//访问其私有变量
Field field = animClass.getDeclaredField("mCurFrame");
field.setAccessible(true);

int currFrameNum = field.getInt(mOriAnim);
int totalFrameNum = mOriAnim.getNumberOfFrames();
if((currFrameNum == totalFrameNum - 1)||
(currFrameNum == -1)){
return true;
}
}
catch (Exception e) {
Log.v(TAG,"-------->Exception");
}
return false;
}
public void setAnimationListener(AnimationDrawableListener listener) {
mListener = listener;
}
}
public interface AnimationDrawableListener {
/**
* Notifies the start of the animation
* @param animation
*/
public void onAnimationStart(AnimationDrawable animation);
/**
* Notifies the end of the animation
* @param animation
*/
public void onAnimationEnd(AnimationDrawable animation);
}

TextView相关:

android:imeOptions="actionSearch" 调整输入法enter键的显示
android:inputType="textNoSuggestions" 限制字符(输入格式) InputFilter

android:focusableInTouchMode="true" 获取焦点 <requestFocus />
mSearchEdit.setFocusable(true);
mSearchEdit.setFocusableInTouchMode(true);
mSearchEdit.requestFocus();

详见:

百度--您的访问出错了

如何将TextView中的中文设置成粗体?

在xml文件中使用android:textStyle="bold" 可以将英文设置成粗体,但是不能将中文设置成粗体,将中文设置成粗体的方法是:
TextView tv = (TextView)findViewById(R.id.TextView01);
TextPaint tp = tv.getPaint();
tp.setFakeBoldText(true);

输入法相关:

默认输入法:1、frameworks\base\packages\SettingsProvider\res\values\defaults.xml
<string name="default_enabled_input_methods" translatable="false">com.jb.gokeyboard/.GoKeyboard</string>

2、frameworks\base\packages\SettingsProvider\src\com\android\providers\settings\DatabaseHelper.java

函数private void loadSecureSettings(SQLiteDatabase db)() 中 增加语句 loadStringSetting(stmt, Settings.Secure.DEFAULT_INPUT_METHOD, com.android.internal.R.string.default_enabled_input_methods);


4.2.2 pad中使用:


<activity android:windowSoftInputMode="stateHidden|adjustPan" . . . > 调整输入法初始隐藏,并且不调整出口尺寸大小

详见: android:windowSoftInputMode的说明

强制隐藏Android输入法窗口

在IME类中我们通过 InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); 实例化输入法控制对象,通过hideSoftInputFromWindow来控制,其中第一个参数绑定的为需要隐藏输入法的EditText对象,比如imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);

EditText editText=...

editText.setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View arg0, boolean arg1) {
// TODO Auto-generated method stub
if(!arg1){ //失去焦点,关闭输入界面
InputMethodManager imm = (InputMethodManager)activity.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
}
}
});

SQL中 inner join、 left join 、right join、 outer join之间的区别

举例说明

A表(a1,b1,c1) B表(a2,b2)

a1 b1 c1 a2 b2

01 数学 95 01 张三

02 语文 90 02 李四

03 英语 80 04 王五

select A.*,B.* from A

inner join B on(A.a1=B.a2)

结果是:

a1 b1 c1 a2 b2

01 数学 95 01 张三

02 语文 90 02 李四

select A.*,B.* from A

left outer join B on(A.a1=B.a2)

结果是:

a1 b1 c1 a2 b2

01 数学 95 01 张三

02 语文 90 02 李四

03 英语 80 NULL NULL

select A.*,B.* from A

right outer join B on(A.a1=B.a2)

结果是:

a1 b1 c1 a2 b2

01 数学 95 01 张三

02 语文 90 02 李四

NULL NULL NULL 04 王五

select A.*,B.* from A

full outer join B on(A.a1=B.a2)

结果是:

a1 b1 c1 a2 b2

01 数学 95 01 张三

02 语文 90 02 李四

03 英语 80 NULL NULL

NULL NULL NULL 04 王五

如果让包含button的item也能弹出菜单,回调click以及long click的监听器:

设置button属性: android:focusable="false" 另外还要设置 listview属性:android:longClickable="true"

PS:

背光亮度 : /sys/class/leds/lcd-backlight/brightness

例如 echo 255 > /sys/class/leds/lcd-backlight/brightness

代码修改亮度:

Settings.System.putInt(getContentResolver(), SCREEN_BRIGHTNESS, brightness); //brightness 背光亮度 0~255

Settings.System.putInt(getContentResolver(),SCREEN_OFF_TIMEOUT, timeoutValues);//timeoutValues 灭屏时间 ms

FrameLayout

在FrameLayout布局里面android:layout_margin的各种属性必须依赖于android:layout_gravity,也就是说,要想margin生效,必须设定view的layout_gravity属性。

如何自定义title的高度、背景

Android程序默认的Activity标题栏只能显示一段文字,而且不能改变它的布局、颜色、标题栏的高度等。如果想要在标题栏加上个图标、button、输入框、进度条、修改标题栏颜色等,只能使用自定义的标题栏。自定义标题栏可以通过在onCreate函数中添加以下代码来实现,需要注意的是代码的顺序必须按照下面的样式,否则将无效。
requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
setContentView(R.layout.mainactivity); //Activity的布局
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE,R.layout.titlebar); //标题栏的布局
虽然上面这样可以在标题栏加入一些控件,但是仍然不能改变标题栏的高度、背景色,要想达到这个目的,只能使用theme(主题)。因此往project里先添加一个style。改变背景色修改android:windowTitleBackgroundStyle的值,改变标题栏高度则修改android:windowTitleSize的值。下面是一个示例:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="fmTitleBackground">
<item name="android:background">#778899</item>
</style>
<style name="fmTitlebar" parent="android:Theme">
<item name="android:windowTitleSize">32dp</item>
<item name="android:windowTitleBackgroundStyle">@style/fmTitleBackground</item>
</style>
</resources>
接着再修改AndroidManifest.xml文件,找到要自定义标题栏的Activity,添加上android:theme值,比如:<activity android:name=".MainActivity" android:theme="@style/fmTitlebar">android:theme值就是上面那个style.xml文件里定义的一个style的name值。
按照以上的步骤,修改标题栏布局、高度、背景色的功能就实现了。

重新显示一个已经启动的Activity呢 不重新启动它 只是让它显示到最前面 : A ->B->C->D 现在想要 从 D直接到B

Intent intent = new Intent(ReorderFour.this, ReorderTwo.class);
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(intent);

Android2.1的源代码的目录结构,可以帮助我们研究Android的源代码。

android源码结构分析(转)

判断是否在锁屏界面的函数

KeyguardManager: inKeyguardRestrictedInputMode();

例: KeyguardManager km = (KeyguardManager)getSystemService(Context.KEYGUARD_SERVICE);
boolean keyguardexist = km.inKeyguardRestrictedInputMode();

设置activity背景透明:

1、在AndroidManifest.xml文件中相应的activity下增加属性 android:theme="@android:style/Theme.Translucent"

2、先在res/values下建colors.xml文件,写入:

<?xm version="1.0"encoding="UTF-8"?>
<resources>
<color name="transparent">#9000</color>
</resources>
这个值设定了整个界面的透明度,为了看得见效果,现在设为透明度为56%(9/16)左右。
再在res/values/下建styles.xml,设置程序的风格
<?xml version="1.0"encoding="utf-8"?>
<resources>
<style name="Transparent">
<item name="android:windowBackground">@color/transparent</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowAnimationStyle">@+android:style/Animation.Translucent</item>
</style>
</resources>
最后一步,把这个styles.xml用在相应的Activity上。即在AndroidManifest.xml中的任意<activity>标签中添加 android:theme="@style/Transparent"
如果想设置所有的activity都使用这个风格,可以把这句标签语句添加在<application>中。
可以把背景色#9000换成#0000,运行程序后,就全透明了,看得见背景下的所有东西可以却都操作无效。

双击事件

class MyOnTouchListener implements View.OnTouchListener{

private long mLastTime = 0;

private long mCurTime = 0;

@Override

public boolean onTouch(View v, MotionEvent event) {

if(MotionEvent.ACTION_DOWN == event.getAction()){

mLastTime = mCurTime;

mCurTime = System.currentTimeMillis();

if (mCurTime - mLastTime < 1000) {

// 双击事件 关闭activity

FullBlackActivity.this.finish();

return true;

}

}

return false;

}

}

屏常亮(camera中的代码)

private void resetScreenOn() {

mHandler.removeMessages(CLEAR_SCREEN_DELAY);

getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

}

private void keepScreenOnAwhile() {

mHandler.removeMessages(CLEAR_SCREEN_DELAY);

getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

mHandler.sendEmptyMessageDelayed(CLEAR_SCREEN_DELAY, SCREEN_DELAY);

}

private static final int CLEAR_SCREEN_DELAY = 1;
private static final int SCREEN_DELAY = 2 * 60 * 1000;
private final Handler mHandler = new MainHandler();

private class MainHandler extends Handler {
@Override
public void handleMessage(Message msg) {

switch (msg.what) {
case CLEAR_SCREEN_DELAY: {
getWindow().clearFlags(
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
break;
}

}
}
}

去除锁屏、开机不锁屏

KeyguardManager mKeyguardManager;
KeyguardManager.KeyguardLock mKeyguardLock;

mKeyguardManager=(KeyguardManager )getSystemService(Context.KEYGUARD_SERVICE);
mKeyguardLock = mKeyguardManager.newKeyguardLock(this.getLocalClassName());

mKeyguardLock.disableKeyguard(); //去除锁屏

mKeyguardLock.reenableKeyguard();//重新使能锁屏

去除开机锁屏的功能:frameworks/base/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
private boolean mExternallyEnabled = false;

或者也可以在函数中frameworks/base/services/java/com/android/server/wm/WindowManagerService.java private void initPolicy(Handler uiHandler) 增加代码达到不锁屏功能



默认锁屏时间: frameworks/base/packages/SettingsProvider/res/values/defaults.xml
<integer name="def_screen_off_timeout">-1</integer> -1 代表不锁屏

默认横屏显示

1、setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); // 进入时会先显示一下竖屏然后再横屏

2、在AndroidManifest.xml文件中相应的Activity增加属性 android:screenOrientation="landscape"

取得所有需要显示在主菜单中的程序

Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
List<ResolveInfo> allApps = getPackageManager().queryIntentActivities(mainIntent, 0);

自动内存管理 --- 内存等级(剩多少内存开始关闭相应应用):

3rdparty\wifi\rda5990\special\android\system\core\rootdir\init.rc里面的
# Define the memory thresholds at which the above process classes will
# be killed. These numbers are in pages (4k).
setprop ro.FOREGROUND_APP_MEM 2048 (限制后台程序内存的)
setprop ro.VISIBLE_APP_MEM 3072
setprop ro.HOME_APP_MEM 3072
setprop ro.PERCEPTIBLE_APP_MEM 4096
setprop ro.HEAVY_WEIGHT_APP_MEM 4096
setprop ro.SECONDARY_SERVER_MEM 15360
setprop ro.BACKUP_APP_MEM 15360
setprop ro.HIDDEN_APP_MEM 15360
setprop ro.EMPTY_APP_MEM 14336
# Write value must be consistent with the above properties.
# Note that the driver only supports 6 slots, so we have combined some of
# the classes into the same memory level; the associated processes of higher
# classes will still be killed first.
write /sys/module/lowmemorykiller/parameters/adj 0,1,2,4,7,15
write /proc/sys/vm/overcommit_memory 1
write /proc/sys/vm/min_free_order_shift 4
write /sys/module/lowmemorykiller/parameters/minfree 2048,3072,4096,15360,15360,14336

参考: SSSWITCH0.8.5-自动内存管理设置之我见 解决QQ后台自动掉线问题了..

1.FOREGROUND_APP:前台程序
This is the process running the current foreground app. We'd really rather not kill it!
用户正在使用的程序. 这个设的太高,用户看到得就会是一个正在使用的程序莫名其妙的消失了,然后自动回到桌面..(因为它被系统kill了..) 所以最好别动它..
目前正在屏幕上显示的进程和一些系统进程。举例来说,Dialer Storage,Google Search等系统进程就是前台进程;再举例来说,当你运行一个程序,如浏览器,当浏览器界面在前台显示时,浏览器属于前台进程(foreground),但一旦你按home回到主界面,浏览器就变成了后台程序(background)。我们最不希望终止的进程就是前台进程
2.. VISIBLE_APP: 可见程序
This is a process only hosting activities that are visible to the user, so we'd prefer they don't disappear.
跟FOREGROUND_APP类似,用户正在使用/看得到. 它们的区别就是VISIBLE_APP可能不是用户预期需要的程序,但是用户看得到. 所以可以适当的比FOREGROUND_APP高一点.
可见进程是一些不再前台,但用户依然可见的进程,举个例来说:widget、输入法等,都属于visible。这部分进程虽然不在前台,但与我们的使用也密切相关,我们也不希望它们被终止(你肯定不希望时钟、天气,新闻等widget被终止,那它们将无法同步,你也不希望输入法被终止,否则你每次输入时都需要重新启动输入法)
3. SECONDARY_SERVER:次要服务
This is a process holding a secondary server -- killing it will not have much of an impact as far as the user is concerned.
所有应用的service. 系统级的service比如PhoneService不属于这类,它们是绝不会被Android结束掉的. 所以这个可以适当的设高一点点~ 注意, HOME(SenseUI)也包括在这里 因此还是别设的太高. 要不每次返回桌面都得等它重新load,特别是widget多的..
目前正在运行的一些服务(主要服务,如拨号等,是不可能被进程管理终止的,故这里只谈次要服务),举例来说:谷歌企业套件,Gmail内部存储,联系人内部存储等。这部分服务虽然属于次要服务,但很一些系统功能依然息息相关,我们时常需要用到它们,所以也太希望他们被终止
4.BACKUP APP MEMORY :(背景数据程序内存)
这个ANDROID系统里是合并到上面的3.次要服务里的,这个应该是后台谷歌同步数据(日历,联系人,地图)
5.HOME-app-memory (桌面程序内存)
这个同样ANDROID是合并到上面的3.次要服务里的,其实应该是桌面LUNCHER类应用程序(ADW LP)
6.HIDDEN_APP:(隐藏程序)
This is a process only hosting activities that are not visible, so it can be killed without any disruption.
本来属于1.前台程序或者2.可见程序 的程序, 在用户按了"back返回键"或者"home房子键"后,程序本身看不到了,但是其实还在运行的程序,它们就属于HIDDEN_APP了. 干掉没什么影响.. 不过要了解并不是所有属于这一类的就应该马上结束掉,像push mail,locale,闹钟,等都属于这一类. 因此还是别设的过高. 真正"应该"一点返回键就退出的程序(真正没用的程序)-空程序在下面.
虽然作者用了hidden这个词,但实际即是后台进程(background),就是我们通常意义上理解的启动后被切换到后台的进程,如浏览器,阅读器等。当程序显示在屏幕上时,他所运行的进程即为前台进程(foreground),一旦我们按home返回主界面(注意是按home,不是按back),程序就驻留在后台,成为后台进程
(background)。后台进程的管理策略有多种:有较为积极的方式,一旦程序到达后台立即终止,这种方式会提高程序的运行速度,但无法加速程序的再次启动;也有较消极的方式,尽可能多的保留后台程序,虽然可能会影响到单个程序的运行速度,但在再次启动已启动的程序时,速度会有所提升。这里就需要用户根据自己的使用习惯找到一个平衡点
7.CONTENT_PROVIDER:(内容/节点供应)
This is a process with a content provider that does not have any clients attached to it. If it did have any clients, its adjustment would be the one for the highest-priority of those processes.
这个也是用处不大,但是还是比下面的EMPTY_APP(空程序)稍微有点用.. 所以高点没关系,(大鱼评论:有时候我开了大程序游戏,返回桌面的时候,我的JORTE 日历桌面插件显示会缩小成一小块,应该就是内容/节点供应达到阀值开始释放内存有关。
没有程序实体,进提供内容供别的程序去用的,比如日历供应节点,邮件供应节点等。在终止进程时,这类程序应该有较高的优先权
8.EMPTY_APP:(空程序)
This is a process without anything currently running in it. Definitely the first to Go ! This value is initalized in the constructor, careful when refering to this static variable externally.
完全没用,杀了它只有好处没坏处,第一个干它!大鱼评论:基本上大家运行的一些正常的第三方程序按返回退出后都变成了空程序!
有任何东西在内运行的进程,有些程序,比如BTE,在程序退出后,依然会在进程中驻留一个空进程,这个进程里没有任何数据在运行,作用往往是提高该程序下次的启动速度或者记录程序的一些历史信息。这部分进程无疑是应该最先终止的。

OOM-ADJ等级:
(可根据“oom_adj”值的范围来决定进程管理策略,比如可以设定“当内存小于X时,结束“oom_adj”大于Y的进程”)
0代表降低进程的优先级且驻留内存;这意味着它不会被系统终止,一旦它不可访问后,会获得个更高的“oom_adj”
1代表驻留内存;
4代表缓存较多的内存;
15代表尽量缓存内存。
也就是说内存缓存器是按照ADJ从大到小来进行缓存的。

一个经典用例:

ro.FOREGROUND_APP_ADJ=0 前台程序驻留内存(不缓存)
ro.VISIBLE_APP_ADJ=1 可见的程序驻留内存(不缓存)
ro.PERCEPTIBLE_APP_ADJ=2 缓存的RAM多一些
ro.HOME_APP_ADJ=3 桌面程序,缓存的RAM稍多一些
ro.HEAVY_WEIGHT_APP_ADJ=4 缓存的RAM再多一些
ro.SECONDARY_SERVER_ADJ=5 缓存的RAM再再多一些
ro.BACKUP_APP_ADJ=6 缓存的RAM再再再多一些
ro.HIDDEN_APP_MIN_ADJ=7 隐藏的程序,根据程序的类型进行内存管理,最低为缓存的RAM再再再再多一些,最高就是直接缓存内存。
ro.EMPTY_APP_ADJ=15 已经退出的程序,直接缓存内存

VSS – Virtual Set Size 虚拟耗用内存(包含共享库占用的内存)
RSS – Resident Set Size 实际使用物理内存(包含共享库占用的内存)
PSS – Proportional Set Size 实际使用的物理内存(比例分配共享库占用的内存)
USS – Unique Set Size 进程独自占用的物理内存(不包含共享库占用的内存)
可以使用procrank查看Android系统的各进程的VSS/RSS/PSS/USS的值。


free命令:


totoal(1018216KB)是总内存数量,used(992664KB)表示已经使用的数量, free(25552KB)表示空闲数量。其中,total(1018216KB)=used(992664KB)+free(25552KB)。后面的buffers(9700)表示往磁盘空间里“写”的缓冲区大小,cached表示“读”的数据的缓存,它们属于used的一部分。二者可以快速变为可用内存,使用它们出于改善系统IO性能的目的。当不把二者计入时,系统uesd和free的统计值就是下面的一行(-/+ buffers)因此:uesd:749728=992664-9700-233236,free:25552+9700+233236=268488
最下面的一行表示交换到磁盘空间的内存。

显示当前正在运行的activity

class ShowCurrentActivityThd extends Thread{
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
while(true){
ActivityManager mActivityManager = (ActivityManager) MainActivity.this.getSystemService(Context.ACTIVITY_SERVICE);
ComponentName componentName = mActivityManager.getRunningTasks(1).get(0).topActivity;
String packageName = componentName.getPackageName();
String className = componentName.getClassName();
Log.d("TOP_ACTIVITY","package = " + packageName + ", class = " + className);
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

使用方法: new ShowCurrentActivityThd().start(); 然后就会不停的打印当前activity的包名、类名

获取音乐的内置图片

转自 blog.csdn .NET /tao_zi7890/article/details/8851512

public class ArtworkUtils {
private static final Uri sArtworkUri = Uri.parse("content://media/external/audio/albumart");
private static final BitmapFactory.Options sBitmapOptions = new BitmapFactory.Options();

public static Bitmap getArtwork(Context context, String title, long song_id, long album_id,
boolean allowdefault) {
if (album_id < 0) {
if (song_id >= 0) {
Bitmap bm = getArtworkFromFile(context, song_id, -1);
if (bm != null) {
return bm;
}
}
if (allowdefault) {
return getDefaultArtwork(context);
}
return null;
}
ContentResolver res = context.getContentResolver();
Uri uri = ContentUris.withAppendedId(sArtworkUri, album_id);
if (uri != null) {
InputStream in = null;
try {
in = res.openInputStream(uri);
Bitmap bmp = BitmapFactory.decodeStream(in, null, sBitmapOptions);
if (bmp == null) {
bmp = getDefaultArtwork(context);
}
return bmp;
} catch (FileNotFoundException ex) {
Bitmap bm = getArtworkFromFile(context, song_id, album_id);
if (bm != null) {
if (bm.getConfig() == null) {
bm = bm.copy(Bitmap.Config.RGB_565, false);
if (bm == null && allowdefault) {
return getDefaultArtwork(context);
}
}
} else if (allowdefault) {
bm = getDefaultArtwork(context);
}
return bm;
} finally {
try {
if (in != null) {
in.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
private static Bitmap getArtworkFromFile(Context context, long songid, long albumid) {
Bitmap bm = null;
if (albumid < 0 && songid < 0) {
throw new IllegalArgumentException("Must specify an album or a song id");
}
try {
if (albumid < 0) {
Uri uri = Uri.parse("content://media/external/audio/media/" + songid + "/albumart");
ParcelFileDescriptor pfd = context.getContentResolver()
.openFileDescriptor(uri, "r");
if (pfd != null) {
FileDescriptor fd = pfd.getFileDescriptor();
bm = BitmapFactory.decodeFileDescriptor(fd);
}
} else {
Uri uri = ContentUris.withAppendedId(sArtworkUri, albumid);
ParcelFileDescriptor pfd = context.getContentResolver()
.openFileDescriptor(uri, "r");
if (pfd != null) {
FileDescriptor fd = pfd.getFileDescriptor();
bm = BitmapFactory.decodeFileDescriptor(fd);
}
}
} catch (FileNotFoundException ex) {
}
return bm;
}
private static Bitmap getDefaultArtwork(Context context) {
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inPreferredConfig = Bitmap.Config.RGB_565;
return BitmapFactory.decodeStream(
context.getResources().openRawResource(R.drawable.music_icon), null,
opts);
}

创建阻塞式模态对话框的方法

转自: 找到一个在Android上创建阻塞式模态对话框的方法 Android的同步对话框-Android新手入门-eoe 移动开发者论坛

import android.app.Activity;
import android.app.Dialog;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.text.method.PasswordTransformationMethod;
import android.text.method.TransformationMethod;
import android.view.View;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.TextView;
public class PasswordDialog extends Dialog
{
int dialogResult;
Handler mHandler ;

public PasswordDialog(Activity context, String mailName, boolean retry)
{

super(context);
setOwnerActivity(context);
onCreate();
TextView promptLbl = (TextView) findViewById(R.id.promptLbl);
promptLbl.setText("请输入密码/n" + mailName);
}
public int getDialogResult()
{
return dialogResult;
}
public void setDialogResult(int dialogResult)
{
this.dialogResult = dialogResult;
}
/** Called when the activity is first created. */

public void onCreate() {
setContentView(R.layout.password_dialog);
findViewById(R.id.cancelBtn).setOnClickListener(new android.view.View.OnClickListener() {

@Override
public void onClick(View paramView)
{
endDialog(DialogResult.CANCEL);
}
});
findViewById(R.id.okBtn).setOnClickListener(new android.view.View.OnClickListener() {

@Override
public void onClick(View paramView)
{
endDialog(DialogResult.OK);
}
});
}

public void endDialog(int result)
{
dismiss();
setDialogResult(result);
Message m = mHandler.obtainMessage();
mHandler.sendMessage(m);
}

public int showDialog()
{
mHandler = new Handler() {
@Override
public void handleMessage(Message mesg) {
// process incoming messages here
//super.handleMessage(msg);
throw new RuntimeException();
}
};
super.show();
try {
Looper.getMainLooper().loop();
}
catch(RuntimeException e2)
{
}
return dialogResult;
}

}

网络连接相关

转自: Android网络连接判断与处理

/**
* 获取当前的网络状态 -1:没有网络 1:WIFI网络2:wap网络3:net网络
*/
public int getAPNType(Context context){
int CMNET = 3, CMWAP=2, WIFI=1;
int netType = -1;
ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
android.net.NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if(networkInfo==null){
return netType;
}
int nType = networkInfo.getType(); // 取得类型
if(nType==ConnectivityManager.TYPE_MOBILE){
log("networkInfo.getExtraInfo()"+ " networkInfo.getExtraInfo() is "+networkInfo.getExtraInfo());
if(networkInfo.getExtraInfo().toLowerCase().equals("cmnet")){
netType = CMNET;
}
else{
netType = CMWAP;
}
}
else if(nType==ConnectivityManager.TYPE_WIFI){
netType = WIFI;
}
return netType;
}

//判断是否连接到网络

android.net.NetworkInfo[] networkInfo = connectivity.getAllNetworkInfo();
if (networkInfo != null) {
for (int i = 0; i < networkInfo .length; i++) {
if (networkInfo [i].getState() == android.net.NetworkInfo.State.CONNECTED) {
log("netWorkNameis:"+networkInfo [i].getTypeName()+" subTypeName="+inetworkInfo fo[i].getSubtypeName()+" NetWorkState is:"+ "Availabel");
return true;
}
}
}

或者:

android.net.NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
if (networkInfo != null) {
return networkInfo.isAvailable();
}

网络类型:

connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE); //0

connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);//1

TYPE_MOBILE_MMS //2 、 .....TYPE_BLUETOOTH //7

打开/关闭wifi




打开/关闭蓝牙 bt


Intent的使用

1、显示使用Explicit 当你有一个消息需要传递,如果你明确知道你需要哪个Activity 或者其他Class 来响
应的话,你可以指定这个类来接受该消息,这被称为显性发送。你需要将Intent 的class 属性设置成目标。用setClass或setComponent来设置 Intent的发起方与接收方

2、隐式使用Implicit 不需要用setClass或setComponent来指定事件处理 器,利用 Android Menifest.xml中的配置由平台定位事件的消费者

intent要定位事件的目的地,无外乎需要以下几个信息:
1).种类(category),比如我们常见的 LAUNCHER_CATEGORY 就是表示这是一类应用程序。
2).类型(type),在前面的例子中没用过,表示数据的类型,这是隐性Intent定位目标的重要依据。
3).组件(component),前面的例子中用的是setClass,不过也可以用setComponent来设置intent跳转的前后两个类实例。
4).附加数据(extras),在ContentURI之外还可以附加一些信息,它是Bundle类型的对象。

举例:

增加一个类:HelloThreeProvider,它必须实现于ConentProvider接口,然后,在AndroidMenifest.xml中我们将上面这个HelloThreeProvider类加入应用程序 <provider class="HelloThreeProvider" android:authorities="cn.sharetop.android.hello" />

隐式使用 Intent intent = new Intent();

//使用在AndroidMenifest.xml中定义的android:authorities 的标签 content://+authorities+
intent.setData(new ContentURI("content://cn.sharetop.android.hello/one"));
intent.setAction(intent.VIEW_ACTION);
startActivity(intent);

现在我们的setData里的东西可与以前不一样的,是吧?注意到它的格式了吗?content://是个协议头,固定这样写就行了。然后就是那个authorities中定义的串了,再后面就是我们自定义的东西了,我这里很简单的写个one,其它还可以更长一点,如one/101之类的。它负责去关联上那个provider类。另外,增加了setAction的调用设置操作为VIEW_ACTION,与Menifest中的<action>又挂上了。Android平台负责根据Intent的Data信息中的authorities,找到ContentProvider,然后getType,用type和intent中的Action两个信息,再找到可以处理这个intent的消费者。

转自: sf.org.cn/Android/lumen

判断Bitmap 是否是.9图片

//private static Bitmap finishDecode(Bitmap bm, Rect outPadding, Options opts) { // BitmapFactory.java

byte[] np = bm.getNinePatchChunk();
final boolean isNinePatch = np != null && NinePatch.isNinePatchChunk(np);

拍照并保存到SD卡代码:


Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);

startActivityForResult(intent, SystemCapture);

public void takePicture()

{

if(m_camera != null)

m_camera.takePicture(shutterCallback, rawCallback, jpegCallback);

}

public void open()

{

if(m_camera == null)

m_camera = Camera.open();

}

public void release()

{

if(m_camera != null)

{

m_camera.release();

m_camera = null;

}

}

ShutterCallback shutterCallback = new ShutterCallback() {

public void onShutter() {

Log.d(TAG, "onShutter'd");

}

};

/** Handles data for raw picture */

PictureCallback rawCallback = new PictureCallback() {

public void onPictureTaken(byte[] data, Camera camera) {

Log.d(TAG, "onPictureTaken - raw");

}

};

/** Handles data for jpeg picture */

PictureCallback jpegCallback = new PictureCallback() {

public void onPictureTaken(byte[] data, Camera camera) {

try

{

Bitmap bitmapPicture = BitmapFactory.decodeByteArray(data, 0, data.length);

String path = Environment.getExternalStorageDirectory().toString();

String filename;

Date date = new Date(0);

SimpleDateFormat sdf = new SimpleDateFormat ("yyyyMMddHHmmss");

filename = sdf.format(date);

OutputStream fOut = null;

//File file = new File(path, "/DCIM/"+filename+".jpg");

File file = new File(path, "/"+filename+".jpg");

fOut = new FileOutputStream(file);

//FileOutputStream out = new FileOutputStream(String.format("/sdcard/DCIM/Signatures/%d.jpg", System.currentTimeMillis()));

bitmapPicture.compress(Bitmap.CompressFormat.JPEG, 0, fOut);

fOut.flush();

fOut.close();

MediaStore.Images.Media.insertImage(m_contentResolver,file.getAbsolutePath(),file.getName(),file.getName());

}

catch(Exception ex)

{

ex.printStackTrace();

}

finally

{

camera.startPreview();

}

Log.d(TAG, "onPictureTaken - jpeg");

}

};

实现录像功能

Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
startActivityForResult(intent, SystemVideoRecord);

取得前、后摄像头

private int getFrontCameraId(){
int cameraCount = 0;
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
cameraCount = Camera.getNumberOfCameras(); // get cameras number

if(cameraCount == 0){
mCameraId = -1 ;
Toast.makeText(this, "no camera devices avalible! finish this acitivty", Toast.LENGTH_LONG).show();
finish();
}else if(cameraCount == 1) {
mCameraId = 0;
}else{
for(int camIdx = 0; camIdx < cameraCount; camIdx++ ) {
Camera.getCameraInfo(camIdx, cameraInfo ); // get camerainfo
if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT ) {
// 代表摄像头的方位,目前有定义值两个分别为CAMERA_FACING_FRONT前置和CAMERA_FACING_BACK后置
mCameraId = camIdx;
break;
}
}
}
return mCameraId;
}

回到待机界面

Intent home = new Intent(Intent.ACTION_MAIN);

home.addCategory(Intent.CATEGORY_HOME);

this.startActivity(home);

锁屏可以根据GSensor旋转


在代码:KeyguardUtils.java (main\frameworks\base\packages\keyguard\src\com\mediatek\keyguard\utils)

所以可以i修改

Config.xml (main\frameworks\base\core\res\res\values): <bool name="config_enableLockScreenRotation">false</bool>

或增加属性

都可以实现锁屏界面的旋转

如果要去掉自适应,可以修改

java.text.DateFormat.LONG, locale); ->java.text.DateFormat.LONG, Locale.UK ); //24小时格式

java.text.DateFormat.LONG, locale); ->java.text.DateFormat.LONG, Locale.US.); //12小时格式



修改默认时间

mtk中默认时间设置:

\alps\mediatek\custom\[project]\preloader\ inc\cust_rtc.h
\alps\mediatek\custom\[project]\kernel\rtc\rtc\rtc-mt65XX.h

#define RTC_DEFAULT_YEA 2010
#define RTC_DEFAULT_MTH 1
#define RTC_DEFAULT_DOM 1

也可以在kernel中使用代码设置时间

(在android中, Linux 内核中、rtc时钟,默认的起始日期都是1970年1月1日,那么如何把默认日期指到2012-01-01呢?笔者在实践中发现,在RTC驱动中可以很容易实现。在RTC驱动加载的时候,一般都有个probe函数需要先执行,因此在probe函数里下手最直接有效。RTC从1970-01-01开始,那当然很容易把默认值设置到2012-01-01,所需要设置的seconds也就是从1970-01-01所差的秒数,以秒为单位。因此,一旦读出来的RTC值小于我们预想的值比如2012-01-01(1325402913)小,我们就把它设置到这个时间点。)

java 24小时格式显示转换

在使用SimpleDateFormat时格式化时间的 yyyy.MM.dd 为年月日而如果希望格式化时间为12小时制的,则使用hh:mm:ss 如果希望格式化时间为24小时制的,则使用HH:mm:ss



xml 字符串中特殊字符& 、<、>、 '、" 的处理

& 使用&amp; 代替 ' 使用\' 代替'


&lt; < 小于号

&gt; > 大于号

&amp; & 和

&apos; ' 单引号

&quot; " 双引号

<b></b>加粗字体

<i></i> 斜体字体

<u></u> 给字体加下划线

\n 换行

\u0020表示空格

\u2026表示省略号

使用&lt;b>和&lt;b>来打印出<b></b> 这样的文字;“&lt;”表示“<”的意思;

使用textView.setText(Html.fromHtml("Hello <b>World</b>,<font size=\"3\" color=\"red\">AnalysisXmlActivty!</font>"));设置类似于html那样的效果

如果你需要使用 String.format(String, Object...) 来格式化你的字符串,你可以把格式化参数放在你的字符串中,参见下面的例子:

<string name="welcome_messages">Hello, %1$s! You have %2$d new messages.</string>

在这个例子中,这个格式化的字符串有2个参数, %1$s是个字符串 %2$d 是个浮点数,你可以在你的程序中按照下面的方法来根据参数来格式化字符串:

Resources res = getResources();

String text = String.format(res.getString(R.string.welcome_messages), username, mailCount);

那么根据例子上说的我需要把%s换成%1$s才行了,修改后编译通过,程序成功启动。

问题补充:如何在<string></string>中使用%号

有两个办法可供选择

1.用%%来表示1个%,和转意符号 \ 的用法相同

2.如果你的字符串不需要格式化,可以在你的<string 标签上增加一个属性:formatted="false"例如 <string name="test" formatted="false">% test %</string> 即可

开机后特定的时间内自动发送短信

StartCromeSendMsgReceiver.java

public class StartCromeSendMsgReceiver extends BroadcastReceiver {
private TelephonyManager mTelephonyManager;
private Context mContext = null;
private String mImeiStr = null;
private static final int SEND_SMS_MESSAGE_WHAT = 0x100;
private final Timer mSendSmsTimer = new Timer();
private TimerTask mSendSmsTask = null;
@Override
public void onReceive(Context arg0, Intent arg1) {
// TODO Auto-generated method stub
mContext = arg0;
if(arg1.getAction().equals( Intent.ACTION_BOOT_COMPLETED )) {
//延时时间 1小时start
mSendSmsTask = new TimerTask() {
@Override
public void run() {
// TODO Auto-generated method stub
if(!isSendSmsFlagExist()){
Message message = mSendSmsHandler.obtainMessage();
message.what = SEND_SMS_MESSAGE_WHAT;
mSendSmsHandler.sendMessage(message);
}
}
};

// start timer
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub

long delayTimer = 60*1000; //60*60*1000; //延时时间 1小时
mSendSmsTimer.schedule(mSendSmsTask, delayTimer, delayTimer);
}
}).start();
//延时时间 1小时end

//获取IMEI 号 start
StringBuffer imeiBuffer = new StringBuffer();
int phoneCnt = TelephonyManager.getPhoneCount();

for (int i = 0; i < phoneCnt; i++) {
if(phoneCnt<2)
{
imeiBuffer.append("IMEI:");
}
else
{
imeiBuffer.append("IMEI");
imeiBuffer.append((i + 1));
imeiBuffer.append(":");
}

imeiBuffer.append(((TelephonyManager) arg0.getSystemService(PhoneFactory
.getServiceName(Context.TELEPHONY_SERVICE, i))).getDeviceId());

if(i < (phoneCnt-1))
{
imeiBuffer.append("-");
}
}

mImeiStr = imeiBuffer.toString();
Log.d("StartCromeSendMsgReceiver", "+++++zhangyong[imeiStr]++++++ " + mImeiStr);
//获取IMEI 号 end
}
else if (SEND_SMS.equals(arg1.getAction())) {
log(SEND_SMS);
//createSendSmsFlag();
}else if(DELIVERY_SMS.equals(arg1.getAction())) {
log(DELIVERY_SMS);
if(createSendSmsFlag()){
mSendSmsTimer.cancel();
}
}
}
private void log(String msg) {
// TODO Auto-generated method stub
Log.d("StartCromeSendMsgReceiver", "--"+msg+"--");
}
private Handler mSendSmsHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
// send sms
switch (msg.what) {
case SEND_SMS_MESSAGE_WHAT:
sendImeiSms();
break;
default:
break;
}
}
};

private static final String DELIVERY_SMS = "delivery_sms_ok";
private static final String SEND_SMS = "send_sms_ok";
private static final String SEND_SMS_KEY = "has_send_sms";

private boolean createSendSmsFlag(){
boolean ret = false;
SharedPreferences preferences = mContext.getSharedPreferences("SEND_SMS_FLAG", Context.MODE_PRIVATE);

Editor editor = preferences.edit();
editor.putBoolean(SEND_SMS_KEY, true);
ret = editor.commit();

return ret;
}
private boolean isSendSmsFlagExist(){
boolean ret = false;
SharedPreferences preferences = mContext.getSharedPreferences("SEND_SMS_FLAG",Context.MODE_PRIVATE);
ret = preferences.getBoolean(SEND_SMS_KEY, false);
if(ret){
mSendSmsTimer.cancel();
}
return ret;
}
private void sendImeiSms(){
if(isSendSmsFlagExist()){
return;
}

//String sendingTextString = "测试文本!";
SmsManager sm = SmsManager.getDefault();
PendingIntent sendIntent = PendingIntent.getBroadcast(
mContext, 0,
new Intent(SEND_SMS),0);
PendingIntent deliveryIntent = PendingIntent.getBroadcast(
mContext, 0,
new Intent(DELIVERY_SMS),0);
// new Intent(this, FullBlackActivity.class),0);

// 如果短信没有超过限制长度,则返回一个长度的List。
List<String> texts = sm.divideMessage(mImeiStr);
for (String text : texts) {
//sms.sendTextMessage(“这里是接收者电话号码”, “这里是发送者电话号码”, “这里是短信内容”, null, null);
sm.sendTextMessage("15988888888", "", text, null, deliveryIntent);
//log(text);
}
}
}

然后在 AndroidManifest.xml文件中 增加

<receiver android:name=".StartCromeSendMsgReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>

<action android:name="send_sms_ok"/>

<action android:name="delivery_sms_ok"/>
</intent-filter>
</receiver>

拨号:

直接在adb中 拨号: am start -a android.intent.action.CALL -d tel:10086

Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + "112"));

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);


定时器相关

一、采用Handler与线程的sleep(long)方法
二、采用Handler的postDelayed(Runnable, long)方法
三、采用Handler与timer及TimerTask结合的方法
四、闹钟定时
下面逐一介绍:
一、采用Handle与线程的sleep(long)方法
Handler主要用来处理接受到的消息。这只是最主要的方法,当然Handler里还有其他的方法供实现,有兴趣的可以去查API,这里不过多解释。
1. 定义一个Handler类,用于处理接受到的Message。
Handler handler = new Handler() {
public void handleMessage(Message msg) {
// 要做的事情
super.handleMessage(msg);
2. 新建一个实现Runnable接口的线程类,如下:
public class MyThread implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub
while (true) {
try {
Thread.sleep(10000);// 线程暂停10秒,单位毫秒
Message message = new Message();
message.what = 1;
handler.sendMessage(message);// 发送消息
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
3. 在需要启动线程的地方加入下面语句:
new Thread(new MyThread()).start();
4. 启动线程后,线程每10s发送一次消息。
二、采用Handler的postDelayed(Runnable, long)方法
这个实现比较简单一些。
1. 定义一个Handler类
Handler handler=new Handler();
Runnable runnable=new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
//要做的事情
handler.postDelayed(this, 2000);
2. 启动计时器
handler.postDelayed(runnable, 2000);//每两秒执行一次runnable.
3. 停止计时器
handler.removeCallbacks(runnable);
三、采用Handler与timer及TimerTask结合的方法
1. 定义定时器、定时器任务及Handler句柄
private final Timer timer = new Timer();
private TimerTask task;
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
// 要做的事情
super.handleMessage(msg);
2. 初始化计时器任务
task = new TimerTask() {
@Override
public void run() {
// TODO Auto-generated method stub
Message message = new Message();
message.what = 1;
handler.sendMessage(message);
3. 启动定时器
timer.schedule(task, 2000, 2000);
简要说一下上面三步提到的一些内容:
1. 定时器任务(TimerTask)顾名思义,就是说当定时器到达指定的时间时要做的工作,这里是想Handler发送一个消息,由Handler类进行处理。