Android悬浮框,在Service中打开悬浮窗;在Service中打开Dialog;

您所在的位置:网站首页 iqooneo悬浮窗怎么使用 Android悬浮框,在Service中打开悬浮窗;在Service中打开Dialog;

Android悬浮框,在Service中打开悬浮窗;在Service中打开Dialog;

2024-06-29 04:11| 来源: 网络整理| 查看: 265

文章介绍了如何在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开启成功后创建悬浮框

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

@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, Uri.parse("package:" + getPackageName()));//应用的包名,可直接跳转到这个应用的悬浮窗设置; 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); }

适配8.0:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { layoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; } else { layoutParams.type = WindowManager.LayoutParams.TYPE_PHONE; }   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(); } }

 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3