這篇文章給大家介紹怎么在Android應用中實現一個全局返回功能,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
思路
廢話不多說了,說說主要的思路吧,關鍵的一個類就是:AccessibilityService,官方文檔地址,這個類與手機里面的一個功能密切相關:輔助功能-服務。官方文檔來看,這個功能是為了方便有障礙的人士更好的使用手機。我們這里就不展開介紹里面的API了,為了實現我們的全局返回功能,我們只需要使用一個函數即可: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.
翻譯過來就是:
執行全局動作。無論該應用程序中的當前應用程序或用戶位置如何,都可以隨時執行此類操作。例如執行HOME鍵,BACK鍵,任務鍵等
其中可以傳入的參數有四個:
從字面就可以理解,我們返回功能需要的就是GLOBAL_ACTION_BACK。所以我們只需要開啟服務,調用函數就可以實現全局返回功能了。
編寫代碼
最重要的服務類
我們要新建一個類去繼承自上面那個類:
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的訂閱函數,當其他地方發送消息之后,我們這里就可以收到,然后判斷是要執行后退還是回到桌面。
然后我們在AndroiManifest里面要注冊我們的服務,但是這個注冊的比較特殊:
首先加入權限聲明:
然后注冊服務:
<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中的內容我們要在xml包中聲明,首先新建一個xml包,如下:

然后新建一個accessibilityservice.xml文件,內容如下:
<?xml version="1.0" encoding="utf-8"?> <accessibility-service xmlns:android="http://schemas.android.com/apk/res/android" android:description="@string/start_floatingBall"/> <!--我這里寫的是開啟懸浮球功能-->
里面還可以設置許多屬性,在這里就不介紹了,有興趣的可以在官方文檔里面查看。
到時候description的顯示效果如下:

好了,到現在就已經完成了AccessibilityService服務的創建與注冊了,接下來在Activity中啟動服務就可以了: startService(new Intent(this,MyAccessibilityService.class));
使用EventBus傳遞事件即可實現返回:EventBus.getDefault().post(MyAccessibilityService.BACK);
但是要打開服務才行,簡單辦法是直接調用Intent跳到設置界面:startActivity(new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS));
或者手動進入設置->輔助功能->服務->找到自己的app,然后開啟服務即可。(不同的系統可能略有差異,小米就是在無障礙里面),界面如下:

懸浮球的簡單實現
1.自定義一個View,畫一個懸浮球:
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);
//畫大圓
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);
//畫小圓圈
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.WHITE);
canvas.drawCircle(width/2,width/2, (float) (width*1.0/4),paint);
}代碼很簡單,是畫了一個大圓,然后一個小點的圓圈。
接下來,把這個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, "點擊了懸浮球 執行后退操作", Toast.LENGTH_SHORT).show();
}
});
floatBall.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
EventBus.getDefault().post(MyAccessibilityService.HOME);
Toast.makeText(context, "長按了懸浮球 執行返回桌面", Toast.LENGTH_SHORT).show();
return false;
}
});
}
public int getScreenWidth() {
return windowManager.getDefaultDisplay().getWidth();
}
}為了簡單起見,就沒有貼上拖動懸浮窗的代碼了,如有需要,可以在文章末尾查看源碼。
上面代碼把view加入到window中,并給view設置了點擊事件,以及長按事件,向AccessibilityService傳遞消息,執行相應的事件。
要顯示懸浮窗,要聲明權限:
然后手動開啟權限!不然無法顯示懸浮窗。
最后我們在Activity中開啟我們自定義的懸浮窗即可:
ViewManager.getInstance(MainActivity.this).showFloatBall();
關于怎么在Android應用中實現一個全局返回功能就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。