I am trying to make an app with floating widget on top of the screen all the time. Looking through examples online I finally assembled a basic thing to start with.
However, whenever I try to close the app, it keeps restarting itself unless I force stop it by going into "App info."
Let me try to post my codes here... MainActivity
public class MainActivity extends AppCompatActivity {
/* Permission request code to draw over other apps */
private static final int DRAW_OVER_OTHER_APP_PERMISSION_REQUEST_CODE = 1222;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
/* start floating widget service */
public void createFloatingWidget(View view) {
//Check if the application has draw over other apps permission or not?
//This permission is by default available for API<23. But for API > 23
//you have to ask for the permission in runtime.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.canDrawOverlays(this)) {
//If the draw over permission is not available open the settings screen
//to grant the permission.
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, DRAW_OVER_OTHER_APP_PERMISSION_REQUEST_CODE);
} else
//If permission is granted start floating widget service
startFloatingWidgetService();
}
/* Start Floating widget service and finish current activity */
private void startFloatingWidgetService() {
startService(new Intent(MainActivity.this, FloatingWidgetService.class));
//startService(new Intent(context, ServiceChatHead.class));
finish();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == DRAW_OVER_OTHER_APP_PERMISSION_REQUEST_CODE) {
//Check if the permission is granted or not.
if (resultCode == RESULT_OK)
//If permission granted start floating widget service
startFloatingWidgetService();
else
//Permission is not available then display toast
Toast.makeText(this,
getResources().getString(R.string.draw_other_app_permission_denied),
Toast.LENGTH_SHORT).show();
} else {
super.onActivityResult(requestCode, resultCode, data);
}
}
And FloatingWidgetService
public class FloatingWidgetService extends Service {
private WindowManager windowManager;
private ImageView chatImage;
private GestureDetector gestureDetector;
@Override public IBinder onBind(Intent intent) {
// Not used
return null;
}
@Override public void onCreate() {
super.onCreate();
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
gestureDetector = new GestureDetector(this, new SingleTapConfirm());
chatImage = new ImageView(this);
chatImage.setImageResource(R.drawable.inosukes);
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
//WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.TOP | Gravity.LEFT;
params.x = 0;
params.y = 100;
chatImage.setOnTouchListener(new View.OnTouchListener() {
private int initialX;
private int initialY;
private float initialTouchX;
private float initialTouchY;
@Override
public boolean onTouch(View arg0, MotionEvent event) {
if (gestureDetector.onTouchEvent(event)) {
// single tap
if (chatImage != null) windowManager.removeView(chatImage);
return true;
} else {
// for move and drag
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
initialX = params.x;
initialY = params.y;
initialTouchX = event.getRawX();
initialTouchY = event.getRawY();
return true;
case MotionEvent.ACTION_UP:
return true;
case MotionEvent.ACTION_MOVE:
params.x = initialX + (int) (event.getRawX() - initialTouchX);
params.y = initialY + (int) (event.getRawY() - initialTouchY);
windowManager.updateViewLayout(chatImage, params);
return true;
}
return false;
}
}
});
windowManager.addView(chatImage, params);
}
private class SingleTapConfirm extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onSingleTapUp(MotionEvent event) {
return true;
}
}
@Override
public void onDestroy() {
super.onDestroy();
if (chatImage != null) windowManager.removeView(chatImage);
//this is not helping to close the app?
System.exit(0);
}
}
Thank you very much in advance!
If method
startService()
is used to start the service in other places,it will restart itself even though the activity binded to it was destroyed.So make sure you start the service only bybindService()
method.refer to this SO Question also..