How to Display a Dialog from a Service

How to display a Dialog from a Service?

I highly, highly, HIGHLY recommend that you DON'T do this (it goes against Android design and UI guidelines). Notifications are the preferred way to accomplish what you are doing (which it sounds as if you have already accomplished).

That being said, if you must do it, I would recommend just using a Dialog themed activity. That way you don't have to start up a separate dialog. Please see http://developer.android.com/guide/topics/ui/themes.html#ApplyATheme for how to do this.

Alert dialog from Android service

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>

How to show Alert Dialog box in Service android

Just remove :

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // 8.0 new features
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY - 1);
} else {
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_TOAST);
}

And try :

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

UPDATE

In Android 6.0 Marshmallow, the user must explicitly allow your app to "draw over other apps". So add

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

Now in marshmallow use this method to handle runtime permission:

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

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case 11:
final boolean overlayEnabled = Settings.canDrawOverlays(this);
// handle the remaining logic
break;
}
}

Now show the dialog in service as below:

    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 (350dp) and WRAP_CONTENT height
final WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
lp.copyFrom(dialogWindowAttributes);
lp.width = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 350, 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();

All set now this solution should work. Good luck

How to show a dialog in Activity from Service class?

there are a lot of ways you can do but i offer you using EventBus Library to handle your events between your service and your activities:

first register EventBus in your activity in onStart() and unregister it in onStop():

class YourActivity : ActivityCompat() {
fun onStart() {
super.onStart()
EventBus.getDefault().register(this)
}

fun onStop() {
EventBus.getDefault().unregister(this)
super.onStop()
}

@Subscribe(threadMode = ThreadMode.MAIN)
fun onEvent(MessageEvent event) {
// show your popup dialog and implement your logics and stop your service
} }

then in your service send your message where you want :

EventBus.getDefault().post(new MessageEvent());

hope be useful.

How to use alertDialog in background service

Code inside Service class to open AlertDialog

private void showAlertDialog() {

KeyguardManager km = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
KeyguardManager.KeyguardLock kl = km.newKeyguardLock("MyKeyguardLock");
kl.disableKeyguard();

PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
WakeLock wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK| PowerManager.ACQUIRE_CAUSES_WAKEUP
| PowerManager.ON_AFTER_RELEASE, "MyWakeLock");
wakeLock.acquire();


final CharSequence[] items = { getString(R.string.test1), getString(R.string.tes2), getString(R.string.test3), getString(R.string.cancel) };
AlertDialog.Builder builder = new AlertDialog.Builder(getApplicationContext());
builder.setTitle("Title");
builder.setItems(items, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int item) {
if (items[item].equals(getString(R.string.test1))) {
dialog.dismiss();

} else if (items[item].equals(getString(R.string.test2))) {
dialog.dismiss();

} else if (items[item].equals(getString(R.string.test3))) {

}else if (items[item].equals(getString(R.string.cancel))) {
dialog.dismiss();


}
}
});

alert = builder.create();
alert.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
alert.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON|
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD|
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED|
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);


alert.show();

alert.setOnDismissListener(new OnDismissListener() {

@Override
public void onDismiss(DialogInterface arg0) {

}
});


alert.setOnCancelListener(new OnCancelListener() {

@Override
public void onCancel(DialogInterface dialog) {

}
});


}

You have to add permissions in Manifest file

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

You can do customize on alert dialog as your requirements.

Done

Launching Dialog from Service

Found this out myself, just add the Intent.FLAG_ACTIVITY_MULTIPLE_TASK flag to the launch Intent; of course in conjunction with the Intent.FLAG_ACTIVITY_NEW_TASK flag.

Launch AlertDialog.Builder from Service

If you want to popup a dialog in Android Service, you have two ways:

  1. Use an Activity as Dialog

  2. Use AlertDialog.Builder, but you'll need to config dialog as System Alert
    by using dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);

Here is the sample code:

AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Test dialog"));
builder.setIcon(R.drawable.icon);
builder.setMessage("Content");
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
//Do something
dialog.dismiss();
});
builder.setNegativeButton("Close", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
dialog.dismiss();
}
});
AlertDialog alert = builder.create();
alert.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
alert.show();

Also, remember to add permission in your AndroidManifest.xml

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

how to show dialog window from background service without open application Activity

To Resolve SYSTEM ALERT PERMISSION You have to get permission of DrawOverlays. You can get this permission through following two steps.

Step 1: Put below code in Main activity which check whether permission is given or not if not then then it will ask for permission.

if (Build.VERSION.SDK_INT >= 23) {
if (!Settings.canDrawOverlays(this)) {
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE);
}
}

Step 2: Then after Add below code in onActivityResult.

if (Build.VERSION.SDK_INT >= 23) {
if (requestCode == ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE) {
if (Settings.canDrawOverlays(this)) {

}
}
}


Related Topics



Leave a reply



Submit