如何从后台服务中显示状态通知或弹出对话框?

3
我已经创建了启动服务Service,用于在我的应用程序中监听传入的消息。即使用户离线,服务也会在后台持续运行,但是当用户离线并且有新消息时,我必须在状态栏或弹出对话框上显示通知(在此情况下,服务未绑定到任何活动)。 我遇到了以下问题:
  1. 在创建通知时,我无法获取上下文和活动。
  2. 当我从服务类显示对话框时,我会收到异常,如"Can't create handler inside thread that has not called Looper.prepare()".
我对Android服务部分还很陌生,不知道该怎么解决。 有人可以指导我如何做吗? 是否有任何链接可以为此指导我? 我因此问题而陷入困境。非常感谢您的帮助。谢谢。

请查看此线程中的CommonsWare回复 - http://stackoverflow.com/questions/3865687/sendbroadcast-if-activity-or-notification - Vino
4个回答

4
你可以发送通知并指定用户启动时应运行的活动:
 private void sendNotification(Bundle bundle){
    String ns = Context.NOTIFICATION_SERVICE;
    NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);
    int icon = R.drawable.icon;
    CharSequence tickerText = "bla bla";
    long when = System.currentTimeMillis();
    Notification notification = new Notification(icon, tickerText, when);
    Context context = getApplicationContext();
    CharSequence contentTitle = "My notification";
    CharSequence contentText = "Hello World!";
    Intent notificationIntent = new Intent(this, ACTIVITY_YOU_WANT_TO_START.class);
    if(bundle!=null)
        notificationIntent.putExtras(bundle); //you may put bundle or not
    PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
    notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
    int any_ID_you_want = 1; 
    //if you send another notification with same ID, this will be replaced by the other one
    mNotificationManager.notify(HELLO_ID, notification);
}

//To play a sound add this:
notification.sound = Uri.parse("file:///sdcard/notification/ringer.mp3"); //for example

你可以启动另一个Activity:

private boolean startActivity(Bundle bundle){
    Intent myIntent = new Intent(mContext, ACTIVITY_YOU_WANT_TO_START.class);
    if(bundle!=null)
         myIntent.putExtras(bundle);//optional
    myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    getApplication().startActivity(myIntent);
    return true;
}

非常感谢您,Sherif。我可以同时播放铃声和通知吗?我该如何实现这个功能? - Balaji Khadake
@SherifelKhatib 我该如何在按钮点击事件中关闭这个弹出活动? - sam_k
@Sam_k 在 OnClickListener 中使用 finish()。顺便说一下,我不太清楚这个答案是什么:p - Sherif elKhatib

2
除了Sheriff的答案,您还需要在AndroidManifest.xml文件中为该Activity使用以下主题:android:theme="@android:style/Theme.Dialog",然后您将获得一个对话框。 :)

1
从服务中添加警报对话框,这个很好用。
final AlertDialog dialog = dialogBuilder.create();
            final Window dialogWindow = dialog.getWindow();
            final WindowManager.LayoutParams dialogWindowAttributes = dialogWindow.getAttributes();

            // Set fixed width (280dp) and WRAP_CONTENT height
            final WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
            lp.copyFrom(dialogWindowAttributes);
            lp.width = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 280, getResources().getDisplayMetrics());
            lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
            dialogWindow.setAttributes(lp);

            // Set to TYPE_SYSTEM_ALERT so that the Service can display it
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                dialogWindow.setType(WindowManager.LayoutParams.TYPE_TOAST);
            }
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                dialogWindow.setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY);
            }
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M)
            {
                dialogWindow.setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
            }
            dialog.show();

但是使用TYPE_SYSTEM_ALERT可能会触发Google针对使用危险权限的应用程序的下架政策。确保您有有效的理由以防谷歌要求。


1
我们只能从服务中显示系统警报对话框。因此,请按以下方式将 "TYPE_SYSTEM_ALERT" 窗口布局参数设置为对话框。
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);

但它需要 SYSTEM_ALERT_WINDOW 权限。因此,请不要忘记在清单文件中添加此权限。

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

编辑: 更好的显示对话框的选项是以以下任一方式之一启动活动。

  1. 使用对话框主题启动活动(android:theme="@android:style/Theme.Dialog")-(或)
  2. 启动半透明活动并在其中显示对话框。

注意:您应该将 Intent.FLAG_ACTIVITY_NEW_TASK 添加到意图中

愉快的编码... :)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接