Android
स्थान
खोज…
परिचय
एंड्रॉइड लोकेशन API का उपयोग विभिन्न प्रयोजनों के लिए विभिन्न प्रकार के ऐप में किया जाता है जैसे कि उपयोगकर्ता स्थान ढूंढना, यह सूचित करना कि जब उपयोगकर्ता ने सामान्य क्षेत्र (जियोफेंसिंग) छोड़ दिया है, और उपयोगकर्ता गतिविधि (चलना, दौड़ना, ड्राइविंग, आदि) की व्याख्या करने में मदद करता है।
हालांकि, एंड्रॉइड लोकेशन एपीआई उपयोगकर्ता स्थान प्राप्त करने का एकमात्र साधन नहीं है। निम्नलिखित एंड्रॉइड के LocationManager
और अन्य सामान्य स्थान पुस्तकालयों का उपयोग करने के तरीके का उदाहरण देगा।
टिप्पणियों
एंड्रॉइड में लोकेशन अवेयर ऐप्स बनाने के लिए, दो रास्ते हैं:
- Android का मूल खुला स्रोत
LocationManager
- Google का
FusedLocationProviderApi
, जो Google Play Services का हिस्सा है
स्थान प्रबंधक
पेशेवरों
- अधिक दानेदार नियंत्रण
- सभी उपकरणों में उपलब्ध है
- Android ढांचे का हिस्सा
विपक्ष
- बैटरी नाली एक मुद्दा है, अगर ठीक से प्रबंधित नहीं किया जाता है
- स्थान प्रदाता को स्विच करने के लिए तर्क की आवश्यकता होती है, यदि उपकरण किसी स्थान को खोजने में असमर्थ है (किसी भवन के अंदर खराब जीपीएस)
विशेषताएं
- NMEA श्रोता
- जीपीएस स्थिति श्रोता
- प्रदाता की स्थिति में परिवर्तन देखें (उदा। GPS उपयोगकर्ता द्वारा बंद कर दिया गया है)
- स्थान स्रोत चुनने के लिए प्रदाताओं की सूची
प्रदाताओं
GPS
- अनुमतियाँ आवश्यक:
- सटीकता: 10 मीटर - 100 मीटर
- बिजली की आवश्यकताएं: उच्च
- उपलब्धता: दुनिया भर में (आकाश के स्पष्ट दृश्य के साथ)
- नोट :
- स्थान अपडेट आम तौर पर हर सेकंड में एक बार आते हैं, लेकिन उन स्थितियों में जहां कुछ समय के लिए जीपीएस का उपयोग नहीं किया गया है और ए-जीपीएस अनुपलब्ध है, एक स्थान प्राप्त करने में कई मिनट लगते हैं।
- ऐसे मामलों में जहां आकाश का स्पष्ट दृश्य बाधित होता है, जीपीएस बिंदु बहुत अच्छी तरह से नहीं हटेंगे (स्थान अंक "कूद") और सटीकता " शहरी घाटी " प्रभाव के कारण कुछ क्षेत्रों में भ्रामक हो सकती है।
नेटवर्क
- अनुमतियाँ आवश्यक:
- सटीकता: 100 मीटर - 1000 मीटर +
- बिजली की आवश्यकताएँ: कम - दवा
- उपलब्धता: सेल टॉवर या वाईफाई सिग्नल की सीमा के भीतर
- टिप्पणियाँ:
- स्थान अपडेट GPS की तुलना में कम बार होता है
- स्थान अपडेट आमतौर पर अच्छी तरह से क्लस्टर नहीं होते हैं (स्थान अंक "कूद") और सटीकता विभिन्न कारकों की संख्या (वाईफाई सिग्नल, सिग्नल शक्ति, सेल टॉवर का प्रकार, आदि) के आधार पर हो सकती है।
निष्क्रिय
- अनुमतियाँ आवश्यक:
- सटीकता: 10 मीटर - 1000 मीटर +
- बिजली की आवश्यकताएँ: कोई नहीं
- उपलब्धता: केवल जब कोई अन्य ऐप जीपीएस या नेटवर्क से कोई स्थान प्राप्त करता है
- टिप्पणियाँ:
- आपको लगातार अपडेट देने के लिए इस पर भरोसा न करें। यह उन अन्य ऐप्स को निष्क्रियता से सुनता है जो स्थान अनुरोध करते हैं, और उन स्थानों को वापस भेजते हैं।
- FusedLocationProviderApi उत्पन्न अंक वापस नहीं करता है, केवल अंतर्निहित स्थान बिंदु उन्हें उत्पन्न करने के लिए उपयोग किया जाता है।
FusedLocationProviderApi
पेशेवरों
- कम बैटरी नाली प्रदान करता है "बॉक्स से बाहर"
- खराब जीपीएस को अच्छी तरह से संभालता है
- अधिक नियमित रूप से अपडेट हो जाता है
विपक्ष
- जीपीएस पर कम दानेदार नियंत्रण
- सभी उपकरणों पर या कुछ देशों में उपलब्ध नहीं हो सकता है
- तीसरे पक्ष के पुस्तकालय निर्भरता की आवश्यकता है
विशेषताएं
- इष्टतम बल्लेबाज बचत के लिए स्थान प्रदाताओं का अच्छा उपयोग
- आमतौर पर अधिक सटीक बिंदु उत्पन्न करता है फिर नेटवर्क स्थान प्रदाता
- पुस्तकालय के अधिक लगातार अद्यतन, अधिक सुधार के लिए अनुमति देता है
- निर्दिष्ट करने के लिए किस प्रकार के प्रदाता का उपयोग करने की आवश्यकता नहीं है
स्थानसुधार प्राथमिकता स्तर
PRIORITY_HIGH_ACCURACY
- अनुमतियाँ आवश्यक:
-
ACCESS_FINE_LOCATION
अधिक सटीक स्थान या के लिएACCESS_COARSE_LOCATION
कम सटीक स्थान के लिए
-
- सटीकता: 10 मीटर - 100 मीटर
- बिजली की आवश्यकताएं: उच्च
- उपलब्धता: जहां कहीं भी Google Play सेवाएं उपलब्ध हैं।
- टिप्पणियाँ:
- यदि
ACCESS_FINE_LOCATION
का उपयोग नहीं किया गया है, तो यह स्थान अपडेट बनाने के लिए GPS का उपयोग नहीं करेगा, लेकिन फिर भी सही परिस्थितियों में एक सटीक सटीक बिंदु ढूंढ लेगा। - यदि
ACCESS_FINE_LOCATION
का उपयोग किया जाता है, तो यह स्थान बिंदुओं को उत्पन्न करने के लिए GPS का उपयोग कर सकता है या नहीं भी कर सकता है, यह इस बात पर निर्भर करता है कि वर्तमान में पर्यावरणीय परिस्थितियों को देखते हुए यह कितना सही है। - यद्यपि यह अन्य सेटिंग्स की तुलना में अधिक सटीक स्थान अपडेट की रिपोर्ट कर सकता है, फिर भी यह " शहरी घाटी " प्रभाव से ग्रस्त है।
- यदि
PRIORITY_BALANCED_POWER_ACCURACY
- अनुमतियाँ आवश्यक:
-
ACCESS_FINE_LOCATION
अधिक सटीक स्थान या के लिएACCESS_COARSE_LOCATION
कम सटीक स्थान के लिए
-
- सटीकता: 100 मीटर - 1000 मीटर +
- पावर आवश्यकताएँ: मेडम
- उपलब्धता: जहां कहीं भी Google Play सेवाएं उपलब्ध हैं।
- टिप्पणियाँ:
-
PRIORITY_HIGH_ACCURACY
रूप में समान नोट - यद्यपि यह संभावना नहीं है, फिर भी यह सेटिंग किसी स्थान को उत्पन्न करने के लिए GPS का उपयोग कर सकती है।
-
PRIORITY_LOW_POWER
- अनुमतियाँ आवश्यक:
- सटीकता: 100 मीटर - 1000 मीटर +
- बिजली की आवश्यकताएँ: कम
- उपलब्धता: जहां कहीं भी Google Play सेवाएं उपलब्ध हैं।
- टिप्पणियाँ:
- शायद जीपीएस का उपयोग नहीं करता है, लेकिन इस प्रकार अब तक अप्रयुक्त।
- अपडेट आमतौर पर बहुत सटीक नहीं होते हैं
- आमतौर पर स्थान में महत्वपूर्ण परिवर्तनों का पता लगाने के लिए उपयोग किया जाता है
PRIORITY_NO_POWER
- अनुमतियाँ आवश्यक:
- सटीकता: 10 मीटर - 1000 मीटर +
- बिजली की आवश्यकताएँ: कोई नहीं
- उपलब्धता: जहां कहीं भी Google Play सेवाएं उपलब्ध हैं।
- टिप्पणियाँ:
-
LocationManager
PASSIVE_PROVIDER
लगभग समान रूप से कार्य - प्राप्त होने पर Google Play Services के अपडेट की रिपोर्ट करता है, जहां
PASSIVE_PROVIDER
उपयोग किए गए अंतर्निहित स्थान अपडेट की रिपोर्ट करता है
-
समस्या निवारण
OnLocationChanged () कभी भी कॉल नहीं किया गया
चूंकि यह एंड्रॉइड लोकेशन प्राप्त करने के साथ एक सामान्य समस्या प्रतीत होती है, इसलिए मैं सामान्य सुधारों की एक त्वरित जांच सूची डालूंगा:
अपनी उपस्थिति की जाँच करें!
सबसे आम मुद्दों में से एक यह है कि सही अनुमति कभी नहीं दी गई थी। यदि आप GPS (नेटवर्क के साथ या उसके बिना) का उपयोग कर रहे हैं, तो
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
उपयोग करें, अन्यथा<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
। गूगल के FusedLocationApi की आवश्यकता हैACCESS_FINE_LOCATION
।
(Android 6+ के लिए) रनटाइम अनुमतियों की जाँच करें !
अनुमति के लिए जाँच करें और अनुरोध करें! यदि आपको कभी भी अनुमति नहीं दी गई है, तो आप क्रैश के साथ समाप्त हो जाएंगे, या इससे भी बदतर (यदि आप सभी अपवादों को पकड़ रहे हैं), तो आप किसी भी चीज़ का संकेत नहीं देंगे! इससे कोई फर्क नहीं पड़ता कि यदि उपयोगकर्ता आपको ऐप की शुरुआत में अनुमति देता है, तो हमेशा यह देखने के लिए जांचें कि क्या आपके पास सभी कॉल के लिए अनुमति है। उपयोगकर्ता आसानी से अपनी सेटिंग्स में जा सकता है और उन्हें रद्द कर सकता है।
अपना कोड दोबारा जांचें!
क्या आप वाकई सही श्रोता हैं? क्या आपने उस
BroadcastReceiver
याIntentService
को अपने प्रकट करने के लिएIntentService
था? क्या आप किसीBroadcastReceiver
क्लास परPendingIntent.getService()
का उपयोग कर रहे हैं, या एकIntentService
वर्ग परgetBroadcast()
करIntentService
? क्या आप वाकई अनुरोध करने के तुरंत बाद अपने श्रोता को अपने कोड में कहीं और अपंजीकृत नहीं कर रहे हैं?
डिवाइस सेटिंग्स की जाँच करें!
जाहिर है, सुनिश्चित करें कि आपके पास स्थान सेवाएँ चालू हैं।
यदि आप नेटवर्क सेवाओं का उपयोग कर रहे हैं, तो क्या आपने "स्कैनिंग ऑलवेज अवेलेबल" चालू किया है? क्या आपके पास अपना स्थान मोड "सर्वश्रेष्ठ" ("उच्च सटीकता") या "बैटरी सेविंग" ("केवल नेटवर्क") पर सेट है?
यदि आप GPS का उपयोग कर रहे हैं, तो क्या आपने स्थान मोड में "सर्वश्रेष्ठ" ("उच्च सटीकता") या "केवल डिवाइस" चालू किया था?
अपना कोड दोबारा जांचें!
हाँ, यह दो बार यहाँ पर है। क्या आपने यह सुनिश्चित करने के लिए कि आपने वास्तव में
LocationManager
PendingIntent
को ठीक से कार्यान्वित किया है, एकPendingIntent
, या इसके विपरीत,LocationListener
का उपयोग करने का प्रयास किया? क्या आप सुनिश्चित हैं कि गतिविधि या सेवा जीवन चक्र के कुछ भाग में स्थान अनुरोध को हटाया नहीं जा रहा है जिसकी आपको उम्मीद नहीं थी?
अपने आसपास की जाँच करें!
क्या आप सैन फ्रांसिस्को के बीच में एक इमारत की पहली मंजिल पर जीपीएस का परीक्षण कर रहे हैं? क्या आप कहीं के बीच में नेटवर्क स्थानों का परीक्षण कर रहे हैं? क्या आप सभी रेडियो संकेतों के एक गुप्त भूमिगत बंकर में काम करते हैं, सोच रहे हैं कि आपके डिवाइस को स्थान क्यों नहीं मिल रहा है? स्थान की समस्याओं का निवारण करने का प्रयास करते समय हमेशा अपने आसपास की जाँच करें!
कई अन्य कम स्पष्ट कारण हो सकते हैं कि स्थान क्यों काम नहीं कर रहा है, लेकिन उन गूढ़ सुधारों की खोज करने से पहले, बस इस त्वरित चेकलिस्ट के माध्यम से चलाएं।
फ़्यूस्ड लोकेशन एपीआई
उदाहरण गतिविधि w / LocationRequest का उपयोग करना
/*
* This example is useful if you only want to receive updates in this
* activity only, and have no use for location anywhere else.
*/
public class LocationActivity extends AppCompatActivity implements
GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mLocationRequest = new LocationRequest()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY) //GPS quality location points
.setInterval(2000) //At least once every 2 seconds
.setFastestInterval(1000); //At most once a second
}
@Override
protected void onStart(){
super.onStart();
mGoogleApiClient.connect();
}
@Override
protected void onResume(){
super.onResume();
//Permission check for Android 6.0+
if(ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
if(mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
}
}
@Override
protected void onPause(){
super.onPause();
//Permission check for Android 6.0+
if(ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
if(mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
}
}
@Override
protected void onStop(){
super.onStop();
mGoogleApiClient.disconnect();
}
@Override
public void onConnected(@Nullable Bundle bundle) {
if(ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
}
@Override
public void onConnectionSuspended(int i) {
mGoogleApiClient.connect();
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
}
@Override
public void onLocationChanged(Location location) {
//Handle your location update code here
}
}
उदाहरण सेवा w / PendingIntent और BroadcastReceiver का उपयोग करना
ExampleActivity
अनुशंसित पढ़ने: LocalBroadcastManager
/*
* This example is useful if you have many different classes that should be
* receiving location updates, but want more granular control over which ones
* listen to the updates.
*
* For example, this activity will stop getting updates when it is not visible, but a database
* class with a registered local receiver will continue to receive updates, until "stopUpdates()" is called here.
*
*/
public class ExampleActivity extends AppCompatActivity {
private InternalLocationReceiver mInternalLocationReceiver;
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
//Create internal receiver object in this method only.
mInternalLocationReceiver = new InternalLocationReceiver(this);
}
@Override
protected void onResume(){
super.onResume();
//Register to receive updates in activity only when activity is visible
LocalBroadcastManager.getInstance(this).registerReceiver(mInternalLocationReceiver, new IntentFilter("googleLocation"));
}
@Override
protected void onPause(){
super.onPause();
//Unregister to stop receiving updates in activity when it is not visible.
//NOTE: You will still receive updates even if this activity is killed.
LocalBroadcastManager.getInstance(this).unregisterReceiver(mInternalLocationReceiver);
}
//Helper method to get updates
private void requestUpdates(){
startService(new Intent(this, LocationService.class).putExtra("request", true));
}
//Helper method to stop updates
private void stopUpdates(){
startService(new Intent(this, LocationService.class).putExtra("remove", true));
}
/*
* Internal receiver used to get location updates for this activity.
*
* This receiver and any receiver registered with LocalBroadcastManager does
* not need to be registered in the Manifest.
*
*/
private static class InternalLocationReceiver extends BroadcastReceiver{
private ExampleActivity mActivity;
InternalLocationReceiver(ExampleActivity activity){
mActivity = activity;
}
@Override
public void onReceive(Context context, Intent intent) {
final ExampleActivity activity = mActivity;
if(activity != null) {
LocationResult result = intent.getParcelableExtra("result");
//Handle location update here
}
}
}
}
स्थान सेवा
नोट: इस सेवा को मैनिफेस्ट में पंजीकृत करना न भूलें!
public class LocationService extends Service implements
GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;
@Override
public void onCreate(){
super.onCreate();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mLocationRequest = new LocationRequest()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY) //GPS quality location points
.setInterval(2000) //At least once every 2 seconds
.setFastestInterval(1000); //At most once a second
}
@Override
public int onStartCommand(Intent intent, int flags, int startId){
super.onStartCommand(intent, flags, startId);
//Permission check for Android 6.0+
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
if (intent.getBooleanExtra("request", false)) {
if (mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, getPendingIntent());
} else {
mGoogleApiClient.connect();
}
}
else if(intent.getBooleanExtra("remove", false)){
stopSelf();
}
}
return START_STICKY;
}
@Override
public void onDestroy(){
super.onDestroy();
if(mGoogleApiClient.isConnected()){
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, getPendingIntent());
mGoogleApiClient.disconnect();
}
}
private PendingIntent getPendingIntent(){
//Example for IntentService
//return PendingIntent.getService(this, 0, new Intent(this, **YOUR_INTENT_SERVICE_CLASS_HERE**), PendingIntent.FLAG_UPDATE_CURRENT);
//Example for BroadcastReceiver
return PendingIntent.getBroadcast(this, 0, new Intent(this, LocationReceiver.class), PendingIntent.FLAG_UPDATE_CURRENT);
}
@Override
public void onConnected(@Nullable Bundle bundle) {
//Permission check for Android 6.0+
if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, getPendingIntent());
}
}
@Override
public void onConnectionSuspended(int i) {
mGoogleApiClient.connect();
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
LocationReceiver
नोट: इस रिसीवर को मैनिफेस्ट में पंजीकृत करना न भूलें!
public class LocationReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if(LocationResult.hasResult(intent)){
LocationResult locationResult = LocationResult.extractResult(intent);
LocalBroadcastManager.getInstance(context).sendBroadcast(new Intent("googleLocation").putExtra("result", locationResult));
}
}
}
LocationManager का उपयोग करके स्थान अपडेट का अनुरोध करना
हमेशा की तरह, आपको यह सुनिश्चित करने की आवश्यकता है कि आपके पास आवश्यक अनुमतियाँ हैं।
public class MainActivity extends AppCompatActivity implements LocationListener{
private LocationManager mLocationManager = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
}
@Override
protected void onResume() {
super.onResume();
try {
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
}
catch(SecurityException e){
// The app doesn't have the correct permissions
}
}
@Override
protected void onPause() {
try{
mLocationManager.removeUpdates(this);
}
catch (SecurityException e){
// The app doesn't have the correct permissions
}
super.onPause();
}
@Override
public void onLocationChanged(Location location) {
// We received a location update!
Log.i("onLocationChanged", location.toString());
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
}
स्थान प्रबंधक के उपयोग से एक अलग थ्रेड पर स्थान अपडेट का अनुरोध करना
हमेशा की तरह, आपको यह सुनिश्चित करने की आवश्यकता है कि आपके पास आवश्यक अनुमतियाँ हैं।
public class MainActivity extends AppCompatActivity implements LocationListener{
private LocationManager mLocationManager = null;
HandlerThread mLocationHandlerThread = null;
Looper mLocationHandlerLooper = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
mLocationHandlerThread = new HandlerThread("locationHandlerThread");
}
@Override
protected void onResume() {
super.onResume();
mLocationHandlerThread.start();
mLocationHandlerLooper = mLocationHandlerThread.getLooper();
try {
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this, mLocationHandlerLooper);
}
catch(SecurityException e){
// The app doesn't have the correct permissions
}
}
@Override
protected void onPause() {
try{
mLocationManager.removeUpdates(this);
}
catch (SecurityException e){
// The app doesn't have the correct permissions
}
mLocationHandlerLooper = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2)
mLocationHandlerThread.quitSafely();
else
mLocationHandlerThread.quit();
mLocationHandlerThread = null;
super.onPause();
}
@Override
public void onLocationChanged(Location location) {
// We received a location update on a separate thread!
Log.i("onLocationChanged", location.toString());
// You can verify which thread you're on by something like this:
// Log.d("Which thread?", Thread.currentThread() == Looper.getMainLooper().getThread() ? "UI Thread" : "New thread");
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
}
रजिस्टर जियोफेंस
मैंने GeoFenceObserversationService
singleton class बनाया है।
GeoFenceObserversationService.java :
public class GeoFenceObserversationService extends Service implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, ResultCallback<Status> {
protected static final String TAG = "GeoFenceObserversationService";
protected GoogleApiClient mGoogleApiClient;
protected ArrayList<Geofence> mGeofenceList;
private boolean mGeofencesAdded;
private SharedPreferences mSharedPreferences;
private static GeoFenceObserversationService mInstant;
public static GeoFenceObserversationService getInstant(){
return mInstant;
}
@Override
public void onCreate() {
super.onCreate();
mInstant = this;
mGeofenceList = new ArrayList<Geofence>();
mSharedPreferences = getSharedPreferences(AppConstants.SHARED_PREFERENCES_NAME, MODE_PRIVATE);
mGeofencesAdded = mSharedPreferences.getBoolean(AppConstants.GEOFENCES_ADDED_KEY, false);
buildGoogleApiClient();
}
@Override
public void onDestroy() {
mGoogleApiClient.disconnect();
super.onDestroy();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
protected void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();
}
@Override
public void onConnected(Bundle connectionHint) {
}
@Override
public void onConnectionFailed(ConnectionResult result) {
}
@Override
public void onConnectionSuspended(int cause) {
}
private GeofencingRequest getGeofencingRequest() {
GeofencingRequest.Builder builder = new GeofencingRequest.Builder();
builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER);
builder.addGeofences(mGeofenceList);
return builder.build();
}
public void addGeofences() {
if (!mGoogleApiClient.isConnected()) {
Toast.makeText(this, getString(R.string.not_connected), Toast.LENGTH_SHORT).show();
return;
}
populateGeofenceList();
if(!mGeofenceList.isEmpty()){
try {
LocationServices.GeofencingApi.addGeofences(mGoogleApiClient, getGeofencingRequest(), getGeofencePendingIntent()).setResultCallback(this);
} catch (SecurityException securityException) {
securityException.printStackTrace();
}
}
}
public void removeGeofences() {
if (!mGoogleApiClient.isConnected()) {
Toast.makeText(this, getString(R.string.not_connected), Toast.LENGTH_SHORT).show();
return;
}
try {
LocationServices.GeofencingApi.removeGeofences(mGoogleApiClient,getGeofencePendingIntent()).setResultCallback(this);
} catch (SecurityException securityException) {
securityException.printStackTrace();
}
}
public void onResult(Status status) {
if (status.isSuccess()) {
mGeofencesAdded = !mGeofencesAdded;
SharedPreferences.Editor editor = mSharedPreferences.edit();
editor.putBoolean(AppConstants.GEOFENCES_ADDED_KEY, mGeofencesAdded);
editor.apply();
} else {
String errorMessage = AppConstants.getErrorString(this,status.getStatusCode());
Log.i("Geofence", errorMessage);
}
}
private PendingIntent getGeofencePendingIntent() {
Intent intent = new Intent(this, GeofenceTransitionsIntentService.class);
return PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
private void populateGeofenceList() {
mGeofenceList.clear();
List<GeoFencingResponce> geoFenceList = getGeofencesList;
if(geoFenceList!=null&&!geoFenceList.isEmpty()){
for (GeoFencingResponce obj : geoFenceList){
mGeofenceList.add(obj.getGeofence());
Log.i(TAG,"Registered Geofences : " + obj.Id+"-"+obj.Name+"-"+obj.Lattitude+"-"+obj.Longitude);
}
}
}
}
AppConstant :
public static final String SHARED_PREFERENCES_NAME = PACKAGE_NAME + ".SHARED_PREFERENCES_NAME";
public static final String GEOFENCES_ADDED_KEY = PACKAGE_NAME + ".GEOFENCES_ADDED_KEY";
public static final String DETECTED_GEOFENCES = "detected_geofences";
public static final String DETECTED_BEACONS = "detected_beacons";
public static String getErrorString(Context context, int errorCode) {
Resources mResources = context.getResources();
switch (errorCode) {
case GeofenceStatusCodes.GEOFENCE_NOT_AVAILABLE:
return mResources.getString(R.string.geofence_not_available);
case GeofenceStatusCodes.GEOFENCE_TOO_MANY_GEOFENCES:
return mResources.getString(R.string.geofence_too_many_geofences);
case GeofenceStatusCodes.GEOFENCE_TOO_MANY_PENDING_INTENTS:
return mResources.getString(R.string.geofence_too_many_pending_intents);
default:
return mResources.getString(R.string.unknown_geofence_error);
}
}
मैंने कहाँ सेवा शुरू की? अनुप्रयोग वर्ग से
-
startService(new Intent(getApplicationContext(),GeoFenceObserversationService.class));
मैंने जियोफ़ाइन्स कैसे पंजीकृत किया?
-
GeoFenceObserversationService.getInstant().addGeofences();
जियोकोडर का उपयोग करके स्थान से पता प्राप्त करें
FusedAPI
से आपको Location
ऑब्जेक्ट मिल जाने के बाद, आप आसानी से उस ऑब्जेक्ट से Address
जानकारी हासिल कर सकते हैं।
private Address getCountryInfo(Location location) {
Address address = null;
Geocoder geocoder = new Geocoder(getActivity(), Locale.getDefault());
String errorMessage;
List<Address> addresses = null;
try {
addresses = geocoder.getFromLocation(
location.getLatitude(),
location.getLongitude(),
// In this sample, get just a single address.
1);
} catch (IOException ioException) {
// Catch network or other I/O problems.
errorMessage = "IOException>>" + ioException.getMessage();
} catch (IllegalArgumentException illegalArgumentException) {
// Catch invalid latitude or longitude values.
errorMessage = "IllegalArgumentException>>" + illegalArgumentException.getMessage();
}
if (addresses != null && !addresses.isEmpty()) {
address = addresses.get(0);
}
return country;
}
एक प्रसारण में स्थान अद्यतन हो रहा है
आने वाले स्थान अपडेट को संभालने के लिए पहले एक ब्रॉडकास्टर क्लास बनाएँ:
public class LocationReceiver extends BroadcastReceiver implements Constants {
@Override
public void onReceive(Context context, Intent intent) {
if (LocationResult.hasResult(intent)) {
LocationResult locationResult = LocationResult.extractResult(intent);
Location location = locationResult.getLastLocation();
if (location != null) {
// Do something with your location
} else {
Log.d(LocationReceiver.class.getSimpleName(), "*** location object is null ***");
}
}
}
}
तब जब आप GoogleApiClient को ऑन-कनेक्टेड कॉलबैक से कनेक्ट करते हैं:
@Override
public void onConnected(Bundle connectionHint) {
Intent backgroundIntent = new Intent(this, LocationReceiver.class);
mBackgroundPendingIntent = backgroundPendingIntent.getBroadcast(getApplicationContext(), LOCATION_REUEST_CODE, backgroundIntent, PendingIntent.FLAG_CANCEL_CURRENT);
mFusedLocationProviderApi.requestLocationUpdates(mLocationClient, mLocationRequest, backgroundPendingIntent);
}
उपयुक्त जीवनचक्र कॉलबैक में स्थान अद्यतन आशय को हटाना न भूलें:
@Override
public void onDestroy() {
if (servicesAvailable && mLocationClient != null) {
if (mLocationClient.isConnected()) {
fusedLocationProviderApi.removeLocationUpdates(mLocationClient, backgroundPendingIntent);
// Destroy the current location client
mLocationClient = null;
} else {
mLocationClient.unregisterConnectionCallbacks(this);
mLocationClient = null;
}
}
super.onDestroy();
}