Η γνώση της τοποθεσίας του χρήστη σας είναι χρήσιμες πληροφορίες πολλές εφαρμογές αναπτύσσουμε και χρησιμοποιούμε σήμερα. Υπάρχουν πολλές δημοφιλείς εφαρμογές βάσει τοποθεσίας εκεί έξω που κάνουν τη ζωή μας ευκολότερη, καθώς και αλλάζοντας τον τρόπο με τον οποίο χρησιμοποιούμε αυτές τις υπηρεσίες. Ένα παράδειγμα είναι η εξαιρετικά δημοφιλής εφαρμογή Foursquare, όπου οι χρήστες που επισκέπτονται συχνά ένα ίδρυμα και κάνουν «check in» συχνά κερδίζουν εκπτώσεις. Uber, το οποίο σας βοηθά να κάνετε μια βόλτα από το κινητό σας τηλέφωνο σε χαμηλότερη τιμή από ένα κανονικό ταξί. Η λίστα είναι μεγάλη και εξακολουθεί να αυξάνεται.
Σε αυτό το άρθρο, πρόκειται να δημιουργήσουμε μια απλή εφαρμογή Android για να προσδιορίσουμε το γεωγραφικό πλάτος και μήκος του χρήστη χρησιμοποιώντας το API υπηρεσιών τοποθεσίας Google του Android. Πότε ανάπτυξη εφαρμογών Android , υπάρχουν δύο τρόποι για να λάβετε την τοποθεσία του χρήστη.
ο πακέτο 'android.location' ήταν διαθέσιμο από το Android για πρώτη φορά και μας παρέχει πρόσβαση σε υπηρεσίες τοποθεσίας. Αυτές οι υπηρεσίες επιτρέπουν στις εφαρμογές να λαμβάνουν περιοδικές ενημερώσεις της γεωγραφικής θέσης της συσκευής.
Το πακέτο παρέχει δύο τρόπους απόκτησης δεδομένων τοποθεσίας:
LocationManager.GPS_PROVIDER: Καθορίζει την τοποθεσία χρησιμοποιώντας δορυφόρους. Ανάλογα με τις συνθήκες, αυτός ο πάροχος ενδέχεται να χρειαστεί λίγη ώρα για να επιστρέψει μια επιδιόρθωση τοποθεσίας.
LocationManager.NETWORK_PROVIDER: Καθορίζει την τοποθεσία με βάση τη διαθεσιμότητα κοντινών πύργων κυψελών και σημείων πρόσβασης WiFi. Αυτό είναι ταχύτερο από το GPS_PROVIDER.
Όταν αναζητάτε τοποθεσία χρήστη πρέπει να παίξετε με αυτούς τους παρόχους και τη διαθεσιμότητά τους. Στην ιδανική περίπτωση, αποκτάτε την πρώτη τοποθεσία χρησιμοποιώντας το NETWORK_PROVIDER, το οποίο μπορεί να μην είναι τόσο ακριβές, αλλά είναι πολύ πιο γρήγορο. Στη συνέχεια, μπορείτε να προσπαθήσετε να αυξήσετε την ακρίβεια ακούγοντας μια καλύτερη διόρθωση τοποθεσίας χρησιμοποιώντας το GPS_PROVIDER.
Τα API που παρέχονται από αυτό το πακέτο είναι αρκετά χαμηλού επιπέδου και απαιτούν από τον προγραμματιστή της εφαρμογής να χειριστεί τις λεπτότερες λεπτομέρειες του καθορισμού πότε να ζητήσει δεδομένα τοποθεσίας και να προγραμματίσει κλήσεις στο API με βελτιστοποιημένο τρόπο. Για να βελτιώσει την εμπειρία προγραμματιστή με υπηρεσίες συστήματος βάσει τοποθεσίας και να διευκολύνει τη διαδικασία ανάπτυξης εφαρμογών που να γνωρίζουν την τοποθεσία, η Google εισήγαγε έναν νέο τρόπο να ζητά την τοποθεσία ενός χρήστη χρησιμοποιώντας τις Υπηρεσίες Google Play. Προσφέρει ένα απλούστερο API με υψηλότερη ακρίβεια, χαμηλή ισχύς geofencing και πολλά άλλα.
Το API υπηρεσιών τοποθεσίας Google, επίσης γνωστό ως FusedLocationProviderApi, είναι ο προτεινόμενος τρόπος της Google για τη λήψη της τοποθεσίας ενός χρήστη. Παρέχει την καλύτερη ακρίβεια με βάση τις ανάγκες μας. Μερικά από τα πλεονεκτήματα της χρήσης αυτού του API έναντι του προηγούμενου είναι:
Απλότητα: Σε αντίθεση με το προηγούμενο API, δεν χρειάζεται πλέον να αντιμετωπίζετε πολλούς παρόχους. Αντ 'αυτού, καθορίζετε υψηλού επιπέδου ανάγκες, όπως «υψηλή ακρίβεια» ή «χαμηλή ισχύ», και θα ακολουθήσει μια κατάλληλη προσέγγιση.
Διαθεσιμότητα: Δίνει στην εφαρμογή σας άμεση πρόσβαση στην καλύτερη, πιο πρόσφατη γνωστή τοποθεσία. Συνήθως αυτές οι πληροφορίες είναι άμεσα διαθέσιμες, απλά πρέπει να τις ζητήσετε.
Απόδοση ισχύος: Ελαχιστοποιεί τη χρήση ισχύος της εφαρμογής σας.
Ευελιξία: Καλύπτει ένα ευρύ φάσμα αναγκών, από χρήσεις προσκηνίου - που απαιτούν πολύ ακριβή δεδομένα τοποθεσίας, έως χρήσεις παρασκηνίου - απαιτούν μόνο περιοδικές ενημερώσεις τοποθεσίας με αμελητέα ισχύ.
Ας δημιουργήσουμε μια εφαρμογή Android βάσει τοποθεσίας χρησιμοποιώντας αυτό το API. Για αυτό, θα χρησιμοποιήσουμε το προτεινόμενο IDE της Google για ανάπτυξη εφαρμογών Android - Android Studio . Το να ξεκινήσετε με το Android Studio είναι αρκετά απλό. Ο ιστότοπός τους περιγράφει λεπτομερώς τη διαδικασία που περιλαμβάνει την εγκατάσταση και τη διαμόρφωση του Android Studio, συμπεριλαμβανομένου του τρόπου εκκίνησης της πρώτης σας εφαρμογής Android για ανάπτυξη.
Το Android Studio πρέπει να κάνει τα πράγματα εξαιρετικά εύκολα για εμάς. Ωστόσο, θα πρέπει να ξεκινήσουμε διαμορφώνοντας το σενάριο build και προσθέτοντας τις Υπηρεσίες Google Play ως εξάρτηση για αυτήν την εφαρμογή. Αυτό μπορεί να γίνει τροποποιώντας το αρχείο 'build.gradle' ως εξής:
dependencies { compile 'com.android.support:appcompat-v7:21.0.3' compile 'com.google.android.gms:play-services:6.5.87' // Add this line }
Τη στιγμή που γράφω αυτό το άρθρο, η τελευταία έκδοση των διαθέσιμων Υπηρεσιών Google Play είναι 6.5.87. Βεβαιωθείτε ότι ελέγχετε πάντα την πιο πρόσφατη διαθέσιμη έκδοση πριν ξεκινήσετε. Σε περίπτωση που οι νεότερες εκδόσεις βγουν αργότερα και αποφασίσετε να την ενημερώσετε για τα δικά σας έργα, δοκιμάστε όλες τις λειτουργίες που σχετίζονται με την τοποθεσία έναντι όλων των εκδόσεων Android που υποστηρίζετε.
Σε αυτό το σημείο, θα πρέπει να μπορούμε να αρχίσουμε να κάνουμε την πραγματική δουλειά για την εφαρμογή μας.
πώς να φτιάξετε ένα παιχνίδι σε επεξεργασία
Τα Android διαθέτουν συγκεκριμένες λειτουργίες ασφαλείας που θα αποτρέψουν οποιαδήποτε αυθαίρετη εφαρμογή να ζητήσει ακριβή τοποθεσία χρήστη. Για να το λύσουμε αυτό, πρέπει να επεξεργαστούμε το 'AndroidManifest.xml' και να προσθέσουμε το άδεια που χρειαζόμαστε για αυτήν την εφαρμογή:
private boolean checkGooglePlayServices(){ int checkGooglePlayServices = GooglePlayServicesUtil .isGooglePlayServicesAvailable(mContext); if (checkGooglePlayServices != ConnectionResult.SUCCESS) { /* * Google Play Services is missing or update is required * return code could be * SUCCESS, * SERVICE_MISSING, SERVICE_VERSION_UPDATE_REQUIRED, * SERVICE_DISABLED, SERVICE_INVALID. */ GooglePlayServicesUtil.getErrorDialog(checkGooglePlayServices, mContext, REQUEST_CODE_RECOVER_PLAY_SERVICES).show(); return false; } return true; }
Ενώ είμαστε σε αυτό, πρέπει επίσης να ορίσουμε την έκδοση των Υπηρεσιών Google Play που χρησιμοποιούμε για αυτήν την εφαρμογή:
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_CODE_RECOVER_PLAY_SERVICES) { if (resultCode == RESULT_OK) { // Make sure the app is not already connected or attempting to connect if (!mGoogleApiClient.isConnecting() && !mGoogleApiClient.isConnected()) { mGoogleApiClient.connect(); } } else if (resultCode == RESULT_CANCELED) { Toast.makeText(mContext, 'Google Play Services must be installed.', Toast.LENGTH_SHORT).show(); finish(); } } }
Πριν από την πρόσβαση σε λειτουργίες που παρέχονται από τις Υπηρεσίες Google Play, πρέπει να ελέγξουμε εάν η συσκευή έχει εγκατεστημένες τις Υπηρεσίες Google Play και ότι η έκδοση είναι αυτή που σκοπεύουμε να χρησιμοποιήσουμε (6.5.87).
protected synchronized void buildGoogleApiClient() { mGoogleApiClient = new GoogleApiClient.Builder(this) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .addApi(LocationServices.API) .build(); }
Αυτή η μέθοδος θα ελέγξει για τις Υπηρεσίες Google Play και σε περίπτωση που η συσκευή δεν την έχει εγκαταστήσει (είναι σπάνια, αλλά έχω δει τέτοιες περιπτώσεις), θα ανοίξει ένα διάλογο με το αντίστοιχο σφάλμα και θα καλέσει τον χρήστη να εγκαταστήσει / ενημερώσει Υπηρεσίες Google Play από το Google Play Store.
Αφού ο χρήστης ολοκληρώσει την ανάλυση που παρέχεται από το 'GooglePlayServicesUtil.getErrorDialog ()', ενεργοποιείται μια μέθοδος επανάκλησης 'onActivityResult ()', οπότε πρέπει να εφαρμόσουμε κάποια λογική για να χειριστούμε αυτήν την κλήση:
package com.bitwoo.userlocation; import android.content.Intent; import android.location.Location; import android.os.Bundle; import android.support.v7.app.ActionBarActivity; import android.view.Menu; import android.view.MenuItem; import android.widget.Toast; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.GooglePlayServicesUtil; import com.google.android.gms.common.api.GoogleApiClient; import com.google.android.gms.location.LocationServices; public class MainActivity extends ActionBarActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener { private static int REQUEST_CODE_RECOVER_PLAY_SERVICES = 200; private GoogleApiClient mGoogleApiClient; private Location mLastLocation; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (checkGooglePlayServices()) { buildGoogleApiClient(); } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } private boolean checkGooglePlayServices() { int checkGooglePlayServices = GooglePlayServicesUtil .isGooglePlayServicesAvailable(this); if (checkGooglePlayServices != ConnectionResult.SUCCESS) { /* * google play services is missing or update is required * return code could be * SUCCESS, * SERVICE_MISSING, SERVICE_VERSION_UPDATE_REQUIRED, * SERVICE_DISABLED, SERVICE_INVALID. */ GooglePlayServicesUtil.getErrorDialog(checkGooglePlayServices, this, REQUEST_CODE_RECOVER_PLAY_SERVICES).show(); return false; } return true; } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_CODE_RECOVER_PLAY_SERVICES) { if (resultCode == RESULT_OK) { // Make sure the app is not already connected or attempting to connect if (!mGoogleApiClient.isConnecting() && !mGoogleApiClient.isConnected()) { mGoogleApiClient.connect(); } } else if (resultCode == RESULT_CANCELED) { Toast.makeText(this, 'Google Play Services must be installed.', Toast.LENGTH_SHORT).show(); finish(); } } } protected synchronized void buildGoogleApiClient() { mGoogleApiClient = new GoogleApiClient.Builder(this) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .addApi(LocationServices.API) .build(); } @Override public void onConnected(Bundle bundle) { } @Override public void onConnectionSuspended(int i) { } @Override public void onConnectionFailed(ConnectionResult connectionResult) { } }
Για πρόσβαση στα API Google, απλώς πρέπει να κάνουμε ένα ακόμη βήμα: δημιουργήστε μια παρουσία του GoogleApiClient. Το Google API Client παρέχει ένα κοινό σημείο εισόδου σε όλες τις υπηρεσίες Google Play και διαχειρίζεται τη σύνδεση δικτύου μεταξύ της συσκευής του χρήστη και κάθε υπηρεσίας Google. Το πρώτο μας βήμα εδώ είναι να ξεκινήσουμε τη σύνδεση. Συνήθως ονομάζω αυτόν τον κωδικό από τη μέθοδο 'onCreate' της δραστηριότητας:
@Override protected void onStart() { super.onStart(); if (mGoogleApiClient != null) { mGoogleApiClient.connect(); } }
Με την αλυσίδα μιας σειράς κλήσεων μεθόδου, καθορίζουμε την εφαρμογή διεπαφής επανάκλησης και το API υπηρεσίας τοποθεσίας που θέλουμε να χρησιμοποιήσουμε. Η εφαρμογή διεπαφής, στην περίπτωση αυτή 'αυτό', θα λάβει απάντηση στην ασύγχρονη μέθοδο 'connect ()' όταν η σύνδεση με τις Υπηρεσίες Google Play επιτύχει, αποτύχει ή τεθεί σε αναστολή. Μετά την προσθήκη αυτού του κώδικα, το 'MainActivity' θα πρέπει να έχει την εξής μορφή:
@Override public void onConnected(Bundle bundle) { mLastLocation = LocationServices.FusedLocationApi.getLastLocation( mGoogleApiClient); if (mLastLocation != null) { Toast.makeText(this, 'Latitude:' + mLastLocation.getLatitude()+', Longitude:'+mLastLocation.getLongitude(),Toast.LENGTH_LONG).show(); } }
Στη συνέχεια, στη μέθοδο 'onStart' καλούμε τη μέθοδο 'connect' και περιμένουμε να κληθεί η μέθοδος επανάκλησης 'onConnected':
protected void createLocationRequest() { mLocationRequest = new LocationRequest(); mLocationRequest.setInterval(20000); mLocationRequest.setFastestInterval(5000); mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); }
Η μέθοδος 'onConnected' θα έχει την εξής μορφή:
protected void startLocationUpdates() { LocationServices.FusedLocationApi.requestLocationUpdates( mGoogleApiClient, mLocationRequest, this); }
Αυτή η επανάκληση ενεργοποιείται όταν είναι συνδεδεμένες οι Υπηρεσίες Google Play, πράγμα που σημαίνει ότι πρέπει να έχουμε την τελευταία γνωστή τοποθεσία. Ωστόσο, αυτή η τοποθεσία μπορεί να είναι μηδενική (είναι σπάνια αλλά όχι αδύνατη). Σε αυτήν την περίπτωση, αυτό που προτείνω είναι να ακούσετε ενημερώσεις τοποθεσίας που θα καλυφθούν στη συνέχεια.
Αφού καλέσετε το 'getLastLocation', ίσως θελήσετε να ζητήσετε περιοδικές ενημερώσεις από το Fused Location Provider. Ανάλογα με την αίτησή σας, αυτή η περίοδος μπορεί να είναι μικρή ή μεγάλη. Για παράδειγμα, εάν δημιουργείτε μια εφαρμογή που παρακολουθεί την τοποθεσία ενός χρήστη ενώ οδηγεί, θα πρέπει να ακούσετε ενημερώσεις σε σύντομα διαστήματα. Από την άλλη πλευρά, εάν η αίτησή σας αφορά την κοινή χρήση της τοποθεσίας χρήστη με τον φίλο του, ίσως χρειαστεί απλώς να ζητήσετε την τοποθεσία μερικές φορές.
Η δημιουργία ενός αιτήματος είναι πολύ εύκολη - μπορείτε να καλέσετε αυτήν τη μέθοδο μέσα στη μέθοδο 'onCreate':
public class MainActivity extends ActionBarActivity implements ConnectionCallbacks, OnConnectionFailedListener, LocationListener { // ... @Override public void onLocationChanged(Location location) { mLastLocation = location; Toast.makeText(this, 'Latitude:' + mLastLocation.getLatitude()+', Longitude:'+mLastLocation.getLongitude(),Toast.LENGTH_LONG).show(); } }
Δημιουργούμε ένα νέο Αίτηση τοποθεσίας αντικείμενο. Ορίστε το διάστημα σε 20 δευτερόλεπτα (20000 χιλιοστά του δευτερολέπτου). Επιπλέον, ορίζουμε ρυθμό ενημέρωσης πεταλούδας σε 5 δευτερόλεπτα. Αυτό λέει στο API να παρέχει ενημερώσεις κάθε 20 δευτερόλεπτα (κατά προτίμηση), αλλά εάν υπάρχει μια αλλαγή διαθέσιμη εντός περιόδου 5 δευτερολέπτων, θα πρέπει να το παρέχει επίσης. Τέλος, θέτουμε την προτεραιότητα σε « PRIORITY_HIGH_ACCURACY ', Μεταξύ των άλλων διαθέσιμων επιλογών προτεραιότητας: PRIORITY_BALANCED_POWER_ACCURACY , PRIORITY_LOW_POWER , PRIORITY_NO_POWER .
Μόλις δημιουργήσετε το αίτημα, είστε έτοιμοι να αρχίσετε να ακούτε ενημερώσεις τοποθεσίας μετά την ενεργοποίηση της μεθόδου 'onConnected ()':
protected void stopLocationUpdates() { if (mGoogleApiClient != null) { LocationServices.FusedLocationApi.removeLocationUpdates( mGoogleApiClient, this); } }
Το μόνο που μένει τώρα είναι να εφαρμόσουμε τη μέθοδο επανάκλησης για να ικανοποιήσουμε το ΤοποθεσίαListener διεπαφή:
ποιο στοιχείο εμπλέκεται στη διεξαγωγή ενός τεστ χρηστικότητας
@Override protected void onStop() { super.onStop(); if (mGoogleApiClient != null) { mGoogleApiClient.disconnect(); } }
Είναι σημαντικό να σταματήσετε ρητά να ακούτε ενημερώσεις όταν δεν τις χρειάζεστε πια ή εάν ο χρήστης αποχωρήσει από την εφαρμογή σας. Η ακόλουθη μέθοδος πρέπει να επικαλεστεί μέσα από την επιστροφή κλήσης 'onPause':
|_+_|
… Και αποσύνδεση του Google API:
Όπως μπορείτε να δείτε, οι θεμελιώδεις ιδέες πίσω από την εφαρμογή εφαρμογών που γνωρίζουν την τοποθεσία στο Android είναι πολύ απλές. Επιπλέον, με τα διαθέσιμα API που είναι τόσο απλά στη χρήση όσο και εύκολα κατανοητά, θα πρέπει να είναι απαράδεκτο να δημιουργείτε βασικές εφαρμογές βάσει τοποθεσίας για Android. Η μικρή εφαρμογή δείγματος που έχουμε δημιουργήσει εδώ έχει σκοπό να δείξει ακριβώς αυτό. Μπορείτε να βρείτε το πλήρες πηγαίος κώδικας για αυτό στο GitHub . Λάβετε υπόψη ότι για να διατηρήσετε τα πράγματα απλά, η εφαρμογή δεν χειρίζεται τη μέθοδο επανάκλησης 'onConnectionFailed'.
Ας ελπίσουμε ότι αυτό το σεμινάριο θα σας βοηθήσει να ξεκινήσετε τη χρήση του API υπηρεσιών τοποθεσίας Google.