如今軟件市場上有不少能夠改變手機地理位置的軟件,更改後打開微信就能夠隨意定位,甚至前幾年有依靠這個技術打廣告爲生的小型公司。php
一獲取地理位置的方法css
獲取地理位置的方法通常分爲兩種。html
1)GPSjava
24顆衛星定位全球(圖片來自維基百科)給出詳解地址:http://zh.wikipedia.org/wiki/GPS;android
可是向衛星對請求信號強度的要求比較高,不少專門的硬件設備有時都達不到,因此手機使用GPS這種方法百分之九十的可能獲取的是null。git
2)networkgithub
這種方法其實又分爲兩種狀況。一種是有線一種爲無線。api
1,有線數組
由於是有線的網絡位置固定,每一個接入點的ip爲又是固定的,網絡的ip和位置就產生一一對應關係。根據接入點的ip既可獲得地理位置。不過這些工做彷佛是系統或者網絡提供商要作的,不用android的開發者解析。微信
2,無線
無線使用的是基站定位。實際上也就是數學上的三點定位。例如移動公司,其基站遍及全國,若是一臺設備想要連無線網,附近的三個基站會根據信號強度判斷出訪問者的相對距離,畫出三個半徑爲距離的園,根據三個圓的交點得知大體地理座標。(圖片來着百度百科)
3,wifi
例如某些平板電腦,不能插入網卡,不能插入手機卡,它們訪問網絡就都是走的wifi,那麼它的地理位置獲取就是根據wifi共享設備的地理位置來大體肯定的。wifi共享設備的地理位置的肯定參看以上1,2;
二:獲取地理位置
android 提供了
locationmanager 類來管理地理位置信息,其中提供了添加,刪除,篩選等很方便的功能。
public class
java.lang.Object
?
android.location.LocationManager
這個對象不能new ,只能從系統獲取
This class provides access to the system location services. These services allow applications to obtain periodic updates of the device's geographical location, or to fire an application-specified Intent
when the device enters the proximity of a given geographical location.
You do not instantiate this class directly; instead, retrieve it through Context.getSystemService(Context.LOCATION_SERVICE)
.
Unless noted, all Location API methods require the ACCESS_COARSE_LOCATION
or ACCESS_FINE_LOCATION
permissions. If your application only has the coarse permission then it will not have access to the GPS or passive location providers. Other providers will still return location results, but the update rate will be throttled and the exact location will be obfuscated to a coarse level of accuracy.
另外,這個對象獲取全部的位置提供者,而且進行刪除,添加,等操做。
太多了,不復制,直接給出api連接好了:http://developer.android.com/reference/android/location/LocationManager.html
在瞭解這個類以後再獲取當前的地理位置就簡單多了。網上有不少代碼。
大體是獲取位置提供者,循環像每一個提供者索要地理信息,信息被系統包裝成了Location這個類。
獲取Location對象後能夠調用
1
2
3
4
5
6
7
8
9
10
11
public
Location getLocation(Context context) {
LocationManager locMan = (LocationManager) context
.getSystemService(Context.LOCATION_SERVICE);
Location location = locMan
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if
(location ==
null
) {
location = locMan
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
}
return
location;
}
爲何要獲取兩次,由於剛纔所說,通常獲取GPS獲取不到,不過其實獲取兩次應該也是null。
對於getLastKownLocation()
Location
getLastKnownLocation(String provider) Returns a Location indicating the data from the last known location fix obtained from the given provider.
他接受一個提供者名字的參數,通常若是調用系統的話有:
GPS_PROVIDER, NETWORK_PROVIDER, 這兩個容易理解,一個是網絡一個是gps 另外,還有一個PASSIVE_PROVIDER
A special location provider for receiving locations without actually initiating a location fix.
This provider can be used to passively receive location updates when other applications or services request them without actually requesting the locations yourself. This provider will return locations generated by other providers. You can query the getProvider()
method to determine the origin of the location update. Requires the permission ACCESS_FINE_LOCATION
, although if the GPS is not enabled this provider might only return coarse fixes.
Constant Value: passive 這個到底是什麼暫時還沒搞懂。
不過你也能夠手動獲取全部提供者,由於有可能本機的設備已經添加了某些位置提供者(下一部分分析添加位置給系統,即 虛擬地理位置),我想大多數軟件都是這麼寫的或者說應該這麼寫,獲取全部位置提供者,而後循環索要location:
List
getProviders(boolean enabledOnly) Returns a list of the names of location providers.
List
getProviders(Criteria criteria, boolean enabledOnly) Returns a list of the names of LocationProviders that satisfy the given criteria, or null if none do.
用到這兩個方法,對於第二個重載的方法的第一個參數,意思是限制條件類,即根據所提供的對位置提供者的限制返回符合要求的名稱。
獲取String數組後就能夠循環獲取位置:
1
2
3
4
5
6
7
8
9
10
11
private
Location getLocation()
{
for
(
int
i =
0
; i < locProvider.length, i ++)
{
Location location = locationManager.getLocation(locProvider.get(i));
if
(location!=
null
)
return
location;
}
return
null
;
}
另外,也能夠對現有的位置提供者進行修改(系統原有的三個修改不了),不過須要
1,獲取LocationProvider 類
LocationProvider
getProvider(String name) Returns the information associated with the location provider of the given name, or null if no provider exists by that name.
2,修改
3刪除原有的
void
removeTestProvider(String provider) Removes the mock location provider with the given name.
4添加修改後的。
void
addTestProvider(String name, boolean requiresNetwork, boolean requiresSatellite, boolean requiresCell, boolean hasMonetaryCost, boolean supportsAltitude, boolean supportsSpeed, boolean supportsBearing, int powerRequirement, int accuracy) Creates a mock location provider and adds it to the set of active providers.
固然要加入相應的權限:
三 虛擬地理位置
其實google play 上就有現成的程序:https://play.google.com/store/apps/details?id=com.lexa.fakegps&hl=zh_TW,
並且github上有託管的源代碼.
具體方法是添加位置提供者,不斷向位置提供者傳遞locaiton信息。
Sets a mock enabled value for the given provider. This value will be used in place of any actual value from the provider.
provider
the provider name
enabled
the mock enabled value
SecurityException
if the ACCESS_MOCK_LOCATION permission is not present or the Settings.Secure.ALLOW_MOCK_LOCATION
} system setting is not enabled
IllegalArgumentException
if no provider with the given name exists
這個也是須要加入特殊權限的:
另外,通過測試發現,不如直接給「gps」傳位置,其餘軟件更容易接受,不過須要使用者把虛擬地理位置選項打開。