當(dāng)我們?cè)谑褂玫腶pp的時(shí)候,如果需要實(shí)時(shí)觀測(cè)到某個(gè)功能的實(shí)時(shí)進(jìn)度并且不影響其他的操作的時(shí)候或者不影響使用其他應(yīng)用的時(shí)候,系統(tǒng)級(jí)的懸浮球是個(gè)非常不錯(cuò)的選擇。
創(chuàng)新互聯(lián)專注于臺(tái)州網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗(yàn)。 熱誠(chéng)為您提供臺(tái)州營(yíng)銷型網(wǎng)站建設(shè),臺(tái)州網(wǎng)站制作、臺(tái)州網(wǎng)頁(yè)設(shè)計(jì)、臺(tái)州網(wǎng)站官網(wǎng)定制、小程序開發(fā)服務(wù),打造臺(tái)州網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供臺(tái)州網(wǎng)站排名全網(wǎng)營(yíng)銷落地服務(wù)。
public class QueueUpFloatService extends Service {
/**
* 啟動(dòng)服務(wù)并傳值
*
* @param activity 啟動(dòng)服務(wù)的activity
* @param modeBean 數(shù)據(jù)對(duì)象
*/
public static void launchService(Activity activity, ModeBean modeBean) {
try {
Intent intent =new Intent(activity, QueueUpFloatService.class);
? ? Bundle bundle =new Bundle();
? ? bundle.putSerializable(KEY_MODEL, modeBean);
? ? intent.putExtras(bundle);
? ? activity.startService(intent);
}catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
}
}
@Override
public void onCreate() {
super.onCreate();
//加一點(diǎn)簡(jiǎn)單的動(dòng)畫?
buttonScale = (ScaleAnimation) AnimationUtils.loadAnimation(this, R.anim.anim_float);
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
layoutParams =new WindowManager.LayoutParams();
if (Build.VERSION.SDK_INT = Build.VERSION_CODES.O) {
layoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
}else {
layoutParams.type = WindowManager.LayoutParams.TYPE_PHONE;
}
layoutParams.format = PixelFormat.RGBA_8888;
layoutParams.gravity = Gravity.LEFT | Gravity.TOP;
layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | ????????????WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
layoutParams.width = ScreenUtils.dp2px(66);
layoutParams.height = ScreenUtils.dp2px(66);
layoutParams.x = ScreenUtils.getRealWidth() - ScreenUtils.dp2px(60);
layoutParams.y = ScreenUtils.deviceHeight() *2 /3;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
ModeBean modeBean = (ModeBean) intent.getExtras().getSerializable(KEY_MODEL);
LayoutInflater layoutInflater = LayoutInflater.from(this);
floatView = layoutInflater.inflate(R.layout.view_float, null);
RelativeLayout rlFloatParent =floatView.findViewById(R.id.rl_float_parent);
rlFloatParent.startAnimation(buttonScale);
TextView tvIndex =floatView.findViewById(R.id.tv_queue_index);
tvIndex.setText(modeBean.title);
floatView.findViewById(R.id.iv_close_float).setOnClickListener(v - stopSelf());
//修改懸浮球的滑動(dòng)實(shí)現(xiàn)
floatView.setOnTouchListener(new FloatingOnTouchListener());
windowManager.addView(floatView, layoutParams);
return super.onStartCommand(intent, flags, startId);
}
private class FloatingOnTouchListenerimplements View.OnTouchListener {
private int x;
private int y;
private long downTime;
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouch(View view, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
downTime = System.currentTimeMillis();
? ? ? ? ? ? ????????x = (int) event.getRawX();
? ? ? ? ? ????????? y = (int) event.getRawY();
break;
? ? ? ????? case MotionEvent.ACTION_MOVE:
int nowX = (int) event.getRawX();
? ? ????????? ? ? ? int nowY = (int) event.getRawY();
? ? ? ????????? ? ? int movedX = nowX -x;
? ? ? ? ????????? ? int movedY = nowY -y;
? ? ? ? ????????? ? x = nowX;
? ? ? ? ? ????????? y = nowY;
? ? ? ? ? ????????? layoutParams.x =layoutParams.x + movedX;
? ? ? ? ? ? ????????layoutParams.y =layoutParams.y + movedY;
? ? ? ? ? ? ? ? ? ? windowManager.updateViewLayout(view, layoutParams);
break;
? ? ? ????? case MotionEvent.ACTION_UP:
/* *
* 這里根據(jù)手指按下和抬起的時(shí)間差來判斷點(diǎn)擊事件還是滑動(dòng)事件
* */
? ? ? ? ????????? ? if ((System.currentTimeMillis() -downTime) 200) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? //檢測(cè)應(yīng)用在前臺(tái)還是后臺(tái)
if (AppUtils.isAppIsInBackground()) {
AppUtils.moveToFront(CloseActivityUtils.activityList.get(CloseActivityUtils.activityList.size() -1).getClass());
? ? ? ? ? ? ? ????????????? } else {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //檢測(cè)棧頂是否為SecondActivity 不是就打開SecondActivity
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (!CloseActivityUtils.activityList.get(CloseActivityUtils.activityList.size() -1)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ????????????????.getClass().getSimpleName().contains("SecondActivity")) {
? ? ? ? ? ? ? ? ? ? ? ? ? ????????? SecondActivity.launchActivity(CloseActivityUtils.activityList.get(CloseActivityUtils.activityList.size() -1));
? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? }
}
break;
? ? ? ? default:
break;
? ? }
? ?return false;
}
}
@Override
public void onDestroy() {
super.onDestroy();
if (null ==floatView) {
return;
? ? ? ? ? ?}
windowManager.removeView(floatView);
? ? ? ? windowManager=null;
}
懸浮窗相信大家都不陌生,比如360手機(jī)衛(wèi)士的加速球,視頻應(yīng)用的小窗,可以占用很少的空間,又能保持跟用戶的交互。懸浮窗可以通過WindowManager.addView添加。具體用法可以看 Android懸浮窗用法總結(jié) ,按照這篇文章添加過懸浮窗之后,會(huì)發(fā)現(xiàn)有的手機(jī)上顯示不出來,這就是權(quán)限的問題了。
到這里,就明白我們只需要處理18=API23下某些rom的權(quán)限。
為什么某些rom那么特殊呢?
因?yàn)樵贏PI 18,Google新增了一個(gè)函數(shù)AppOpsManager,不過在這個(gè)版本,該函數(shù)是隱藏的 ( Android 4.3 隱藏功能 App Ops 分析 ),到API 19才公開。用這個(gè)函數(shù)可以對(duì)manifest申請(qǐng)的權(quán)限做一層限制,于是就有了360手機(jī)衛(wèi)士,小米安全中心。。。
檢測(cè)這些rom的權(quán)限,方法是一樣的,可以通過反射使用AppOpsManager.checkOp
檢測(cè)應(yīng)用是否有權(quán)限,可以防止異常,或者點(diǎn)擊事件沒反應(yīng)。為了給用戶提供更好地體驗(yàn),我們應(yīng)該引導(dǎo)用戶去權(quán)限設(shè)置頁(yè)面開啟權(quán)限。這些特殊rom的權(quán)限設(shè)置是不一樣的,所以需要先判斷手機(jī)rom,再分別去對(duì)應(yīng)的權(quán)限設(shè)置頁(yè)面。
具體方法見: Android判斷手機(jī)ROM
未完待續(xù)。。。
參考:
這個(gè)懸浮窗是一個(gè)類似于微信通話的小屏視頻框,利于Service開啟和保持。懸浮是利用WindowManager實(shí)現(xiàn)
你好,
android 手機(jī)讓浮動(dòng)窗口顯示的設(shè)置步驟:
點(diǎn)擊設(shè)置圖標(biāo)
點(diǎn)擊“設(shè)置”列表中“管理應(yīng)用程序”
找到要設(shè)置浮動(dòng)窗口的軟件
進(jìn)入“應(yīng)用程序信息”
點(diǎn)擊“應(yīng)用程序信息”最下面的“權(quán)限”
在“權(quán)限”頁(yè)面中勾選“顯示懸浮窗”。這樣就開啟了浮動(dòng)窗
android手機(jī)版本繁多,各個(gè)廠家的rom不一樣,設(shè)置也不一樣。
1、首先打開微信軟件app。
2、進(jìn)去后主頁(yè)后找到右下角的我的。
3、然后點(diǎn)擊一下。
4、進(jìn)去我的以后找到設(shè)置并點(diǎn)擊進(jìn)去。
5、找到顯示懸浮窗點(diǎn)擊一下并選擇小程序支付就開啟顯示懸浮窗了。
當(dāng)前標(biāo)題:android懸浮窗,android懸浮窗穿透
網(wǎng)頁(yè)URL:http://m.rwnh.cn/article46/dscodeg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站導(dǎo)航、做網(wǎng)站、Google、虛擬主機(jī)、軟件開發(fā)、網(wǎng)頁(yè)設(shè)計(jì)公司
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)