Androidサスペンション設定で、クリックイベントをサポートします.

8826 ワード

サービスクラスを1つアップロードするだけで十分だと思います.activityでこのサービスを起動します.
実現する機能は、メイン画面に切り替わったときに表示される浮遊アイコン、アプリに入ったときに解除される浮遊アイコンです.
4.0以上のシステムを表示したい場合は、アプリケーション内で浮遊アイコンの表示を選択する必要があります.
コードは主にネット上のリソースを借りて、自分でクリックイベントに応答する機能を追加した.
また、私のクラスにはスクリーンをロックする機能もありますので、これは使用者自身で無視してください.
public class ZMLockService extends Service {

	Context context;
	private Intent zdLockIntent = null;
	private int phoneState = 0;
	private KeyguardManager mKeyguardManager = null;
	private KeyguardManager.KeyguardLock mKeyguardLock = null;
	private View.OnClickListener mClickListener;

	public static final String OPERATION = "operation";
	public static final int OPERATION_SHOW = 100;
	public static final int OPERATION_HIDE = 101;

	private static final int HANDLE_CHECK_ACTIVITY = 200;

	private boolean isAdded = false; //         
	private static WindowManager wm;
	private static WindowManager.LayoutParams params;
	private Button btn_floatView;

	private List<String> homeList; //           
	private ActivityManager mActivityManager;

	@Override
	public IBinder onBind(Intent intent) {
		Log_I("log");

		return null;
	}

	@Override
	public void onCreate() {
		super.onCreate();
		this.context = this;
		Log_I("   Service");

		MyPhoneStateListener myPhoneStateListener = new MyPhoneStateListener();
		//   TelephonyManager
		TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
		//       Listener    TelephonyManager
		telephonyManager.listen(myPhoneStateListener,
				PhoneStateListener.LISTEN_CALL_STATE);

		zdLockIntent = new Intent(ZMLockService.this, LockActivity.class);
		zdLockIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

		/*      */
		IntentFilter mScreenOnFilter = new IntentFilter(
				"android.intent.action.SCREEN_ON");
		ZMLockService.this.registerReceiver(mScreenOnReceiver, mScreenOnFilter);

		/*      */
		IntentFilter mScreenOffFilter = new IntentFilter(
				"android.intent.action.SCREEN_OFF");
		mScreenOffFilter.setPriority(Integer.MAX_VALUE);
		ZMLockService.this.registerReceiver(mScreenOffReceiver,
				mScreenOffFilter);

		//      
		homeList = getHomes();
		createFloatView();
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {

		flags = START_STICKY;

		return super.onStartCommand(intent, flags, startId);
	}

	@Override
	public void onStart(Intent intent, int startId) {
		super.onStart(intent, startId);

		int operation = intent.getIntExtra(OPERATION, OPERATION_SHOW);
		switch (operation) {
		case OPERATION_SHOW:
			mHandler.removeMessages(HANDLE_CHECK_ACTIVITY);
			mHandler.sendEmptyMessage(HANDLE_CHECK_ACTIVITY);
			break;
		case OPERATION_HIDE:
			mHandler.removeMessages(HANDLE_CHECK_ACTIVITY);
			break;
		}
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		if (mHandler != null) {
			mHandler.removeMessages(HANDLE_CHECK_ACTIVITY);
		}
		Log_I("   Service");
		ZMLockService.this.unregisterReceiver(mScreenOnReceiver);
		ZMLockService.this.unregisterReceiver(mScreenOffReceiver);
		//                ,     service
		// if(this.getSharedPreferences(Constant.SP_JS,
		// 0).getString(Constant.SP_JS_LOCK, "1").equals("1")){
		// startService(new Intent(ZMLockService.this, ZMLockService.class));
		// }
	}

	private Handler mHandler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case HANDLE_CHECK_ACTIVITY:
				if (isHome()) {
					if (!isAdded) {
						wm.addView(btn_floatView, params);
						isAdded = true;
					}
				} else {
					if (isAdded) {
						wm.removeView(btn_floatView);
						isAdded = false;
					}
				}
				mHandler.sendEmptyMessageDelayed(HANDLE_CHECK_ACTIVITY, 1000);
				break;
			}
		}
	};

	//        ,            
	private BroadcastReceiver mScreenOnReceiver = new BroadcastReceiver() {

		@Override
		public void onReceive(Context context, Intent intent) {

			if (intent.getAction().equals("android.intent.action.SCREEN_ON")) {
				mKeyguardManager = (KeyguardManager) context
						.getSystemService(Context.KEYGUARD_SERVICE);
				mKeyguardLock = mKeyguardManager.newKeyguardLock("zdLock 1");
				mKeyguardLock.disableKeyguard();
			}
		}

	};

	//     /      ,      KeyguardManager            
	private BroadcastReceiver mScreenOffReceiver = new BroadcastReceiver() {
		@Override
		public void onReceive(Context context, Intent intent) {
			String action = intent.getAction();
			if (((action.equals("android.intent.action.SCREEN_OFF") || action
					.equals("android.intent.action.SCREEN_ON")) && phoneState == 0)) {

				// Log.e("TEST", "    ,phoneState:"+phoneState);
				mKeyguardManager = (KeyguardManager) context
						.getSystemService(Context.KEYGUARD_SERVICE);
				mKeyguardLock = mKeyguardManager.newKeyguardLock("zdLock 1");
				//          
				mKeyguardLock.disableKeyguard();
				Log_I("  LockActivity,Time" + new Date().getTime());
				//         
				startActivity(zdLockIntent);
			}
		}

	};

	/**
	 *      
	 */
	private void createFloatView() {
		btn_floatView = new Button(getApplicationContext());
		btn_floatView.setBackgroundResource(R.drawable.float_view);

		wm = (WindowManager) getApplicationContext().getSystemService(
				Context.WINDOW_SERVICE);
		params = new WindowManager.LayoutParams();

		//   window type
		params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
		/*
		 *      params.type = WindowManager.LayoutParams.TYPE_PHONE;           ,
		 *          
		 */

		params.format = PixelFormat.RGBA_8888; //       ,       

		//   Window flag
		params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
				| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
		/*
		 *    flags       “  ”。        ,       ,            。
		 * wmParams.flags=LayoutParams.FLAG_NOT_TOUCH_MODAL |
		 * LayoutParams.FLAG_NOT_FOCUSABLE | LayoutParams.FLAG_NOT_TOUCHABLE;
		 */

		//          
		params.width = 100;
		params.height = 100;

		//       Touch  
		btn_floatView.setOnTouchListener(new OnTouchListener() {

			int lastX;
			int lastY;
			int paramX;
			int paramY;

			public boolean onTouch(View v, MotionEvent event) {
				
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					lastX = (int) event.getRawX();
					lastY = (int) event.getRawY();
					paramX = params.x;
					paramY = params.y;
					Log_I("down");
					break;
				case MotionEvent.ACTION_MOVE:
					int dx = (int) event.getRawX() - lastX;
					int dy = (int) event.getRawY() - lastY;
					params.x = paramX + dx;
					params.y = paramY + dy;
					//        
					wm.updateViewLayout(btn_floatView, params);
					Log_I("move");
					break;
				case MotionEvent.ACTION_UP:
					if(Math.abs(event.getRawX()-lastX)<5&&Math.abs(event.getRawY()-lastY)<5){
						Toast.makeText(context, "   ,   !", Toast.LENGTH_SHORT).show();
					}
					Log_I("up");
					break;
				}
				return true;
			}
		});

		wm.addView(btn_floatView, params);
		isAdded = true;
	}

	/**
	 *                
	 * 
	 * @return               
	 */
	private List<String> getHomes() {
		List<String> names = new ArrayList<String>();
		PackageManager packageManager = this.getPackageManager();
		//   
		Intent intent = new Intent(Intent.ACTION_MAIN);
		intent.addCategory(Intent.CATEGORY_HOME);
		List<ResolveInfo> resolveInfo = packageManager.queryIntentActivities(
				intent, PackageManager.MATCH_DEFAULT_ONLY);
		for (ResolveInfo ri : resolveInfo) {
			names.add(ri.activityInfo.packageName);
		}
		return names;
	}

	/**
	 *            
	 */
	public boolean isHome() {
		if (mActivityManager == null) {
			mActivityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
		}
		List<RunningTaskInfo> rti = mActivityManager.getRunningTasks(1);
		return homeList.contains(rti.get(0).topActivity.getPackageName());
	}

	void Log_I(String log) {
		LogHelper.Log_I(this.getClass().getSimpleName(), log);
	}

	public View.OnClickListener getmClickListener() {
		return mClickListener;
	}

	public void setmClickListener(View.OnClickListener mClickListener) {
		this.mClickListener = mClickListener;
	}

	class MyPhoneStateListener extends PhoneStateListener {
		@Override
		public void onCallStateChanged(int state, String phoneNumber) {
			switch (state) {
			//         
			case TelephonyManager.CALL_STATE_IDLE:
				phoneState = TelephonyManager.CALL_STATE_IDLE;
				break;
			//         
			case TelephonyManager.CALL_STATE_OFFHOOK:
				phoneState = TelephonyManager.CALL_STATE_OFFHOOK;
				break;
			//         
			case TelephonyManager.CALL_STATE_RINGING:
				phoneState = TelephonyManager.CALL_STATE_RINGING;
				break;
			default:
				break;
			}
		}
	}

}