开发者

Alert dialog from Android service

开发者 https://www.devze.com 2023-01-14 07:10 出处:网络
How do 开发者_开发百科I display dialog from a service?Another way without using an activity: AlertDialog alertDialog = new AlertDialog.Builder(this)

How do 开发者_开发百科I display dialog from a service?


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" />


android-smspopup does exactly that.

A service receives a sms and it starts an Activity with:

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

EDIT: The dialog activity is started here with this code

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

With getPopupIntent() declared as followed (code 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 class obviously defines the dialog activity. Its declared as followed in 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>


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.

Before we begin: AppCompat Library

This guide presumes you are using Android AppCompat libray.

Before we begin: Permissions

This method needs the SYSTEM_ALERT_WINDOW permission. 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:

<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:

@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

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

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


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?


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 mact is the Cast class to use in Alert Builder ...that works fine for me hope it help .


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

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.


Here is a more detailed explanation how to display AlertDialog from the service using translucent Activity, and how to avoid some issues.

0

精彩评论

暂无评论...
验证码 换一张
取 消