Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Floating widget / Overlay on Android launcher

Does anyone have any idea how this can be implemented?

Some examples:

  • https://play.google.com/store/apps/details?id=gpc.myweb.hinet.net.PopupVideo
  • https://play.google.com/store/apps/details?id=com.milone.floatwidget

Any idea? Thanks.

like image 564
shiami Avatar asked Jul 12 '12 01:07

shiami


2 Answers

That is done using an overlay on top the existing activity regardless. You can find the source found here on my github to demonstrate the proof of concept that was on android's stackexchange.com question in which someone who suffered from a disability and could not swipe the screen to scroll and was looking for a way to do this conveniently, in which I cobbled together the code to show 'Page Up/Page Down' with minimum movement, just by tapping on the text (really, its a button) which overlaid on top of a activity. But due to the way Android and security worked, the scrolling event could not be injected into the currently running activity.

The way it works is this, from the onCreate activity there's this

WindowManager.LayoutParams layOutParams = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
                WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
                PixelFormat.TRANSLUCENT);

The flag that is needed is WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY and WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH.

The onus is to ensure that the touch is being handled which means watching out when the touch event 'hits' on a area and to act accordingly. By "listening" in on the View's onTouch event, that is:

LayoutInflater layOutInflater = (LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE);
View myView = layOutInflater.inflate(R.layout.myview, null);

myView.setOnTouchListener(new OnTouchListener(){
    @Override
    public boolean onTouch(View v, MotionEvent event) {
      ....
    }
});

For example, imagine a button within that myview layout, so using a button widget,

Button myButton = (Button)myView.findViewById(R.id.myButton);
Rect outRectHit = new Rect();
myButton.getHitRect(outRectHit);

Now we need to determine the 'collision' of the boundaries of the touch, which happens inside the onTouch handler:

float x = event.getX();
float y = event.getY();
if (x > outRectHit.left && x < outRectHit.right &&
    y > outRectHit.top && y < outRectHit.bottom){
     ... Handle this accordingly
}

This brief summary explains how to do such a thing as an overlay on-top of any activity.

Just to make sure, that the code gets debugged and does not interfere in any shape or form with any activity shown. For example, what happens if the activity is in fact a OpenGL game, what do you do?

That is to illustrate what needs to be watched out for.

like image 140
t0mm13b Avatar answered Nov 14 '22 22:11

t0mm13b


You might want to have a look at Tooleap SDK. It offers the simplest way of turning regular Android Activities into floating widgets.

E.g., let's say you have an Activity called MyActivity

Intent intent = new Intent(context, MyActivity.class);
TooleapPopOutMiniApp miniApp = new TooleapPopOutMiniApp(context, intent);
Tooleap tooleap = Tooleap.getInstance(context);
tooleap.addMiniApp(miniApp);

MyActivity will now become available as a floating widget on top of any other application.

like image 40
Korkamin Avatar answered Nov 14 '22 23:11

Korkamin