在Service 中彈出一個(gè)窗口

工作上遇到點(diǎn)事情,需要在Service層中彈一個(gè)對(duì)話框出來(lái),自定義的,不僅僅是dialog那種。最后找到了兩種解決方案:

1、通過(guò)windowManager彈出一個(gè)windows

2、彈出一個(gè)Activity ,讓Activity 的Theme主題設(shè)置style為Customdialog(customDialog繼承自Dialog),這樣彈出的時(shí)候就會(huì)跟一個(gè)dialog類似,強(qiáng)行偽裝成窗口

代碼具體實(shí)現(xiàn):(只給出關(guān)鍵地方代碼,有需要的請(qǐng)自己學(xué)習(xí)相關(guān)知識(shí),不要做懶人,對(duì)你們不好)

Looper.prepare();

wm = (WindowManager) context.getApplicationContext().getSystemService("window");

scanView = LayoutInflater.from(context).inflate(R.layout.scan_window,null);

WindowManager.LayoutParams wmParams = new WindowManager.LayoutParams();

wmParams.type = 2002;

wmParams.format = 1;

wmParams.flags = 40;

wmParams.width = 500;

wmParams.height = 500;

wm.addView(scanView, wmParams);

scanView.setOnClickListener(new OnClickListener(){

@Override

public void onClick(View arg0) {

// TODO Auto-generated method stub

wm.removeView(scanView);

}});

Looper.loop();

為什么要加Looper 呢,因?yàn)镾ervice 線程中只有主線程能夠loop,網(wǎng)上查了方法,但是不能用。因?yàn)镾ervice 不是很支持UI渲染線程,所以必須要加上Looer才行。


但是僅僅是這樣是不夠的,這僅僅是彈出一個(gè)窗口,咱們還得請(qǐng)求相應(yīng)的權(quán)限

在AndroidMainfest中添加


簡(jiǎn)書好搞笑,代碼貼不上

其中呢,R.layout.scan_window是一個(gè)自定義布局,要實(shí)現(xiàn)啥控件,啥效果可以直接在里面操作。恩,差不多方法1 就是這樣


方法二:

其實(shí)這個(gè)辦法非常取巧。但笨的人沒有智商只能靠機(jī)智了。不是很推薦這個(gè)方法。

在Service 中開啟一個(gè)活動(dòng),然后像在活動(dòng)中一樣想干啥就干啥。

Intent intent = new Intent();

intent.setClass(context, CaptureActivity.class);

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

context.startActivity(intent);

記住,Service 不是很喜歡開啟活動(dòng),因此在開啟活動(dòng)的時(shí)候一定要加上AddFlags

開啟活動(dòng)以后,為了弄一個(gè)窗口的樣式,我們改一下主題


AndroidMainfest中的代碼


style中的代碼

要控制窗口屬性什么的就在這里控制吧


然后問(wèn)題來(lái)了

控件出來(lái)爽是爽了,如果活動(dòng)本身沒有關(guān)閉按鈕,如果不允許物理鍵盤鏈接,怎么通過(guò)service中的方法來(lái)關(guān)閉呢?

試用了很多辦法,因?yàn)槲议_啟的活動(dòng)是含有多線程的,所以普通的finish 方法并不理想(比如說(shuō)將活動(dòng)設(shè)置成static 靜態(tài)全局變量,然后new一個(gè)實(shí)例,關(guān)閉等等)

后來(lái)還是用到了廣播,多么樸實(shí)無(wú)華的解決方案

這是在service層的代碼

Intent intent = new Intent();

intent.setAction("close"); // 說(shuō)明動(dòng)作

context.sendBroadcast(intent);// 該函數(shù)用于發(fā)送廣播

然后在Activity 中的onResume ?注冊(cè)一個(gè)接收者

IntentFilter filter = new IntentFilter();

filter.addAction("close");

registerReceiver(this.broadcastReceiver, filter); // 注冊(cè)

然后要加上一個(gè)這樣的函數(shù)

private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {

@Override

public void onReceive(Context context, Intent intent) {

finish();

unregisterReceiver(this); // 這句話必須要寫要不會(huì)報(bào)錯(cuò),不寫雖然能關(guān)閉,會(huì)報(bào)一堆錯(cuò)

}

};

恩,這樣就實(shí)現(xiàn)了。

THX

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容