最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android懸浮球及全局返回功能的實(shí)現(xiàn)示例

 更新時(shí)間:2017年04月21日 10:19:07   作者:CSU_IceLee  
這篇文章主要介紹了Android懸浮球及全局返回功能的實(shí)現(xiàn)示例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。

先來(lái)一發(fā)效果圖:

前面是返回效果,最后一下是實(shí)現(xiàn)home鍵的效果


前言

很久之前,就想做一個(gè)懸浮球了,畢竟是程序猿嘛,有想要的功能的時(shí)候總是想自己嘗試一下,于是興致勃勃的找了好久,都沒(méi)有找到全局返回功能該如何實(shí)現(xiàn)!最后也無(wú)疾而終,就在前兩天,又想到了這個(gè)功能,今天硬是花了好久,從一個(gè)同類軟件獲得了一點(diǎn)靈感,有一個(gè)關(guān)鍵的地方被我察覺(jué)到了,順著這個(gè)思路找了很多資料,便實(shí)現(xiàn)了全局返回功能。

思路

廢話不多說(shuō)了,說(shuō)說(shuō)主要的思路吧,關(guān)鍵的一個(gè)類就是:AccessibilityService,官方文檔地址,這個(gè)類與手機(jī)里面的一個(gè)功能密切相關(guān):輔助功能-服務(wù)。官方文檔來(lái)看,這個(gè)功能是為了方便有障礙的人士更好的使用手機(jī)。我們這里就不展開(kāi)介紹里面的API了,為了實(shí)現(xiàn)我們的全局返回功能,我們只需要使用一個(gè)函數(shù)即可:boolean performGlobalAction (int action),官方解釋如下:

Performs a global action. Such an action can be performed at any moment regardless of the current application or user location in that application. For example going back, going home, opening recents, etc.

翻譯過(guò)來(lái)就是:

執(zhí)行全局動(dòng)作。無(wú)論該應(yīng)用程序中的當(dāng)前應(yīng)用程序或用戶位置如何,都可以隨時(shí)執(zhí)行此類操作。例如執(zhí)行HOME鍵,BACK鍵,任務(wù)鍵等

其中可以傳入的參數(shù)有四個(gè):

  1. GLOBAL_ACTION_BACK
  2. GLOBAL_ACTION_HOME
  3. GLOBAL_ACTION_NOTIFICATIONS
  4. GLOBAL_ACTION_RECENTS

從字面就可以理解,我們返回功能需要的就是GLOBAL_ACTION_BACK。所以我們只需要開(kāi)啟服務(wù),調(diào)用函數(shù)就可以實(shí)現(xiàn)全局返回功能了。

編寫(xiě)代碼

最重要的服務(wù)類

我們要新建一個(gè)類去繼承自上面那個(gè)類:

public class MyAccessibilityService extends AccessibilityService {
 public static final int BACK = 1;
 public static final int HOME = 2;
 private static final String TAG = "ICE";

 @Override
 public void onCreate() {
 super.onCreate();
 //使用EventBus代替廣播
 EventBus.getDefault().register(this);
 }

 @Override
 public void onAccessibilityEvent(AccessibilityEvent event) { }

 @Override
 public void onInterrupt() {}

 @Subscribe
 public void onReceive(Integer action){
 switch (action){
 case BACK:
 performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK);
 break;
 case HOME:
 performGlobalAction(AccessibilityService.GLOBAL_ACTION_HOME);
 break;
 }
 }

}

上面的onReceive方法是我們使用EventBus的訂閱函數(shù),當(dāng)其他地方發(fā)送消息之后,我們這里就可以收到,然后判斷是要執(zhí)行后退還是回到桌面。

然后我們?cè)贏ndroiManifest里面要注冊(cè)我們的服務(wù),但是這個(gè)注冊(cè)的比較特殊:

首先加入權(quán)限聲明:

復(fù)制代碼 代碼如下:
<uses-permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE"/>

然后注冊(cè)服務(wù):

<service
 android:name=".MyAccessibilityService"
 android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
 <intent-filter>
 <action android:name="android.accessibilityservice.AccessibilityService"/>
 </intent-filter>
 <meta-data
 android:name="android.accessibilityservice"
 android:resource="@xml/accessibilityservice"/>
</service>

其中resource中的內(nèi)容我們要在xml包中聲明,首先新建一個(gè)xml包,如下:

然后新建一個(gè)accessibilityservice.xml文件,內(nèi)容如下:

<?xml version="1.0" encoding="utf-8"?>
<accessibility-service
 xmlns:android="http://schemas.android.com/apk/res/android"
 android:description="@string/start_floatingBall"/>

<!--我這里寫(xiě)的是開(kāi)啟懸浮球功能-->

里面還可以設(shè)置許多屬性,在這里就不介紹了,有興趣的可以在官方文檔里面查看。

到時(shí)候description的顯示效果如下:

好了,到現(xiàn)在就已經(jīng)完成了AccessibilityService服務(wù)的創(chuàng)建與注冊(cè)了,接下來(lái)在Activity中啟動(dòng)服務(wù)就可以了: startService(new Intent(this,MyAccessibilityService.class));

使用EventBus傳遞事件即可實(shí)現(xiàn)返回:EventBus.getDefault().post(MyAccessibilityService.BACK);

但是要打開(kāi)服務(wù)才行,簡(jiǎn)單辦法是直接調(diào)用Intent跳到設(shè)置界面:startActivity(new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS));

或者手動(dòng)進(jìn)入設(shè)置->輔助功能->服務(wù)->找到自己的app,然后開(kāi)啟服務(wù)即可。(不同的系統(tǒng)可能略有差異,小米就是在無(wú)障礙里面),界面如下:


懸浮球的簡(jiǎn)單實(shí)現(xiàn)

1.自定義一個(gè)View,畫(huà)一個(gè)懸浮球:

public class FloatingView extends View {

 public int height = 150;
 public int width = 150;
 private Paint paint;


 public FloatingView(Context context){
 super(context);
 paint = new Paint();
 }

 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
 super.onMeasure(widthMeasureSpec, heightMeasureSpec);
 setMeasuredDimension(height,width);
 }

 @Override
 protected void onDraw(Canvas canvas) {
 super.onDraw(canvas);
 //畫(huà)大圓
 paint.setStyle(Paint.Style.FILL);
 paint.setAntiAlias(true);
 paint.setColor(getResources().getColor(R.color.state_one));
 canvas.drawCircle(width/2,width/2,width/2,paint);
 //畫(huà)小圓圈
 paint.setStyle(Paint.Style.STROKE);
 paint.setColor(Color.WHITE);
 canvas.drawCircle(width/2,width/2, (float) (width*1.0/4),paint);

 }

代碼很簡(jiǎn)單,是畫(huà)了一個(gè)大圓,然后一個(gè)小點(diǎn)的圓圈。

接下來(lái),把這個(gè)view展示在桌面:

public class ViewManager {
 FloatingView floatBall;
 WindowManager windowManager;
 public static ViewManager manager;
 Context context;
 private WindowManager.LayoutParams floatBallParams;

 private ViewManager(Context context) {
 this.context = context;
 }

 public static ViewManager getInstance(Context context) {
 if (manager == null) {
 manager = new ViewManager(context);
 }
 return manager;
 }
 public void showFloatBall() {
 floatBall = new FloatingView(context);
 windowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
 if (floatBallParams == null) {
 floatBallParams = new WindowManager.LayoutParams();
 floatBallParams.width = floatBall.width;
 floatBallParams.height = floatBall.height;
 floatBallParams.gravity = Gravity.TOP | Gravity.LEFT;
 floatBallParams.type = WindowManager.LayoutParams.TYPE_TOAST;
 floatBallParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
 floatBallParams.format = PixelFormat.RGBA_8888;
 }

 windowManager.addView(floatBall, floatBallParams);

 floatBall.setOnClickListener(new View.OnClickListener() {
 @Override
 public void onClick(View v) {
 EventBus.getDefault().post(MyAccessibilityService.BACK);
 Toast.makeText(context, "點(diǎn)擊了懸浮球 執(zhí)行后退操作", Toast.LENGTH_SHORT).show();
 }
 });

 floatBall.setOnLongClickListener(new View.OnLongClickListener() {
 @Override
 public boolean onLongClick(View v) {
 EventBus.getDefault().post(MyAccessibilityService.HOME);
 Toast.makeText(context, "長(zhǎng)按了懸浮球 執(zhí)行返回桌面", Toast.LENGTH_SHORT).show();
 return false;
 }
 });

 }

 public int getScreenWidth() {
 return windowManager.getDefaultDisplay().getWidth();
 }

}

為了簡(jiǎn)單起見(jiàn),就沒(méi)有貼上拖動(dòng)懸浮窗的代碼了,如有需要,可以在文章末尾查看源碼。

上面代碼把view加入到window中,并給view設(shè)置了點(diǎn)擊事件,以及長(zhǎng)按事件,向AccessibilityService傳遞消息,執(zhí)行相應(yīng)的事件。

要顯示懸浮窗,要聲明權(quán)限:

復(fù)制代碼 代碼如下:

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

然后手動(dòng)開(kāi)啟權(quán)限!不然無(wú)法顯示懸浮窗。

最后我們?cè)贏ctivity中開(kāi)啟我們自定義的懸浮窗即可:

ViewManager.getInstance(MainActivity.this).showFloatBall();

結(jié)束語(yǔ)

現(xiàn)在看來(lái),實(shí)現(xiàn)一個(gè)全局返回功能真的非常簡(jiǎn)單,但是當(dāng)初就真的找了非常久,怎么找,怎么試都沒(méi)法實(shí)現(xiàn)這個(gè)功能,于是嘗試著去學(xué)學(xué)別的懸浮窗的代碼,但是沒(méi)辦法,加殼了,反編譯后沒(méi)法看。但是我注意到了一個(gè)細(xì)節(jié),它要我打開(kāi)服務(wù)才能使用懸浮窗的功能,所以就從這里下手,慢慢找到了實(shí)現(xiàn)全局返回的方法。

源碼地址:https://github.com/CHNicelee/FloatingBall

demo下載地址:FloatingBall_jb51.rar

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論

富裕县| 伊宁市| 越西县| 南靖县| 巢湖市| 华亭县| 玉门市| 日土县| 元江| 内乡县| 安多县| 土默特左旗| 南通市| 商丘市| 顺昌县| 泸州市| 惠安县| 舞钢市| 通城县| 阳信县| 屏山县| 驻马店市| 怀集县| 洛宁县| 磴口县| 佛冈县| 涿鹿县| 澎湖县| 龙岩市| 雷山县| 永年县| 巴青县| 沽源县| 马公市| 宁波市| 台中县| 织金县| 故城县| 疏勒县| 建宁县| 临清市|