1
public class MyCustomService extends Service {
    private WindowManager windowManager;
    private ImageView chatHead;
    WindowManager.LayoutParams params;
    private static Context mContext;

    IBinder mBinder = new LocalBinder();

    public static Socket client;

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

    public class LocalBinder extends Binder {
        public MyCustomService getServerInstance() {
            return MyCustomService.this;
        }
    }

    // Fires when a service is first initialized
    public void onCreate() {
        super.onCreate();
        this.mContext = this;

        windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
    }

    // Fires when a service is started up
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        IO.Options opts = new IO.Options();
        opts.query = "auth_token=51";
        try {
            client = IO.socket("http://192.168.0.106:3000/",opts);
            client.on("message", onMessage);

            client.connect();
        }
        catch (URISyntaxException e) {
            e.printStackTrace();
        }

        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        client.disconnect();
        client.close();
        if (chatHead != null) windowManager.removeView(chatHead);
    }

    public void addView(){
        windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
    
        chatHead = new ImageView(mContext);
        chatHead.setImageResource(R.drawable.android_head);
    
        WindowManager.LayoutParams params = new WindowManager.LayoutParams(
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.TYPE_PHONE,
            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
        PixelFormat.TRANSLUCENT);

        params.gravity = Gravity.TOP | Gravity.LEFT;
        params.x = 0;
        params.y = 100;

        windowManager.addView(chatHead, params);
    }

    private Emitter.Listener onMessage = new Emitter.Listener() {
        @Override
        public void call(Object... args) {
            addView();
        }
    };
}

I want to make alert window from a service. When I call the function addView from the onCreate method of the service its works without any error.

The onMessage method is called when I emit new data to socket. So I just want to show the alert window when I get message from the socket, but it gives me an error if I call function addView from the onMessage function:

Can't create handler inside thread that has not called Looper.prepare()

But if I call it from the onCreate method of the service its works.

Donald Duck
  • 8,409
  • 22
  • 75
  • 99
medo
  • 479
  • 3
  • 9
  • 24

1 Answers1

3

public void call(Object... args) is not called from UI thread. You can do that via Handler.

Handler mHandler = new Handler(Looper.getMainLooper());
...
...
...
private Emitter.Listener onMessage = new Emitter.Listener() {

   @Override
   public void call(Object... args) {

      mHandler.post(new Runnable(){

         @Override
         public void run (){
         addView();
         }
     });
};
egoldx
  • 1,490
  • 1
  • 9
  • 14