【问题标题】:Alert dialog from Android service来自 Android 服务的警报对话框
【发布时间】:2010-08-30 10:31:54
【问题描述】:

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

【问题讨论】:

标签: android service


【解决方案1】:

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

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

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

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

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

【讨论】:

【解决方案2】:

android-smspopup 正是这样做的。

一个服务收到一条短信,它会启动一个Activity

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

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

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

getPopupIntent() 声明如下(代码here):

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;
    }

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>

【讨论】:

  • 谢谢,搜索和尝试新方法需要几个小时。谢谢它的作品。
【解决方案3】:

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

从服务中,您可以轻松地显示一个 Material Design 样式的对话框来操作其 Window 类型、属性和 LayoutParams。

开始之前:AppCompat 库

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

开始之前:权限

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

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

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;
    }
}

创建您的自定义材料设计对话框主题

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>

启动您的对话框

在您的服务内部:

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();

【讨论】:

  • 什么是RC_OVERLAY
  • @avi 是请求码整数。您可以选择任何数字并将其设置为常数!
  • @araks 谢谢,太好了。你只需要在“dialog.show()”之后设置“lp”
【解决方案4】:

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

【讨论】:

  • 也许是个闹钟?有时会有弹出窗口的原因!
【解决方案5】:

首先,您需要将 Activity 投入服务 所以在你的活动中添加

public static Activity mactivity;

在创建时添加这个

mactivity = YourActivity.this;

当我们转移到您的服务时,请声明:

YourActivity mact;
YourActivity act;

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

mact = (YourActivity) act.mactivity;

警报对话框将如下所示:

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
            }
        });

请记住,mact 是在警报生成器中使用的 Cast 类...对我来说很好,希望对您有所帮助。

【讨论】:

    【解决方案6】:

    当我需要显示对话框时,我会在服务内部调用以下内容。

    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();
    }
    

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

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

    【讨论】:

      【解决方案7】:

      Here 更详细地解释了如何使用半透明的Activity 从服务中显示AlertDialog,以及如何避免一些问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-05-02
        • 2015-04-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-25
        相关资源
        最近更新 更多