Back to project page AppFloater.
The source code is released under:
GNU General Public License
If you think the Android project AppFloater listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
package tt.co.justins.appfloater; /*from w ww .j a v a 2 s. co m*/ import android.annotation.TargetApi; import android.app.Service; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.PixelFormat; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.os.Binder; import android.os.Build; import android.os.Bundle; import android.os.IBinder; import android.util.Log; import android.view.Gravity; import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; import android.view.WindowManager; import android.widget.ImageView; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; /** * Created by Justin on 10/31/13. */ @TargetApi(11) public class FloatService extends Service { List<ImageView> viewList = new ArrayList<ImageView>(); WindowManager windowManager; PackageManager packageManager; Binder binder = new FloatBinder(); SharedPreferences mPreferences; class IconHolder { public ImageView view; public int statusId; public String packageName; public Drawable defaultIcon; public Drawable statusIcon; public float x_pos; public float y_pos; IconHolder(ImageView view, Drawable baseIcon, String packageName) { this.view = view; this.defaultIcon = baseIcon; this.statusIcon = baseIcon; this.statusId = 0; this.packageName = new String(packageName); } } public class FloatBinder extends Binder { FloatService getService() { return FloatService.this; } } @Override public IBinder onBind(Intent intent) { return binder; } @Override public void onCreate() { super.onCreate(); windowManager = (WindowManager) getSystemService(WINDOW_SERVICE); packageManager = getPackageManager(); mPreferences = getSharedPreferences("appfloat.prefs", MODE_PRIVATE); } @Override public int onStartCommand(Intent intent, int flags, int startId) { if(intent == null) { Log.d("AppFloat", "Service started with null intent"); floatSavedApps(); } else { Log.d("AppFloat", "Service started with intent"); Bundle bundle = intent.getExtras(); String packageName = bundle.getString("appPackage"); int resourceId = bundle.getInt("resId"); floatApp(packageName, resourceId); } return START_STICKY; } private Set<String> getPrefPackageList() { Set<String> packageNames = new HashSet<String>(); packageNames = mPreferences.getStringSet("packageNames", packageNames); return packageNames; } private void addToPrefPackageList(String packageName) { if(packageName == null) return; Set<String> oldPackageNameList = getPrefPackageList(); Set<String> newPackageNameList = new HashSet<String>(oldPackageNameList); newPackageNameList.add(packageName); SharedPreferences.Editor editor = mPreferences.edit(); editor.putStringSet("packageNames", newPackageNameList); editor.commit(); Log.d("AppFloat", newPackageNameList.size() + " package names in saved preferences"); } private void addIconToScreen(final String packageName, int resourceId, int x, int y) { if(viewList.size() >= 5) { return; } final ImageView iconView = new ImageView(this); viewList.add(iconView); Drawable draw = getIcon(packageName, resourceId); iconView.setImageDrawable(draw); IconHolder iconHolder = new IconHolder(iconView, draw, packageName); iconView.setTag(iconHolder); final WindowManager.LayoutParams params = new WindowManager.LayoutParams(); setWindowParams(params, x, y); windowManager.addView(iconView, params); ViewConfiguration vc = ViewConfiguration.get(iconView.getContext()); final int mScaledTouchSlop = 20; final int mLongPressTimeOut = vc.getLongPressTimeout(); final int mTapTimeOut = vc.getTapTimeout(); iconView.setOnTouchListener(new View.OnTouchListener() { private WindowManager.LayoutParams paramsF = params; private int initialX; private int initialY; private float initialTouchX; private float initialTouchY; @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: Log.d("AppFloat", "Action Down"); initialX = paramsF.x; initialY = paramsF.y; initialTouchX = event.getRawX(); initialTouchY = event.getRawY(); return false; case MotionEvent.ACTION_MOVE: Log.d("AppFloat", "Action Move"); paramsF.x = initialX + (int) (event.getRawX() - initialTouchX); paramsF.y = initialY + (int) (event.getRawY() - initialTouchY); windowManager.updateViewLayout(iconView, paramsF); return false; case MotionEvent.ACTION_UP: Log.d("AppFloat", "Action Up"); Log.d("AppFloat", "DistanceX: " + Math.abs(initialTouchX - event.getRawX())); Log.d("AppFloat", "DistanceY: " + Math.abs(initialTouchY - event.getRawY())); Log.d("AppFloat", "elapsed gesture time: " + (event.getEventTime() - event.getDownTime())); if((Math.abs(initialTouchX - event.getRawX()) <= mScaledTouchSlop) && (Math.abs(initialTouchY - event.getRawY()) <= mScaledTouchSlop)) { if((event.getEventTime() - event.getDownTime()) < mTapTimeOut ) { Log.d("AppFloat", "Click Detected"); startAppActivity(packageName); } else if((event.getEventTime() - event.getDownTime()) >= mLongPressTimeOut) { Log.d("AppFloat", "Long Click Detected"); } } default: Log.d("AppFloat", "Action Default"); break; } return false; } }); } private void startAppActivity(String packageName) { Intent intent = packageManager.getLaunchIntentForPackage(packageName); if(intent != null) { startActivity(intent); } } private void setWindowParams(WindowManager.LayoutParams params, int x, int y) { params.height = WindowManager.LayoutParams.WRAP_CONTENT; params.width = WindowManager.LayoutParams.WRAP_CONTENT; params.type = WindowManager.LayoutParams.TYPE_PHONE; params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; params.format = PixelFormat.TRANSLUCENT; params.gravity = Gravity.TOP | Gravity.LEFT; if(x < 0 || y < 0) { params.y = dpToPx(100) * viewList.size(); } else { params.x = (int) x; params.y = (int) y; } } private int dpToPx(int dp) { return (int) (dp * getResources().getDisplayMetrics().density + 0.5f); } private Drawable getIcon(String packageName, int resourceId) { Drawable icon = null; if(resourceId == 0) { Log.v("AppFloat", "Resource ID not found, attempting to load package icon"); try { icon = getPackageIcon(packageName); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } } else { Log.v("AppFloat", "Loading image using Resource ID"); icon = getPackageImage(packageName, resourceId); } if(icon == null) { Log.v("AppFloat", "Using default image for icon"); icon = getResources().getDrawable(R.drawable.ic_launcher); } return icon; } private Drawable getPackageImage(String packageName, int resourceId) { return packageManager.getDrawable(packageName, resourceId, null); } private Drawable getPackageIcon(String appPackage) throws PackageManager.NameNotFoundException { Drawable draw = null; try { draw = packageManager.getApplicationIcon(appPackage); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } return draw; } private Drawable mergeBitmap(Drawable base, Drawable status) { Bitmap bitmap = Bitmap.createBitmap(base.getIntrinsicWidth(), base.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); Canvas c = new Canvas(bitmap); int top = base.getIntrinsicHeight() - status.getIntrinsicHeight(); base.setBounds(0, 0, base.getIntrinsicWidth(), base.getIntrinsicHeight()); status.setBounds(0, 70, 30, 100); base.draw(c); status.draw(c); Drawable draw = new BitmapDrawable(getResources(), bitmap); return draw; } /* * Public binding methods used by attached application */ public void updateIconStatus(int statusId) { updateIconStatus(statusId, 0); } public void updateIconStatus(int statusId, int iconArrayIndex) { Drawable statusIcon; IconHolder holder = (IconHolder) viewList.get(iconArrayIndex).getTag(); Log.d("AppFloat", "updateIcon position: " + statusId); switch(statusId) { case 1: statusIcon = getResources().getDrawable(R.drawable.one); break; case 2: statusIcon = getResources().getDrawable(R.drawable.two); break; case 3: statusIcon = getResources().getDrawable(R.drawable.three); break; case 4: statusIcon = getResources().getDrawable(R.drawable.four); break; case 5: statusIcon = getResources().getDrawable(R.drawable.five); break; case 6: statusIcon = getResources().getDrawable(R.drawable.six); break; case 7: statusIcon = getResources().getDrawable(R.drawable.seven); break; case 8: statusIcon = getResources().getDrawable(R.drawable.eight); break; case 9: statusIcon = getResources().getDrawable(R.drawable.nine); break; default: statusIcon = getResources().getDrawable(R.drawable.nineplus); } holder.statusId = statusId; holder.statusIcon = mergeBitmap(holder.defaultIcon, statusIcon); holder.view.setImageDrawable(holder.statusIcon); } public void floatApp(String packageName, int resourceId) { addIconToScreen(packageName, resourceId, -1, -1); } public void floatSavedApps() { Set<String> packageNames = getPrefPackageList(); for(String packageName : packageNames) { addIconToScreen(packageName, 0, -1, -1); //TODO add a way to save resource IDs } } public void removeIconsFromScreen() { for(ImageView view : viewList ) { windowManager.removeView(view); } viewList.clear(); //onDestroy(); } public void saveIconsToPref() { for(ImageView view : viewList) { IconHolder holder = (IconHolder) view.getTag(); addToPrefPackageList(holder.packageName); holder.x_pos = view.getX(); holder.y_pos = view.getY(); } } public void clearPrefPackageList() { SharedPreferences.Editor editor = mPreferences.edit(); editor.remove("packageNames"); editor.commit(); } @Override public void onDestroy() { super.onDestroy(); } }