2012-01-12 18 views
45

में किसी सेवा के माध्यम से जीपीएस स्थान प्राप्त करें मुझे पृष्ठभूमि सेवा का उपयोग करके उपयोगकर्ता के स्थानों की निगरानी करने की आवश्यकता है, और फिर उन्हें लोड करें और उपयोगकर्ता को पथ दिखाएं।एंड्रॉइड

एक गतिविधि का उपयोग करना, जीपीएस स्थानों को प्राप्त करना काफी आसान था, लेकिन जब मुझे एक सेवा के माध्यम से ऐसा करना पड़ा, तो मुझे एक समस्या आई, क्योंकि ऐसा लगता है कि यह केवल लूपर धागे (या ऐसा कुछ) के लिए काम करता है।

जैसा कि मैंने समाधान के लिए इंटरनेट खोजा है, मुझे पता चला है कि कई लोगों को एक ही समस्या है, लेकिन मुझे एक समाधान समाधान नहीं मिला। कुछ लोग कहते हैं कि आपको तैयारी-> लूप-> छोड़ने की ज़रूरत है, और कुछ कहते हैं कि आपको हैंडलर थ्रेड का उपयोग करना है, लेकिन फिर भी, मुझे यह नहीं पता कि उचित तरीके से ऐसी चीजें कैसे करें।

+0

दीवाना धागे में: डी आप looper धागे मतलब है। एक लूपर थ्रेड एक अनुरोध कतार तंत्र के साथ एक विशेष धागा है। मुख्य या यूआई थ्रेड एक लूपर थ्रेड है। किसी सेवा के साथ समस्या के लिए, क्या आप मुख्य थ्रेड पर requestLocationUpdates का आह्वान कर रहे हैं? या आप इसे एक अलग धागे में कर रहे हैं? चूंकि गतिविधियों और सेवाओं को मुख्य थ्रेड के माध्यम से चलाया जाता है जो एक लूपर थ्रेड होता है, इसलिए अनुरोध आवंटन स्थान अद्यतन समान होना चाहिए। क्या आप इस मुद्दे का उल्लेख करने वाली अन्य पोस्टों को इंगित कर सकते हैं जिनके बारे में आप बात कर रहे हैं? –

उत्तर

-7

ठीक है, मैं onCreate पर कोई हैंडलर बनाने के द्वारा इसका समाधान कर लिया सेवा के, और वहां से जीपीएस कार्यों को बुलाओ।

+62

कृपया कोड पोस्ट करें। यह वास्तव में दूसरों की मदद करेगा जो उत्तर की तलाश करते समय इस पृष्ठ पर ठोकर खाएंगे। – Razgriz

+1

इसका उत्तर बहुत समय पहले दिया गया था, लेकिन मैं समझाने की कोशिश करूंगा: चूंकि जीपीएस हैंडलिंग को यूआई थ्रेड पर चलाने की जरूरत है, यूआई थ्रेड पर चलने वाली सेवा पर किसी भी तरीके पर हैंडलर ऑब्जेक्ट बनाएं (जैसे क्रिएट) और इसे सेवा में एक क्षेत्र में स्थापित करें। इससे भी, किसी भी समय आपको जीपीएस ऑपरेशंस का उपयोग करने की ज़रूरत है, बस इस हैंडलर इंस्टेंस पर पोस्ट (रननेबल) पर कॉल करें। –

+0

क्या आप कोड पोस्ट कर सकते हैं? – delive

40

मुझे समझ में नहीं आता कि सेवा में स्थान सुनने की कार्यक्षमता को लागू करने में समस्या क्या है। यह गतिविधि में आप जो करते हैं उसके समान दिखता है। बस एक स्थान श्रोता परिभाषित करें और स्थान अपडेट के लिए पंजीकरण करें। आप उदाहरण के रूप में निम्न कोड का उल्लेख कर सकते हैं:

मालसूची फ़ाइल:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> 
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> 
<application 
    android:icon="@drawable/ic_launcher" 
    android:label="@string/app_name" > 
    <activity android:label="@string/app_name" android:name=".LocationCheckerActivity" > 
     <intent-filter > 
      <action android:name="android.intent.action.MAIN" /> 
      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 
    </activity> 
    <service android:name=".MyService" android:process=":my_service" /> 
</application> 

सेवा फ़ाइल:

import android.app.Service; 
import android.content.Context; 
import android.content.Intent; 
import android.location.Location; 
import android.location.LocationManager; 
import android.os.Bundle; 
import android.os.IBinder; 
import android.util.Log; 

public class MyService extends Service 
{ 
private static final String TAG = "BOOMBOOMTESTGPS"; 
private LocationManager mLocationManager = null; 
private static final int LOCATION_INTERVAL = 1000; 
private static final float LOCATION_DISTANCE = 10f; 

private class LocationListener implements android.location.LocationListener{ 
    Location mLastLocation; 
    public LocationListener(String provider) 
    { 
     Log.e(TAG, "LocationListener " + provider); 
     mLastLocation = new Location(provider); 
    } 
    @Override 
    public void onLocationChanged(Location location) 
    { 
     Log.e(TAG, "onLocationChanged: " + location); 
     mLastLocation.set(location); 
    } 
    @Override 
    public void onProviderDisabled(String provider) 
    { 
     Log.e(TAG, "onProviderDisabled: " + provider);    
    } 
    @Override 
    public void onProviderEnabled(String provider) 
    { 
     Log.e(TAG, "onProviderEnabled: " + provider); 
    } 
    @Override 
    public void onStatusChanged(String provider, int status, Bundle extras) 
    { 
     Log.e(TAG, "onStatusChanged: " + provider); 
    } 
} 
LocationListener[] mLocationListeners = new LocationListener[] { 
     new LocationListener(LocationManager.GPS_PROVIDER), 
     new LocationListener(LocationManager.NETWORK_PROVIDER) 
}; 
@Override 
public IBinder onBind(Intent arg0) 
{ 
    return null; 
} 
@Override 
public int onStartCommand(Intent intent, int flags, int startId) 
{ 
    Log.e(TAG, "onStartCommand"); 
    super.onStartCommand(intent, flags, startId);  
    return START_STICKY; 
} 
@Override 
public void onCreate() 
{ 
    Log.e(TAG, "onCreate"); 
    initializeLocationManager(); 
    try { 
     mLocationManager.requestLocationUpdates(
       LocationManager.NETWORK_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE, 
       mLocationListeners[1]); 
    } catch (java.lang.SecurityException ex) { 
     Log.i(TAG, "fail to request location update, ignore", ex); 
    } catch (IllegalArgumentException ex) { 
     Log.d(TAG, "network provider does not exist, " + ex.getMessage()); 
    } 
    try { 
     mLocationManager.requestLocationUpdates(
       LocationManager.GPS_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE, 
       mLocationListeners[0]); 
    } catch (java.lang.SecurityException ex) { 
     Log.i(TAG, "fail to request location update, ignore", ex); 
    } catch (IllegalArgumentException ex) { 
     Log.d(TAG, "gps provider does not exist " + ex.getMessage()); 
    } 
} 
@Override 
public void onDestroy() 
{ 
    Log.e(TAG, "onDestroy"); 
    super.onDestroy(); 
    if (mLocationManager != null) { 
     for (int i = 0; i < mLocationListeners.length; i++) { 
      try { 
       mLocationManager.removeUpdates(mLocationListeners[i]); 
      } catch (Exception ex) { 
       Log.i(TAG, "fail to remove location listners, ignore", ex); 
      } 
     } 
    } 
} 
private void initializeLocationManager() { 
    Log.e(TAG, "initializeLocationManager"); 
    if (mLocationManager == null) { 
     mLocationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE); 
    } 
} 
} 
+0

मुझे पता है, यह एक साइड प्रोजेक्ट पर ठीक काम करता है, लेकिन मैं कुछ लोगों के साथ काम करता हूं और किसी कारण से, मुझे हमेशा अपवाद मिलता है: java.lang.RuntimeException: थूपर के अंदर हैंडलर नहीं बना सकता जिसे लूपर नहीं कहा जाता है। तैयार करें() मैंने कोड को देखा है और मैं नहीं देख सकता कि यह एक विशेष धागे पर काम करता है, और बस आपके कोड की तरह, सेवा एक निर्दिष्ट नाम के साथ एक प्रक्रिया पर चलती है। –

+0

शायद ऐसा इसलिए है क्योंकि सेवा की अपनी प्रक्रिया है, और जब आप बाद में एप्लिकेशन खोलते हैं, तो यह एक अलग थ्रेड का उपयोग करता है, जो मूल नहीं है? –

+1

बीटीडब्ल्यू, क्या "ऑनडिस्टॉय" विधि के लिए "removeUpdates" को कॉल करना आवश्यक है? मुझे लगता है कि इसे हटाने से स्मृति रिसाव नहीं होगा, नहीं? –

2

बस के पूरक है, मैं इस तरह से लागू किया है और आमतौर पर मेरी सेवा वर्ग

में काम किया मेरी सेवा

@Override 
public void onCreate() 
{ 
    mHandler = new Handler(Looper.getMainLooper()); 
    mHandler.post(this); 
    super.onCreate(); 
} 

@Override 
public void onDestroy() 
{ 
    mHandler.removeCallbacks(this);  
    super.onDestroy(); 
} 

@Override 
public void run() 
{ 
    InciarGPSTracker(); 
} 
17
public class GPSService extends Service implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, com.google.android.gms.location.LocationListener { 
    private LocationRequest mLocationRequest; 
    private GoogleApiClient mGoogleApiClient; 
    private static final String LOGSERVICE = "#######"; 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
     buildGoogleApiClient(); 
     Log.i(LOGSERVICE, "onCreate"); 

    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     Log.i(LOGSERVICE, "onStartCommand"); 

     if (!mGoogleApiClient.isConnected()) 
      mGoogleApiClient.connect(); 
     return START_STICKY; 
    } 


    @Override 
    public void onConnected(Bundle bundle) { 
     Log.i(LOGSERVICE, "onConnected" + bundle); 

     Location l = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient); 
     if (l != null) { 
      Log.i(LOGSERVICE, "lat " + l.getLatitude()); 
      Log.i(LOGSERVICE, "lng " + l.getLongitude()); 

     } 

     startLocationUpdate(); 
    } 

    @Override 
    public void onConnectionSuspended(int i) { 
     Log.i(LOGSERVICE, "onConnectionSuspended " + i); 

    } 

    @Override 
    public void onLocationChanged(Location location) { 
     Log.i(LOGSERVICE, "lat " + location.getLatitude()); 
     Log.i(LOGSERVICE, "lng " + location.getLongitude()); 
     LatLng mLocation = (new LatLng(location.getLatitude(), location.getLongitude())); 
     EventBus.getDefault().post(mLocation); 

    } 

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
     Log.i(LOGSERVICE, "onDestroy - Estou sendo destruido "); 

    } 

    @Nullable 
    @Override 
    public IBinder onBind(Intent intent) { 
     return null; 
    } 

    @Override 
    public void onConnectionFailed(ConnectionResult connectionResult) { 
     Log.i(LOGSERVICE, "onConnectionFailed "); 

    } 

    private void initLocationRequest() { 
     mLocationRequest = new LocationRequest(); 
     mLocationRequest.setInterval(5000); 
     mLocationRequest.setFastestInterval(2000); 
     mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); 

    } 

    private void startLocationUpdate() { 
     initLocationRequest(); 

     if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 
      // TODO: Consider calling 
      // ActivityCompat#requestPermissions 
      // here to request the missing permissions, and then overriding 
      // public void onRequestPermissionsResult(int requestCode, String[] permissions, 
      //           int[] grantResults) 
      // to handle the case where the user grants the permission. See the documentation 
      // for ActivityCompat#requestPermissions for more details. 
      return; 
     } 
     LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this); 
    } 

    private void stopLocationUpdate() { 
     LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this); 

    } 

    protected synchronized void buildGoogleApiClient() { 
     mGoogleApiClient = new GoogleApiClient.Builder(this) 
       .addOnConnectionFailedListener(this) 
       .addConnectionCallbacks(this) 
       .addApi(LocationServices.API) 
       .build(); 
    } 

} 
+0

मैं देखने के लिए स्थान भेजने के लिए lib EventBus का उपयोग कर रहा हूं। -> EventBus.getDefault()। पोस्ट (mLocation) – vrbsm

+0

यह पृष्ठभूमि में नहीं चल रहा है। मैं रेड एमआई नोट 3 का उपयोग कर रहा हूं। ऐप चालू होने पर यह ठीक काम कर रहा है लेकिन सेवा के रूप में काम नहीं कर रहा है। –

+1

यहां अनुमतियों और स्थान सेटिंग्स से निपटने के लिए कैसे ?? –

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^