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

模擬按鍵

adb shell input keyevent 3     :模擬home鍵  3 = KeyEvent.KEYCODE_HOME

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

[plain]  view plain copy
 
  1. Runtime.getRuntime().exec("pm install xxx.apk");   
需要在manifest.xml文件中,加上INSTALL_PACKAGES的權限,可以用 Package install的receiver來處理安裝成功后的操作
或者:
  1.      /** 
  2.      * 安裝apk 
  3.      * @param url 
  4.      */  
  5.     private void installApk(){  
  6.         File apkfile = new File(saveFileName);  
  7.         if (!apkfile.exists()) {  
  8.             return;  
  9.         }      
  10.         Intent i = new Intent(Intent.ACTION_VIEW);  
  11.         i.setDataAndType(Uri.parse("file://" + apkfile.toString()), "application/vnd.android.package-archive");   
  12.         mContext.startActivity(i);  
  13. }


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

資源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)語句之前調用才行
 取得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。 

取得某個文件夾下特定格式文件列表

[plain]  view plain copy
 
  1. private static final String MUSIC_PATH = new String("/sdcard/");  
  2. File file =  new File(MUSIC_PATH);  
  3.          File fileArray[] = file.listFiles(new FilenameFilter() {  
  4.              @Override  
  5.             public boolean accept(File dir, String filename) {  
  6.                 // TODO Auto-generated method stub  
  7.                 return (filename.endsWith(".mp3"));  
  8.             }  
  9.         });  
  10.   
  11.       List<String> mMusicList = new ArrayList<String>();  
  12.         for(File item: fileArray){  
  13.             mMusicList.add(item.getName());  
  14.         }  

 

屏常亮代碼:

 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);		
		}

轉自:http://www.cnblogs.com/bastard/archive/2012/06/29/2570405.html

 

/**

* 簡單實現了一個方法來判斷動畫的狀態。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();

詳見: http://hi.baidu.com/ljlkings/item/7c8d2b0e68efe4076c9048d5

如何將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" . . . >   調整輸入法初始隱藏,並且不調整出口尺寸大小

詳見: http://www.cnblogs.com/snowberg/archive/2012/07/10/2618910.html  

 強制隱藏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的源代碼。

http://www.cnblogs.com/xilinch/archive/2013/04/07/3003670.html

判斷是否在鎖屏界面的函數

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();//重新使能鎖屏

默認橫屏顯示

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

參考:http://bbs.hiapk.com/thread-1165395-1-1.html       http://bbs.fengbao.com/thread-869501-1-1.html

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的包名、類名

獲取音樂的內置圖片

轉自 http://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);  
    }  

創建阻塞式模態對話框的方法

轉自:http://blog.csdn.net/winux/article/details/6269687  和 http://www.eoeandroid.com/thread-272252-1-1.html

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;
}

}

網絡連接相關

轉自:http://blog.csdn.net/tao_zi7890/article/details/9278955

/**
    * 獲取當前的網絡狀態  -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

Intent的使用

1、顯示使用Explicit 當你有一個消息需要傳遞,如果你明確知道你需要哪個Activity 或者其他Class 來響
應的話,你可以指定這個類來接受該消息,這被稱為顯性發送。你需要將Intent 的class 屬性設置成目標。
用setClass或setComponent來設置 Intent的發起方與接收方

2、隱式使用Implicit 不需要用setClass或setComponent來指定事件處理 器,利用AndroidMenifest.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的消費者。

轉自:http://www.sf.org.cn/Android/lumen/20979.html

判斷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); 

設置(Settings)默認值

frameworks/base/packages/SettingsProvider/src/com/Android/providers/settings/DatabaseHelper.java

loadIntegerSetting(stmt, Settings.System.SCREEN_OFF_TIMEOUT, R.integer.def_screen_off_timeout);

R.integer.def_screen_off_timeout來初始化。我們為了讓系統永不鎖屏,只需要把資源 R.integer.def_screen_off_timeout設為-1即可。查看文件

frameworks\base\packages\SettingsProvider\res\values\defaults.xml  設置里面的默認值  例:def_screen_off_timeout  默認鎖屏時間frameworks\base\packages\SettingsProvider\src\com\android\providers\settings\DatabaseHelper.java  函數loadSystemSettings(SQLiteDatabase db) 加載各個默認值SoundSettings.java mDtmfToneDefaultValue 默認按鍵音

開機默認鎖屏 :

frameworks/policies/base/phone/com/Android/internal/policy/impl/KeyguardViewMediator.java
該文件中有一個變量定義如下:
    /**
     * External apps (like the phone app) can tell us to disable the keygaurd.
     */
    private boolean mExternallyEnabled = true;
mExternallyEnabled是用來管理是否開啟屏幕鎖的關鍵。默認值是打開屏鎖       

xml 字符串中特殊字符& 和 ' 的處理

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

開機后特定的時間內自動發送短信 

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>

定時器相關

一、采用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類進行處理。
2. java.util.Timer.schedule(TimerTask task, long delay):這個方法是說,dalay/1000秒后執行task.只執行一次。
java.util.Timer.schedule(TimerTask task, long delay, long period):這個方法是說,delay/1000秒后執行task,然后進過period/1000秒再次執行task,這個用於循環任務,執行無數次,當然,你可以用timer.cancel();取消計時器的執行。
四、鬧鍾定時
AlarmManager am = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(SEND_SMS_BEGIN), 0);
am.set(AlarmManager.RTC_WAKEUP, 60*1000, pendingIntent);

android.mk 編譯選項

definitions.mk    定義各類函數 例: define my-dir   define all-makefiles-under     define all-subdir-makefiles   define all-java-files-under
build/core/config.mk  各類變量的定義   例: BUILD_PACKAGE:= $(BUILD_SYSTEM)/package.mk   BUILD_STATIC_LIBRARY:= $(BUILD_SYSTEM)/static_library.mk  BUILD_SHARED_LIBRARY:= $(BUILD_SYSTEM)/shared_library.mk

耳機狀態

private static final String HEADSET_STATE_PATH = "/sys/class/switch/h2w/state";    保存狀態文件位置

private boolean isHeadsetExists(){       //判斷耳機是否插入的函數    FM源碼 FMplayService.java  
        char[] buffer = new char[1024];
        int newState = 0;
        try {
            FileReader file = new FileReader(HEADSET_STATE_PATH);
            int len = file.read(buffer, 0, 1024);
            newState = Integer.valueOf((new String(buffer, 0, len)).trim());
        } catch (FileNotFoundException e) {
            Log.e(LOGTAG, "This kernel does not have wired headset support");
        } catch (Exception e) {
            Log.e(LOGTAG, "" , e);
        }
        return newState != 0;
   }

未插入耳機:

# cat /sys/class/switch/h2w/state
cat /sys/class/switch/h2w/state
0

插入耳機:
# cat /sys/class/switch/h2w/state
cat /sys/class/switch/h2w/state
1

sd卡和sim卡狀態判斷

 

//sdcard是否可讀寫 

public boolean IsCanUseSdCard() { 
    try { 
        return Environment.getExternalStorageState().equals( 
                Environment.MEDIA_MOUNTED); 
    } catch (Exception e) { 
        e.printStackTrace(); 
    } 
    return false; 

//sim卡是否可讀 

public boolean isCanUseSim() { 
    try { 
        TelephonyManager mgr = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); 
         return TelephonyManager.SIM_STATE_READY == mgr.getSimState(); 
    } catch (Exception e) { 
        e.printStackTrace(); 
    } 
    return false; 

 

 

開機啟動,檢查sim卡是否發生變更

(1)注冊receiver,設置意圖過濾器
<receiver android:name=".receiver.BootCompleteReceiver" >
    <intent-filter android:priority="1000" >
        <action android:name="android.intent.action.BOOT_COMPLETED" />
    </intent-filter>
</receiver>
(2)接受開機廣播,並判斷sim卡時候發生更改
public class BootCompleteReceiver extends BroadcastReceiver {
    private static final String TAG = "BootCompleteReceiver";
    private SharedPreferences sp;
    private TelephonyManager tm;
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.i(TAG,"手機重啟了");
        sp = context.getSharedPreferences("config", Context.MODE_PRIVATE);
        boolean protecting = sp.getBoolean("protecting", false);
        //如果防盜保護開啟
        if(protecting){
                //判斷sim卡是否發生了變化
        tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
            String currentSim = tm.getSimSerialNumber();
            String savedSim= sp.getString("sim", "");
            if(savedSim.equals(currentSim)){
                    // sim卡為發生變化, do nothint
            }else{
                //sim卡發生了變化
                //發送報警短信 給安全號碼
                SmsManager smsManager = SmsManager.getDefault();
                String destinationAddretss = sp.getString("safenumber", "");
                smsManager.sendTextMessage(destinationAddretss, null, "sim change !!!", null, null);
            }
        }
    }
}

 

 

判斷SIM卡屬於哪個移動運營商

第一種方法:
獲取手機的IMSI碼,並判斷是中國移動\中國聯通\中國電信  
TelephonyManager telManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); 
/** 獲取SIM卡的IMSI碼
* SIM卡唯一標識:IMSI 國際移動用戶識別碼(IMSI:International Mobile Subscriber Identification Number)是區別移動用戶的標志,
* 儲存在SIM卡中,可用於區別移動用戶的有效信息。IMSI由MCC、MNC、MSIN組成,其中MCC為移動國家號碼,由3位數字組成,
* 唯一地識別移動客戶所屬的國家,我國為460;MNC為網絡id,由2位數字組成,
* 用於識別移動客戶所歸屬的移動網絡,中國移動為00,中國聯通為01,中國電信為03;MSIN為移動客戶識別碼,采用等長11位數字構成。
* 唯一地識別國內GSM移動通信網中移動客戶。所以要區分是移動還是聯通,只需取得SIM卡中的MNC字段即可  
*/ 
String imsi = telManager.getSubscriberId();
if(imsi!=null){  
if(imsi.startsWith("46000") || imsi.startsWith("46002")){
//因為移動網絡編號46000下的IMSI已經用完,所以虛擬了一個46002編號,134/159號段使用了此編號  
//中國移動  
}else if(imsi.startsWith("46001")){  
//中國聯通  
}else if(imsi.startsWith("46003")){ 
//中國電信 
}  
}
第二種方法
TelephonyManager telManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); 
String operator = telManager.getSimOperator();
if(operator!=null){  
if(operator.equals("46000") || operator.equals("46002")){  
//中國移動  
}else if(operator.equals("46001")){  
//中國聯通  
}else if(operator.equals("46003")){  
//中國電信 
}  
}  
在文件 AndroidManifest.xml中添加權限 

<uses-permission  android:name="android.permission.READ_PHONE_STATE"/> 

取得sim卡的網絡類型

  public String getNetworkTypeName() {
        switch (getNetworkType()) {
            case NETWORK_TYPE_GPRS:
                return "GPRS";
            case NETWORK_TYPE_EDGE:
                return "EDGE";
            case NETWORK_TYPE_UMTS:
                return "UMTS";
            case NETWORK_TYPE_HSDPA:
                return "HSDPA";
            case NETWORK_TYPE_HSUPA:
                return "HSUPA";
            case NETWORK_TYPE_HSPA:
                return "HSPA";
            case NETWORK_TYPE_CDMA:
                return "CDMA";
            case NETWORK_TYPE_EVDO_0:
                return "CDMA - EvDo rev. 0";
            case NETWORK_TYPE_EVDO_A:
                return "CDMA - EvDo rev. A";
            case NETWORK_TYPE_EVDO_B:
                return "CDMA - EvDo rev. B";
            case NETWORK_TYPE_1xRTT:
                return "CDMA - 1xRTT";
            default:
                return "UNKNOWN";
        }
    }

手機卡種類:

private String getSimType() {
        // 獲得SIMType   
        String simType = "";
        // 獲得系統服務,從而取得sim數據   
        TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); 
        int type = tm.getNetworkType();
        System.out.println(Contants.DEBUG+" NetWorkType:"+type);
        //Test1:聯通USIM卡,在這兒取出來的值為10-------NETWORK_TYPE_HSPA
        //Test2:中國移動 神州行OTA 2-----NETWORK_TYPE_EDGE
        //Test3:中國移動 動感地帶OTA 2-----NETWORK_TYPE_EDGE
        //...
 
        switch (type) {
            case TelephonyManager.NETWORK_TYPE_UNKNOWN://0
                simType= "UNKOWN";
                break;
            case TelephonyManager.NETWORK_TYPE_GPRS://1
                simType= "SIM";
                break;
            case TelephonyManager.NETWORK_TYPE_EDGE://2
                simType= "SIM";
                break;
            case TelephonyManager.NETWORK_TYPE_UMTS://3
                simType= "USIM";
                break;
            case TelephonyManager.NETWORK_TYPE_CDMA://4
                simType= "Either IS95A or IS95B Card";
                break;
            case TelephonyManager.NETWORK_TYPE_EVDO_0://5
                simType= "EVDO revision 0 Card";
                break;
            case TelephonyManager.NETWORK_TYPE_EVDO_A://6
                simType= "EVDO revision A Card";
                break;
            case TelephonyManager.NETWORK_TYPE_1xRTT://7
                simType= "1xRTT Card";
                break;
            case TelephonyManager.NETWORK_TYPE_HSDPA://8
                simType= "HSDPA Card";
                break;
            case TelephonyManager.NETWORK_TYPE_HSUPA://9
                simType= "HSUPA Card";
                break;
            case TelephonyManager.NETWORK_TYPE_HSPA://10
                simType= "USIM";
                break;
             
        }
        System.out.println(Contants.DEBUG+" sim type :"+simType);
        return simType;
    }
各種手機卡知識:http://bbs.csdn.net/topics/390199890

單態模式實例

一:public class Singleton {
  private Singleton(){}  //注意這是private 只供內部調用
  private static Singleton instance = new Singleton();  //這里提供了一個供外部訪問本class的靜態方法,可以直接訪問  
  public static Singleton getInstance() {
    return instance;   
  } 
}
二:public class Singleton {
  private static Singleton instance = null;
  public static synchronized Singleton getInstance() {//注意一定要加上關鍵字 synchronized  否則有可能得到多個Singleton實例
  if (instance==null){
    instance=new Singleton();
}
  return instance;
  }
}

修改 特殊字符的命令(工程命令,如展訊*#*#83789#*#*)

TwelveKeyDialer.java afterTextChanged->

SpecialCharSequenceMgr.java ->handleChars ->handleSecretCode

/**
     * Handles secret codes to launch arbitrary activities in the form of *#*#<code>#*#*.
     * If a secret code is encountered an Intent is started with the android_secret_code://<code>
     * URI.
     *
     * @param context the context to use
     * @param input the text to check for a secret code in
     * @return true if a secret code was encountered
     */
    static boolean handleSecretCode(Context context, String input) {
        // Secret codes are in the form *#*#<code>#*#*
        int len = input.length();
        if (len > 8 && input.startsWith("*#*#") && input.endsWith("#*#*")) {
            Intent intent = new Intent(Intents.SECRET_CODE_ACTION,
                    Uri.parse("android_secret_code://" + input.substring(4, len - 4)));
            context.sendBroadcast(intent);
            return true;
        }
        return false;
    }

makefile詳解

http://blog.csdn.net/zirconsdu/article/details/8005415

 

默認字體大小

 

frameworks/base/core/java/android/content/res/Configuration.java里面,有個fontScale=1

screen 默認拉伸大小  

settings->screen->Screen Scale

默認大小: DEFALUT_SCREEN_SCALE      手機存放路徑: /sys/class/graphics/fb0/scale 或 /sys/class/graphics/fb2/scale

ScreenScaleManager.cpp

#define MAIN_DISPLAY_SCALE_FILE"/sys/class/graphics/fb0/scale"
#define AUX_DISPLAY_SCALE_FILE"/sys/class/graphics/fb2/scale"

獲得圓角圖片的方法

 

[java]  view plain copy
 
  1. public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, float roundPx) {  
  2.   
  3. Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888);  
  4. Canvas canvas = new Canvas(output);  
  5.   
  6. final int color = 0xff424242;  
  7. final Paint paint = new Paint();  
  8. final Rect rect = new Rect(00, bitmap.getWidth(), bitmap.getHeight());  
  9. final RectF rectF = new RectF(rect);  
  10.   
  11. paint.setAntiAlias(true);  
  12. canvas.drawARGB(0000);  
  13. paint.setColor(color);  
  14. canvas.drawRoundRect(rectF, roundPx, roundPx, paint);  
  15.   
  16. paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));  
  17. canvas.drawBitmap(bitmap, rect, rect, paint);  
  18.   
  19. return output;  
  20. }  

網絡下載

 

[java]  view plain copy
 
  1. private Runnable mdownApkRunnable = new Runnable() {        
  2.         @Override    
  3.         public void run() {    
  4.             try {    
  5.                 URL url = new URL(apkUrl);    
  6.                 
  7.                 HttpURLConnection conn = (HttpURLConnection)url.openConnection();    
  8.                 conn.connect();    
  9.                 int length = conn.getContentLength();    
  10.                 InputStream is = conn.getInputStream();    
  11.                     
  12.                 File file = new File(savePath);    
  13.                 if(!file.exists()){    
  14.                     file.mkdir();    
  15.                 }    
  16.                 String apkFile = saveFileName;    
  17.                 File ApkFile = new File(apkFile);    
  18.                 FileOutputStream fos = new FileOutputStream(ApkFile);    
  19.                     
  20.                 int count = 0;    
  21.                 byte buf[] = new byte[1024];    
  22.                     
  23.                 do{                     
  24.                     int numread = is.read(buf);    
  25.                     count += numread;    
  26.                     progress =(int)(((float)count / length) * 100);    
  27.                     //更新進度    
  28.                     mHandler.sendEmptyMessage(DOWN_UPDATE);    
  29.                     if(numread <= 0){        
  30.                         //下載完成通知安裝    
  31.                         mHandler.sendEmptyMessage(DOWN_OVER);    
  32.                         break;    
  33.                     }    
  34.                     fos.write(buf,0,numread);    
  35.                 }while(!interceptFlag);//點擊取消就停止下載.    
  36.                     
  37.                 fos.close();    
  38.                 is.close();    
  39.             } catch (MalformedURLException e) {    
  40.                 e.printStackTrace();    
  41.             } catch(IOException e){    
  42.                 e.printStackTrace();    
  43.             }    
  44.                 
  45.         }    
  46.     };    
  47.         
  48.      /**  
  49.      * 下載apk  
  50.      * @param url  
  51.      */    
  52.         
  53.     private void downloadApk(){    
  54.         downLoadThread = new Thread(mdownApkRunnable);    
  55.         downLoadThread.start();    
  56.     }    

一個彈出AlertDialog實例、機器重啟(reboot)實例

 

[java]  view plain copy
 
  1. new AlertDialog.Builder(EthernetStaticIP.this)  
  2. <span style="white-space:pre">  </span>.setTitle(R.string.str_about)  
  3. <span style="white-space:pre">  </span>.setMessage(R.string.str_reboot)  
  4. <span style="white-space:pre">  </span>.setPositiveButton(R.string.str_ok,   
  5. <span style="white-space:pre">      </span> new DialogInterface.OnClickListener()  
  6. <span style="white-space:pre">      </span> {  
  7. <span style="white-space:pre">      </span>    public void onClick(DialogInterface dialoginterfacd,int i)  
  8. <span style="white-space:pre">      </span>    {  
  9. <span style="white-space:pre">      </span>    <span style="white-space:pre"> </span>//reboot  
  10. <span style="white-space:pre">      </span>    /*final static */String SYSTEMUI_REBOOT_ACTION = "com.android.systemui.reboot";  
  11.                 Intent intent = new Intent();  
  12.                 intent.setAction(SYSTEMUI_REBOOT_ACTION);  
  13.                 EthernetStaticIP.this.sendBroadcast(intent);  
  14. <span style="white-space:pre">      </span>    }  
  15. <span style="white-space:pre">      </span> }   
  16. <span style="white-space:pre">  </span>)  
  17. <span style="white-space:pre">  </span>.setNegativeButton(R.string.str_cancel,  
  18. <span style="white-space:pre">      </span> new DialogInterface.OnClickListener()  
  19. <span style="white-space:pre">  </span> {  
  20. <span style="white-space:pre">          </span>public void onClick(DialogInterface dialoginterfacd,int i)  
  21. <span style="white-space:pre">          </span>{  
  22. <span style="white-space:pre">              </span>finish();  
  23. <span style="white-space:pre">          </span>}  
  24. <span style="white-space:pre">  </span> }  <span style="white-space:pre">      </span>  
  25. <span style="white-space:pre">  </span>)  
  26. <span style="white-space:pre">  </span>.show();  

reboot代碼:

 

frameworks\base\services\java\com\android\server\wm\WindowManagerService.java   增加代碼 

 

[java]  view plain copy
 
  1. final static String SYSTEMUI_POWEROFF_ACTION = "com.android.systemui.poweroff";  
  2. final static String SYSTEMUI_REBOOT_ACTION = "com.android.systemui.reboot";  
  3. final BroadcastReceiver mAdditionalReceiver = new BroadcastReceiver() {  
  4.     @Override  
  5.     public void onReceive(Context context, Intent intent) {  
  6.         if(SYSTEMUI_POWEROFF_ACTION.equals(intent.getAction())){  
  7.             Log.d(TAG,"wms calling shutdown dlg from broadcast..");  
  8.             shutdown();//ShutdownThread.shutdown(context,true);  
  9.         }else if(SYSTEMUI_REBOOT_ACTION.equals(intent.getAction())){      
  10.             Log.d(TAG,"wms calling shutdown dlg from broadcast..");  
  11.             reboot();  
  12.         }  
  13.     }  
  14. };  
  15. public void shutdown() {  
  16.     ShutdownThread.shutdown(mContext, true);  
  17. }     
  18. public void reboot() {  
  19.     ShutdownThread.reboot(mContext, nullfalse);  
  20. }  

及注冊廣播接收

 

 

[java]  view plain copy
 
  1. IntentFilter f = new IntentFilter();  
  2. f.addAction(SYSTEMUI_POWEROFF_ACTION);  
  3. f.addAction(SYSTEMUI_REBOOT_ACTION);      
  4. mContext.registerReceiver(mAdditionalReceiver, f);  

獲得內存信息,cpu信息、頻率等

通過讀取文件/proc/cpuinfo系統CPU的類型等多種信息。
讀取/proc/stat 所有CPU活動的信息來計算CPU使用率 ,   "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq" 存儲最大頻率的文件的路徑, cpuinfo_min_freq最低頻率,scaling_cur_freq當前頻率

通過讀取文件/proc/meminfo的信息獲取Memory的總量。
ActivityManager. getMemoryInfo(ActivityManager.MemoryInfo)獲取當前的可用Memory量


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM