How to show status notification or popup dialog from background service?
I have created bootup Service
which listen for incoming messages in my application. Service is continuosly running in backgroung thought application is closed that is user goes offline. While user is offline and there is new message I have to show notifiacation on status bar or popup dialog(Here in this situaction service is not bound to any of Activity). I am facing following problems:
- While creating notification I am not getting Context and Activity.
- While I am displaying dialog from service class I am getting exception as
"Can't create handler inside thread that has not called Looper.prepare()".
I am new one for android services part and don't know hoe to solve this. Can anybody guide me how to do this? Is there any link which will guide me for this? I开发者_C百科 got stucked due to this problem. Help highly appreciated. Thanks.
You can send a notification and specify what Activity should be run when user initiates it:
private void sendNotification(Bundle bundle){
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);
int icon = R.drawable.icon;
CharSequence tickerText = "bla bla";
long when = System.currentTimeMillis();
Notification notification = new Notification(icon, tickerText, when);
Context context = getApplicationContext();
CharSequence contentTitle = "My notification";
CharSequence contentText = "Hello World!";
Intent notificationIntent = new Intent(this, ACTIVITY_YOU_WANT_TO_START.class);
if(bundle!=null)
notificationIntent.putExtras(bundle); //you may put bundle or not
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
int any_ID_you_want = 1;
//if you send another notification with same ID, this will be replaced by the other one
mNotificationManager.notify(HELLO_ID, notification);
}
//To play a sound add this:
notification.sound = Uri.parse("file:///sdcard/notification/ringer.mp3"); //for example
You can start another Activity:
private boolean startActivity(Bundle bundle){
Intent myIntent = new Intent(mContext, ACTIVITY_YOU_WANT_TO_START.class);
if(bundle!=null)
myIntent.putExtras(bundle);//optional
myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getApplication().startActivity(myIntent);
return true;
}
In addition to Sheriff's answer , you have to use following theme
android:theme="@android:style/Theme.Dialog"
for that Activity in AndroidManifest.xml . Then you will get a Dialog. :)
To add an Alert Dialog from Service, this worked fine
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
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
dialogWindow.setType(WindowManager.LayoutParams.TYPE_TOAST);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
dialogWindow.setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY);
}
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M)
{
dialogWindow.setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
}
dialog.show();
But using TYPE_SYSTEM_ALERT might trigger Google takedown policy of apps using dangerous permissions. Make sure you have a valid justification in case google requires it.
We can show dialog from service only if it is a system alert dialog. So, set TYPE_SYSTEM_ALERT
window layout parameter to Dialog as follows,
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
But, it needs SYSTEM_ALERT_WINDOW permission
. So, don't forget to add this permissin in Manifest file.
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
Edit: Better option to show dialog is to start activity as one of the below ways.
- Start Activity with Dialog Theme (android:theme="@android:style/Theme.Dialog") -(or)
- Start Translucent Activity and show Dialog in it.
Note: You should add Intent.FLAG_ACTIVITY_NEW_TASK to intent
Happy coding ... :)
精彩评论