2015年5月24日 星期日

偵測耳機硬體鍵單擊雙擊判斷

以上一篇為例,還需準備一個共用class,在共用的class裡設置一個int count = 0;

當點擊硬體鍵時,共用class裡的count++,再搭配cTimer.schedule(cTimerTask,500);

執行後500毫秒才開始判斷count ==1 或==2 在傳遞訊息給主程式執行播放、暫停、下一首。



首先要在MainFest添加共用class:

<application
        android:name=".PP"
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:launchMode="singleInstance" >
<activity
.
.


共用class:

public class PP extends Application {

int count =0;
private MyHandler handler ;


    // 傳遞訊息的方法  
    public void setHandler(MyHandler handler) {
        this.handler = handler;
    }
     
    // 得到訊息方法  
    public MyHandler getHandler() {
        return handler;
    }
   
    //點擊硬體鍵count++
    public void addcount(){
    count++;
    }
   
    //得到硬體鍵點擊的次數
    public int getcount(){
    return count;
    }
   
    //回復count初始化
    public void recovercount(){
    count = 0;
    }
}



BroadcastReceiver.java

public class MediaButtonReceiver extends BroadcastReceiver {
private static final String TAG = "MediaButtonReceiver";
private PP pp ; //共用class
private static final int CHANGED = 0x0010;
private static final int CHANGEDNEXTSONG = 0x0011;
private MyHandler mHandler ;  
private boolean isStart = true;
private Timer cTimer = null;


@Override
public void onReceive(final Context context, Intent intent) {

// 獲得Action
String intentAction = intent.getAction();
// 獲得KeyEvent对象
KeyEvent keyEvent = (KeyEvent) intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
// 按下 / 鬆開按鈕
int keyAction = keyEvent.getAction();
pp = (PP)context.getApplicationContext();
mHandler = pp.getHandler();  

if (Intent.ACTION_MEDIA_BUTTON.equals(intentAction) && (KeyEvent.ACTION_DOWN == keyAction)) {

// 獲得按鍵字節碼
int keyCode = keyEvent.getKeyCode();

if (KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE == keyCode) {

}
if (KeyEvent.KEYCODE_HEADSETHOOK == keyCode) {
pp.addcount();
if (cTimer == null){
cTimer = new Timer();
cTimer.schedule(cTimerTask,500);
}
cTimer=null;

}
if (KeyEvent.KEYCODE_MEDIA_PREVIOUS == keyCode) {
}
if (KeyEvent.KEYCODE_MEDIA_STOP == keyCode) {
}
// 輸出點擊的按鍵碼
} else if (KeyEvent.ACTION_UP == keyAction) {

}

}

private TimerTask cTimerTask = new TimerTask() {
@Override
public void run() {
isStart = true;

if (isStart) {
if (pp.getcount() == 1 ){

// 發送消息,判斷當點1下,發送CHANGED到class,再由Activity接收
mHandler.sendEmptyMessage(CHANGED); 

} else if (pp.getcount() == 2 || pp.getcount() > 2){

                 // 發送消息,判斷當點2下,發送CHANGEDNEXTSONG到class,再由 Activity接收
mHandler.sendEmptyMessage(CHANGEDNEXTSONG);

}
pp.recovercount();//初始化共用count=0;

}
isStart = false;
}
};

}



Activity.java

public class PlayListActivity extends Activity {

private static final int CHANGED = 0x0010;
private static final int CHANGEDNEXTSONG = 0x0011;
        private MyHandler handler ; 

.
.


protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
                setContentView(R.layout.playlist);
listView = (ListView) findViewById(R.id.listView);
imgFront = (ImageView) findViewById(R.id.front);
imgPlay = (ImageView) findViewById(R.id.play);
imgPause = (ImageView) findViewById(R.id.pause);
.
.
.


                pp = (PP) getApplicationContext();
handler = new MyHandler();{
pp.setHandler(handler); 


}

.
.
.



public class MyHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if(msg.what == CHANGED) {

  // 當接收的訊息為CHANGED,也就是點一下,播放歌曲
           
}
            }  else if (msg.what == CHANGEDNEXTSONG){

 // 當接收的訊息為CHANGEDNEXTSONG,也就是點兩下,下一首
         
            }
        }
}










監聽耳機硬體鍵事件

出處:http://blog.csdn.net/shineflowers/article/details/44857549

在工作​​中,我們有時候會處理到耳機按鍵的邏輯,主要分為兩類,一種是短按,一種是長按。

監聽耳機的按鍵事件的方法有兩種:

方法一:註冊監聽Media Button的按鍵事件
此方法即使程式在背景情況下或鎖屏情況下,按線控耳機按鈕依然可控制歌曲播放。

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioManager;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;

public class MainActivity extends Activity {

private AudioManager mAudioManager;
private ComponentName mComponentName;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
// AudioManager註冊一個MediaButton對象
mComponentName = new ComponentName(getPackageName(), MediaButtonReceiver.class.getName());
}



@Override
protected void onResume() {
mAudioManager.registerMediaButtonEventReceiver(mComponentName); //註冊
registerReceiver(headSetReceiver, new IntentFilter(Intent.ACTION_HEADSET_PLUG)); 
//註冊
super.onResume();
}

@Override
protected void onPause() { 


//取消註冊,但若要背景下依然可控制歌曲播放的話,這兩項務必要移除掉。
mAudioManager.unregisterMediaButtonEventReceiver(mComponentName);
unregisterReceiver(headSetReceiver);
super.onPause();
}

@Override
protected void onDestroy() {
mAudioManager = null;
mComponentName = null;
super.onDestroy();
}

private final BroadcastReceiver headSetReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(Intent.ACTION_HEADSET_PLUG)) {
// phone headset plugged
if (intent.getIntExtra("state", 0) == 1) {
// do something
// Log.d(TAG, "耳機檢測:插入");
// Toast.makeText(context, "耳機檢測:插入", Toast.LENGTH_SHORT) .show();
mAudioManager.registerMediaButtonEventReceiver(mComponentName);
// phone head unplugged
} else {
// do something
// Log.d(TAG, "耳機檢測:没有插入");
// Toast.makeText(context, "耳機檢測:没有插入", Toast.LENGTH_SHORT).show();

mAudioManager.unregisterMediaButtonEventReceiver(mComponentName);
}
}
}
};



MediaButtonReceiver.java

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.view.KeyEvent;
import android.widget.Toast;

public class MediaButtonReceiver extends BroadcastReceiver {

private static String TAG = "MediaButtonReceiver";

@Override
public void onReceive(Context context, Intent intent) {
獲得
// 獲得Action
String intentAction = intent.getAction();
// KeyEvent對象 
KeyEvent keyEvent = (KeyEvent) intent
.getParcelableExtra(Intent.EXTRA_KEY_EVENT);

Log.i(TAG, "Action ---->" + intentAction + " KeyEvent----->" + keyEvent.toString());
// 按下 / 鬆開 按鈕 
int keyAction = keyEvent.getAction();

if (Intent.ACTION_MEDIA_BUTTON.equals(intentAction)
&& (KeyEvent.ACTION_DOWN == keyAction)) {
// 獲得按鍵字結碼 
int keyCode = keyEvent.getKeyCode();

// 獲得事件的時間
// long downtime = keyEvent.getEventTime();

// 獲得按件碼 keyCode
// StringBuilder sb = new StringBuilder();
//這些都是可能的按鍵碼,打印出來用戶按下的鍵
// if (KeyEvent.KEYCODE_MEDIA_NEXT == keyCode) {
// sb.append("KEYCODE_MEDIA_NEXT");
// }
// 說明:當我們按下MEDIA_BUTTON中間按鈕時,實際出發的是KEYCODE_HEADSETHOOK 而不是
// KEYCODE_MEDIA_PLAY_PAUSE

if (KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE == keyCode) {
// sb.append("KEYCODE_MEDIA_PLAY_PAUSE");

}
if (KeyEvent.KEYCODE_HEADSETHOOK == keyCode) {
// sb.append("KEYCODE_HEADSETHOOK");
}
if (KeyEvent.KEYCODE_MEDIA_PREVIOUS == keyCode) {
// sb.append("KEYCODE_MEDIA_PREVIOUS");
}
if (KeyEvent.KEYCODE_MEDIA_STOP == keyCode) {
// sb.append("KEYCODE_MEDIA_STOP");
}
//輸出點擊的按鍵碼
// Log.i(TAG, sb.toString());
// Toast.makeText(context, sb.toString(), Toast.LENGTH_SHORT).show();

} else if (KeyEvent.ACTION_UP == keyAction) {
Log.i("chengjie", "aaa");
}
}
}
注意,在AndroidManifest.xml中定義

<receiver android:name="com.lenovo.longexposure.MediaButtonReceiver" >
<intent-filter android:priority="2147483647" >
<action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter>
</receiver>


注意這種方法只能監聽耳機的短按事件,如果想監聽長按事件,請用方法二。

方法二:直接監聽onKeyDown方法



@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (KeyEvent.KEYCODE_HEADSETHOOK == keyCode) { //按下了耳機鍵
if (event.getRepeatCount() == 0) { //如果長按的话,getRepeatCount值會一值變大
//短按
} else {
//長按
}
}
}

--------------------------------分隔線-------------------------------------------------------------------

BroadcastReceiver基本使用方法:

BroadcastReceiver用於監聽被廣播的事件(Intent)

為了達到這個目的,BroadcastReceiver必須進行註冊,註冊方法有以下2種:

1. 在AndroidManifest.xml當中進行註冊

2. 在應用程式的代碼當中進行註冊

第一種方法:

activity_test.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.testbroadcastreceiver.TestActivity" >

    <Button
        android:id="@+id/sendButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="sendBroadcaster" />

</RelativeLayout>


TestActivity.java :

public class TestActivity extends Activity {

private Button sendButton;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);

sendButton = (Button) findViewById(R.id.sendButton);
sendButton.setOnClickListener(new BroadcastListener());
}

class BroadcastListener implements OnClickListener {

@Override
public void onClick(View v) {
System.out.println("發送intent");
    //宣告一個intent,把需要用到的廣播裝入intent再送出給Receive
    //,讓Receiver根據收到的廣播來處理自訂要做的事
Intent intent = new Intent();
intent.setAction(Intent.ACTION_EDIT);
TestActivity.this.sendBroadcast(intent);

}
}
}

TestReceiver.java:

public class TestReceiver extends BroadcastReceiver{

public TestReceiver(){
System.out.println("啟動TestReceiver");
}

@Override
public void onReceive(Context context, Intent intent) {
System.out.println("執行OnReceiver");
}

}

AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.testbroadcastreceiver"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="21" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".TestActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
     
          在這裡寫入TestReceiver,並把廣播動作都寫進去。
        <receiver android:name=".TestReceiver">
<intent-filter>
   <action android:name="android.intent.action.EDIT"/>
</intent-filter>            
        </receiver>
     
    </application>

</manifest>

執行結果:

發送intent

啟動TestReceiver

執行OnReceiver

第二種方法:

1 註冊BroadcastReceiver:

registerReceiver(receiver,filter);

2 取消註冊BroadcastReceiver(receiver);

如果一個BroadcastReceiver用於更新UI,那麼通常會使用這種方法進行註冊

在Activity啟動的時候註冊BroadcastReceiver,在Activity被摧毀以後取消註冊

activity_test.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.testbroadcastreceiver.TestActivity" >

    <Button
        android:id="@+id/registerButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="regBroadcaster" />

       <Button
        android:id="@+id/unregisterButton"
        android:layout_width="wrap_content"
        android:layout_below="@+id/registerButton"
        android:layout_height="wrap_content"
        android:text="UnBroadcaster" />
   
</RelativeLayout>

TestActivity.java:

public class TestActivity extends Activity {

private Button registerButton;
private Button unregisterButton;
private SMSReceiver smsReceiver = null ;
private static final String SMS_ACTION = "android.provider.Telephony.SMS_RECEIVED";

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);

registerButton = (Button) findViewById(R.id.registerButton);
unregisterButton = (Button) findViewById(R.id.unregisterButton);
registerButton.setOnClickListener(new RegisterButtonListener());
unregisterButton.setOnClickListener(new UnRegisterButtonListener());
}

class RegisterButtonListener implements OnClickListener {

@Override
public void onClick(View v) {
smsReceiver = new SMSReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(SMS_ACTION);
TestActivity.this.registerReceiver(smsReceiver, filter);
System.out.println("註冊廣播");
}
}

class UnRegisterButtonListener implements OnClickListener {

@Override
public void onClick(View v) {

System.out.println("取消註冊");


}
}
}

BroadcastReceiver.java

public class SMSReceiver extends BroadcastReceiver{

public SMSReceiver(){
System.out.println("啟動TestReceiver");
}

@Override
public void onReceive(Context context, Intent intent) {
System.out.println("執行OnReceiver");
}

}

當到DDMS的Emulator Control去記一封訊息,模擬器會收到訊息

2015年5月21日 星期四

權限大全

  1 android.permission.ACCESS_CHECKIN_PROPERTIES
  2 //允許讀寫訪問”properties”表在checkin數據庫中,改值可以修改上傳
  3
  4 android.permission.ACCESS_COARSE_LOCATION
  5 //允許一個程序訪問CellID或WiFi熱點來獲取粗略的位置
  6
  7 android.permission.ACCESS_FINE_LOCATION
  8 //允許一個程序訪問精良位置(如GPS)
  9
 10 android.permission.ACCESS_LOCATION_EXTRA_COMMANDS
 11 //允許應用程序訪問額外的位置提供命令
 12
 13 android.permission.ACCESS_MOCK_LOCATION
 14 //允許程序創建模擬位置提供用於測試
 15
 16 android.permission.ACCESS_NETWORK_STATE
 17 //允許程序訪問有關GSM網絡信息
 18
 19 android.permission.ACCESS_SURFACE_FLINGER
 20 //允許程序使用SurfaceFlinger底層特性
 21
 22 android.permission.ACCESS_WIFI_STATE
 23 //允許程序訪問Wi-Fi網絡狀態信息
 24
 25 android.permission.ADD_SYSTEM_SERVICE
 26 //允許程序發布系統級服務
 27
 28 android.permission.BATTERY_STATS
 29 //允許程序更新手機電池統計信息
 30
 31 android.permission.BLUETOOTH
 32 //允許程序連接到已配對的藍牙設備
 33
 34 android.permission.BLUETOOTH_ADMIN
 35 //允許程序發現和配對藍牙設備
 36
 37 android.permission.BRICK
 38 //請求能夠禁用設備(非常危險
 39
 40 android.permission.BROADCAST_PACKAGE_REMOVED
 41 //允許程序廣播一個提示消息在一個應用程序包已經移除後
 42
 43 android.permission.BROADCAST_STICKY
 44 //允許一個程序廣播常用intents
 45
 46 android.permission.CALL_PHONE
 47 //允許一個程序初始化一個電話撥號不需通過撥號用戶界面需要用戶確認
 48
 49 android.permission.CALL_PRIVILEGED
 50 //允許一個程序撥打任何號碼,包含緊急號碼無需通過撥號用戶界面需要用戶確認
 51
 52 android.permission.CAMERA
 53 //請求訪問使用照相設備
 54
 55 android.permission.CHANGE_COMPONENT_ENABLED_STATE
 56 //允許一個程序是否改變一個組件或其他的啟用或禁用
 57
 58 android.permission.CHANGE_CONFIGURATION
 59 //允許一個程序修改當前設置,如本地化
 60
 61 android.permission.CHANGE_NETWORK_STATE
 62 //允許程序改變網絡連接狀態
 63
 64 android.permission.CHANGE_WIFI_STATE
 65 //允許程序改變Wi-Fi連接狀態
 66
 67 android.permission.CLEAR_APP_CACHE
 68 //允許一個程序清楚緩存從所有安裝的程序在設備中
 69
 70 android.permission.CLEAR_APP_USER_DATA
 71 //允許一個程序清除用戶設置
 72
 73 android.permission.CONTROL_LOCATION_UPDATES
 74 //允許啟用禁止位置更新提示從無線模塊
 75
 76 android.permission.DELETE_CACHE_FILES
 77 //允許程序刪除緩存文件
 78
 79 android.permission.DELETE_PACKAGES
 80 //允許一個程序刪除包
 81
 82 android.permission.DEVICE_POWER
 83 //允許訪問底層電源管理
 84
 85 android.permission.DIAGNOSTIC
 86 //允許程序RW診斷資源
 87
 88 android.permission.DISABLE_KEYGUARD
 89 //允許程序禁用鍵盤鎖
 90
 91 android.permission.DUMP
 92 //允許程序返回狀態抓取信息從系統服務
 93
 94 android.permission.EXPAND_STATUS_BAR
 95 //允許一個程序擴展收縮在狀態欄,android開發網提示應該是一個類似Windows Mobile中的托盤程序
 96
 97 android.permission.FACTORY_TEST
 98 //作為一個工廠測試程序,運行在root用戶
 99
100 android.permission.FLASHLIGHT
101 //訪問閃光燈,android開發網提示HTC Dream不包含閃光燈
102
103 android.permission.FORCE_BACK
104 //允許程序強行一個後退操作是否在頂層activities
105
106 android.permission.FOTA_UPDATE
107 //暫時不了解這是做什麼使用的,android開發網分析可能是一個預留權限.
108
109 android.permission.GET_ACCOUNTS
110 //訪問一個帳戶列表在Accounts Service中
111
112 android.permission.GET_PACKAGE_SIZE
113 //允許一個程序獲取任何package佔用空間容量
114
115 android.permission.GET_TASKS
116 //允許一個程序獲取信息有關當前或最近運行的任務,一個縮略的任務狀態,是否活動等等
117
118 android.permission.HARDWARE_TEST
119 //允許訪問硬件
120
121 android.permission.INJECT_EVENTS
122 //允許一個程序截獲用戶事件如按鍵、觸摸、軌跡球等等到一個時間流,android 開發網提醒算是hook技術吧
123
124 android.permission.INSTALL_PACKAGES
125 //允許一個程序安裝packages
126
127 android.permission.INTERNAL_SYSTEM_WINDOW
128 //允許打開窗口使用系統用戶界面
129
130 android.permission.INTERNET
131 //允許程序打開網絡套接字
132
133 android.permission.MANAGE_APP_TOKENS
134 //允許程序管理(創建、催後、 z- order默認向z軸推移)程序引用在窗口管理器中
135
136 android.permission.MASTER_CLEAR
137 //目前還沒有明確的解釋,android開發網分析可能是清除一切數據,類似硬格機
138
139 android.permission.MODIFY_AUDIO_SETTINGS
140 //允許程序修改全局音頻設置
141
142 android.permission.MODIFY_PHONE_STATE
143 //允許修改話機狀態,如電源,人機接口等
144
145 android.permission.MOUNT_UNMOUNT_FILESYSTEMS
146 //允許掛載和反掛載文件系統可移動存儲
147
148 android.permission.PERSISTENT_ACTIVITY
149 //允許一個程序設置他的activities顯示
150
151 android.permission.PROCESS_OUTGOING_CALLS
152 //允許程序監視、修改有關播出電話
153
154 android.permission.READ_CALENDAR
155 //允許程序讀取用戶日曆數據
156
157 android.permission.READ_CONTACTS
158 //允許程序讀取用戶聯繫人數據
159
160 android.permission.READ_FRAME_BUFFER
161 //允許程序屏幕波或和更多常規的訪問幀緩衝數據
162
163 android.permission.READ_INPUT_STATE
164 //允許程序返回當前按鍵狀態
165
166 android.permission.READ_LOGS
167 //允許程序讀取底層系統日誌文件
168
169 android.permission.READ_OWNER_DATA
170 //允許程序讀取所有者數據
171
172 android.permission.READ_SMS
173 //允許程序讀取短信息
174
175 android.permission.READ_SYNC_SETTINGS
176 //允許程序讀取同步設置
177
178 android.permission.READ_SYNC_STATS
179 //允許程序讀取同步狀態
180
181 android.permission.REBOOT
182 //請求能夠重新啟動設備
183
184 android.permission.RECEIVE_BOOT_COMPLETED
185 //允許一個程序接收到
186
187 android.permission.RECEIVE_MMS
188 //允許一個程序監控將收到MMS彩信,記錄或處理
189
190 android.permission.RECEIVE_SMS
191 //允許程序監控一個將收到短信息,記錄或處理
192
193 android.permission.RECEIVE_WAP_PUSH
194 //允許程序監控將收到WAP PUSH信息
195
196 android.permission.RECORD_AUDIO
197 //允許程序錄製音頻
198
199 android.permission.REORDER_TASKS
200 //允許程序改變Z軸排列任務
201
202 android.permission.RESTART_PACKAGES
203 //允許程序重新啟動其他程序
204
205 android.permission.SEND_SMS
206 //允許程序發送SMS短信
207
208 android.permission.SET_ACTIVITY_WATCHER
209 //允許程序監控或控制activities已經啟動全局系統中
210
211 android.permission.SET_ALWAYS_FINISH
212 //允許程序控制是否活動間接完成在處於後台時
213
214 android.permission.SET_ANIMATION_SCALE
215 //修改全局信息比例
216
217 android.permission.SET_DEBUG_APP
218 //配置一個程序用於調試
219
220 android.permission.SET_ORIENTATION
221 //允許底層訪問設置屏幕方向和實際旋轉
222
223 android.permission.SET_PREFERRED_APPLICATIONS
224 //允許一個程序修改列表參數PackageManager.addPackageToPreferred() 和PackageManager.removePackageFromPreferred()方法
225
226 android.permission.SET_PROCESS_FOREGROUND
227 //允許程序當前運行程序強行到前台
228
229 android.permission.SET_PROCESS_LIMIT
230 //允許設置最大的運行進程數量
231
232 android.permission.SET_TIME_ZONE
233 //允許程序設置時間區域
234
235 android.permission.SET_WALLPAPER
236 //允許程序設置壁紙
237
238 android.permission.SET_WALLPAPER_HINTS
239 //允許程序設置壁紙hits
240
241 android.permission.SIGNAL_PERSISTENT_PROCESSES
242 //允許程序請求發送信號到所有顯示的進程中
243
244 android.permission.STATUS_BAR
245 //允許程序打開、關閉或禁用狀態欄及圖標Allows an application to open, close, or disable the status bar and its icons.
246
247 android.permission.SUBSCRIBED_FEEDS_READ
248 //允許一個程序訪問訂閱RSS Feed內容提供
249
250 android.permission.SUBSCRIBED_FEEDS_WRITE
251 //系統暫時保留改設置,android開發網認為未來版本會加入該功能。
252
253 android.permission.SYSTEM_ALERT_WINDOW
254 //允許一個程序打開窗口使用TYPE_SYSTEM_ALERT,顯示在其他所有程序的頂層(Allows an application to open windows using the type TYPE_SYSTEM_ALERT, shown on top of all other applications. )
255
256 android.permission.VIBRATE
257 //允許訪問振動設備
258
259 android.permission.WAKE_LOCK
260 //允許使用PowerManager的WakeLocks保持進程在休眠時從屏幕消失
261
262 android.permission.WRITE_APN_SETTINGS
263 //允許程序寫入API設置
264
265 android.permission.WRITE_CALENDAR
266 //允許一個程序寫入但不讀取用戶日曆數據
267
268 android.permission.WRITE_CONTACTS
269​​ //允許程序寫入但不讀取用戶聯繫人數據
270
271 android.permission.WRITE_GSERVICES
272 //允許程序修改Google服務地圖
273
274 android.permission.WRITE_OWNER_DATA
275 //允許一個程序寫入但不讀取所有者數據
276
277 android.permission.WRITE_SETTINGS
278 //允許程序讀取或寫入系統設置
279
280 android.permission.WRITE_SMS
281 //允許程序寫短信
282
283 android.permission.WRITE_SYNC_SETTINGS
284 //允許程序寫入同步設置

來電事件處理

以mp3Player為例:

先在AndroidMainfest裡設定攔截號碼權限:
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>

Activity:

public class MainActivity extends Activity {

private boolean isCellPlay;

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.playlist);
.
.
.


//偵聽來電事件
TelephonyManager phoneyMana = (TelephonyManager)

getSystemService(this.TELEPHONY_SERVICE);

phoneyMana.listen(new myPhoneStateListener(),PhoneStateListener.LISTEN_CALL_STATE);

}


/* 來電事件處理 */
private class myPhoneStateListener extends PhoneStateListener {
@Override
public void onCallStateChanged(int state, String incomingNumber) {
switch (state) {
case TelephonyManager.CALL_STATE_RINGING://來電時,要處理的動作
if (mediaplayer.isPlaying()) {

mediaplayer.pause(); //音樂暫停
isCellPlay = true;//標記來電時暫停

}
break;
case TelephonyManager.CALL_STATE_IDLE://掛斷電話時要處理的動作
if (isCellPlay) {
isCellPlay = false;
mediaplayer.start(); //音樂繼續播放
}
break;
}
}
}

MP3進度bar

在xml上建立一個seekbar:

 <SeekBar
          android:id="@+id/seekbar"
          android:layout_width="fill_parent"
          android:layout_height="wrap_content"
          android:layout_marginBottom="5dp"
           />

Activity主要有幾個關鍵:

boolean isStart ; 紀錄TimerTask是否要運行
boolean isfirst = true; 紀錄若是第一次開啟就new Timer();
總之當歌曲播完時就先暫停TimerTask運行,等到開始播放再運行TimerTask,不然bar會亂掉

public class PlayListActivity extends Activity {


private MediaPlayer mediaplayer;

private SeekBar seekbar;

private boolean isStart ;  //讓mTimerTask是否開始運行

private boolean isfirst = true;

private Timer mTimer ;
.
.
略...

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.playlist);

seekbar = (SeekBar) findViewById(R.id.seekbar);
.
.
略...

seekbar.setOnSeekBarChangeListener(new MySeekbar()); //bar綁定偵聽
.
.
.

//在播放部分
private void playSong(String path) {
try {
mediaplayer.reset();
mediaplayer.setDataSource(path); // 播放歌曲路徑
mediaplayer.prepare();
seekbar.setMax(mediaplayer.getDuration());//bar長度設為歌曲長度
if (isfirst) {  //第一次啟用產生new Timer();
mTimer = new Timer();
mTimer.schedule(mTimerTask, 0, 300);
isfirst=false;
}
isStart = true;
mediaplayer.start(); // 開始播放
mediaplayer.setOnCompletionListener(new OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {//撥放完後暫停TimerTask
isStart = false;
nextSong(); // 播放完後播下一首
}
});
} catch (IOException e) {
}
}

private TimerTask mTimerTask = new TimerTask() {  
        @Override  
        public void run() {    
            if(isStart) {   //如果isStart = true,開始運行
            seekbar.setProgress(mediaplayer.getCurrentPosition());
            }  //TimerTask會一直更新,使bar會隨著歌曲播放而改變bar位置
           
        }  
    };

         //進度條處理
class MySeekbar implements OnSeekBarChangeListener {

@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
// TODO Auto-generated method stub

}
               
                 //拖移進度條時,TimerTask暫停運行,不然在你沒放開手指前bar會一直亂跳
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
isStart = false; 
}
               
                //放開進度條時,TimerTask運行,歌曲會因為你拖移進度條放開後改變播放位置
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
isStart = true;
mediaplayer.seekTo(seekbar.getProgress());
}

}








2015年5月17日 星期日

android项目中刷新activity界面

出處: http://blog.csdn.net/cryhelyxx/article/details/24502025

android項目中在sqlite數據庫插入/更新/刪除數據後:


1. 刷新當前activity界面數據(手動刷新):

在activity類下新增一個refresh()方法:

/**
* 刷新, 這種刷新方法,只有一個Activity實例。
*/
public void refresh() {

onCreate(null);

}



2. 刷新另一個activity界面數據(自動刷新):

在涉及到sqlite3數據庫操作的activity類下重寫onResume()方法:(此處建議複習下activity的生命週期, 並了解下onResume()方法的使用)



/**
* 調用onCreate(), 目的是刷新數據,

* 從另一activity界面返回到該activity界面時, 此方法自動調用

*/
@Override

protected void onResume() {

super.onResume();

onCreate(null);

}

由此, 涉及到sqlite數據庫數據的插入/更新/刪除的activity的類, 建議像上面一樣重寫onResume()


方法, 這是本人在實踐中解決"刷新另一activity界面數據"的可行方法

2015年5月16日 星期六

Android使用全局變量傳遞數據

原文: http://www.cnblogs.com/xiaochao1234/p/4045632.html


ndroid中Application是用來保存全局變量的,在package創建的時候就存在了,

到所有的activity都被destroy掉之後才會被釋放掉。所以當我們需要全局變量的時候只要在

application中去實現,通過調用Context的getApplicationContext或者Activity的getApplication方

法來獲得一個Application對象,就可以設置或讀取全局變量的值。

啟動Application時,系統會創建一個PID,即進程ID,所有的Activity就會在此進程上運行。

那麽我們在Application創建的時候初始化全局變量,同一個應用的所有Activity都可以取到這

些全局變量的值,換句話說,我們在某一個Activity中改變了這些全局變量的值,那麽在同一

個應用的其他Activity中值就會改變。

實例演試:如果把輸入裏的內容設置為全局變量,那麽有下面兩種情況。




具體實現方法如下:

一. 新建共享的全局變量

新建一個共享變量的類WirelessApp,需要繼承Application

Java代碼 

package com.wirelessqa.testintent; 

import android.app.Application;
/**

* 繼承application,設置全局變量

* @author bixiaopeng 2013-2-18 上午11:32:19

*/

public class WirelessApp extends Application {

private String username;


public String getUsername() {
returnusername;
}


public void setUsername(String username) {
this.username = username;
}


}


二.配置AndroidMainifest.xml


AndroidMainifest.xml中聲明一下全局變量的類,這時Android就會建立一個全局可用的實例

Application屬性中設置android:name=".WirelessApp"



三.調用全局變量

可以在其它任何地方使用Content.getApplicationConext()來獲取這個實例,再來獲取全局變量


Java代碼

package com.wirelessqa.testintent;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText; 
 
public class MainActivity extends Activity { 
 
private EditText edit = null; 
 
private Button button = null; 
 
@Override 
 
protected void onCreate(Bundle savedInstanceState) { 
 
super.onCreate(savedInstanceState); 
 
setContentView(R.layout.activity_main); 
 
edit = (EditText)findViewById(R.id.edit); 
 
button = (Button)findViewById(R.id.btn_submit); 
 
button.setOnClickListener(new OnClickListener() {

@Override 
 
public void onClick(View v) { 
 
String result = edit.getText().toString(); 
 
//獲得應用程序實例
WirelessApp app = (WirelessApp)getApplicationContext(); 
 
//給全局變量賦值
app.setUsername(result); 
 
//啟動另一個activity
Intent intent = new Intent(MainActivity.this, ResultActivity.class);
startActivity(intent);
 
}); 
 
 
}


四.調用全局變量的值

Java代碼
package com.wirelessqa.testintent;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

/**
* 顯示結果的Activity
*
* @author bixiaopeng 2013-2-18 上午11:29:50
*/
public class ResultActivity extends Activity {

private TextView text = null;

@Override 
 
protected void onCreate(Bundle savedInstanceState) { 
 
super.onCreate(savedInstanceState); 
 
setContentView(R.layout.activity_result); 
 
//獲得應用程序實例
WirelessApp app = (WirelessApp) getApplicationContext(); 
 
String result = app.getUsername();//取值 
 
text = (TextView) findViewById(R.id.txt_result); 
 
text.setText(result); 
 
}

}

2015年5月8日 星期五

Android 禁止螢幕旋轉 & 螢幕旋轉不刷新 Activity & 動態更改螢幕方向

資料來源:http://jashliao.pixnet.net/blog/post/171083806-android-%E7%A6%81%E6%AD%A2%E8%9E%A2%E5%B9%95%E6%97%8B%E8%BD%89-%26-%E8%9E%A2%E5%B9%95%E6%97%8B%E8%BD%89%E4%B8%8D%E5%88%B7%E6%96%B0-activity-

一、禁止螢幕旋轉:

打開工程中的 AndroidManifest.xml 檔,在 <activity> </activity> 中,添加一條屬性資訊:

android:screenOrientation="portrait" (強制豎屏)

android:screenOrientation="landscape" (強制橫屏)

二、螢幕旋轉不刷新 Activity:

當螢幕旋轉時,會重新執行 Activity 中的 onCreate() 方法,即刷新了 Activity 的顯示。若是不

想刷新,可以用第一種方法鎖屏,也可以用以下方法:

1、打開工程中的 AndroidManifest.xml 檔,在 <activity> </activity> 中,添加一條屬性資訊:

android:configChanges=”orientation|keyboardHidden”

注:這個屬性指的是,當後邊屬性值代表的事件發生時,Activity 會執行某個函數,orientation 指的是當螢幕旋轉時,keyboardHidden 指的是鍵盤輔助功能改變。“|”為或符號,指這兩個中任意一個發生,就執行 Activity 某個函數。

注2:如果你的開發 API 等級等於或高於 13,你還需要設置 screenSize,因為 screenSize 會在螢幕旋轉時改變。

2、在對應 Activity 中重寫 onConfigurationChanged() 方法:

@Override

public void onConfigurationChanged(Configuration newConfig) {

// TODO Auto-generated method stub

super.onConfigurationChanged(newConfig);

if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {

// 什麼都不用寫
}

else {

// 什麼都不用寫

}
}

注:如果在 if、else 中,使用了 setContentView(R.layout.xxxx) 函數,那麼就可以實現:每次

螢幕旋轉時,調用不同的佈局。

三、動態更改螢幕方向:

有些時候,我們不需要把程式寫死,需要在程式中有需要的時候旋轉螢幕,例如:在“設
置”裏添加一個 ListView 項,可通過點擊選擇橫屏或豎屏。(比如:電子書軟體)

假設有一個按鈕,我們僅重寫 OnClick() 函數:

@Override

public void onClick(View v) {

// 如果是豎排,則改為橫排

if (getRequestedOrientation() == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}

// 如果是橫排,則改為豎排

else if (getRequestedOrientation() == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

}

}


重點就是:getRequestedOrientation() 函數、setRequestedOrientation() 函數的使用。

注意:使用這種方法,必須事先在 AndroidManifest.xml 的 <activity> </activity> 中,添加
android:screenOrientation 屬性值,不然 getRequestedOrientation() 可能會出問題。





2015年5月6日 星期三

HttpClient


出處:http://www.360doc.com/content/10/0805/11/61497_43814046.shtml

HttpClient 4 設置超時httpclient 超時有時httpclient的時候,需要等待N長時間,可能此時你決定放棄或者重試。實現上非常簡單添加一個參數即可httpClient.getParams().setIntParameter("http.socket.timeout",3000); 這裡的超時單位是毫秒。

這裡的http.socket.timeout相當於SO_TIMEOUT

HttpConnectionManagerParams managerParams = httpClient
.getHttpConnectionManager().getParams();
//設置連接超時時間(單位毫秒)
managerParams.setConnectionTimeout(30000);
//設置讀數據超時時間(單位毫秒)
managerParams.setSoTimeout(120000);


1,設置get方法請求超時為5 秒
Java代碼
GetMethod getMethod= new GetMethod(url);
getMethod.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, 5000 );
Java代碼
GetMethod getMethod= new GetMethod(url);
getMethod.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, 5000 );


2,設置Http 連接超時為5秒
Java代碼
HttpClient httpClient= new HttpClient();
httpClient.getHttpConnectionManager().getParams().setConnectionTimeout( 5000 );
Java代碼
HttpClient httpClient= new HttpClient();
httpClient.getHttpConnectionManager().getParams().setConnectionTimeout( 5000 );


設置連接超時和請求超時,這兩個超時的意義不同,需要分別設置。