来自 Android 服务的警报对话框

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3599563/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 10:55:17  来源:igfitidea点击:

Alert dialog from Android service

androidservice

提问by d-man

How do I display dialog from a service?

如何显示来自服务的对话框?

采纳答案by Macarse

android-smspopupdoes exactly that.

android-smspopup正是这样做的。

A service receives a sms and it starts an Activitywith:

服务收到一条短信,并以以下内容开头Activity

android:theme="@android:style/Theme.Dialog"

EDIT:The dialog activity is started herewith this code

编辑:使用此代码在此处启动对话活动

private void notifyMessageReceived(SmsMmsMessage message) {
    (...)
    context.startActivity(message.getPopupIntent());
    (...)
}

With getPopupIntent()declared as followed (code here):

随着getPopupIntent()宣布为其次(代码在这里):

public Intent getPopupIntent() {
    Intent popup = new Intent(context, SmsPopupActivity.class);
    popup.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
    popup.putExtras(toBundle());
    return popup;
    }

SmsPopupActivityclass obviously defines the dialog activity. Its declared as followed in AndroidManifest.xml:

SmsPopupActivity类显然定义了对话活动。其声明如下AndroidManifest.xml

    <activity
        android:name=".ui.SmsPopupActivity"
        android:configChanges="keyboardHidden|orientation|screenSize"
        android:launchMode="singleTask"
        android:screenOrientation="user"
        android:taskAffinity="net.everythingandroid.smspopup.popup"
        android:theme="@style/DialogTheme" >
    </activity>

回答by Eliran Kuta

Another way without using an activity:

另一种不使用活动的方法:

AlertDialog alertDialog = new AlertDialog.Builder(this)
                    .setTitle("Title")
                    .setMessage("Are you sure?")
                    .create();

alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
alertDialog.show();

Please note that you have to use this permission:

请注意,您必须使用此权限:

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

回答by araks

Material styled Dialog from a Service

来自服务的材质样式对话框

From a Service, you can easily show a Material Design styled Dialog manipulating its Window type, attributes and LayoutParams.

从服务中,您可以轻松地显示一个 Material Design 风格的对话框,操作其窗口类型、属性和布局参数。

Before we begin: AppCompat Library

开始之前:AppCompat 库

This guide presumes you are using Android AppCompat libray.

本指南假定您使用的是 Android AppCompat 库。

Before we begin: Permissions

开始之前:权限

This method needs the SYSTEM_ALERT_WINDOWpermission. Usually a Service that wants to display a Dialog also has some Views drawn over the system UI (added using WindowManager.addView()method) so you might have already declared this permission usage inside you manifest. If not, add this line:

此方法需要SYSTEM_ALERT_WINDOW权限。通常,想要显示对话框的服务也会在系统 UI 上绘制一些视图(使用WindowManager.addView()方法添加),因此您可能已经在清单中声明了此权限用法。如果没有,请添加以下行:

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

In Android 6.0 Marshmallow, the user must explicitly allow your app to "draw over other apps". You can programmatically start the system settings Activity that contains the switch:

Android 6.0 Marshmallow 中,用户必须明确允许您的应用“覆盖其他应用”。您可以以编程方式启动包含开关的系统设置 Activity:

@Override
protected void onResume() {
    super.onResume();
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.canDrawOverlays(this)) {
        openOverlaySettings();
    }
}

@TargetApi(Build.VERSION_CODES.M)
private void openOverlaySettings() {
    final Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                                     Uri.parse("package:" + getPackageName()));
    try {
        startActivityForResult(intent, RC_OVERLAY);
    } catch (ActivityNotFoundException e) {
        Log.e(TAG, e.getMessage());
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch (requestCode) {
        case RC_OVERLAY:
            final boolean overlayEnabled = Settings.canDrawOverlays(this);
            // Do something...
            break;
    }
}

Create your custom Material Design Dialog theme

创建您的自定义 Material Design Dialog 主题

Inside themes.xmlcreate this theme and customize it with your app colors:

在里面themes.xml创建这个主题并使用您的应用程序颜色对其进行自定义:

<style name="AppTheme.MaterialDialogTheme" parent="Theme.AppCompat.Light.Dialog">
    <item name="colorPrimary">@color/brand_primary</item>
    <item name="colorPrimaryDark">@color/brand_primary_dark</item>
    <item name="colorAccent">@color/brand_accent</item>

    <item name="android:windowBackground">@drawable/dialog_background_light</item>

    <item name="android:textColorPrimary">@color/primary_text_light</item>
    <item name="android:textColorSecondary">@color/secondary_text_light</item>
    <item name="android:textColorTertiary">@color/secondary_text_light</item>
</style>

Launch your Dialog

启动你的对话框

Inside your Service:

在您的服务中:

final AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this, R.style.AppTheme_MaterialDialogTheme);

dialogBuilder.setTitle(R.string.dialog_title);
dialogBuilder.setMessage(R.string.dialog_message);
dialogBuilder.setNegativeButton(R.string.btn_back,
        new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        }
);

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
dialogWindow.setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
dialogWindowAttributes.windowAnimations = R.style.DialogAnimation;
dialog.show();

回答by p__

The documentation suggests that you should make use of notifications. Re-evaluate why you might need to use dialogs. What are you trying to achieve?

该文档建议您应该使用通知。重新评估您可能需要使用对话框的原因。你想达到什么目的?

回答by Mohamed Hocine

firstable you need to cast your Activity in Service so in your Activity add

首先你需要在服务中投射你的活动,所以在你的活动中添加

public static Activity mactivity;

and in On create add this

并在创建时添加这个

mactivity = YourActivity.this;

and when we move to your Service alse declare this :

当我们转向您的服务时,还要声明:

YourActivity mact;
YourActivity act;

and in on Create service this is our casting

在创建服务中,这是我们的演员表

mact = (YourActivity) act.mactivity;

and the alert dialog will be look like this :

警报对话框将如下所示:

AlertDialog.Builder builder = new AlertDialog.Builder(mact);
        builder.setMessage(getResources().getString(R.string.string));
        builder.setIcon(R.drawable.chat);
        builder.setTitle(R.string.app_name);
        builder.setPositiveButton(getResources().getString(R.string.Ok), new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface paramDialogInterface, int paramInt) {
                // TODO Auto-generated method stub
               your message
            }
        });

remember that mactis the Cast class to use in Alert Builder ...that works fine for me hope it help .

请记住,这mact是在 Alert Builder 中使用的 Cast 类……这对我来说很好用,希望它有所帮助。

回答by edreamz

I am calling the below, inside the service when I need to show a dialog.

当我需要显示一个对话框时,我在服务内部调用下面的。

public void ShowYesNoDialog() {

    DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            switch (which) {
                case DialogInterface.BUTTON_POSITIVE:
                    //Yes Button Clicked
                    break;

                case DialogInterface.BUTTON_NEGATIVE:
                    //No button clicked
                    break;
            }
        }
    };

    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setMessage("Did the dialog display?")
    .setPositiveButton("Yes", dialogClickListener)
    .setNegativeButton("No", dialogClickListener);
    AlertDialog alertDialog = builder.create();
    alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); 
    alertDialog.show();
}

Make sure you have the below permission added to the manifest. android.permission.SYSTEM_ALERT_WINDOW

确保您已将以下权限添加到清单中。android.permission.SYSTEM_ALERT_WINDOW

I also think that for SDK 23 and above, the user should explicitly set the "Draw over other Apps" permission from the Application manager for the App that starts this service.

我还认为,对于 SDK 23 及更高版本,用户应该从启动此服务的应用程序的应用程序管理器中明确设置“绘制其他应用程序”权限。

回答by Dmitry Frank

Hereis a more detailed explanation how to display AlertDialogfrom the service using translucent Activity, and how to avoid some issues.

这里更详细地解释了如何AlertDialog使用 translucent 从服务中显示Activity,以及如何避免一些问题。