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:
Use an
Activity
asDialog
Use
AlertDialog.Builder
, but you'll need to config dialog as System Alert
by usingdialog.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
How to Add Manifest Permission to an Application
Clicking Urls Opens Default Browser
Checkbox in Recyclerview Keeps on Checking Different Items
How to Disable Copy/Paste From/To Edittext
How to Handle Dynamic Json in Retrofit
What's the Best Way to Limit Text Length of Edittext in Android
How to Find Serial Number of Android Device
How to Return a Result (Startactivityforresult) from a Tabhost Activity
How to Make a Phone Call in Android and Come Back to My Activity When the Call Is Done
Difference Between Getdefaultsharedpreferences and Getsharedpreferences
How to Check Grants Permissions At Run-Time
How to Install an Apk File in the Android Emulator
Difference Between Adjustresize and Adjustpan in Android
Java.Lang.Runtimeexception: Unable to Instantiate Activity Componentinfo
How to Make Bitmap Compress Without Change the Bitmap Size
How to Programmatically Add Views to Views
List of Android Permissions Normal Permissions and Dangerous Permissions in API 23