android服务弹框,如何在Android Service中开启对话框

最近碰到一个需求,需要在其他应用前台运行时弹出自己应用的对话框,通知用户信息。当然,这么做是完全和Android设计模式相悖的。通常情况下,当应用处于后台时,要以通知栏的形式和用户交互。但是,具体要如何实现了?让我们一起试试。

直接使用AlertDialog并显示

最初的想法很简单,我在Service中直接create一个对话框,然后调用show方法不就行了吗?代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33public class RunningService extends Service{

@Override

public IBinder onBind(Intent intent){

return null;

}

@Override

public int onStartCommand(Intent intent, int flags, int startId){

showDialog();

new Handler().postDelayed(new Runnable() {

@Override

public void run(){

showDialog();

}

}, 5 * 1000);

return START_STICKY;

}

private void showDialog(){

AlertDialog dialog = new AlertDialog.Builder(App.getContext()).setTitle(R.string.prompt)

.setMessage(getString(R.string.remove_ads_push_dialog_text))

.setCancelable(false)

.setPositiveButton(getString(R.string.confirm), new DialogInterface.OnClickListener() {

public void onClick(DialogInterface dialog, int id){

}

})

.create();

dialog.show();

}

}

为了方便测试,我们让对话框弹出时间延迟5s。

在AndroidManifest注册该Service:

1

并在应用入口开启Service:

1startService(new Intent(this, RunningService.class));

但是发现,应用在切回桌面后,并没有弹出对话框,而且Service也关闭了。其实是因为程序抛出了异常。上网找相关资料,原来只有依附于Activity或Fragment才能开启对话框,否则将抛出异常。那是不是意味着没办法在Service启动对话框呢?实际上并不是,我们需要额外做一个设置即可。

Dialog设置成TYPE_SYSTEM_ALERT

将Dialog Type设置成TYPE_SYSTEM_ALERT:

1

2

3

4

5

6

7

8

9

10

11

12private void showDialog(){

AlertDialog dialog = new AlertDialog.Builder(App.getContext()).setTitle(R.string.prompt)

.setMessage(getString(R.string.remove_ads_push_dialog_text))

.setCancelable(false)

.setPositiveButton(getString(R.string.confirm), new DialogInterface.OnClickListener() {

public void onClick(DialogInterface dialog, int id){

}

})

.create();

dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);

dialog.show();

}

关键代码dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);

并在AndroidManifest中添加权限:

1

启动应用后,发现这次不会跑异常了,但返回桌面后,还是没见到弹出对话框。是程序出错了吗?如果在dialog.show();之后打印Log,是能正常打印的,说明对话框确实已经显示。如果此时返回我们的应用,会发现刚才没显示的对话框显示了。可以知道,虽然这种方案可以显示出对话框,但并不是我们想要的效果。我们需要在其他应用中显示对话框,而不需要回到自己的应用。

使用对话框主题Activity

我们知道,在Service中开启一个Activity是没有问题的,为何不用Activity作为我们的对话框呢?

定义Activity Dialog样式

1

2

3

在Service中启动对话框Activity

1

2

3

4

5

6

7

8new Handler().postDelayed(new Runnable() {

@Override

public void run(){

Intent dialogIntent = new Intent(SendActivePackageService.this, PushDialogActivity.class);

dialogIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

startActivity(dialogIntent);

}

}, Config.DELAY_SHOW_PUSH_DIALOG);

需要注意setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)不能少,否则开启对话框时会强制跳转到对话框所属的应用。

举个简单的例子,比如现在正使用优酷客户端。这时,后台服务弹出对话框了,该对话框并不是直接覆盖在优酷客户端上,而是先跳转到你的应用,再弹出对话框。这显然不是我们想要的,大家可以试试。

目前,最后一种解决方案真正解决了我们的需求。但还是重复一遍,因为非常重要:

切忌在其他应用中弹出自己应用的对话框,类似的场景应该采用Notification来解决。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值