Reputation: 1
I am doing an application where I should use the Service to open a PopUpwindow at certain Intervals of time. I tried it by keeping the popup window code in other activity as method and calling it in the service. But it ended up in vain. So I have copied all popupWindow code to the service here I cannot use findViewById.
My service code is as follows
public class TimeService extends Service {
View layout;
LayoutInflater inflater;
public PopupWindow pw;
private RadioGroup options_group;
private RadioButton option_button;
Button submit_popup,close_popup;
// constant
public static final long NOTIFY_INTERVAL = 10 * 10000; // 100 seconds
// run on another Thread to avoid crash
private Handler mHandler = new Handler();
// timer handling
private Timer mTimer = null;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
// cancel if already existed
if (mTimer != null) {
mTimer.cancel();
} else {
// recreate new
mTimer = new Timer();
}
// schedule task
mTimer.scheduleAtFixedRate(new TimeDisplayTimerTask(), 0, NOTIFY_INTERVAL);
}
class TimeDisplayTimerTask extends TimerTask {
@Override
public void run() {
// run on another thread
mHandler.post(new Runnable() {
@Override
public void run() {
// display toast
try {
inflater = (LayoutInflater) TimeService.this.
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
layout = inflater.inflate(R.layout.layout_popup, (ViewGroup) findViewById(R.id.popup_1));
pw = new PopupWindow(layout, 300, 370, true);
pw.showAtLocation(layout, Gravity.CENTER, 0, 0);
submit_popup = (Button) layout.findViewById(R.id.popup_submit);
close_popup = (Button) layout.findViewById(R.id.popup_cancel);
options_group=(RadioGroup) layout.findViewById(R.id.radioGroup);
submit_popup.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
pw.dismiss();
}
});
submit_popup.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int selectedId=options_group.getCheckedRadioButtonId();
option_button=(RadioButton) layout.findViewById(selectedId);
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
}
I am getting error in the line
layout = inflater.inflate(R.layout.layout_popup, (ViewGroup) findViewById(R.id.popup_1));
and the error is cannot resolve method findViewbyId(int).
Please help me with the code. What I am doing wrong.
Thanks in advance.
I have tried using the code
layout = inflater.inflate(R.layout.layout_popup, null);
I am getting the error or stacktrace as follows
07-22 01:17:39.789 940-957/system_process W/WindowManager: Attempted to add window with token that is not a window: null. Aborting.
07-22 01:17:39.790 27060-27060/highski.developers.cflash W/System.err: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?
07-22 01:17:39.790 27060-27060/highski.developers.cflash W/System.err: at android.view.ViewRootImpl.setView(ViewRootImpl.java:562)
07-22 01:17:39.790 27060-27060/highski.developers.cflash W/System.err: at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:282)
07-22 01:17:39.790 27060-27060/highski.developers.cflash W/System.err: at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:85)
07-22 01:17:39.790 27060-27060/highski.developers.cflash W/System.err: at android.widget.PopupWindow.invokePopup(PopupWindow.java:1104)
07-22 01:17:39.790 27060-27060/highski.developers.cflash W/System.err: at android.widget.PopupWindow.showAtLocation(PopupWindow.java:933)
07-22 01:17:39.790 27060-27060/highski.developers.cflash W/System.err: at android.widget.PopupWindow.showAtLocation(PopupWindow.java:897)
07-22 01:17:39.791 27060-27060/highski.developers.cflash W/System.err: at highski.developers.cflash.service.TimeService$TimeDisplayTimerTask$1$override.run(TimeService.java:85)
07-22 01:17:39.791 27060-27060/highski.developers.cflash W/System.err: at highski.developers.cflash.service.TimeService$TimeDisplayTimerTask$1$override.access$dispatch(TimeService.java)
07-22 01:17:39.791 27060-27060/highski.developers.cflash W/System.err: at highski.developers.cflash.service.TimeService$TimeDisplayTimerTask$1.run(TimeService.java:0)
07-22 01:17:39.791 27060-27060/highski.developers.cflash W/System.err: at android.os.Handler.handleCallback(Handler.java:739)
07-22 01:17:39.791 27060-27060/highski.developers.cflash W/System.err: at android.os.Handler.dispatchMessage(Handler.java:95)
07-22 01:17:39.791 27060-27060/highski.developers.cflash W/System.err: at android.os.Looper.loop(Looper.java:135)
07-22 01:17:39.791 27060-27060/highski.developers.cflash W/System.err: at android.app.ActivityThread.main(ActivityThread.java:5254)
07-22 01:17:39.791 27060-27060/highski.developers.cflash W/System.err: at java.lang.reflect.Method.invoke(Native Method)
07-22 01:17:39.791 27060-27060/highski.developers.cflash W/System.err: at java.lang.reflect.Method.invoke(Method.java:372)
07-22 01:17:39.791 27060-27060/highski.developers.cflash W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
07-22 01:17:39.791 27060-27060/highski.developers.cflash W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Upvotes: 0
Views: 4289
Reputation: 1933
AlertDialog should be managed by Activity which has a window, since Service is a non-UI component, so you cannot show a dialog in the service, otherwise app will crash:
Caused by: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
at android.app.Dialog.show(Dialog.java:325)
You have two ways to show dialog in service:
1, Start a dialog theme activity, and show a dialog in this activity's onCreate
method.
android:theme="@android:style/Theme.Holo.Light.Dialog"
OR
2, Set the dialog as system alert:
AlertDialog.Builder builder = new AlertDialog.Builder(getApplicationContext());
builder.setTitle("title")
.setMessage("message");
AlertDialog dialog = builder.create();
// set the dialog as system alert
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
dialog.show();
Upvotes: 0
Reputation: 4182
See the Answer Here
Show dialog alert from a non-activity class in android
The problem is 'You can show AlertDialogs ,dialog or Popupwindow from your Service Activity only
'.
Although this is not a good idea to show dialog from receiver or Service (better is to use Notification), But if you want to do so you can create an Activity as dialog and show
Upvotes: 0
Reputation: 8149
Pass null values in 2nd parameter
layout = inflater.inflate(R.layout.layout_popup, (ViewGroup) findViewById(R.id.popup_1));
to
layout = inflater.inflate(R.layout.layout_popup, null);
Update:
private Handler mHandler;
@Override
public void onCreate() {
mHandler = new Handler(Looper.getMainLooper());
//... do like above and remove perivous updated
}
Upvotes: 1
Reputation: 68
You need to use Handler
private Handler handler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
if (msg.what == 0) {
// add your code here.
}
return false;
}
});
add call the handler in ua Run() method.
handler.sendEmptyMessage(0);
All the best.
Upvotes: 0
Reputation: 3388
you cannot directly make changes in ui inside a service instead use broadcast receiver and intent filter to notify your activity/fragment and update from there
Some use reference onservices
http://www.vogella.com/tutorials/AndroidServices/article.html
https://androidexperinz.wordpress.com/2012/02/14/communication-between-service-and-activity-part-1/
Upvotes: 3