Android 案頭浮動框

來源:互聯網
上載者:User

    最近公司在做一個支付組件。持續做了一個月,我做了三個版本,現在項目突然終止,我也無事可做,就想把這個項目中用到的浮動框效果拿出來,曬一曬,鞏固知識的同時
也順便幫幫有需要的人,也不失為一件樂事。
    該浮動框其實挺簡單,就是一個開機廣播啟動一個後台Service,不斷的從記憶體中查看商城用戶端啟動,如果啟動,就發送一個廣播,運行支付組件;當商城退出時,支付組件
也退出。
    先看來:

(注意:該圖為私人收藏圖,請勿隨意轉載。)
    下面說說過程與核心代碼。
    一、服務隨著開機完成自動啟動。

        (1)、開機廣播接收者代碼。BootCompleteReceiver.java

public class BootCompleteReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {Log.i("BootCompleteReceiver", "接到開機廣播");Intent iAppServiceIntent = new Intent(context, AppService.class);context.startService(iAppServiceIntent);}}

上面代碼中的AppService.class是廣播接收者啟動的服務。
資訊清單檔內的許可權和註冊。
許可權

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

註冊

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

(2)、開機後啟動的服務AppService.java

public class AppService extends Service {private String TAG = "AppService";private RunningTaskInfo info;private static WindowManager wm;private ActivityManager am;private PackageManager pm;private String actionStart = "com.handaer.receiver.FLOAT_VIEW_START_ACTION"; //自訂action名字,private String actionStop = "com.handaer.receiver.FLOAT_VIEW_STOP_ACTION"; //自訂action名字Handler handler = new Handler();Timer timer = null;TimerTask task = new TimerTask() {public void run() {handler.post(new Runnable() {@Overridepublic void run() {getAppInfo();}});};};public int onStartCommand(Intent intent, int flags, int startId) {if (timer == null) {timer = new Timer();timer.scheduleAtFixedRate(task, 0, 500);}return super.onStartCommand(intent, flags, startId);};@Overridepublic IBinder onBind(Intent intent) {return null;}private void getAppInfo() {am = (ActivityManager) this.getSystemService(Context.ACTIVITY_SERVICE);pm = this.getPackageManager();ApplicationInfo actInfo;List<RunningTaskInfo> list = am.getRunningTasks(1);info = list.get(0);ComponentName cn = info.topActivity;String name = cn.getPackageName();try {actInfo = pm.getApplicationInfo(name, PackageManager.GET_META_DATA);Bundle metaData = actInfo.metaData;Log.i(TAG, "AppService正在運行");if (metaData != null) {String metaValue = metaData.getString("com.handaer.newhbddemo");if ("com.handaer.around".equals(metaValue)|| "com.handaer.pay".equals(metaValue)) {// 發送自訂廣播 com.handaer.receiver.FLOAT_VIEW_START_ACTIONIntent intent = new Intent();intent.setAction(actionStart);sendBroadcast(intent);}} else {// 發送自訂廣播 com.handaer.receiver.FLOAT_VIEW_STOP_ACTIONIntent intent = new Intent();intent.setAction(actionStop);Bundle bundle = new Bundle();sendBroadcast(intent);}   } catch (NameNotFoundException e) {e.printStackTrace();   }}}

getAppInfo()中的代碼是從記憶體中擷取任務棧第一個任務,然後通過ActivityManager擷取到其詳細資料中的name,然後判斷是否為商城應用,然後再做相應的處理。

(3)、下面是兩個自訂廣播FloatViewStartReceiver.java 和 FloatViewStopReceiver.java 

FloatViewStartReceiver比較簡單,就是啟動 FloatWeigtService服務

public class FloatViewStartReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {Log.i("FloatViewStartReceiver", "收到啟動廣播");Intent intentStart = new Intent(context, FloatWeigtService.class);try {context.startService(intentStart);} catch (Exception e) {e.printStackTrace();}}}

資訊清單檔中註冊:

<receiver android:name=".receiver.FloatViewStartReceiver" >            <intent-filter>                <action android:name="com.handaer.receiver.FLOAT_VIEW_START_ACTION" />            </intent-filter>        </receiver>

自訂廣播接收者FloatViewStopReceiver.java ,接收到廣播後會停止 FloatWeigtService 

public class FloatViewStopReceiver extends BroadcastReceiver {private RunningServiceInfo runningServiceInfo;private String serviceName = "com.handaer.hbdpay.service.FloatWeigtService";@Overridepublic void onReceive(Context context, Intent intent) {ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);PackageManager pm = context.getPackageManager();List<ActivityManager.RunningServiceInfo> serviceList = am.getRunningServices(Integer.MAX_VALUE);if (serviceList.size() == 0) {return;}for (int i = 0; i < serviceList.size(); i++) {runningServiceInfo = serviceList.get(i);if (runningServiceInfo.service.getClassName().equals(serviceName)) {ComponentName name = runningServiceInfo.service;Intent i2 = new Intent();i2.setComponent(name);try {context.stopService(i2);} catch (Exception e) {e.printStackTrace();}break;}}}}

在資訊清單檔註冊 FloatViewStopReceiver

 <receiver android:name=".receiver.FloatViewStopReceiver" >            <intent-filter>                <action android:name="com.handaer.receiver.FLOAT_VIEW_STOP_ACTION" />            </intent-filter>         </receiver>

 (4)、下面是 負責建立浮動框的 FloatWeigtService.java ,該服務會建立和取消浮動框。FloatView

public class FloatView extends LinearLayout {private WindowManager wm;public static int viewWidth;public static int viewHeight;private int screenWidth;private int width;private int yDown;private int xValueInView;private int yValueInView;private int xInScreen;private int yInScreen;private WindowManager.LayoutParams params;private ImageView iv_short;public FloatView(Context context) {super(context);wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);screenWidth = wm.getDefaultDisplay().getWidth();LayoutInflater inflater = LayoutInflater.from(context);View view = inflater.inflate(R.layout.float_view, this);iv_short = (ImageView) view.findViewById(R.id.iv_short);width = view.getWidth();LinearLayout deskView = (LinearLayout) view.findViewById(R.id.ll_base_title_view);viewWidth = deskView.getLayoutParams().width;viewHeight = deskView.getLayoutParams().height;}public void updataLocation() {params.x = (int) (xInScreen - xValueInView);params.y = (int) (yInScreen - yValueInView);wm.updateViewLayout(this, params);}public void setParams(WindowManager.LayoutParams params) {this.params = params;}@Overridepublic boolean onTouchEvent(MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN://按下浮動框後記錄浮動框的位置xValueInView = (int) event.getX();yValueInView = (int) event.getY();yDown = (int) event.getRawY();xInScreen = (int) event.getRawX();yInScreen = (int) (event.getRawY());break;case MotionEvent.ACTION_MOVE://移動浮動框時,不斷的更新浮動框updataLocation()xInScreen = (int) event.getRawX();yInScreen = (int) (event.getRawY());//只有浮動框移動位置才會更新。不加這段代碼,當按住浮動框時,浮動框會自己彈開一段距離。可能和我案頭有關係。int abs = Math.abs(yInScreen - yDown);if (abs != 0) {updataLocation();}break;case MotionEvent.ACTION_UP://抬起時,將浮動框靠螢幕右邊顯示。params.x = screenWidth;params.y = (int) (yInScreen - yValueInView);wm.updateViewLayout(this, params);break;default:break;}return true;}}

完。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.