Android浮動小球與開機自啓動

 

  看着手機上的360浮動小球,不評價其具體的功能與實用性,至少在UI設計與交互方面是個不小的創新。java

  

  如圖片左上角所示,球中還會顯示當前手機的運行情況,向下拉動還會有彈射來達到加速、清理等目的。android

  那好,先來實現一個相似的小球(僅限於形狀,功能你懂得)。安全

  查閱了相關資料,整個界面除了小球之外,其餘部分均是作透明處理。app

  一、因爲用到了CompatModeWrapper,因此須要在AndroidManifest.xml中添加如下權限:ide

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

  要想在應用中被啓動爲一個Activity或Service,須要註冊,這裏是Service:post

1 <service android:name=".Service1" />

 

  二、界面透明化處理,總體代碼以下:spa

 1 package com.XXX.autostart;  2 
 3 import android.view.View;  4 
 5 import android.app.Service;  6 import android.content.Intent;  7 import android.graphics.PixelFormat;  8 import android.os.Handler;  9 import android.os.IBinder;  10 import android.view.Gravity;  11 import android.view.LayoutInflater;  12 import android.view.MotionEvent;  13 import android.view.WindowManager;  14 import android.view.View.OnClickListener;  15 import android.view.View.OnTouchListener;  16 import android.view.WindowManager.LayoutParams;  17 import android.widget.ImageButton;  18 import android.widget.LinearLayout;  19 
 20 public class Service1 extends Service  21 {  22  LinearLayout mFloatLayout;  23  WindowManager.LayoutParams wmParams;  24  WindowManager mWindowManager;  25 
 26  ImageButton mFloatView;  27 
 28  @Override  29     public void onCreate()  30  {  31         // TODO Auto-generated method stub
 32         super.onCreate();  33 
 34  createFloatView();  35  }  36 
 37  @Override  38     public IBinder onBind(Intent intent)  39  {  40         // TODO Auto-generated method stub
 41         return null;  42  }  43 
 44     private void createFloatView()  45  {  46         wmParams = new WindowManager.LayoutParams();  47 
 48         mWindowManager = (WindowManager)getApplication().getSystemService(getApplication().WINDOW_SERVICE);  49 
 50         wmParams.type = LayoutParams.TYPE_PHONE;  51         wmParams.format = PixelFormat.RGBA_8888;  52 
 53         wmParams.flags = LayoutParams.FLAG_NOT_FOCUSABLE;  54 
 55         wmParams.gravity = Gravity.LEFT | Gravity.TOP;  56 
 57         wmParams.x = 0;  58         wmParams.y = 0;  59 
 60         wmParams.width = WindowManager.LayoutParams.WRAP_CONTENT;  61         wmParams.height = WindowManager.LayoutParams.WRAP_CONTENT;  62 
 63         LayoutInflater inflater = LayoutInflater.from(getApplication());  64         mFloatLayout = (LinearLayout) inflater.inflate(R.layout.float_layout, null);  65 
 66  mWindowManager.addView(mFloatLayout, wmParams);  67 
 68         mFloatView = (ImageButton)mFloatLayout.findViewById(R.id.float_id);  69 
 70         mFloatLayout.measure(View.MeasureSpec.makeMeasureSpec(0,  71  View.MeasureSpec.UNSPECIFIED), View.MeasureSpec  72                 .makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));  73 
 74 
 75         mFloatView.setOnTouchListener(new OnTouchListener() {  76  @Override  77             public boolean onTouch(View v, MotionEvent event) {  78                 // TODO Auto-generated method stub
 79 
 80                 wmParams.x = (int) event.getRawX() - mFloatView.getMeasuredWidth() / 2;  81 
 82                 wmParams.y = (int) event.getRawY() - mFloatView.getMeasuredHeight() / 2 - 25;  83 
 84  mWindowManager.updateViewLayout(mFloatLayout, wmParams);  85                 return false;  86  }  87  });  88 
 89         mFloatView.setOnClickListener(new OnClickListener() {  90 
 91  @Override  92             public void onClick(View v) {  93                 // TODO Auto-generated method stub
 94  mFloatView.setVisibility(View.INVISIBLE);  95 
 96                 Handler handler = new Handler();  97                 handler.postDelayed(new Runnable() {  98                     public void run() {  99  mFloatView.setVisibility(View.VISIBLE); 100  } 101                 }, 3000); 102 
103  } 104  }); 105  } 106 
107  @Override 108     public void onDestroy() 109  { 110         // TODO Auto-generated method stub
111         super.onDestroy(); 112         if(mFloatLayout != null) 113  { 114  mWindowManager.removeView(mFloatLayout); 115  } 116  } 117 
118 }

  這裏是利用ImageButton組件來實現小球,關鍵在於其顯示的圖片是圓形。設計

  所以,要想將浮動窗口實現爲其餘形狀,只需製做相應的圖片賦給組件。
code

  對於小球的功能,只是實現了在手機屏幕上隨意拖動,單擊消失三秒後重現。orm

 

  三、浮動小球有了,怎麼讓它啓動呢?注意上面實現的類Service1,繼承的是Service。

  在ManiActivity.java中,讓其顯現的方式很簡單,代碼以下:

1 finish(); 2 Intent intent = new Intent(getApplicationContext(), Service1.class); 3 startService(intent);

  注意,這裏對於MainActivity類不須要作任何處理,新建工程時默認就好。固然,要實現其餘功能例外。

  代碼finish();可加可不加,加上以後使得程序一運行就只剩下小球,原來的界面讓其消失。

  效果圖以下,圖形找的是紅色小火焰。

      

 

  四、到此,浮動小球就實現了,那怎麼讓它開機自啓動呢?

  其實也很簡單,用到了BroadcastReceiver。

  仍是先添加權限:

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

  另外,對於系統的廣播消息,要想在開機等時刻可以捕獲到,還需添加如下內容:

1 <receiver android:name=".BootBroadcastReceiver">
2         <intent-filter>
3                 <action android:name="android.intent.action.BOOT_COMPLETED" />
4         </intent-filter>
5 </receiver>

  實現代碼以下:

 1 package com.XXX.autostart;  2 
 3 import android.content.BroadcastReceiver;  4 import android.content.Context;  5 import android.content.Intent;  6 
 7 public class BootBroadcastReceiver extends BroadcastReceiver {  8 
 9     static final String ACTION = "android.intent.action.BOOT_COMPLETED"; 10 
11  @Override 12     public void onReceive(Context context, Intent intent) { 13 
14         if (intent.getAction().equals(ACTION)) { 15             Intent intent1 = new Intent(context, Service1.class); 16  intent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 17  context.startService(intent1); 18  } 19  } 20 }

  

  將手機ReBoot,能夠發現紅色小球會自行啓動,不過速度比較慢(和360安全衛士相比)。

相關文章
相關標籤/搜索