Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> android鎖屏創建流程

android鎖屏創建流程

編輯:關於Android編程

本文簡單分析,android啟動之後,鎖屏界面啟動過程。   android系統開機後會運行PhoneWindowManage管理系統相關按鍵和事件,   看下PhoneWindowManager鎖屏相關   1.Pwm初始化KeyguardViewMediator類,用來接受PhoneWindowManager傳遞相關事件   [java]   <PRE class=java name="code">    /** {@inheritDoc} */       public void init(Context context, IWindowManager windowManager,               WindowManagerFuncs windowManagerFuncs,               LocalPowerManager powerManager) {           mContext = context;           mWindowManager = windowManager;           mWindowManagerFuncs = windowManagerFuncs;           mPowerManager = powerManager;        <SPAN style="COLOR: #ff0000">   mKeyguardMediator = new KeyguardViewMediator(context, this, powerManager);   </SPAN> ........}</PRE><BR>   <PRE></PRE>   <P>2.系統啟動完成會調用SystemReady函數,進入鎖屏流程</P>   <PRE class=java name="code">  /** {@inheritDoc} */       public void systemReady() {           // tell the keyguard    <SPAN style="COLOR: #ff0000">        mKeyguardMediator.onSystemReady();   </SPAN>        android.os.SystemProperties.set("dev.bootcomplete", "1");            synchronized (mLock) {               updateOrientationListenerLp();               mSystemReady = true;               mHandler.post(new Runnable() {                   public void run() {                       updateSettings();                   }               });           }       }</PRE>   <P>3.KeyguradMediator中onSystemReady函數</P>   <PRE class=java name="code"> /**       * Let us know that the system is ready after startup.       */       public void onSystemReady() {           synchronized (this) {               if (DBG_WAKE) Log.d(TAG, "onSystemReady");               mSystemReady = true;               doKeyguardLocked();           }       }</PRE>   <P><BR>   4.doKeyguardLocked進入鎖屏判斷,是否有第三方鎖屏應用文件。</P>   <PRE class=java name="code">    /**       * Enable the keyguard if the settings are appropriate.  Return true if all       * work that will happen is done; returns false if the caller can wait for       * the keyguard to be shown.       */       private void doKeyguardLocked() {           // if another app is disabling us, don't show            if (!mExternallyEnabled && !mUpdateMonitor.DM_IsLocked()) {               if (DEBUG) Xlog.d(TAG, "doKeyguard: not showing because externally disabled");                  // note: we *should* set mNeedToReshowWhenReenabled=true here, but that makes                // for an occasional ugly flicker in this situation:                // 1) receive a call with the screen on (no keyguard) or make a call                // 2) screen times out                // 3) user hits key to turn screen back on                // instead, we reenable the keyguard when we know the screen is off and the call                // ends (see the broadcast receiver below)                // TODO: clean this up when we have better support at the window manager level                // for apps that wish to be on top of the keyguard                return;           }              // if the keyguard is already showing, don't bother            if (mKeyguardViewManager.isShowing()) {               if (DEBUG) Xlog.d(TAG, "doKeyguard: not showing because it is already showing");               return;           }              // if the setup wizard hasn't run yet, don't show            final boolean requireSim = !SystemProperties.getBoolean("keyguard.no_require_sim",                   false);           final boolean provisioned = mUpdateMonitor.isDeviceProvisioned();           final IccCard.State state = mUpdateMonitor.getSimState(Phone.GEMINI_SIM_1);           final IccCard.State stateGemini = mUpdateMonitor.getSimState(Phone.GEMINI_SIM_2);           boolean lockedOrMissing = state.isPinLocked()                   || state == IccCard.State.PERM_DISABLED                   && requireSim;                      boolean lockedOrMissingGemini = stateGemini.isPinLocked()                   || stateGemini == IccCard.State.PERM_DISABLED                   && requireSim;                      if (FeatureOption.MTK_GEMINI_SUPPORT){               lockedOrMissing = lockedOrMissing || lockedOrMissingGemini;           }              boolean keyguardisable = mLockPatternUtils.isLockScreenDisabled();                      Log.i(TAG, "lockedOrMissing is "+lockedOrMissing+", requireSim="+requireSim               +", provisioned="+provisioned+", keyguardisable="+keyguardisable);                      if (!lockedOrMissing && !provisioned) {               if (DEBUG) Log.d(TAG, "doKeyguard: not showing because device isn't provisioned"                       + " and the sim is not locked or missing");               return;           }              if (keyguardisable && !lockedOrMissing) {               if (DEBUG) Log.d(TAG, "doKeyguard: not showing because lockscreen is off");               return;           }              if (DEBUG) Log.d(TAG, "doKeyguard: showing the lock screen");           showLocked();       }</PRE>   <P>5.沒有第三方鎖屏應用或禁用鎖屏,則進入showLocked函數</P>   <PRE class=java name="code">  /**       * Send message to keyguard telling it to show itself       * @see #handleShow()       */       private void showLocked() {           if (DEBUG) Xlog.d(TAG, "showLocked");           // ensure we stay awake until we are finished displaying the keyguard            mShowKeyguardWakeLock.acquire();           Message msg = mHandler.obtainMessage(SHOW);                       if (isAlarmBoot() && !mChecked) {               mChecked = true;               Log.i(TAG, "it's alarm boot, delay 3s to show");               mHandler.sendMessageDelayed(msg, 5000);            } else {               mHandler.sendMessage(msg);            }       }</PRE>   <P><BR>   6.showLocked函數通過handler,發送顯示鎖屏信息或延時處理,handler接受消息,直接調用handleShow處理<BR>   </P>   <PRE class=java name="code">  /**       * Handle message sent by {@link #showLocked}.       * @see #SHOW       */       private void handleShow() {           synchronized (KeyguardViewMediator.this) {               if (DEBUG) Xlog.d(TAG, "handleShow");               if (!mSystemReady) return;               if (mShowing == true) return;               mShowCount++;               //avoid the int overflow                if (mShowCount == (int)Math.pow(2, 32)){                   mShowCount=2;               }               Xlog.d(TAG, "handleShow, count="+mShowCount);                  mKeyguardViewManager.show();               mShowing = true;               adjustUserActivityLocked();               adjustStatusBarLocked();                              try {                   ActivityManagerNative.getDefault().closeSystemDialogs("lock");               } catch (RemoteException e) {               }                  // Do this at the end to not slow down display of the keyguard.                playSounds(true);                  mShowKeyguardWakeLock.release();           }       }   </PRE>   <P>7.進入KeyguardViewManager中的show();KeyguardViewManager是鎖屏管理處理類,該類在KeyguraMeditor初始化</P>   <PRE class=java name="code">    /**       * Show the keyguard.  Will handle creating and attaching to the view manager       * lazily.       */       public synchronized void show() {           if (DEBUG) Xlog.d(TAG, "show(); mKeyguardView==" + mKeyguardView);              Resources res = mContext.getResources();           boolean enableScreenRotation =                   SystemProperties.getBoolean("lockscreen.rot_override",false)                   || res.getBoolean(R.bool.config_enableLockScreenRotation);           if (mKeyguardHost == null) {               if (DEBUG) Xlog.d(TAG, "keyguard host is null, creating it...");                  mKeyguardHost = new KeyguardViewHost(mContext, mCallback);                  final int stretch = ViewGroup.LayoutParams.MATCH_PARENT;               int flags = WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN                       | WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER                       | WindowManager.LayoutParams.FLAG_KEEP_SURFACE_WHILE_ANIMATING                       | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN                       | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;               if (mUpdateMonitor.DM_IsLocked()) {//in the first created                    flags &= ~WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN;                   flags |= WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;                   flags |= WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;               } else {                   flags &= ~WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;                   flags &= ~WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;                   flags |= WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN;               }               if (!mNeedsInput) {                   flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;               }               if (ActivityManager.isHighEndGfx(((WindowManager)mContext.getSystemService(                       Context.WINDOW_SERVICE)).getDefaultDisplay())) {                   flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;               }               WindowManager.LayoutParams lp = new WindowManager.LayoutParams(                       stretch, stretch, WindowManager.LayoutParams.TYPE_KEYGUARD,                       flags, PixelFormat.TRANSLUCENT);               lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;               lp.windowAnimations = com.android.internal.R.style.Animation_LockScreen;               if (ActivityManager.isHighEndGfx(((WindowManager)mContext.getSystemService(                       Context.WINDOW_SERVICE)).getDefaultDisplay())) {                   lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;                   lp.privateFlags |=                           WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED;               }                  lp.setTitle("Keyguard");               mWindowLayoutParams = lp;                  mViewManager.addView(mKeyguardHost, lp);           }              if (enableScreenRotation || FeatureOption.MTK_TB_APP_LANDSCAPE_SUPPORT) {               if (DEBUG) Log.d(TAG, "Rotation sensor for lock screen On!");               mWindowLayoutParams.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR;           } else {               if (DEBUG) Log.d(TAG, "Rotation sensor for lock screen Off!");               mWindowLayoutParams.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;           }              mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams);              if (mKeyguardView == null) {               if (DEBUG) Xlog.d(TAG, "keyguard view is null, creating it...");               mKeyguardView = mKeyguardViewProperties.createKeyguardView(mContext, mUpdateMonitor, this);               mKeyguardView.setId(R.id.lock_screen);               mKeyguardView.setCallback(mCallback);                  final ViewGroup.LayoutParams lp = new FrameLayout.LayoutParams(                       ViewGroup.LayoutParams.MATCH_PARENT,                       ViewGroup.LayoutParams.MATCH_PARENT);                  mKeyguardHost.addView(mKeyguardView, lp);                  if (mScreenOn) {                   mKeyguardView.show();               }           }              // Disable aspects of the system/status/navigation bars that are not appropriate or            // useful for the lockscreen but can be re-shown by dialogs or SHOW_WHEN_LOCKED activities.            // Other disabled bits are handled by the KeyguardViewMediator talking directly to the            // status bar service.            int visFlags = ( View.STATUS_BAR_DISABLE_BACK                   | View.STATUS_BAR_DISABLE_HOME);                      mKeyguardHost.setSystemUiVisibility(visFlags);              mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams);           mKeyguardHost.setVisibility(View.VISIBLE);           mKeyguardView.requestFocus();       }</PRE><PRE class=java name="code"> </PRE>   <P>show函數主要鎖屏界面添加到ViewManager中顯示,主要看下KeyguardView創建工程 </P>   <P>mKeyguardView = mKeyguardViewProperties.createKeyguardView(mContext, mUpdateMonitor, this);</P>   <P>看下mKeyguraViewProperties</P>   <P>通過源碼可知KeyViewMediator初始化創建,傳入KeyguardViewManager</P>   <P>mKeyguardViewProperties<BR>   = new LockPatternKeyguardViewProperties(mLockPatternUtils, mUpdateMonitor);</P>   <P>mKeyguardViewManager = new KeyguardViewManager(<BR>   context, WindowManagerImpl.getDefault(), this,<BR>   mKeyguardViewProperties, mUpdateMonitor);<BR>   8.LockPatternKeyguardViewProperties類中CreateKeyGuardView函數,初始化LockPatternKeyguardView,LockPatternKeyguardView便是我們的鎖屏界面</P>   <PRE class=java name="code">/**   * Knows how to create a lock pattern keyguard view, and answer questions about   * it (even if it hasn't been created, per the interface specs).   */   public class LockPatternKeyguardViewProperties implements KeyguardViewProperties {          private final LockPatternUtils mLockPatternUtils;       private final KeyguardUpdateMonitor mUpdateMonitor;          /**       * @param lockPatternUtils Used to know whether the pattern enabled, and passed       *   onto the keygaurd view when it is created.       * @param updateMonitor Used to know whether the sim pin is enabled, and passed       *   onto the keyguard view when it is created.       */       public LockPatternKeyguardViewProperties(LockPatternUtils lockPatternUtils,               KeyguardUpdateMonitor updateMonitor) {           mLockPatternUtils = lockPatternUtils;           mUpdateMonitor = updateMonitor;       }          public KeyguardViewBase createKeyguardView(Context context,               KeyguardUpdateMonitor updateMonitor,               KeyguardWindowController controller) {           return new LockPatternKeyguardView(context, updateMonitor,                   mLockPatternUtils, controller);       }          public boolean isSecure() {           return mLockPatternUtils.isSecure() || isSimPinSecure();       }          private boolean isSimPinSecure() {           final IccCard.State simState = mUpdateMonitor.getSimState(Phone.GEMINI_SIM_1);           final IccCard.State sim2State = mUpdateMonitor.getSimState(Phone.GEMINI_SIM_2);           return (simState == IccCard.State.PIN_REQUIRED                   || simState == IccCard.State.PUK_REQUIRED                   || simState == IccCard.State.PERM_DISABLED                   || sim2State == IccCard.State.PIN_REQUIRED                   || sim2State == IccCard.State.PUK_REQUIRED                   || sim2State == IccCard.State.PERM_DISABLED                   || simState == IccCard.State.ABSENT                   && sim2State == IccCard.State.ABSENT);       }      }</PRE>   <P>9.看下LockPatternKeyguardView初始流程</P>   <PRE class=java name="code">    /**       * @param context Used to inflate, and create views.       * @param updateMonitor Knows the state of the world, and passed along to each       *   screen so they can use the knowledge, and also register for callbacks       *   on dynamic information.       * @param lockPatternUtils Used to look up state of lock pattern.       */       public LockPatternKeyguardView(               Context context,               KeyguardUpdateMonitor updateMonitor,               LockPatternUtils lockPatternUtils,               KeyguardWindowController controller) {           super(context);              mHandler = new Handler(this);           mConfiguration = context.getResources().getConfiguration();           mEnableFallback = false;           mRequiresSim = TextUtils.isEmpty(SystemProperties.get("keyguard.no_require_sim"));           mUpdateMonitor = updateMonitor;           mLockPatternUtils = lockPatternUtils;           mWindowController = controller;           mHasOverlay = false;              mUpdateMonitor.registerDeviceInfoCallback(this);           mUpdateMonitor.registerPhoneStateCallback(this);              mKeyguardScreenCallback = new KeyguardScreenCallback() {                  public void goToLockScreen() {                   mForgotPattern = false;                   if (mIsVerifyUnlockOnly) {                       // navigating away from unlock screen during verify mode means                        // we are done and the user failed to authenticate.                        mIsVerifyUnlockOnly = false;                       getCallback().keyguardDone(false);                   } else {                       updateScreen(Mode.LockScreen, false);                   }               }                  public void goToUnlockScreen() {                   final IccCard.State simState = mUpdateMonitor.getSimState(Phone.GEMINI_SIM_1);                   final IccCard.State sim2State = mUpdateMonitor.getSimState(Phone.GEMINI_SIM_2);                   if (stuckOnLockScreenBecauseSimMissing()                       || (simState == IccCard.State.PUK_REQUIRED                        && !mLockPatternUtils.isPukUnlockScreenEnable())                       || (sim2State == IccCard.State.PUK_REQUIRED                        && !mLockPatternUtils.isPukUnlockScreenEnable())){                       // stuck on lock screen when sim missing or                        // puk'd but puk unlock screen is disabled                        return;                   }                   if (!isSecure()) {                       getCallback().keyguardDone(true);                   } else {                       updateScreen(Mode.UnlockScreen, false);                   }               }                  public void forgotPattern(boolean isForgotten) {                   if (mEnableFallback) {                       mForgotPattern = isForgotten;                       updateScreen(Mode.UnlockScreen, false);                   }               }                  public boolean isSecure() {                   return LockPatternKeyguardView.this.isSecure();               }                  public boolean isVerifyUnlockOnly() {                   return mIsVerifyUnlockOnly;               }                  public void recreateMe(Configuration config) {                   removeCallbacks(mRecreateRunnable);                   post(mRecreateRunnable);               }                  public void takeEmergencyCallAction() {                   mHasOverlay = true;                      // Continue showing FaceLock area until dialer comes up or call is resumed                    if (mLockPatternUtils.usingBiometricWeak() &&                           mLockPatternUtils.isBiometricWeakInstalled() && mFaceLockServiceRunning) {                       showFaceLockAreaWithTimeout(FACELOCK_VIEW_AREA_EMERGENCY_DIALER_TIMEOUT);                   }                      // FaceLock must be stopped if it is running                    stopAndUnbindFromFaceLock();                      pokeWakelock(EMERGENCY_CALL_TIMEOUT);                   if (TelephonyManager.getDefault().getCallState()                           == TelephonyManager.CALL_STATE_OFFHOOK) {                       mLockPatternUtils.resumeCall();                   } else {                       Intent intent = new Intent(ACTION_EMERGENCY_DIAL);                       intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK                               | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);                       getContext().startActivity(intent);                   }               }                  public void pokeWakelock() {                   getCallback().pokeWakelock();               }                  public void pokeWakelock(int millis) {                   getCallback().pokeWakelock(millis);               }                  public void keyguardDone(boolean authenticated) {                   getCallback().keyguardDone(authenticated);                   mSavedState = null; // clear state so we re-establish when locked again                }                  public void keyguardDoneDrawing() {                   // irrelevant to keyguard screen, they shouldn't be calling this                }                  public void reportFailedUnlockAttempt() {                   mUpdateMonitor.reportFailedAttempt();                   final int failedAttempts = mUpdateMonitor.getFailedAttempts();                   if (DEBUG) Xlog.d(TAG, "reportFailedPatternAttempt: #" + failedAttempts +                       " (enableFallback=" + mEnableFallback + ")");                      final boolean usingPattern = mLockPatternUtils.getKeyguardStoredPasswordQuality()                           == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;                      final int failedAttemptsBeforeWipe = mLockPatternUtils.getDevicePolicyManager()                           .getMaximumFailedPasswordsForWipe(null);                      final int failedAttemptWarning = LockPatternUtils.FAILED_ATTEMPTS_BEFORE_RESET                           - LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT;                      final int remainingBeforeWipe = failedAttemptsBeforeWipe > 0 ?                           (failedAttemptsBeforeWipe - failedAttempts)                           : Integer.MAX_VALUE; // because DPM returns 0 if no restriction                       if (remainingBeforeWipe < LockPatternUtils.FAILED_ATTEMPTS_BEFORE_WIPE_GRACE) {                       // If we reach this code, it means the user has installed a DevicePolicyManager                        // that requests device wipe after N attempts.  Once we get below the grace                        // period, we'll post this dialog every time as a clear warning until the                        // bombshell hits and the device is wiped.                        if (remainingBeforeWipe > 0) {                           showAlmostAtWipeDialog(failedAttempts, remainingBeforeWipe);                       } else {                           // Too many attempts. The device will be wiped shortly.                            Slog.i(TAG, "Too many unlock attempts; device will be wiped!");                           showWipeDialog(failedAttempts);                       }                   } else {                       boolean showTimeout =                           (failedAttempts % LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT) == 0;                       if (usingPattern && mEnableFallback) {                           if (failedAttempts == failedAttemptWarning) {                               showAlmostAtAccountLoginDialog();                               showTimeout = false; // don't show both dialogs                            } else if (failedAttempts >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_RESET) {                               mLockPatternUtils.setPermanentlyLocked(true);                               updateScreen(mMode, false);                               // don't show timeout dialog because we show account unlock screen next                                showTimeout = false;                           }                       }                       if (showTimeout) {                           showTimeoutDialog();                       }                   }                   mLockPatternUtils.reportFailedPasswordAttempt();               }                  public boolean doesFallbackUnlockScreenExist() {                   return mEnableFallback;               }                  public void reportSuccessfulUnlockAttempt() {                   mFailedFaceUnlockAttempts = 0;                   mLockPatternUtils.reportSuccessfulPasswordAttempt();               }           };              /**           * We'll get key events the current screen doesn't use. see           * {@link KeyguardViewBase#onKeyDown(int, android.view.KeyEvent)}           */           setFocusableInTouchMode(true);           setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);           <SPAN style="COLOR: #cc0000">   updateScreen(getInitialMode(), false);   </SPAN>        maybeEnableFallback(context);       }</PRE><PRE class=java name="code">一些CallBack函數的實現,updateScreen函數才是初始更新鎖屏</PRE><PRE class=java name="code"> </PRE><PRE class=java name="code">10.updateScreen,根據當前鎖屏模式,更新顯示相應的鎖屏界面,</PRE><PRE class=java name="code" sizcache="0" sizset="16"><PRE class=java name="code"> private void updateScreen(Mode mode, boolean force) {              Log.v(TAG, "**** UPDATE SCREEN: mode=" + mode                   + " last mode=" + mMode + ", force = " + force);              mMode = mode;              // Re-create the lock screen if necessary            if (mode == Mode.LockScreen || mShowLockBeforeUnlock) {               if (force || mLockScreen == null) {                   recreateLockScreen();               }           }              // Re-create the unlock screen if necessary. This is primarily required to properly handle            // SIM state changes. This typically happens when this method is called by reset()            if (mode == Mode.UnlockScreen) {               final UnlockMode unlockMode = getUnlockMode();               if (force || mUnlockScreen == null || unlockMode != mUnlockScreenMode) {                   recreateUnlockScreen(unlockMode);               }           }              // visibleScreen should never be null            final View goneScreen = (mode == Mode.LockScreen) ? mUnlockScreen : mLockScreen;           final View visibleScreen = (mode == Mode.LockScreen) ? mLockScreen : mUnlockScreen;              // do this before changing visibility so focus isn't requested before the input            // flag is set            mWindowController.setNeedsInput(((KeyguardScreen)visibleScreen).needsInput());              if (DEBUG_CONFIGURATION) {               Xlog.v(TAG, "Gone=" + goneScreen);               Xlog.v(TAG, "Visible=" + visibleScreen);           }              if (mScreenOn) {               if (goneScreen != null && goneScreen.getVisibility() == View.VISIBLE) {                   ((KeyguardScreen) goneScreen).onPause();               }               if (visibleScreen.getVisibility() != View.VISIBLE) {                   ((KeyguardScreen) visibleScreen).onResume();               }           }              if (goneScreen != null) {               goneScreen.setVisibility(View.GONE);           }           visibleScreen.setVisibility(View.VISIBLE);           requestLayout();              if (!visibleScreen.requestFocus()) {               throw new IllegalStateException("keyguard screen must be able to take "                       + "focus when shown " + visibleScreen.getClass().getCanonicalName());           }       }</PRE><BR>   11.recreateLockScreen(),創建鎖屏   <PRE></PRE>   <PRE class=java name="code"><P>    private void recreateLockScreen() {           Log.i(TAG, "recreateLockScreen");           if (mLockScreen != null) {               ((KeyguardScreen) mLockScreen).onPause();               ((KeyguardScreen) mLockScreen).cleanUp();               removeView(mLockScreen);           }</P><P>        mLockScreen = createLockScreen();           mLockScreen.setVisibility(View.INVISIBLE);           addView(mLockScreen);       }   </P>這裡可以自己在framework中寫一個鎖屏文件,替換系統原理的鎖屏,</PRE><PRE class=java name="code">很簡單,最後調用show顯示鎖屏界面</PRE><PRE class=java name="code"> </PRE><PRE class=java name="code"> </PRE><PRE class=java name="code"> </PRE><PRE class=java name="code"> </PRE><PRE class=java name="code"> </PRE><PRE class=java name="code"> </PRE>   <PRE></PRE>   <PRE></PRE>   <PRE></PRE>   <PRE></PRE>   <PRE></PRE>   <PRE></PRE>   <PRE></PRE>      </PRE>    
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved