詳解android6.0版本下懸浮窗實現(xiàn)
懸浮窗在安卓中實現(xiàn)起來還是比較容易的,這幾天在網(wǎng)上溫習了相關(guān)資料,運行在我安卓6.0手機上才發(fā)現(xiàn),原來在6.0手機上不是行的。
第一反應(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, "當前無權(quán)限使用懸浮窗,請授權(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(); } } } }
對應(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(); } }
簡單地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; // 以屏幕左上角為原點,設(shè)置x、y初始值 // lp.x = 0; // lp.y = 0; //設(shè)置懸浮窗口類型 lp.type = WindowManager.LayoutParams.TYPE_PHONE; //設(shè)置懸浮窗口不接受焦點及觸摸事件 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)限(當然還有注冊Service):
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
- android 添加隨意拖動的桌面懸浮窗口
- Android實現(xiàn)桌面懸浮窗、蒙板效果實例代碼
- 不依賴于Activity的Android全局懸浮窗的實現(xiàn)
- Android實現(xiàn)類似360,QQ管家那樣的懸浮窗
- Android 懸浮窗權(quán)限各機型各系統(tǒng)適配大全(總結(jié))
- android編程實現(xiàn)懸浮窗體的方法
- Android應(yīng)用內(nèi)懸浮窗的實現(xiàn)方案示例
- Android懸浮窗屏蔽懸浮窗外部所有的點擊事件的實例代碼
- Android中懸浮窗口的實現(xiàn)原理實例分析
- android實現(xiàn)可自由移動、監(jiān)聽點擊事件的懸浮窗
相關(guān)文章
Android Listview notifyDataSetChanged() 不起作用的
這篇文章主要介紹了Android Listview notifyDataSetChanged()不起作用的解決方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧2024-08-08Android入門之ActivityGroup+GridView實現(xiàn)Tab分頁標簽的方法
這篇文章主要介紹了Android入門之ActivityGroup+GridView實現(xiàn)Tab分頁標簽的方法,非常實用的功能,需要的朋友可以參考下2014-08-08Android自定義加載控件實現(xiàn)數(shù)據(jù)加載動畫
這篇文章主要為大家詳細介紹了Android自定義加載控件實現(xiàn)數(shù)據(jù)加載動畫的相關(guān)資料,仿美團、京東數(shù)據(jù)加載動畫、小人奔跑動畫,感興趣的小伙伴們可以參考一下2016-04-04Android Service中使用Toast無法正常顯示問題的解決方法
這篇文章主要介紹了Android Service中使用Toast無法正常顯示問題的解決方法,分析了Service中Toast無法正常顯示的原因與相關(guān)的解決方法,具有一定參考借鑒價值,需要的朋友可以參考下2016-10-10Android Studio使用教程(五):Gradle命令詳解和導(dǎo)入第三方包
這篇文章主要介紹了Android Studio使用教程(五):Gradle命令詳解和導(dǎo)入第三方包,本文講解了導(dǎo)入Android Studio、Gradle常用命令等內(nèi)容,需要的朋友可以參考下2015-05-05使用RecyclerView實現(xiàn)Item點擊事件
這篇文章主要介紹了使用RecyclerView實現(xiàn)Item點擊事件,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-08-08Android向node.js編寫的服務(wù)器發(fā)送數(shù)據(jù)并接收請求
這篇文章主要為大家詳細介紹了Android向node.js編寫的服務(wù)器發(fā)送數(shù)據(jù),并接收請求,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-10-10