詳解android6.0版本下懸浮窗實(shí)現(xiàn)
懸浮窗在安卓中實(shí)現(xiàn)起來還是比較容易的,這幾天在網(wǎng)上溫習(xí)了相關(guān)資料,運(yùn)行在我安卓6.0手機(jī)上才發(fā)現(xiàn),原來在6.0手機(jī)上不是行的。
第一反應(yīng)肯定是權(quán)限相關(guān)問題,做了相關(guān)處理后,果然讓懸浮窗原形畢露了。直接貼代碼。
public class MainActivity extends AppCompatActivity {
private static final int ALERT_WINDOW_PERMISSION_CODE = 100;
private Button start_float;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
start_float = (Button) findViewById(R.id.start_float);
this.start_float.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (Build.VERSION.SDK_INT > 22) {
sdk23Permission();
} else {
startService(new Intent(MainActivity.this, FloatService.class));
finish();
}
}
});
}
/**
* @description 安卓6.0下權(quán)限處理
* @author ldm
* @time 2017/3/20 15:00
*/
public void sdk23Permission() {
if (!Settings.canDrawOverlays(this)) {
Toast.makeText(MainActivity.this, "當(dāng)前無權(quán)限使用懸浮窗,請(qǐng)授權(quán)!", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, ALERT_WINDOW_PERMISSION_CODE);
} else {
startService(new Intent(MainActivity.this, FloatService.class));
finish();
}
}
/**
* 用戶返回
*/
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == ALERT_WINDOW_PERMISSION_CODE) {
if (!Settings.canDrawOverlays(this)) {
Toast.makeText(MainActivity.this, "權(quán)限授予失敗,無法開啟懸浮窗", Toast.LENGTH_SHORT).show();
} else {
startService(new Intent(MainActivity.this, FloatService.class));
finish();
}
}
}
}
對(duì)應(yīng)Service:
public class FloatService extends Service {
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
FloatViewUtils.getInstance(this).addFloatView();
super.onCreate();
}
}
簡(jiǎn)單地FloatView:
public class FloatView extends View {
public static final int WIDTH = 150;
public static final int HEIGHT = 150;
private Paint circlePaint;
private Paint textPaint;
private static final String text = "50%";
public FloatView(Context context) {
this(context, null, 0);
}
public FloatView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public FloatView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initPaints();
}
/**
* @description 初始化相關(guān)畫筆Paint
* @author ldm
* @time 2017/3/20
*/
private void initPaints() {
circlePaint = new Paint();
circlePaint.setAntiAlias(true);
circlePaint.setColor(Color.GRAY);
textPaint = new Paint();
//設(shè)置抗鋸齒
textPaint.setAntiAlias(true);
//設(shè)置字體大小
textPaint.setTextSize(30);
//設(shè)置顏色
textPaint.setColor(Color.WHITE);
//設(shè)置(仿)粗體
textPaint.setFakeBoldText(true);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(WIDTH, HEIGHT);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawCircle(WIDTH / 2, HEIGHT / 2, WIDTH / 2, circlePaint);
float textWidth = textPaint.measureText(text);
float x = WIDTH / 2 - textWidth / 2;
Paint.FontMetrics fms = textPaint.getFontMetrics();
float dy = -(fms.descent + fms.ascent) / 2;
float y = HEIGHT / 2 + dy;
canvas.drawText(text, x, y, textPaint);
}
}
以及FloatView管理工具類:
public class FloatViewUtils {
private static FloatViewUtils instance;
private Context mContext;
private WindowManager manager;
private FloatView floatView;
private FloatViewUtils(Context mContext) {
this.mContext = mContext;
manager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
floatView = new FloatView(mContext);
}
public static FloatViewUtils getInstance(Context mContext) {
if (null == instance) {
synchronized (FloatViewUtils.class) {
if (null == instance) {
instance = new FloatViewUtils(mContext);
}
}
}
return instance;
}
public void addFloatView() {
WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
//懸浮窗口大小
lp.width = floatView.WIDTH;
lp.height = floatView.HEIGHT;
// 調(diào)整懸浮窗口位置
lp.gravity = Gravity.LEFT | Gravity.CENTER;
// 以屏幕左上角為原點(diǎn),設(shè)置x、y初始值
// lp.x = 0;
// lp.y = 0;
//設(shè)置懸浮窗口類型
lp.type = WindowManager.LayoutParams.TYPE_PHONE;
//設(shè)置懸浮窗口不接受焦點(diǎn)及觸摸事件
lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
//設(shè)置圖片格式,效果為背景透明
lp.format = PixelFormat.RGBA_8888;
manager.addView(floatView, lp);
}
}
最后不要忘記在AndroidManifest.xml中添加權(quán)限(當(dāng)然還有注冊(cè)Service):
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- android 添加隨意拖動(dòng)的桌面懸浮窗口
- Android實(shí)現(xiàn)桌面懸浮窗、蒙板效果實(shí)例代碼
- 不依賴于Activity的Android全局懸浮窗的實(shí)現(xiàn)
- Android實(shí)現(xiàn)類似360,QQ管家那樣的懸浮窗
- Android 懸浮窗權(quán)限各機(jī)型各系統(tǒng)適配大全(總結(jié))
- android編程實(shí)現(xiàn)懸浮窗體的方法
- Android應(yīng)用內(nèi)懸浮窗的實(shí)現(xiàn)方案示例
- Android懸浮窗屏蔽懸浮窗外部所有的點(diǎn)擊事件的實(shí)例代碼
- Android中懸浮窗口的實(shí)現(xiàn)原理實(shí)例分析
- android實(shí)現(xiàn)可自由移動(dòng)、監(jiān)聽點(diǎn)擊事件的懸浮窗
相關(guān)文章
Android RecyclerView實(shí)現(xiàn)水平、垂直方向分割線
這篇文章主要為大家詳細(xì)介紹了Android RecyclerView實(shí)現(xiàn)水平、垂直方向分割線,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07
Android實(shí)現(xiàn)簡(jiǎn)易計(jì)算功能
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)簡(jiǎn)易計(jì)算功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-06-06
Android 實(shí)現(xiàn)按兩次返回鍵退出程序(兩種方法)
這篇文章主要介紹了Android 實(shí)現(xiàn)按兩次返回鍵退出程序(兩種方法)的相關(guān)資料,這里不僅實(shí)現(xiàn)還對(duì)原理進(jìn)行了分析,需要的朋友可以參考下2017-07-07
android計(jì)算器簡(jiǎn)單實(shí)現(xiàn)代碼
這篇文章主要為大家詳細(xì)介紹了android計(jì)算器的簡(jiǎn)單實(shí)現(xiàn)代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-03-03
Android開發(fā)Jetpack組件DataBinding用例詳解
這篇文章主要為大家介紹了Android開發(fā)Jetpack組件DataBinding的使案用例詳解說明,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2022-02-02
flutter實(shí)現(xiàn)頭部tabTop滾動(dòng)欄
這篇文章主要為大家詳細(xì)介紹了flutter實(shí)現(xiàn)頭部tabTop滾動(dòng)欄,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03
Android自定義Chronometer實(shí)現(xiàn)短信驗(yàn)證碼秒表倒計(jì)時(shí)功能
這篇文章主要介紹了Android自定義ChronometerView實(shí)現(xiàn)類似秒表倒計(jì)時(shí),短信驗(yàn)證碼倒計(jì)時(shí)功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-11-11
android實(shí)現(xiàn)定時(shí)拍照功能
這篇文章主要為大家詳細(xì)介紹了android實(shí)現(xiàn)定時(shí)拍照功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-05-05
Android通過應(yīng)用程序創(chuàng)建快捷方式的方法
這篇文章主要介紹了Android通過應(yīng)用程序創(chuàng)建快捷方式的方法,涉及Android基于應(yīng)用程序創(chuàng)建快捷方式的圖標(biāo)及動(dòng)作等技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-09-09

