public class FlashController {
	private final static String TAG = "FlashController";
	private static FlashController mInstance;

	public final static int LEVEL_MAX = 7;
	public final static int LEVEL_OFF = 0;
	private int currentLevel;

	private Parameters parameters;
	private Camera camera;

	private int switchSound;
	private SoundPool soundPool;
	private boolean isSoundInit;// 是否可以播放
	private boolean enableSound;// 是否可以开声音

	private long AUTO_CLOSE_TIME_INTERVAL = 0;
	private AlarmManager alarmManager;// FIXME这个可以Softreference
	private PendingIntent autoCloseRequest;
	private long flashOpenTimeMills = 0;

	private List<OnFlashLevelChangedListener> observers;
	private int lisenseState = -1;
	private boolean lisenseEnable;
	private FlashHelper flashHelper;

	private Object CAMERA_LOCK = new Object();
	private boolean isCameraInited = false;

	// FIXME 执行完毕之后是否需要显式去停止
	private Runnable cameraInitTask = new Runnable() {

		@Override
		public void run() {
			initCamera(hasCameraReleased());
		}
	};

	private FlashController() {
		lisenseEnable = true;
		currentLevel = LEVEL_OFF;
		flashHelper = new FlashHelper();
		enableSound = MPreferenceManager.getInstance().isSwitchSoundOn();
	}

	public static FlashController getInstance() {
		if (mInstance == null)
			mInstance = new FlashController();
		return mInstance;
	}

	// FIXME 在哪释放
	public void releaseInstance() {
		if (mInstance != null) {
			relaseSwitchSound();
			releaseAutoCloseMgr();
			releaseCamera();
			mInstance = null;
			observers.removeAll(observers);
		}
	}

	// FIXME 线程执行完毕之后需不需要停止
	public void initCameraSync() {
		Thread cameraInitThread = new Thread(cameraInitTask);
		cameraInitThread.start();
	}

	/*
	 * 回到桌面的时候需要调用一次
	 */
	public void initCamera() {
		initCamera(hasCameraReleased());
	}
	
	private void initCamera(boolean needReconnect) {
		synchronized (CAMERA_LOCK) {
			if(isCameraInited == false) {
				if (needReconnect && camera != null) {
					camera = null;
				}
				try {
					if (camera == null)
						camera = Camera.open();
					parameters = camera.getParameters();
				} catch (RuntimeException re) {
					parameters = null;
				}
				if (needReconnect && currentLevel > LEVEL_OFF) {
					currentLevel = LEVEL_OFF;
					notifyFlashLevelChanged();//重新打开需要通知对应的观察者
					turnFlashOffIfCameraReleased();
				}
				isCameraInited = parameters != null;
			}
		}
	}
	
	/*
	 * 关灯灭屏时释放Camera，亮屏幕时不着急调用，首次调用时打开
	 */
	public void releaseCamera() {
		synchronized (CAMERA_LOCK) {
			if (camera != null) {
				try {
					camera.release();
				} catch (RuntimeException re) {
					Log.v(TAG, "camera already released");
				}
				camera = null;
				isCameraInited = false;
			}
		}
	}

	public void initSwitchSound() {
		if (enableSound && (isSoundInit == false || soundPool == null)) {
			soundPool = new SoundPool(2, AudioManager.STREAM_MUSIC, 0);
			soundPool.setOnLoadCompleteListener(soundInitListener);
			switchSound = soundPool.load(FlashApp.getContext(),
					R.raw.flashswitch, 1);
		}
	}

	OnLoadCompleteListener soundInitListener = new OnLoadCompleteListener() {
		@Override
		public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
			isSoundInit = true;
		}
	};

	/*
	 * 关灯灭屏时释放，亮屏幕时不着急调用，首次调用时打开
	 */
	public void relaseSwitchSound() {
		if (soundPool != null && isSoundInit) {
			soundPool.release();
			soundPool = null;
			isSoundInit = false;
		}
	}

	public void enableSound() {
		enableSound = true;
		initSwitchSound();// 打开这个时，用户应该很快想去试试，所以提前加载
	}

	public void disabelSound() {
		enableSound = false;
		relaseSwitchSound();
	}

	// FIXME 这样还是不能确保，可能那一次没有声音
	public void playSwitchSound() {
		initSwitchSound();
		if (enableSound && isSoundInit)
			soundPool.play(switchSound, 1.5f, 1.5f, 0, 0, 1);
	}

	private void initAutoCloseMgr() {
		if (alarmManager == null) {
			alarmManager = (AlarmManager) FlashApp.getContext()
					.getSystemService(Context.ALARM_SERVICE);
		}
	}

	public void releaseAutoCloseMgr() {
		cancelAutoCloseTask();
		alarmManager = null;
		autoCloseRequest = null;
	}

	/*
	 * 调用时机 1. 开灯的时候 2. 调整设置项的时候 FIXME 如果时间已经过了
	 */
	private void requestAutoCloseTask() {
		requestAutoCloseTask(0);
	}
	
	public void requestAutoCloseTask(long autoCloseTimInterval) {
		initAutoCloseMgr();
		
		if(autoCloseTimInterval > 0) {
			AUTO_CLOSE_TIME_INTERVAL = autoCloseTimInterval;
		} else if(AUTO_CLOSE_TIME_INTERVAL == 0) {
			AUTO_CLOSE_TIME_INTERVAL = MPreferenceManager.getInstance().getAutoCloseTime() * 60000;
		}
		
		if (currentLevel > LEVEL_OFF) {
			long triggleAtMills = flashOpenTimeMills + AUTO_CLOSE_TIME_INTERVAL;
			Intent requestIntent = ServiceHelper.getAutoCloseIntent();
			autoCloseRequest = PendingIntent.getService(FlashApp.getContext(),
					0, requestIntent, PendingIntent.FLAG_CANCEL_CURRENT);
			alarmManager
					.set(AlarmManager.RTC, triggleAtMills, autoCloseRequest);
		}
	}

	public void cancelAutoCloseTask() {
		if (autoCloseRequest != null) {
			alarmManager.cancel(autoCloseRequest);
			autoCloseRequest = null;
		}
	}

	public int toggleFlash() {
		initCamera();
		if (currentLevel == LEVEL_OFF) {
			turnFlashOn();
		} else {
			turnFlashOff();
		}
		return currentLevel;
	}

	private void turnFlashOn() {
		if (isCameraInited && currentLevel == LEVEL_OFF) {
			parameters.setFlashMode(Parameters.FLASH_MODE_TORCH);
			try {
				camera.setParameters(parameters);
			} catch (RuntimeException re) {
				initCamera(true);
				parameters.setFlashMode(Parameters.FLASH_MODE_TORCH);
			}
			currentLevel = LEVEL_MAX;
			flashOpenTimeMills = System.currentTimeMillis();

			requestAutoCloseTask();
			playSwitchSound();
		}
	}

	public void turnFlashOff() {
		if (isCameraInited && currentLevel > LEVEL_OFF) {
			parameters.setFlashMode(Parameters.FLASH_MODE_OFF);
			try {
				camera.setParameters(parameters);
			} catch (RuntimeException re) {
				initCamera(true);
				parameters.setFlashMode(Parameters.FLASH_MODE_OFF);
			}
			currentLevel = LEVEL_OFF;
			flashOpenTimeMills = 0;
			cancelAutoCloseTask();

			playSwitchSound();
		}
	}
	
	public void turnFlashOffIfCameraReleased() {
		if(currentLevel > LEVEL_OFF) {
			currentLevel = LEVEL_OFF;
			flashOpenTimeMills = 0;
	
			cancelAutoCloseTask();
		}
	}
	/*
	 * 调节亮度需要lisenseEnable才可以
	 */
	public int turnFlashUp() {
		if (lisenseEnable && currentLevel < LEVEL_MAX) {
			flashHelper.changeFlashLight(true);
			currentLevel++;
		}
		return currentLevel;
	}

	public int turnFlashDown() {
		if (lisenseEnable && currentLevel > LEVEL_OFF + 1) {
			flashHelper.changeFlashLight(false);
			currentLevel--;
		}
		return currentLevel;
	}

	public boolean hasCameraReleased() {
		boolean hasReleased = false;
		if(camera == null) {
			hasReleased = true;
			isCameraInited = false;
		} else {
			try {
				parameters = camera.getParameters();
			} catch (RuntimeException re) {
				hasReleased = true;
				isCameraInited = false;
			}
		}
		return hasReleased;
	}

	public int getCurrentLevel() {
		return currentLevel;
	}

	public boolean isFlashOn() {
		return currentLevel > LEVEL_OFF;
	}

	public void notifyFlashLevelChanged() {
		if (observers != null) {
			for (OnFlashLevelChangedListener observer : observers) {
				observer.onFlashLevelChanged(currentLevel);
			}
		}
	}

	public void setLisenseState(int lisenseState) {
		if (this.lisenseState != lisenseState) {
			this.lisenseState = lisenseState;

			lisenseEnable = lisenseState == MLisenseMangaer.STATE_PURCHASED
					|| lisenseState == MLisenseMangaer.STATE_TRYING;
			
			if(!lisenseEnable) {
				//关闭对应设置项，并通知更新
				MPreferenceManager prefsMgr = MPreferenceManager.getInstance();
				prefsMgr.toggleKeyguardPanel(false, true);
				prefsMgr.toggleLauncherPanel(false, true);
				//FIXME preference的写入考虑使用队列的形式
			}
		}
	}
	
	public int getLisenseState() {
		return lisenseState;
	}
	
	public boolean islisenseEnable() {
		return lisenseEnable;
	}
	
	public boolean isPurchased() {
		return lisenseState == MLisenseMangaer.STATE_PURCHASED;
	}
	
	public void addObserver(OnFlashLevelChangedListener listener) {
		if (observers == null)
			observers = new ArrayList<OnFlashLevelChangedListener>();
		if (!observers.contains(listener)) {
			observers.add(listener);
		}
	}

	public void removeObserver(OnFlashLevelChangedListener listener) {
		if (observers != null && observers.contains(listener)) {
			observers.remove(listener);
		}
	}

	public interface OnFlashLevelChangedListener {
		public void onFlashLevelChanged(int currentLevel);
	}
} public class ServiceHelper {
	public static void startLauncherPanelService() {
		Intent intent = new Intent(PanelService.ACTION_LAUNCHER);
		intent.putExtra(PanelService.CONTROL_TYPE_KEY,
				PanelService.CONTROL_TYPE_START);
		FlashApp.getContext().startService(intent);
	}

	public static void stopLauncherPanelService() {
		Intent intent = new Intent(PanelService.ACTION_LAUNCHER);
		intent.putExtra(PanelService.CONTROL_TYPE_KEY,
				PanelService.CONTROL_TYPE_STOP);
		FlashApp.getContext().startService(intent);
	}

	public static void startKeyguardPanelService() {
		Intent intent = new Intent(PanelService.ACTION_KEYGUARD);
		intent.putExtra(PanelService.CONTROL_TYPE_KEY,
				PanelService.CONTROL_TYPE_START);
		FlashApp.getContext().startService(intent);
	}

	public static void stopKeyguardPanelService() {
		Intent intent = new Intent(PanelService.ACTION_KEYGUARD);
		intent.putExtra(PanelService.CONTROL_TYPE_KEY,
				PanelService.CONTROL_TYPE_STOP);
		FlashApp.getContext().startService(intent);
	}

	public static void callPanelServiceWhenScreenOn() {
		Intent intent = new Intent(PanelService.ACTION_PANEL_SERVICE);
		intent.putExtra(PanelService.CONTROL_TYPE_KEY,
				PanelService.CONTROL_TYPE_SCREEN_ON);
		FlashApp.getContext().startService(intent);
	}

	public static void callPanelServiceWhenScreenOff() {
		Intent intent = new Intent(PanelService.ACTION_PANEL_SERVICE);
		intent.putExtra(PanelService.CONTROL_TYPE_KEY,
				PanelService.CONTROL_TYPE_SCREEN_OFF);
		FlashApp.getContext().startService(intent);
	}

	public static void callPanelServiceWhenUserPresent() {
		Intent intent = new Intent(PanelService.ACTION_PANEL_SERVICE);
		intent.putExtra(PanelService.CONTROL_TYPE_KEY,
				PanelService.CONTROL_TYPE_USER_PRESENT);
		FlashApp.getContext().startService(intent);
	}

	/*
	 * service启动入口
	 * 1. MainActivity界面，用户点击桌面icon进入
	 * 2. 重启，boot_complete广播
	 *
	 * 
	 */
	public static void startPanelService() {
		MPreferenceManager mPrefsMgr = MPreferenceManager.getInstance();
		boolean isLauncherPanelService = mPrefsMgr.isLauncherPanelShown();
		boolean isKeyguardPanelService = mPrefsMgr.isKeyguardPanelShown();
		if (isLauncherPanelService && isKeyguardPanelService) {
			Intent intent = new Intent(PanelService.ACTION_PANEL_SERVICE);
			intent.putExtra(PanelService.CONTROL_TYPE_KEY,
					PanelService.CONTROL_TYPE_START);
			FlashApp.getContext().startService(intent);
		} else if (isLauncherPanelService) {
			startLauncherPanelService();
		} else if (isKeyguardPanelService) {
			startKeyguardPanelService();
		}
	}
	
	public static void stopPanelService() {
		Intent intent = new Intent(PanelService.ACTION_PANEL_SERVICE);
		intent.putExtra(PanelService.CONTROL_TYPE_KEY,
				PanelService.CONTROL_TYPE_STOP);
		FlashApp.getContext().startService(intent);
	}
	
	public static Intent getAutoCloseIntent() {
		Intent requestIntent = new Intent(
				ControlService.ACTION_AUTO_CLOSE);
		requestIntent.putExtra(ControlService.CONTROL_TYPE_KEY, ControlService.CONTROL_TYPE_SHOW_ACDIALOG);
		return requestIntent;
	}
} public class CommonDataHelper {
//	private final static String VERSION_FORMATE ="V %1$s";
	public static String getCurrentAppVersion(Context context) {
		String version = "1.0.0";
        PackageManager packageManager = context.getPackageManager();
		try {
			PackageInfo packInfo = packageManager.getPackageInfo(context.getPackageName(),0);
			version = packInfo.versionName;
		} catch (NameNotFoundException e) {
			e.printStackTrace();
		}
        return version;
	}
	
	public static String getCurrentAppVersionInfo(Context context, String format) {
        return String.format(format, getCurrentAppVersion(context));
	}
	
	public static int getCurrentAppVersionCode(Context context) {
		int versionCode = 1;
        PackageManager packageManager = context.getPackageManager();
		try {
			PackageInfo packInfo = packageManager.getPackageInfo(context.getPackageName(),0);
			versionCode = packInfo.versionCode;
		} catch (NameNotFoundException e) {
			e.printStackTrace();
		}
        return versionCode;
	}
	
	public static String getDeviceInfo(Context context) {
		try {
			org.json.JSONObject json = new org.json.JSONObject();
			android.telephony.TelephonyManager tm = (android.telephony.TelephonyManager) context
					.getSystemService(Context.TELEPHONY_SERVICE);

			String device_id = tm.getDeviceId();

			android.net.wifi.WifiManager wifi = (android.net.wifi.WifiManager) context
					.getSystemService(Context.WIFI_SERVICE);

			String mac = wifi.getConnectionInfo().getMacAddress();
			json.put("mac", mac);

			if (TextUtils.isEmpty(device_id)) {
				device_id = mac;
			}

			if (TextUtils.isEmpty(device_id)) {
				device_id = android.provider.Settings.Secure.getString(
						context.getContentResolver(),
						android.provider.Settings.Secure.ANDROID_ID);
			}

			json.put("device_id", device_id);

			return json.toString();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
} public class LightmeConstants {
	public final static String APP_IDENTIFY = "6c1e42416976493cbdbe254554b4bef2";
} public class MConnectHelper {
	public static final String MSTORE_URI_HEADER = "mstore:";
    public static final String SOFTWARE_URL_BASE = "http://app.meizu.com/phone/apps/";
    public static final String MSTORE_IDENTIFY = "45e228a5a533488c8d46f7b5284d4ec7";
    
	private Context context;
	private Resources resource;

	public MConnectHelper(Context context) {
		resource = context.getResources();
		this.context = context;
	}
	
	public void sendLockMsgWithMail(int lisenseState) {
		String subject = resource.getString(R.string.lock_subject);
		String defaultContent = String.format(resource
				.getString(R.string.lock_content_default), MLisenseMangaer.getLisenseInfo(lisenseState));
		sendInfoWithMail(subject, defaultContent);
	}
	
	public void sendFeedbackWithMail() {
		String subject = resource.getString(R.string.feedback_subject);
		String defaultContent = resource
				.getString(R.string.feedback_content_default);
		sendInfoWithMail(subject, defaultContent);
	}

	private void sendInfoWithMail(String subject, String defaultContent) {
		Intent intent = getBaseShareIntent();

		List<ResolveInfo> resInfos = context.getPackageManager()
				.queryIntentActivities(intent, 0);
		List<Intent> targetIntents = null;
		Intent targetIntent = null;
		if (resInfos != null && !resInfos.isEmpty()) {
			targetIntents = new ArrayList<Intent>();
			for (ResolveInfo resInfo : resInfos) {
				ActivityInfo activityInfo = resInfo.activityInfo;
				if (activityInfo.packageName.contains("mail")) {
					targetIntent = getMailIntent(subject, defaultContent);
					targetIntent.setPackage(activityInfo.packageName);
					targetIntents.add(targetIntent);
				}
			}
			
			if(targetIntents.size() == 0)//FIXME 对于卸载邮箱的用户
				return ;
			
			Intent chooserIntent = Intent.createChooser(
					targetIntents.remove(0), "选择邮件应用");
			
			if (chooserIntent == null)
				return;
			chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS,
					targetIntents.toArray(new Intent[] {}));

			try {
				context.startActivity(chooserIntent);
			} catch (android.content.ActivityNotFoundException ex) {
				Toast.makeText(context, "Can't find share component to share",
						Toast.LENGTH_SHORT).show();
			}
		}
	}

	public Intent getMailIntent(String subject, String defaultContent) {
		Intent emailIntent = getBaseShareIntent();
		String[] emailReciver = new String[] { "dichengsiyu@gmail.com" };

		emailIntent.putExtra(Intent.EXTRA_EMAIL, emailReciver);
		emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
		emailIntent.putExtra(Intent.EXTRA_TEXT, defaultContent);
		return emailIntent;
	}

	private Intent getBaseShareIntent() {
		Intent intent = new Intent(Intent.ACTION_SEND);
		intent.setType("text/plain");
		return intent;
	}

	public void jumpToMarket(String appIdentify) {
		try {
			Intent intent = new Intent();
			intent.setData(Uri.parse(MSTORE_URI_HEADER
					+ SOFTWARE_URL_BASE + appIdentify));
			intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
			intent.setClassName("com.meizu.mstore",
					"com.meizu.mstore.MStoreMainPlusActivity");
			context.startActivity(intent);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
} public class MLisenseMangaer {
	private final static String TAG = "MLisenseMangaer";

	public final static int STATE_UNKNOWN = 0;
	public final static int STATE_PURCHASED = 1;
	public final static int STATE_TRYING = 2;
	public final static int STATE_EXPIRED = 3;

	public final static int EXPIRE_DAYS = 3;
	public final static String APK_PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCB4xYVRA7w13J6dBWA+oERVDRnefb8J5N7zeD3e6JfExk76F59YRDbmDVPL+ztwwboy+R3RSQKIHM/DYymqAHnbq4m/tKXCS6BcL9MeH6Cc2xas2dNNfzOjDrb/5oqvzHI+0TPX3gU2ZML3Udsw4Q+QT+jYOgLbMYfbps3OZne5QIDAQAB/wJQnyPGfR72CNv5zR+qA4qjxSMBUSQh55awBgR4Jrwd3G+6/yH540pB/oP+GsTp0Sof/dEFaR85968aEhBGRcnpEl9OITISZRwMp654/LD6kzdsjMBjfPXiYRSLjygcbG//gOVxZbnmU2Nz5pnuFvav8wIDAQAB";

	private Context mContext;
	// 服务的实例对象
	private ILicensingService mLicensingService = null;
	private OnLisenseStateChangeListener mListener;

	public MLisenseMangaer() {
		// for local check
		this(null);
	}

	public MLisenseMangaer(OnLisenseStateChangeListener listener) {
		mListener = listener;
		mContext = FlashApp.getContext();
	}

	// 服务绑定的回调，可用于判断服务是否绑定成功
	private ServiceConnection mLicenseConnection = new ServiceConnection() {

		public void onServiceDisconnected(ComponentName name) {
			if (mListener != null)
				mListener.onRemoteServiceDisconnected();
			mLicensingService = null;
		}

		public void onServiceConnected(ComponentName name, IBinder service) {
			Log.v(TAG, "服务绑定成功，获取服务实例");
			mLicensingService = ILicensingService.Stub.asInterface(service);
			if (mListener != null)
				mListener.onRemoteServiceConnected();
		}
	};

	public void bindRemoteService() {
		if (mLicensingService == null) {
			// 绑定服务
			Intent serviceIntent = new Intent();
			serviceIntent.setAction(ILicensingService.class.getName());
			mContext.bindService(serviceIntent, mLicenseConnection,
					Context.BIND_AUTO_CREATE);
		} else {
			if (mListener != null)
				mListener.onRemoteServiceConnected();
		}
	}

	public void unbindRemoteService() {
		// 如果服务已经绑定，在退出时需要反绑服务
		if (mLicensingService != null) {
			mContext.unbindService(mLicenseConnection);
		}
	}

	// doCheck()方法演示了如何使用license服务来验证授权是否合法
	public int doRemoteCheck() {

		// 该第三方应用的包名,可使用getApplication().getPackageName()获取本应用包名
		final String packageName = mContext.getPackageName();

		// 保存服务验证的结果值
		LicenseResult result = null;
		int lisenseState = STATE_UNKNOWN;
		if (mLicensingService != null) {
			try {
				// 调用服务接口进行验证,获取返回的结果值
				// FIXME 为什么有的时候为空
				result = mLicensingService.checkLicense(packageName);
			} catch (RemoteException e) {
				Log.e(TAG, "获取证书失败");
				// 作为UNKNOWN来处理，这种异常不需要显示错误
				lisenseState = STATE_TRYING;
			}

			if (result != null
					&& result.getResponseCode() == LicenseResult.RESPONSE_CODE_SUCCESS) {
				// license验证服务验证通过,需要接着对服务返回的结果再次进行校验(使用自己的公钥进行验证)
				boolean bSuccess = LicenseCheckHelper.checkResult(
						APK_PUBLIC_KEY, result);

				if (bSuccess
						&& result.getPurchaseType() == LicenseResult.PURCHASE_TYPE_NORMAL) {
					// 验证成功，并且为正式版本
					lisenseState = STATE_PURCHASED;

					// FIXME 获取子产品
				} else if (result.getPurchaseType() == LicenseResult.PURCHASE_TYPE_TRIAL) {
					// 验证成功，是试用版本
					// 该方法返回license文件的生成日期（注:该日期的值只精确到天，即时分秒为随机值）
					Calendar beginCal = result.getStartDate();
					// Log.v("", "试用开始的日期为: " + beginCal.get(Calendar.YEAR) +
					// "年"
					// + (beginCal.get(Calendar.MONTH) + 1) + "月"
					// + beginCal.get(Calendar.DAY_OF_MONTH) + "日");
					/**
					 * 以下是可供参考的过期判断
					 */
					// 你自己定义的过期天数
					final int expireDays = 3;
					// 获取当前日期
					Calendar nowCal = Calendar.getInstance();
					// 求剩余的天数
					long dif = nowCal.getTimeInMillis()
							- beginCal.getTimeInMillis();
					int passDay = (int) (dif / (24 * 60 * 60 * 1000));
					int left = expireDays - passDay;
					if (left > 0) {
						// 未过期
						Log.v(TAG, "未过期");
						lisenseState = STATE_TRYING;
					} else {
						// 过期
						Log.e(TAG, "过期");
						lisenseState = STATE_EXPIRED;
					}
					// FIXME 获取子产品
				} else {
					// 验证不成功或者版本类型不对，可按试用版处理
					// FIXME 状态一定要对，作为UNKNOWN来处理
					lisenseState = STATE_TRYING;
					Log.e(TAG, "license验证不通过");
				}
			} else {
				// license验证服务验证不通过
				lisenseState = STATE_UNKNOWN;// 用友盟来统计？
				if (result!= null && result.getResponseCode() == LicenseResult.RESPONSE_CODE_NO_LICENSE_FILE) {
					// 不存在与应用对应的license文件
					Log.e(TAG, "无对应的license文件");
				} else {
					// license文件无效
					Log.e(TAG, "license文件无效");
				}
			}
		}
		MPreferenceManager.getInstance().setLocalLisenseState(lisenseState);
		return lisenseState;
	}

	public static String getLisenseInfo(int lisenseState) {
		Resources resource = FlashApp.getContext().getResources();
		String lisenseInfo;
		switch (lisenseState) {
		case STATE_TRYING:
			lisenseInfo = resource.getString(R.string.lisense_state_trying);
			break;
		case STATE_EXPIRED:
			lisenseInfo = resource.getString(R.string.lisense_state_expired);
			break;
		case STATE_UNKNOWN:
			lisenseInfo = resource.getString(R.string.lisense_state_unknown);
			break;
		default:
			lisenseInfo = null;
			break;
		}
		return lisenseInfo;
	}

	public interface OnLisenseStateChangeListener {
		public void onRemoteServiceConnected();
		public void onRemoteServiceDisconnected();
	}
} public interface OnLisenseStateChangeListener {
	public void onRemoteServiceConnected();
	public void onRemoteServiceDisconnected();
} public class MNotificationHelper {
	public final static int NOTIFICATION_TYPE_LAUCHER_PANEL = 0;
	public final static int NOTIFICATION_TYPE_KEYGUARD_PANEL = 1;
	public final static int NOTIFICATION_TYPE_KEYGUARD_SHOCK = 2;
	public final static int NOTIFICATION_TYPE_CLOSE_PANEL = 3;
	
	private NotificationManager mManager;
	
	public MNotificationHelper() {
		Context context = FlashApp.getContext();
		mManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
	}
	
	public void notifyPanelOpen(int notifyType) {
		Context context = FlashApp.getContext();
		Resources resource = context.getResources();
		String title = null;
		String content = null;
		String ticker = null;
		switch(notifyType) {
			case NOTIFICATION_TYPE_LAUCHER_PANEL:
				title = resource.getString(R.string.launcher_panel);
				content = resource.getString(R.string.notification_launcher_panel_open_content);
				ticker = resource.getString(R.string.notification_launcher_panel_open_ticker);
				break;
			case NOTIFICATION_TYPE_KEYGUARD_PANEL:
				title = resource.getString(R.string.keyguard_panel);
				content = resource.getString(R.string.notification_keyguard_panel_open_content);
				ticker = resource.getString(R.string.notification_keyguard_panel_open_ticker);
				break;	
			case NOTIFICATION_TYPE_KEYGUARD_SHOCK:
				title = resource.getString(R.string.keyguard_shock);
				content = resource.getString(R.string.notification_keyguard_shock_enable_content);
				ticker = resource.getString(R.string.notification_keyguard_shock_enable_ticker);
				break;
		}
		NotificationCompat.Builder builder = new NotificationCompat.Builder(
				FlashApp.getContext()).setContentTitle(title)
				.setSmallIcon(R.drawable.ic_logo)
				.setContentText(content).setTicker(ticker).setAutoCancel(true);
		
		Intent intent = new Intent(context, SettingActivity.class);
		PendingIntent pi = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
		builder.setContentIntent(pi);
		mManager.notify(notifyType, builder.build());
	}
	
	public void notifyPanelCloseWhenLock() {
		Context context = FlashApp.getContext();
		Resources resource = context.getResources();
		String title = resource.getString(R.string.notification_panel_close_when_lock_title);
		String content = resource.getString(R.string.notification_panel_close_when_lock_content);
		String ticker = resource.getString(R.string.notification_panel_close_when_lock_ticker);
		
		NotificationCompat.Builder builder = new NotificationCompat.Builder(
				FlashApp.getContext()).setContentTitle(title)
				.setSmallIcon(R.drawable.ic_logo_locked)
				.setContentText(content).setTicker(ticker).setAutoCancel(true);
		
		Intent intent = new Intent(context, SettingActivity.class);
		PendingIntent pi = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
		builder.setContentIntent(pi);
		mManager.notify(NOTIFICATION_TYPE_CLOSE_PANEL, builder.build());
	}
	
	public void cancelNotify(int notifyType) {
		mManager.cancel(notifyType);
	}
} public class MPreferenceManager {
	private static MPreferenceManager mInstance;
	private SharedPreferences mPrefs;
	
	public final static String KEY_AUTO_CLOSE = "auto_close";
	public final static String KEY_AUTO_CLOSE_TIME = "auto_close_time";
	
	public final static String KEY_SHOW_LAUNCHER_PANEL = "show_launcher_panel";
	public final static String KEY_PANEL_X = "panel_x";
	public final static String KEY_PANEL_Y = "panel_y";
	public final static String KEY_SHOW_KEYGUARD_PANEL = "show_keyguard_panel";
	public final static String KEY_KEYGURAD_SHOCK_ENABLE = "enable_keyguard_shock";
	public final static String KEY_VERSION_CODE = "version_code";
	public final static String KEY_FIRST_START_DATE = "first_start_date";
	public final static String KEY_FIRST_SHOW_LAUNCHER = "first_show_launcher";
	public final static String KEY_FIRST_SHOW_KEYGUARD = "first_show_keyguard";
	public final static String KEY_ENABLE_SWITCH_SOUND = "enable_switch_sound";
	public final static String KEY_NEED_REFRESH_SETTING = "key_need_refresh_setting";
	
	public final static String KEY_LOCAL_LISENSE_STATE = "local_lisense_state";
	public final static String KEY_LISENSE_EXPIRED_TIMEMILLS = "lisense_expired_timemills";
	
	private MPreferenceManager() {
		mPrefs =PreferenceManager.getDefaultSharedPreferences(FlashApp.getContext());
	}
	
	public static MPreferenceManager getInstance() {
		if(mInstance == null)
			mInstance = new MPreferenceManager();
		return mInstance;
	}
	
	public void toggleLauncherPanel(boolean setShown, boolean needRefreshSetting) {
		Editor edit = mPrefs.edit();
		edit.putBoolean(KEY_SHOW_LAUNCHER_PANEL, setShown);
		if(needRefreshSetting)
			edit.putBoolean(KEY_NEED_REFRESH_SETTING, needRefreshSetting);
		edit.commit();
	}
	
	public boolean isLauncherPanelShown() {
		return mPrefs.getBoolean(KEY_SHOW_LAUNCHER_PANEL, false);
	}
	
	public void setFirstShowLauncherDate() {
		Editor edit = mPrefs.edit();
		edit.putLong(KEY_FIRST_SHOW_LAUNCHER, System.currentTimeMillis());
		edit.commit();
	}
	
	public long getFirstShowLauncherDate() {
		return mPrefs.getLong(KEY_FIRST_SHOW_LAUNCHER, 0);
	}
	
	public void toggleKeyguardPanel(boolean setShown, boolean needRefreshSetting) {
		Editor edit = mPrefs.edit();
		edit.putBoolean(KEY_SHOW_KEYGUARD_PANEL, setShown);
		if(setShown == false)
			edit.putBoolean(KEY_KEYGURAD_SHOCK_ENABLE, false);
		if(needRefreshSetting)
			edit.putBoolean(KEY_NEED_REFRESH_SETTING, needRefreshSetting);
		edit.commit();
	} 
	
	public boolean isKeyguardPanelShown() {
		return mPrefs.getBoolean(KEY_SHOW_KEYGUARD_PANEL, false);
	}
	
	public void toggleKeyguardShock(boolean enable) {
		Editor edit = mPrefs.edit();
		edit.putBoolean(KEY_KEYGURAD_SHOCK_ENABLE, enable);
		edit.commit();
	}
	
	public boolean isKeyguardShockEnable() {
		return mPrefs.getBoolean(KEY_KEYGURAD_SHOCK_ENABLE, false);
	}
	
	public void setFirstShowKeyguardDate() {
		Editor edit = mPrefs.edit();
		edit.putLong(KEY_FIRST_SHOW_KEYGUARD, System.currentTimeMillis());
		edit.commit();
	}
	
	public long getFirstShowKeyguardDate() {
		return mPrefs.getLong(KEY_FIRST_SHOW_KEYGUARD, 0);
	}
	
	public void setPanelPos(int x, int y) {
		Editor edit = mPrefs.edit();
		edit.putInt(KEY_PANEL_X, x);
		edit.putInt(KEY_PANEL_Y, y);
		edit.commit();
	}
	
	public Point getPanelPos() {
		int x = mPrefs.getInt(KEY_PANEL_X, -1);
		int y = mPrefs.getInt(KEY_PANEL_Y, -1);
		if(x == -1 || y == -1)
			return null;
		else
			return new Point(x, y);
	}
	
	public void clearPanelPos() {
		Editor edit = mPrefs.edit();
		edit.remove(KEY_PANEL_X);
		edit.remove(KEY_PANEL_Y);
		edit.commit();
	}
	
	public long getFirtStartDate() {
		return mPrefs.getLong(KEY_FIRST_START_DATE, 0);
	}
	
	public void setVersionCode(int versionCode) {
		Editor edit = mPrefs.edit();
		edit.putInt(KEY_VERSION_CODE, versionCode);
		edit.commit();
	}
	
	public int getVersionCode() {
		return mPrefs.getInt(KEY_VERSION_CODE, 0);
	}
	
	public void setFirstStartDate() {
		Editor edit = mPrefs.edit();
		edit.putLong(KEY_FIRST_START_DATE, System.currentTimeMillis());
		edit.commit();
	}
	
	public boolean isAutoClose() {
		return mPrefs.getBoolean(KEY_AUTO_CLOSE, false);
	}
	
	public int getAutoCloseTime() {
		return mPrefs.getInt(KEY_AUTO_CLOSE_TIME, 2);
	}
	
	public void setAutoCloseTime(int autoCloseTime) {
		Editor edit = mPrefs.edit();
		edit.putInt(KEY_AUTO_CLOSE_TIME, autoCloseTime);
		edit.commit();
	}
	
	public boolean isSwitchSoundOn() {
		return mPrefs.getBoolean(KEY_ENABLE_SWITCH_SOUND, true);
	}
	
	public int getLocalLisenseState() {
		return mPrefs.getInt(KEY_LOCAL_LISENSE_STATE, MLisenseMangaer.STATE_UNKNOWN);
	}
	
	public void setLocalLisenseState(int lisenseState) {
		Editor edit = mPrefs.edit();
		edit.putInt(KEY_LOCAL_LISENSE_STATE, lisenseState);
		edit.commit();
	}
	
	public long getExpiredTimeMills() {
		return mPrefs.getLong(KEY_LISENSE_EXPIRED_TIMEMILLS, 0);
	}
	
	public void setExpiredTimeMills(long expiredTimeMills) {
		Editor edit = mPrefs.edit();
		edit.putLong(KEY_LISENSE_EXPIRED_TIMEMILLS, expiredTimeMills);
		edit.commit();
	}
	
	public boolean needRefreshSetting() {
		return mPrefs.getBoolean(KEY_NEED_REFRESH_SETTING, false);
	}
	
	public void setNeedRefreshSetting(boolean needRefresh) {
		Editor edit = mPrefs.edit();
		edit.putBoolean(KEY_NEED_REFRESH_SETTING, needRefresh);
		edit.commit();
	}
} public class SmartBarUtils {

    /**
     * 调用 ActionBar.setTabsShowAtBottom(boolean) 方法。
     * 
     * <p>如果 android:uiOptions="splitActionBarWhenNarrow"，则可设置ActionBar Tabs显示在底栏。
     * 
     * <p>示例：</p>
     * <pre class="prettyprint">
     * public class MyActivity extends Activity implements ActionBar.TabListener {
     * 
     *     protected void onCreate(Bundle savedInstanceState) {
     *         super.onCreate(savedInstanceState);
     *         ...
     *         
     *         final ActionBar bar = getActionBar();
     *         bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
     *         SmartBarUtils.setActionBarTabsShowAtBottom(bar, true);
     *         
     *         bar.addTab(bar.newTab().setText("tab1").setTabListener(this));
     *         ...
     *     }
     * }
     * </pre>
     */
    public static void setActionBarTabsShowAtBottom(ActionBar actionbar, boolean showAtBottom) {
        try {
            Method method = Class.forName("android.app.ActionBar").getMethod(
                    "setTabsShowAtBottom", new Class[] { boolean.class });
            try {
                method.invoke(actionbar, showAtBottom);
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    
    /**
     * 调用 ActionBar.setActionBarViewCollapsable(boolean) 方法。
     * 
     * <p>设置ActionBar顶栏无显示内容时是否隐藏。
     * 
     * <p>示例：</p>
     * <pre class="prettyprint">
     * public class MyActivity extends Activity {
     * 
     *     protected void onCreate(Bundle savedInstanceState) {
     *         super.onCreate(savedInstanceState);
     *         ...
     *         
     *         final ActionBar bar = getActionBar();
     *         
     *         // 调用setActionBarViewCollapsable，并设置ActionBar没有显示内容，则ActionBar顶栏不显示
     *         SmartBarUtils.setActionBarViewCollapsable(bar, true);
     *         bar.setDisplayOptions(0);
     *     }
     * }
     * </pre>
     */
    public static void setActionBarViewCollapsable(ActionBar actionbar, boolean collapsable) {
        try {
            Method method = Class.forName("android.app.ActionBar").getMethod(
                    "setActionBarViewCollapsable", new Class[] { boolean.class });
            try {
                method.invoke(actionbar, collapsable);
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    
    /**
     * 调用 ActionBar.setActionModeHeaderHidden(boolean) 方法。
     * 
     * <p>设置ActionMode顶栏是否隐藏。
     * 
     * <p>示例：</p>
     * <pre class="prettyprint">
     * public class MyActivity extends Activity {
     * 
     *     protected void onCreate(Bundle savedInstanceState) {
     *         super.onCreate(savedInstanceState);
     *         ...
     *         
     *         final ActionBar bar = getActionBar();
     *         
     *         // ActionBar转为ActionMode时，不显示ActionMode顶栏
     *         SmartBarUtils.setActionModeHeaderHidden(bar, true);
     *     }
     * }
     * </pre>
     */
    public static void setActionModeHeaderHidden(ActionBar actionbar, boolean hidden) {
        try {
            Method method = Class.forName("android.app.ActionBar").getMethod(
                    "setActionModeHeaderHidden", new Class[] { boolean.class });
            try {
                method.invoke(actionbar, hidden);
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    
    
    
    /**
     * 调用ActionBar.setBackButtonDrawable(Drawable)方法
     * 
     * <p>设置返回键图标
     * 
     * <p>示例：</p>
     * <pre class="prettyprint">
     * public class MyActivity extends Activity {
     * 
     *     protected void onCreate(Bundle savedInstanceState) {
     *         super.onCreate(savedInstanceState);
     *         ...
     *         
     *         final ActionBar bar = getActionBar();
     *         // 自定义ActionBar的返回键图标
     *         SmartBarUtils.setBackIcon(bar, getResources().getDrawable(R.drawable.ic_back));
     *         ...
     *     }
     * }
     * </pre>
     */
    public static void setBackIcon(ActionBar actionbar, Drawable backIcon) {
        try {
            Method method = Class.forName("android.app.ActionBar").getMethod(
                    "setBackButtonDrawable", new Class[] { Drawable.class });
            try {
                method.invoke(actionbar, backIcon); 
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (NotFoundException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    
    public static void setHomeupIcon(View decorView, Drawable homeUpDrawable) {
    	
    }
    
    public static void toogleActionBar(View view, boolean show) {
        int flags = !show ? View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
        			:View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
        view.setSystemUiVisibility(flags);
	}
    
} public class SeekPreference extends Preference implements OnSeekBarChangeListener {
	private int MAX_PROGRESS;
	private int MIN_PROGRESS;
	private int PROGRESS_RATE;//seekbar分成越多份就滑动越流畅，如果每一格放得太大，就会出现事件调用不到的情况
	private int MAX_VALUE;
	private int MIN_VALUE;
	private int PROGRESS_INCREMENT;
	private SeekBar mSeekBar;
	private TextView mSummary;
	private int currentValue;
	
	public SeekPreference(Context context) {
		this(context, null);
	}

	public SeekPreference(Context context, AttributeSet attrs) {
		this(context, attrs, -1);
	}

	public SeekPreference(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);

		TypedArray mTypeArray = context.obtainStyledAttributes(attrs,
				R.styleable.SeekPreference);

		MAX_PROGRESS = mTypeArray.getInt(
				R.styleable.SeekPreference_maxProgress, 100);
		MIN_PROGRESS = mTypeArray.getInt(
				R.styleable.SeekPreference_minProgress, 0);
		PROGRESS_INCREMENT = mTypeArray.getInt(
				R.styleable.SeekPreference_progressIncrement, 1);
		PROGRESS_RATE = mTypeArray.getInt(
				R.styleable.SeekPreference_progressRate, 1);
		
		MAX_VALUE = MAX_PROGRESS / PROGRESS_RATE;
		MIN_VALUE = MIN_PROGRESS / PROGRESS_RATE;
		currentValue = MIN_VALUE;
		
		mTypeArray.recycle();
	}
	
	@Override
    protected void onSetInitialValue(final boolean restoreValue, final Object defaultValue) {
        try {
        	currentValue = restoreValue ? getPersistedInt(MIN_VALUE) : MIN_VALUE;
        } catch (NumberFormatException ex) {
        	currentValue = MIN_VALUE;
        }
    }

	@Override
	protected View onCreateView(ViewGroup parent) {
		return LayoutInflater.from(getContext()).inflate(getLayoutResource(), parent,
					false);
	}
	
	@Override
	protected void onBindView(View view) {
		super.onBindView(view);
		
		mSeekBar = (SeekBar) view.findViewById(R.id.seekbar);
		mSeekBar.setMax(MAX_PROGRESS - MIN_PROGRESS);
		mSeekBar.setKeyProgressIncrement(PROGRESS_INCREMENT);
		mSeekBar.setOnSeekBarChangeListener(this);
		mSummary = (TextView) view.findViewById(R.id.summary);
		mSeekBar.setProgress(currentValue * PROGRESS_RATE - MIN_PROGRESS);
	}

	@Override
	public void onProgressChanged(SeekBar seekBar, int value,
			boolean fromUser) {
		currentValue = (value + MIN_PROGRESS) / PROGRESS_RATE;
		mSummary.setText(currentValue+"分钟");
	}

	@Override
	public void onStartTrackingTouch(SeekBar seekBar) {
		
	}

	@Override
	public void onStopTrackingTouch(SeekBar seekBar) {
		persistInt(currentValue);
		notifyChanged();
		callChangeListener(currentValue);
	}
}
import com.hellodev.lightme.FlashController;
import com.hellodev.lightme.R;
import com.hellodev.lightme.service.ServiceHelper;
import com.hellodev.lightme.util.CommonDataHelper;
import com.hellodev.lightme.util.LightmeConstants;
import com.hellodev.lightme.util.MConnectHelper;
import com.hellodev.lightme.util.MLisenseMangaer;
import com.hellodev.lightme.util.MLisenseMangaer.OnLisenseStateChangeListener;
import com.hellodev.lightme.util.MNotificationHelper;
import com.hellodev.lightme.util.MPreferenceManager;
import com.hellodev.lightme.util.SmartBarUtils;
import com.hellodev.lightme.view.SeekPreference;
import com.umeng.analytics.MobclickAgent;
import android.app.ActionBar;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.CheckBoxPreference;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceActivity;
import android.preference.PreferenceScreen;
import android.view.MenuItem;
import android.view.View;
import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.widget.ImageButton;
import android.widget.LinearLayout;
package com.hellodev.lightme.activity;



public class SettingActivity extends PreferenceActivity implements
		OnPreferenceChangeListener, OnPreferenceClickListener, OnClickListener, OnLisenseStateChangeListener {
	private CheckBoxPreference showLauncherPanel, showKeyguardPanel,
			enableKeyguardShock, enableSwitchSound;
	private PreferenceScreen about, market, version;
	private SeekPreference autoCloseTime;

	public final static String KEY_ABOUNT = "about";
	public final static String KEY_MARKET = "market";
	public final static String KEY_VERSION = "version";

	private MConnectHelper connectHelper;