博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android悬浮框,在Service中打开悬浮窗;在Service中打开Dialog;
阅读量:5355 次
发布时间:2019-06-15

本文共 11422 字,大约阅读时间需要 38 分钟。

文章介绍了如何在Service中显示悬浮框,在Service中弹出Dialog,在Service中做耗时的轮询操作;

背景需求:

公司的项目现在的逻辑是这样的:发送一个指令,然后3秒一次轮询去查询这个指令是否成功,在这期间界面有遮盖不可操作;

然后需求改了,因为遮盖界面不让用户操作体验不好;现在的需求是:这个轮询查询指令是否成功的操作在后端进行,界面有一个悬浮框用来提示用户正在查询指令;

嗯,在后端查询指令让用户无感,可以用Service实现,然后悬浮框使用WindowMessage实现,轮询查询指令使用Handler或IntentService实现;大致就是这样,先来个Demo;

1、开启服务:需要的信息由Activity使用Intent传递给Service;

Intent intent = new Intent(this,MyService.class);        intent.putExtra("args","晨");        startService(intent);
public class MyService extends Service {    public MyService() {    }    @Override    public IBinder onBind(Intent intent) {        throw new UnsupportedOperationException("Not yet implemented");    }    @Override    public void onCreate() {        super.onCreate();    }    @Override    public int onStartCommand(Intent intent, int flags, int startId) {       args = intent.getStringExtra("args");        return super.onStartCommand(intent, flags, startId);    }    @Override    public void onDestroy() {        super.onDestroy();    }}

Service中的onCreate只在创建的时候执行一次,onStartCommand()每次开启这个Service都会执行;同时别忘记这个注册:

2、在Service开启成功后创建悬浮框,

@Override    public int onStartCommand(Intent intent, int flags, int startId) {       args = intent.getStringExtra("args");       initView();        return super.onStartCommand(intent, flags, startId);    } /**     * 使用系统级别的WindowManager展示悬浮框,需要6.0以上的权限;     */    private void initView() {        if (Build.VERSION.SDK_INT >= 23) {            if (!Settings.canDrawOverlays(this)) {                Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                intent.setData(Uri.parse( "package:"+"com.example.administrator.xuanfudemo"));  //应用的包名,可直接跳转到这个应用的悬浮窗设置;                startActivity(intent);            } else {                openWindow();            }        }else {            openWindow();        }    }    private void openWindow(){        windowManager = (WindowManager) this.getSystemService(WINDOW_SERVICE);        WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();        layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;        layoutParams.width = ViewGroup.LayoutParams.WRAP_CONTENT;        layoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;//        layoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;//        layoutParams.token = this.getWindow().getDecorView().getWindowToken();  //这样设置,在activity中打开悬浮框可绕过权限;        layoutParams.flags =  WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;        layoutParams.format = PixelFormat.TRANSLUCENT;  //透明        layoutParams.gravity = Gravity.TOP | Gravity.RIGHT;  //右上角显示        view = LayoutInflater.from(this).inflate(R.layout.view_win,null);        windowManager.addView(view,layoutParams);    }

悬浮框需要权限,而且这个权限属于危险级权限,API23以上需要用户手动开启;

3、使用Handler轮询查询指令;

查询到指令后弹框提示,弹出Dialog。在Service中弹出Dialog需要设置下方代码,同时还要有弹窗权限;

dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
private Handler mHandler = new Handler(){        @Override        public void dispatchMessage(Message msg) {            super.dispatchMessage(msg);            switch (msg.what){                case HANDLERSIGN:                    Log.i(TAG, "dispatchMessage: "+args+(++num));                    mHandler.sendEmptyMessageDelayed(HANDLERSIGN,HANDLERTIME);                    if (num == 5){                        AlertDialog.Builder builder = new AlertDialog.Builder(MyService.this);                        builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {                            @Override                            public void onClick(DialogInterface dialogInterface, int i) {                                MyService.this.stopSelf();                            }                        });                        AlertDialog dialog = builder.create();                        dialog.setMessage("我的计数"+num);                        dialog.setTitle("提示");                        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);                        dialog.show();                    }                    break;            }        }    };    private final String TAG = "ccb";    private String args;    private int num;    private final int HANDLERSIGN = 10;    private final int HANDLERTIME = 2010;    @Override    public int onStartCommand(Intent intent, int flags, int startId) {       args = intent.getStringExtra("args");       initView();        initData();        return super.onStartCommand(intent, flags, startId);    }  private void initData() {        mHandler.sendEmptyMessageDelayed(HANDLERSIGN,HANDLERTIME);    }

4、在服务销毁时,清空Handler信息关闭悬浮框;

@Override    public void onDestroy() {        super.onDestroy();        Log.i(TAG, "onDestroy: 啊,ByKill");        mHandler.removeCallbacksAndMessages(null);        if (windowManager != null) windowManager.removeView(view);    }

全部的Service代码:

悬浮框我使用了两种,另外一种是FloatWindow,有兴趣的可以去GitHub查一下;

package com.example.administrator.xuanfudemo;import android.Manifest;import android.app.AlertDialog;import android.app.Service;import android.content.DialogInterface;import android.content.Intent;import android.graphics.PixelFormat;import android.net.Uri;import android.os.Build;import android.os.Handler;import android.os.IBinder;import android.os.Message;import android.provider.Settings;import android.support.v4.app.ActivityCompat;import android.util.Log;import android.view.Gravity;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.view.WindowManager;import com.yhao.floatwindow.FloatWindow;import com.yhao.floatwindow.PermissionListener;import com.yhao.floatwindow.Screen;import com.yhao.floatwindow.ViewStateListener;public class MyService extends Service {    private WindowManager windowManager;    private View view;    public MyService() {    }    @Override    public IBinder onBind(Intent intent) {        throw new UnsupportedOperationException("Not yet implemented");    }    @Override    public void onCreate() {        super.onCreate();    }    private Handler mHandler = new Handler(){        @Override        public void dispatchMessage(Message msg) {            super.dispatchMessage(msg);            switch (msg.what){                case HANDLERSIGN:                    Log.i(TAG, "dispatchMessage: "+args+(++num));                    mHandler.sendEmptyMessageDelayed(HANDLERSIGN,HANDLERTIME);                    if (num == 5){                        AlertDialog.Builder builder = new AlertDialog.Builder(MyService.this);                        builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {                            @Override                            public void onClick(DialogInterface dialogInterface, int i) {                                MyService.this.stopSelf();//                                if (windowManager != null) windowManager.removeView(view);                            }                        });                        AlertDialog dialog = builder.create();                        dialog.setMessage("我的计数"+num);                        dialog.setTitle("提示");                        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);                        dialog.show();                    }                    break;            }        }    };    private final String TAG = "ccb";    private String args;    private int num;    private final int HANDLERSIGN = 10;    private final int HANDLERTIME = 2010;    @Override    public int onStartCommand(Intent intent, int flags, int startId) {       args = intent.getStringExtra("args");//       initView();       initView2();        initData();        return super.onStartCommand(intent, flags, startId);    }    /**     * FloatWindow使用FloatWindow库展示悬浮框;可拖拽     */    private void initView2() {        FloatWindow                .with(getApplicationContext())                .setView(LayoutInflater.from(this).inflate(R.layout.view_win,null))                .setWidth(100)                               //设置控件宽高                .setHeight(Screen.height,0.2f)                .setX(100)                                   //设置控件初始位置                .setY(Screen.height,0.3f)                .setDesktopShow(true)                        //桌面显示                .setViewStateListener(new ViewStateListener() {                    @Override                    public void onPositionUpdate(int i, int i1) {                    }                    @Override                    public void onShow() {                    }                    @Override                    public void onHide() {                    }                    @Override                    public void onDismiss() {                    }                    @Override                    public void onMoveAnimStart() {                    }                    @Override                    public void onMoveAnimEnd() {                    }                    @Override                    public void onBackToDesktop() {                    }                })                .setPermissionListener(new PermissionListener() {                    @Override                    public void onSuccess() {                    }                    @Override                    public void onFail() {                    }                })                .build();        FloatWindow.get().show();    }    /**     * 使用系统级别的WindowManager展示悬浮框,需要6.0以上的权限;     */    private void initView() {        if (Build.VERSION.SDK_INT >= 23) {            if (!Settings.canDrawOverlays(this)) {                Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                intent.setData(Uri.parse( "package:"+"com.example.administrator.xuanfudemo"));                startActivity(intent);            } else {                openWindow();            }        }else {            openWindow();        }    }    private void openWindow(){        windowManager = (WindowManager) this.getSystemService(WINDOW_SERVICE);        WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();        layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;        layoutParams.width = ViewGroup.LayoutParams.WRAP_CONTENT;        layoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;//        layoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;//        layoutParams.token = this.getWindow().getDecorView().getWindowToken();        layoutParams.flags =  WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;        layoutParams.format = PixelFormat.TRANSLUCENT;        layoutParams.gravity = Gravity.TOP | Gravity.RIGHT;        view = LayoutInflater.from(this).inflate(R.layout.view_win,null);        windowManager.addView(view,layoutParams);    }    private void initData() {        mHandler.sendEmptyMessageDelayed(HANDLERSIGN,HANDLERTIME);    }    @Override    public void onDestroy() {        super.onDestroy();        Log.i(TAG, "onDestroy: 啊,ByKill");        mHandler.removeCallbacksAndMessages(null);        if (windowManager != null) windowManager.removeView(view);        FloatWindow.destroy();    }}

 

转载于:https://www.cnblogs.com/cuichen16/p/10785960.html

你可能感兴趣的文章
Linux常用命令(七)
查看>>
Linux常用命令(九)
查看>>
Linux常用命令(十一)
查看>>
Linux常用命令(十)
查看>>
实验吧之这就是一个坑
查看>>
Linux常用命令(十二)
查看>>
Linux常用命令(十三)
查看>>
Linux常用命令(十五)
查看>>
Linux常用命令(十四)
查看>>
Linux常用命令(十七)
查看>>
Linux常用命令(十六)
查看>>
Linux常用命令(二十四)
查看>>
4种java定时器
查看>>
Vue.js 教程
查看>>
linux 设置网卡
查看>>
hive 语法 case when 语法
查看>>
Ajax:js读取txt内容(json格式内容)
查看>>
Task 7 买书最低价格问题
查看>>
Selenium3+python自动化007-警告框
查看>>
html5 相同形状的图形进行循环
查看>>