emi
emi

Reputation: 91

Launch popup window from service

I need to launch a popup window from a service to do something specific inside my application. I do not seem to find a good way to do it. Inside onCreate() I create the popup window but when I launch it with showAtLocation I get this error:

10-06 13:39:49.573: ERROR/AndroidRuntime(5966): Caused by: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?

Can someone please help? Thanks,

-em

Upvotes: 7

Views: 12967

Answers (2)

Nari Kim Shin
Nari Kim Shin

Reputation: 2499

I had the same problem and here if how i solved it. At first time i've tried to use Android's native PopupWindow class, but later i decided to use WindowManager like this way :

public class MyService extends Service {

private View mView;

private WindowManager.LayoutParams mParams;
private WindowManager mWindowManager;

@Override
public void onCreate() {
    super.onCreate();

    mView = new MyLoadView(this);

    mParams = new WindowManager.LayoutParams(
            WindowManager.LayoutParams.MATCH_PARENT, 150, 10, 10,
            WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
            WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
            PixelFormat.TRANSLUCENT);

    mParams.gravity = Gravity.CENTER;
    mParams.setTitle("Window test");

    mWindowManager = (WindowManager)getSystemService(WINDOW_SERVICE);
    mWindowManager.addView(mView, mParams);

}

@Override
public IBinder onBind(Intent intent) {
    return null;
}

@Override
public void onDestroy() {
    super.onDestroy();
    ((WindowManager)getSystemService(WINDOW_SERVICE)).removeView(mView);
    mView = null;
}

public class MyLoadView extends View {

    private Paint mPaint;

    public MyLoadView(Context context) {
        super(context);
        mPaint = new Paint();
        mPaint.setTextSize(50);
        mPaint.setARGB(200, 200, 200, 200);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawText("test test test", 0, 100, mPaint);
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
}
}

And you can call this service class via intent :

intent = new Intent(mContext, MyService.class);
if (intent != null) {
     getContext().startService(intent);
}

Also, set permission in your manifest file :

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

I referenced Android's LoadAverageService.java class, and i finally created a popup window from service! This is a very simple example, so you might need to add something more if you want to develop complex functions. Hope this will help you and others.

Upvotes: 8

slkorolev
slkorolev

Reputation: 6001

Service runs in background without UI so you have to start some avtivity with calling startActivity with appropriate Intent.

Upvotes: 0

Related Questions