服務與控制介面(Activity)的互動---仿qq後台服務(一),activity後台
qq的後台服務,在我們按2下返回鍵,退出應用app後,訊息來了,會突破鎖屏,點亮螢幕,看見訊息彈出框,後面可以進行一系列的操作。qq的服務是不會被360殺死的,是屬於我們所說的流氓軟體,會在後台偷跑流量的,只有使用者手動在應用程式裡面關閉才行的。我所寫的demo,暫時不會有這個流氓軟體的功能的,以後如果有業務需求,也許會加上的,關於螢幕解鎖,不同的手機的解鎖方式是不同的迷宮解鎖,密碼解鎖...但是系統解鎖都是可以解的。還有就是因為急著出版本,所以這一版本暫時沒有突破鎖屏過後的彈出框,這個功能在下一版本會有的,我會繼續更新的。廢話也說了這麼多了,上代碼吧。
業務需求:
1.有個介面,上面有這幾個元素:
停止按鈕
開始按鈕
複位按鈕
進度條0%-100%
2.後台有個服務,包含以下邏輯:
有個進度值,初始是0%,最小是0%,最大是100%
初始狀態是停止的,什麼都不做
收到開始命令後,每秒增加1%的進度
收到停止命令後,停下進度增長,進度維持目前的數值,什麼都不做
收到複位命令後,將進度調整為0%
3.介面與服務的協作邏輯表達為用例如下:
開啟介面介面上什麼都不動,進度條為0
點開始,服務開始按內在邏輯走進度,並通知介面更新進度條控制項
點停止,服務中的進度邏輯停止
如果在進度走到20%的時候,退出介面(Home鍵、返回、熄屏、返回+熄屏),等待10秒再進入,應看到進度條處在30%的地方,且仍舊在走
停止時點複位,介面中的進度條應瞬間回到0%,且停留在0%
進行時點複位,介面中的進度條應瞬間回到0%,且繼續走
<span style="font-size:12px;">package com.example.localservice;import android.app.Activity;import android.app.KeyguardManager;import android.app.KeyguardManager.KeyguardLock;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.content.IntentFilter;import android.os.Bundle;import android.os.PowerManager;import android.util.Log;import android.view.View;import android.view.View.OnClickListener;import android.view.WindowManager;import android.widget.Button;import android.widget.ProgressBar;import android.widget.TextView;public class MainActivity extends Activity implements OnClickListener, Ctroller {private static final String TAG = "MainActivity";private ProgressBar progressBar;private Button startBtn;private Button stopBtn;private Button resetBtn;private TextView tx;private Intent intent = new Intent();private UpdateReceiver updateReceiver;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//動態註冊廣播接收器 updateReceiver = new UpdateReceiver(); IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction("com.example.localservice.UPDATE"); registerReceiver(updateReceiver, intentFilter); progressBar = (ProgressBar) findViewById(R.id.progressBar);startBtn = (Button) findViewById(R.id.start);stopBtn = (Button) findViewById(R.id.stop);resetBtn = (Button) findViewById(R.id.reset);tx = (TextView) findViewById(R.id.tx);startBtn.setOnClickListener(this);stopBtn.setOnClickListener(this);resetBtn.setOnClickListener(this);Intent in = new Intent(this, MyService.class);startService(in);//開機發送廣播,拿資料intent.setAction("com.example.localservice.NOTIFICATION");intent.putExtra("click", "data");sendBroadcast(intent);}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.start:intent.setAction("com.example.localservice.NOTIFICATION");intent.putExtra("click", "start");sendBroadcast(intent);break;case R.id.stop:intent.setAction("com.example.localservice.NOTIFICATION");intent.putExtra("click", "stop");sendBroadcast(intent);break;case R.id.reset:intent.setAction("com.example.localservice.NOTIFICATION");intent.putExtra("click", "reset");sendBroadcast(intent);break;}}public class UpdateReceiver extends BroadcastReceiver{@Overridepublic void onReceive(Context context, Intent intent) { //拿到進度,更新UI int progress = intent.getIntExtra("progress", 0); progressBar.setProgress(progress); tx.setText(progress + "%"); if(progress % 10 == 0){ SoundManager.getInstance(context).playSound(SoundManager.NETERROR); }else{ SoundManager.getInstance(context).stopSound(); } if(progress % 20 == 0){ lighten(); }else { } }}@Overrideprotected void onPause() {super.onPause();MyService.IS_DESTORY = false;}@Overrideprotected void onResume() {super.onResume();MyService.IS_DESTORY = false;}@Overrideprotected void onDestroy() {super.onDestroy();unregisterReceiver(updateReceiver);SoundManager.getInstance(this).stopSound();MyService.IS_DESTORY = true;Log.i(TAG, "------>>onDestroy");}/** * 點亮螢幕 */public void lighten() {PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);if (!pm.isScreenOn()) {// 擷取電源管理器對象PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP| PowerManager.SCREEN_DIM_WAKE_LOCK, "bright");// 點亮螢幕wl.acquire();if (!MyService.IS_DESTORY) {// 解鎖getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);} else {// 擷取電源管理器對象KeyguardManager km = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);// 得到鍵盤鎖管理器對象KeyguardLock kl = km.newKeyguardLock("unLock");// 解鎖kl.disableKeyguard();// kl.reenableKeyguard();// 重新啟用自動加鎖// wl.release();// 釋放}}}@Overridepublic void dismissKeyguard() {getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);}@Overridepublic void runOnUI(Runnable run) {runOnUiThread(run);}}</span>
<span style="font-size:12px;">package com.example.localservice;import android.app.KeyguardManager;import android.app.KeyguardManager.KeyguardLock;import android.app.Service;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.content.IntentFilter;import android.os.Bundle;import android.os.Handler;import android.os.IBinder;import android.os.Message;import android.os.PowerManager;import android.provider.Settings;import android.text.TextUtils;import android.view.WindowManager;public class MyService extends Service {public static final int MAX_PROGRESS = 100;private int progress = 0;private ServiceReciver serviceReciver;private int ok = 0;public static boolean IS_DESTORY = false;private Ctroller object;@Overridepublic IBinder onBind(Intent intent) {return null;}@Overridepublic void onCreate() {super.onCreate();// 動態註冊廣播接收器serviceReciver = new ServiceReciver();IntentFilter intentFilter = new IntentFilter();intentFilter.addAction("com.example.localservice.NOTIFICATION");registerReceiver(serviceReciver, intentFilter);}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {// TODO Auto-generated method stubreturn super.onStartCommand(intent, flags, startId);}@Overridepublic void onDestroy() {super.onDestroy();unregisterReceiver(serviceReciver);}/** * 類比下載任務,每秒鐘更新一次 */public void startDownLoad() {new Thread(new Runnable() {@Overridepublic void run() {while (ok < MAX_PROGRESS) {ok += 1;progress += 1;// 發送Action為com.example.localservice.UPDATE的廣播if(IS_DESTORY){Intent intent = new Intent(MyService.this, MainActivity.class);intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);startActivity(intent);Intent in = new Intent();in.putExtra("progress", progress);in.setAction("com.example.localservice.UPDATE");sendBroadcast(in);}else {Intent in = new Intent();in.putExtra("progress", progress);in.setAction("com.example.localservice.UPDATE");sendBroadcast(in);}try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}//if (progress % 20 == 0) {//lighten();//setBrightness();//}}}}).start();}public void stop() {Intent in = new Intent();in.putExtra("progress", progress);in.setAction("com.example.localservice.UPDATE");sendBroadcast(in);}public void reset() {progress = 0;Intent in = new Intent();in.putExtra("progress", progress);in.setAction("com.example.localservice.UPDATE");sendBroadcast(in);}public class ServiceReciver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {String extra = intent.getStringExtra("click");if ("data".equals(extra)) {Intent in = new Intent();in.putExtra("progress", progress);in.setAction("com.example.localservice.UPDATE");sendBroadcast(in);}if ("start".equals(extra)) {// myThread.start();ok = progress;startDownLoad();}if ("stop".equals(extra)) {ok = 101;stop();}if ("reset".equals(extra)) {reset();}}}//// 改變亮度//public static void SetLightness(Activity act, int value) {//try {//System.putInt(act.getContentResolver(), System.SCREEN_BRIGHTNESS,//value);//WindowManager.LayoutParams lp = act.getWindow().getAttributes();//lp.screenBrightness = (value <= 0 ? 1 : value) / 255f;//act.getWindow().setAttributes(lp);//} catch (Exception e) {//Toast.makeText(act, "無法改變亮度", Toast.LENGTH_SHORT).show();//}//}////// 擷取亮度//public static int GetLightness(Activity act) {//return System.getInt(act.getContentResolver(),//System.SCREEN_BRIGHTNESS, -1);//}/** * 點亮螢幕 */public void lighten() {PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);if (!pm.isScreenOn()) {// 擷取電源管理器對象PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP| PowerManager.SCREEN_DIM_WAKE_LOCK, "bright");// 點亮螢幕wl.acquire();if (!IS_DESTORY) {// 解鎖//kl.disableKeyguard();} else {Intent intent = new Intent(this, MainActivity.class);intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);startActivity(intent);// 擷取電源管理器對象KeyguardManager km = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);// 得到鍵盤鎖管理器對象KeyguardLock kl = km.newKeyguardLock("unLock");// 解鎖kl.disableKeyguard();// kl.reenableKeyguard();// 重新啟用自動加鎖// wl.release();// 釋放}}}/** * 改變螢幕亮度 */protected void setBrightness() {WindowManager.LayoutParams lp = ((MainActivity) object).getWindow().getAttributes();int brightness = Settings.System.getInt(((MainActivity) object).getContentResolver(), Settings.System.SCREEN_BRIGHTNESS, 0);// if(brightness <217)// lp.screenBrightness = 0.85f;// else// brightness += 10;// if(brightness > 255)// brightness = 60;lp.screenBrightness = brightness / 255.0f;((MainActivity) object).getWindow().setAttributes(lp);Settings.System.putInt(((MainActivity) object).getContentResolver(),Settings.System.SCREEN_BRIGHTNESS, brightness);}}</span>後面增加新的需求,如果進度條跑到10.20.30.40.50.60.70.80,90.100,會發出提示聲音。如果進度條跑到20.40.60.80.100,會點亮螢幕,解鎖。其實在updateReceiver中的
<span style="font-size:12px;">if(progress % 10 == 0){ SoundManager.getInstance(context).playSound(SoundManager.NETERROR); }else{ SoundManager.getInstance(context).stopSound(); } if(progress % 20 == 0){ lighten(); }else { }</span>應該放在服務中更好,我比較懶,在demo中就沒改了,好了,暫時就這麼多了,等下一版本吧。:http://download.csdn.net/detail/u012301841/8250881