Karrthik Reddy
Karrthik Reddy

Reputation: 1

Not able to use findViewbyId in Service

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

Answers (5)

Weiyi
Weiyi

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

Arjun saini
Arjun saini

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

Sohail Zahid
Sohail Zahid

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

rak
rak

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

SaravInfern
SaravInfern

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

How to service works see how service works

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

Related Questions