I am android developer .I create system window overlay .I want to bounce bubble only stay left top corner, right top corner,bottom left corner.bottom right corner .you stretch ball from top right corner to center then ball direct bounce top right corner .ball just stay only four corner like Facebook messenger . i also try some days but i don't know to do this.here is my code any one please tell what is change in this code.
package com.example.bubble;
import java.io.IOException;
import java.io.InputStream;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.PixelFormat;
import android.graphics.drawable.BitmapDrawable;
import android.os.Handler;
import android.os.IBinder;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.WindowManager;
import android.widget.RelativeLayout;
@SuppressWarnings("deprecation")
public class PlayerService extends Service
{
private static final int HIDDEN_FRACTION = 20; // Controls fraction of the tray hidden when open
private static final int MOVEMENT_REGION_FRACTION = 20; // Controls fraction of y-axis on screen within which the tray stays.
private static final int VIEW_CROP_FRACTION = 12; // Controls fraction of the tray chipped at the right end.
private static final int ANIMATION_FRAME_RATE = 30; // Animation frame rate per second.
private static final int VIEW_DIM_X_DP = 170; // Width of the tray in dps
private static final int VIEW_DIM_Y_DP = 170; // Height of the tray in dps
// Layout containers for various widgets
private WindowManager mWindowManager; // Reference to the window
private WindowManager.LayoutParams mWindowParams; // Parameters of the root layout
private RelativeLayout mRootLayout; // Root layout
private RelativeLayout mCoverLayout; // Contains album cover of the active song
// Variables that control drag
private int mStartDragX;
//private int mStartDragY; // Unused as yet
private int mPrevDragX;
private int mPrevDragY;
private boolean mIsTrayOpen = true;
// Controls for animations
private Timer mTrayAnimationTimer;
private TrayAnimationTimerTask mTrayTimerTask;
private Handler mAnimationHandler = new Handler();
@Override
public IBinder onBind(Intent intent) {
// Not used
return null;
}
@Override
public void onCreate() {
// Get references to all the views and add them to root view as needed.
mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
mRootLayout = (RelativeLayout) LayoutInflater.from(this).
inflate(R.layout.service_player, null);
mCoverLayout = (RelativeLayout) mRootLayout.findViewById(R.id.cover_layout);
mCoverLayout.setOnTouchListener(new TrayTouchListener());
mWindowParams = new WindowManager.LayoutParams(
Utils.dpToPixels(VIEW_DIM_X_DP, getResources()),
Utils.dpToPixels(VIEW_DIM_Y_DP, getResources()),
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
PixelFormat.TRANSLUCENT);
mWindowParams.gravity = Gravity.TOP | Gravity.LEFT;
mWindowManager.addView(mRootLayout, mWindowParams);
// Post these actions at the end of looper message queue so that the layout is
// fully inflated once these functions execute
mRootLayout.postDelayed(new Runnable() {
@Override
public void run() {
// Reusable variables
RelativeLayout.LayoutParams params;
InputStream is;
Bitmap bmap;
int containerNewWidth = (VIEW_CROP_FRACTION-1)*mCoverLayout.getHeight()/VIEW_CROP_FRACTION;
// Setup background album cover
is=null;
try {
//is = getAssets().open(mPlaylist.getCurrentSongInfo().mAlbumCoverPath);
is=getAssets().open("adele.png");
} catch (IOException e) {
e.printStackTrace();
}
bmap = Utils.loadMaskedBitmap(is, mCoverLayout.getHeight(), containerNewWidth);
params = (RelativeLayout.LayoutParams) mCoverLayout.getLayoutParams();
params.width = (bmap.getWidth() * mCoverLayout.getHeight()) / bmap.getHeight();
params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT,0);
mCoverLayout.setLayoutParams(params);
mCoverLayout.requestLayout();
mCoverLayout.setBackgroundDrawable(new BitmapDrawable(getResources(), bmap));
// Setup the root layout
mWindowParams.x = -mCoverLayout.getLayoutParams().width;
mWindowParams.y = (getApplicationContext().getResources().getDisplayMetrics().heightPixels-mRootLayout.getHeight()) / 2;
mWindowManager.updateViewLayout(mRootLayout, mWindowParams);
// Make everything visible
mRootLayout.setVisibility(View.VISIBLE);
// Animate the Tray
mTrayTimerTask = new TrayAnimationTimerTask();
mTrayAnimationTimer = new Timer();
mTrayAnimationTimer.schedule(mTrayTimerTask, 0, ANIMATION_FRAME_RATE);
}
}, ANIMATION_FRAME_RATE);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent.getBooleanExtra("stop_service", false)){
// If it's a call from the notification, stop the service.
stopSelf();
}else{
// Make the service run in foreground so that the system does not shut it down.
Intent notificationIntent = new Intent(this, PlayerService.class);
notificationIntent.putExtra("stop_service", true);
PendingIntent pendingIntent = PendingIntent.getService(this, 0, notificationIntent, 0);
Notification notification = new Notification(
R.drawable.ic_launcher,
"Spotify tray launched",
System.currentTimeMillis());
notification.setLatestEventInfo(
this,
"Spotify tray",
"Tap to close the widget.",
pendingIntent);
startForeground(86, notification);
}
return START_STICKY;
}
// The app is closing.
@Override
public void onDestroy() {
if (mRootLayout != null)
mWindowManager.removeView(mRootLayout);
}
// Drags the tray as per touch info
private void dragTray(int action, int x, int y){
switch (action){
case MotionEvent.ACTION_DOWN:
// Cancel any currently running animations/automatic tray movements.
if (mTrayTimerTask!=null){
mTrayTimerTask.cancel();
mTrayAnimationTimer.cancel();
}
// Store the start points
mStartDragX = x;
//mStartDragY = y;
mPrevDragX = x;
mPrevDragY = y;
break;
case MotionEvent.ACTION_MOVE:
// Calculate position of the whole view according to the drag, and update layout.
float deltaX = x-mPrevDragX;
float deltaY = y-mPrevDragY;
mWindowParams.x += deltaX;
mWindowParams.y += deltaY;
mPrevDragX = x;
mPrevDragY = y;
mWindowManager.updateViewLayout(mRootLayout, mWindowParams);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
// When the view is released, bring it back to "open" or "closed" state.
if ((mIsTrayOpen && (x-mStartDragX)<=0) ||
(!mIsTrayOpen && (x-mStartDragX)>=0))
mIsTrayOpen = !mIsTrayOpen;
mTrayTimerTask = new TrayAnimationTimerTask();
mTrayAnimationTimer = new Timer();
mTrayAnimationTimer.schedule(mTrayTimerTask, 0, ANIMATION_FRAME_RATE);
break;
}
}
// Listens to the touch events on the tray.
private class TrayTouchListener implements OnTouchListener {
@Override
public boolean onTouch(View v, MotionEvent event) {
final int action = event.getActionMasked();
switch (action) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
// Filter and redirect the events to dragTray()
dragTray(action, (int)event.getRawX(), (int)event.getRawY());
break;
default:
return false;
}
return true;
}
}
// Timer for animation/automatic movement of the tray.
private class TrayAnimationTimerTask extends TimerTask{
// Ultimate destination coordinates toward which the tray will move
int mDestX;
int mDestY;
public TrayAnimationTimerTask(){
// Setup destination coordinates based on the tray state.
super();
if (!mIsTrayOpen){
mDestX = -mCoverLayout.getWidth();
}else{
mDestX = -mRootLayout.getWidth()/HIDDEN_FRACTION;
}
// Keep upper edge of the widget within the upper limit of screen
int screenHeight = getResources().getDisplayMetrics().heightPixels;
mDestY = Math.max(
screenHeight/MOVEMENT_REGION_FRACTION,
mWindowParams.y);
// Keep lower edge of the widget within the lower limit of screen
mDestY = Math.min(
((MOVEMENT_REGION_FRACTION-1)*screenHeight)/MOVEMENT_REGION_FRACTION - mRootLayout.getWidth(),
mDestY);
mDestX = Math.max(mWindowParams.x,screenHeight/MOVEMENT_REGION_FRACTION);
// Keep lower edge of the widget within the lower limit of screen
mDestX = Math.min(mDestX,((MOVEMENT_REGION_FRACTION-1)*screenHeight)/MOVEMENT_REGION_FRACTION - mRootLayout.getWidth());
}
// This function is called after every frame.
@Override
public void run() {
// handler is used to run the function on main UI thread in order to
// access the layouts and UI elements.
mAnimationHandler.post(new Runnable() {
@Override
public void run() {
// Update coordinates of the tray
mWindowParams.x = (2*(mWindowParams.x-mDestX))/3 + mDestX;
mWindowParams.y = (2*(mWindowParams.y-mDestY))/3 + mDestY;
mWindowManager.updateViewLayout(mRootLayout, mWindowParams);
// Cancel animation when the destination is reached
if (Math.abs(mWindowParams.x-mDestX)<2 && Math.abs(mWindowParams.y-mDestY)<2){
TrayAnimationTimerTask.this.cancel();
mTrayAnimationTimer.cancel();
}
}
});
}
}
}