Android浮动小球与开机自启动
看着手机上的360浮动小球,不评价其具体的功能与实用性,至少在UI设计与交互方面是个不小的创新。
如图片左上角所示,球中还会显示当前手机的运行状况,向下拉动还会有弹射来达到加速、清理等目的。
那好,先来实现一个类似的小球(仅限于形状,功能你懂得)。
查阅了相关资料,整个界面除了小球以外,其他部分均是做透明处理。
1、由于用到了CompatModeWrapper,所以需要在AndroidManifest.xml中添加以下权限:
1 <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
要想在应用中被启动为一个Activity或Service,需要注册,这里是Service:
1 <service android:name=".Service1" />
2、界面透明化处理,整体代码如下:
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组件来实现小球,关键在于其显示的图片是圆形。
因此,要想将浮动窗口实现为其他形状,只需制作相应的图片赋给组件。
对于小球的功能,只是实现了在手机屏幕上随意拖动,单击消失三秒后重现。
3、浮动小球有了,怎么让它启动呢?注意上面实现的类Service1,继承的是Service。
在ManiActivity.java中,让其显现的方式很简单,代码如下:
1 finish();
2 Intent intent = new Intent(getApplicationContext(), Service1.class);
3 startService(intent);
注意,这里对于MainActivity类不需要做任何处理,新建工程时默认就好。当然,要实现其他功能例外。
代码finish();可加可不加,加上之后使得程序一运行就只剩下小球,原来的界面让其消失。
效果图如下,图形找的是红色小火焰。
4、到此,浮动小球就实现了,那怎么让它开机自启动呢?
其实也很简单,用到了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安全卫士相比)。