Android P平台 :http://androidxref.com/9.0.0_r3/
1. Settings 界面打开,流程大致如下:
111 void setLocationEnabled(boolean enabled) { // 从数据库拿值,看下此刻的 LOCATION_MODE 112 final int currentMode = Settings.Secure.getInt(mContext.getContentResolver(), 113 Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF); 114 115 if (isRestricted()) { ---> 当前用户是否有权限 116 // Location toggling disabled by user restriction. Read the current location mode to 117 // update the location master switch. 118 if (Log.isLoggable(TAG, Log.INFO)) { 119 Log.i(TAG, "Restricted user, not setting location mode"); 120 } 121 if (mListener != null) { 122 mListener.onLocationModeChanged(currentMode, true); 123 } 124 return; 125 } // 主要看下这个地方 126 updateLocationEnabled(mContext, enabled, UserHandle.myUserId(), 127 Settings.Secure.LOCATION_CHANGER_SYSTEM_SETTINGS); 128 refreshLocationMode(); 129 }
54 public static void updateLocationEnabled(Context context, boolean enabled, int userId, 55 int source) { 56 Settings.Secure.putIntForUser( 57 context.getContentResolver(), Settings.Secure.LOCATION_CHANGER, source, 58 userId); 59 Intent intent = new Intent(LocationManager.MODE_CHANGING_ACTION); 60 61 final int oldMode = Settings.Secure.getIntForUser(context.getContentResolver(), 62 Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF, userId); 63 final int newMode = enabled 64 ? Settings.Secure.LOCATION_MODE_HIGH_ACCURACY 65 : Settings.Secure.LOCATION_MODE_OFF; 66 intent.putExtra(CURRENT_MODE_KEY, oldMode); 67 intent.putExtra(NEW_MODE_KEY, newMode); 68 context.sendBroadcastAsUser( 69 intent, UserHandle.of(userId), android.Manifest.permission.WRITE_SECURE_SETTINGS); 70 LocationManager locationManager = 71 (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); 72 LocationManagerWrapper wrapper = new LocationManagerWrapper(locationManager); 73 wrapper.setLocationEnabledForUser(enabled, UserHandle.of(userId)); 74 }
60 /** Wraps {@code LocationManager.setLocationEnabledForUser} method */ 61 public void setLocationEnabledForUser(boolean enabled, UserHandle userHandle) { 62 mLocationManager.setLocationEnabledForUser(enabled, userHandle); 63 } 64}
2. Framework 调用流程大致如下:
这个方法里主要看这段代码:
2657 Settings.Secure.putStringForUser( 2658 mContext.getContentResolver(), 2659 Settings.Secure.LOCATION_PROVIDERS_ALLOWED, ---> 字段发生变化,而注册的地方也在LMS 2660 locationProvidersAllowed.toString(), 2661 userId); 2662 }
350 // listen for settings changes 351 mContext.getContentResolver().registerContentObserver( 352 Settings.Secure.getUriFor(Settings.Secure.LOCATION_PROVIDERS_ALLOWED), true, 353 new ContentObserver(mLocationHandler) { 354 @Override 355 public void onChange(boolean selfChange) { 356 synchronized (mLock) { 357 updateProvidersLocked(); ---> 字段发生变化时执行 358 } 359 } 360 }, UserHandle.USER_ALL);
1664 private void updateProvidersLocked() { 1665 boolean changesMade = false; 1666 for (int i = mProviders.size() - 1; i >= 0; i--) { 1667 LocationProviderInterface p = mProviders.get(i); 1668 boolean isEnabled = p.isEnabled(); ---> 使能各provider,这块流程待会单列出来 1669 String name = p.getName(); 1670 boolean shouldBeEnabled = isAllowedByCurrentUserSettingsLocked(name); 1671 if (isEnabled && !shouldBeEnabled) { 1672 updateProviderListenersLocked(name, false); 1673 // If any provider has been disabled, clear all last locations for all providers. 1674 // This is to be on the safe side in case a provider has location derived from 1675 // this disabled provider. 1676 mLastLocation.clear(); 1677 mLastLocationCoarseInterval.clear(); 1678 changesMade = true; 1679 } else if (!isEnabled && shouldBeEnabled) { 1680 updateProviderListenersLocked(name, true); 1681 changesMade = true; 1682 } 1683 } 1684 if (changesMade) { ---> 广播给监听者 1685 mContext.sendBroadcastAsUser(new Intent(LocationManager.PROVIDERS_CHANGED_ACTION), 1686 UserHandle.ALL); 1687 mContext.sendBroadcastAsUser(new Intent(LocationManager.MODE_CHANGED_ACTION), 1688 UserHandle.ALL); 1689 } 1690 }
在细看下上面提到的 使能各provider,可以知道所有的provider都是实现了LocationProviderInterface,这里由于是原生的代码,我们选取GnssLocationProvider看下:
1269 @Override 1270 public boolean isEnabled() { 1271 synchronized (mLock) { 1272 return mEnabled; ---> 如果打开则为true 1273 } 1274 } 具体细节可以看下源码mEnabled赋值的地方就理解了,至此,打开流程就梳理完毕。
文章同步来自微信公众号,更多内容关注公众号:蘑菇君先生