2013-02-25 51 views
7

मैं इस तरह कुछ करना चाहता हूँ:एक सेवा में एंड्रॉयड स्थान अद्यतन

  • अपने आवेदन शुरू होता है मैं एक सेवा है जो मेरे स्थान

  • की जाँच करनी चाहिए शुरू करने के लिए आवेदन पृष्ठभूमि में चला जाता जब चाहते हैं मैं सेवा

बंद करना चाहते हैं मैं दो प्रमुख समस्याएं हैं:

  1. मैं कैसे पता लगा सकता हूं कि मेरा एप्लिकेशन पृष्ठभूमि में जाता है? मैं कई गतिविधियों को घेरता हूं, और मैंने कोशिश की कि मेरी मुख्य गतिविधि में ओवरराइडिंग पर रोकें, लेकिन जब मैं दूसरी गतिविधि शुरू करता हूं तो ऑन पॉज़ भी कहा जाता है।

  2. यह समस्या अधिक महत्वपूर्ण है: मेरी सेवा जो मेरे स्थान की जांच करती है, कैसा दिखना चाहिए? मैंने कई दृष्टिकोणों की कोशिश की, लेकिन कोई सफलता नहीं मिली।

मेरी सेवा इस तरह दिखती है, और यह काम नहीं कर रही है। इसे काम करने के लिए मुझे क्या बदलना चाहिए?

package com.pivoscore.service; 

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

public class LocationService extends Service { 

    private LocationListener locationListener; 

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

    @Override 
    public int onStartCommand(final Intent intent, final int flags, final int startId) { 
     super.onStartCommand(intent, flags, startId); 
     return Service.START_STICKY; 
    } 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
     final LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE); 
     this.locationListener = new MyLocationListener(); 
     locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 100, 0, this.locationListener); 
    } 

    private static class MyLocationListener implements LocationListener { 

     @Override 
     public void onLocationChanged(final Location location) { 
     } 

     @Override 
     public void onProviderDisabled(final String provider) { 
     } 

     @Override 
     public void onProviderEnabled(final String provider) { 
     } 

     @Override 
     public void onStatusChanged(final String provider, final int status, final Bundle extras) { 
     } 

    } 

} 
+0

ऑनर्यूम() विधि, सेवा खोज स्थान जानकारी और ऑन पॉज़() विधि स्थान को हटा दें। – user2060383

+0

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

+0

android.permission.ACCESS_COARSE_LOCATION android.permission.ACCESS_FINE_LOCATION android.permission.ACCESS_NETWORK_STATE आप अपने मैनिफ़ेस्ट फ़ाइल में इन अनुमति जोड़ा है? –

उत्तर

4

यह exaclty मदद करेंगे क्या अपने requirment है, लेकिन मत भूलना अनुमति जोड़ें मैं टिप्पणी में जोड़ दिया है और यह भी प्रकट फ़ाइल में वर्धित सेवा टैग करने के लिए मत भूलना कोड Snipet

के बाद किया जाता है
public class LocationService extends Service { 
public static final String BROADCAST_ACTION = "Hello World"; 
private static final int TWO_MINUTES = 1000 * 60 * 2; 
public LocationManager locationManager; 
public MyLocationListener listener; 
public Location previousBestLocation = null; 

Intent intent; 
int counter = 0; 

@Override 
public void onCreate() { 
    super.onCreate(); 
    intent = new Intent(BROADCAST_ACTION);  
} 

@Override 
public void onStart(Intent intent, int startId) {  
    locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); 
    listener = new MyLocationListener();   
    locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, listener); 
    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, listener); 
} 

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

protected boolean isBetterLocation(Location location, Location currentBestLocation) { 
    if (currentBestLocation == null) { 
     // A new location is always better than no location 
     return true; 
    } 

    // Check whether the new location fix is newer or older 
    long timeDelta = location.getTime() - currentBestLocation.getTime(); 
    boolean isSignificantlyNewer = timeDelta > TWO_MINUTES; 
    boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES; 
    boolean isNewer = timeDelta > 0; 

    // If it's been more than two minutes since the current location, use the new location 
    // because the user has likely moved 
    if (isSignificantlyNewer) { 
     return true; 
    // If the new location is more than two minutes older, it must be worse 
    } else if (isSignificantlyOlder) { 
     return false; 
    } 

    // Check whether the new location fix is more or less accurate 
    int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy()); 
    boolean isLessAccurate = accuracyDelta > 0; 
    boolean isMoreAccurate = accuracyDelta < 0; 
    boolean isSignificantlyLessAccurate = accuracyDelta > 200; 

    // Check if the old and new location are from the same provider 
    boolean isFromSameProvider = isSameProvider(location.getProvider(), 
      currentBestLocation.getProvider()); 

    // Determine location quality using a combination of timeliness and accuracy 
    if (isMoreAccurate) { 
     return true; 
    } else if (isNewer && !isLessAccurate) { 
     return true; 
    } else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) { 
     return true; 
    } 
    return false; 
} 

/** Checks whether two providers are the same */ 
private boolean isSameProvider(String provider1, String provider2) { 
    if (provider1 == null) { 
     return provider2 == null; 
    } 
    return provider1.equals(provider2); 
} 

@Override 
public void onDestroy() {  
    // handler.removeCallbacks(sendUpdatesToUI);  
    super.onDestroy(); 
    Log.v("STOP_SERVICE", "DONE"); 
    locationManager.removeUpdates(listener);   
} 

public static Thread performOnBackgroundThread(final Runnable runnable) { 
    final Thread t = new Thread() { 
     @Override 
     public void run() { 
      try { 
       runnable.run(); 
      } finally { 

      } 
     } 
    }; 
    t.start(); 
    return t; 
} 


public class MyLocationListener implements LocationListener 
{ 

    public void onLocationChanged(final Location loc) 
    { 
     Log.i("**************************************", "Location changed"); 
     if(isBetterLocation(loc, previousBestLocation)) { 
      loc.getLatitude(); 
      loc.getLongitude();    
      intent.putExtra("Latitude", loc.getLatitude()); 
      intent.putExtra("Longitude", loc.getLongitude());  
      intent.putExtra("Provider", loc.getProvider());     
      sendBroadcast(intent);   
      /*final Geocoder geocoder = new Geocoder(getApplicationContext(), Locale.getDefault());   
      String Text = ""; 
      try { 
       List<Address> addresses = geocoder.getFromLocation(loc.getLatitude(), loc.getLongitude(), 1);     
       Text = "My current location is: "+addresses.get(0).getAddressLine(0); 

      } catch (Exception e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
       Text = "My current location is: " +"Latitude = " + loc.getLatitude() + ", Longitude = " + loc.getLongitude(); 
      } 
      */ 
      //Toast.makeText(getApplicationContext(), "Location polled to server", Toast.LENGTH_SHORT).show(); 
     }        
    } 

    public void onProviderDisabled(String provider) 
    { 
     Toast.makeText(getApplicationContext(), "Gps Disabled", Toast.LENGTH_SHORT).show(); 
    } 


    public void onProviderEnabled(String provider) 
    { 
     Toast.makeText(getApplicationContext(), "Gps Enabled", Toast.LENGTH_SHORT).show(); 
    } 


    public void onStatusChanged(String provider, int status, Bundle extras) 
    { 

    } 

} 
+0

आपके महान उत्तर के लिए धन्यवाद। मुझे अपने AndroidManifest.xml पर निम्न कोड जोड़ने की आवश्यकता है ताकि किसी गतिविधि से सेवा शुरू करने में सक्षम हो सके: '' –

0

इस कोड का प्रयास करें .. इस का उपयोग करते हुए आप पा सकते हैं कि आपका आवेदन अग्रभूमि या पृष्ठभूमि में है के द्वारा। आशा है कि यह आपकी मदद करेगा।

try { 
    foreground = new ForegroundCheckTask().execute(ctx).get(); 
} 

====================================== 


class ForegroundCheckTask extends AsyncTask<Context, Void, Boolean> { 

@Override 
protected Boolean doInBackground(Context... params) { 
    final Context context = params[0].getApplicationContext(); 
    return isAppOnForeground(context); 
} 

private boolean isAppOnForeground(Context context) { 
    ActivityManager activityManager = (ActivityManager) context 
      .getSystemService(Context.ACTIVITY_SERVICE); 
    List<RunningAppProcessInfo> appProcesses = activityManager 
      .getRunningAppProcesses(); 
    if (appProcesses == null) { 
     return false; 
    } 
    final String packageName = context.getPackageName(); 


    String activePackageName = activityManager.getRunningTasks(1).get(0).topActivity.getPackageName(); 
    if (activePackageName.equals(packageName)) { 
     return true; 
    } 
    else{ 
     return false; 
    } 


} 

} 
+0

इस कोड को काम करने के लिए मुझे किन अनुमतियों की आवश्यकता है? – ffddani

+0

ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION भविष्य के स्थान कोड के लिए और कुछ भी नहीं, बस अपने AndroidManifest – akuzma

+0

पर कोई भी सेवा जोड़ने की याद रखें .. केवल संदर्भ का उपयोग करें .. और अग्रभूमि एक बूलियन मान है .. ctx संदर्भ है .. इसे चुनें और मुझे दो अपनी टिप्पणियों को जानें। – itsrajesh4uguys

2
  1. आवेदन एंड्रॉयड में एक दृश्य घटक नहीं है। यह क्रियाकलापों में बांटा गया है, उनमें से प्रत्येक दृश्यमान, रुका हुआ और अन्यथा नष्ट होने पर चलाया जाता है। इसलिए, पृष्ठभूमि में जाने वाले पूरे आवेदन की कोई अवधारणा नहीं है, गतिविधियों को उनकी व्यक्तिगत दृश्यता के आधार पर रोक दिया गया है और फिर से शुरू किया गया है और इस मामले में अन्य गतिविधियों से पूरी तरह से स्वतंत्र हैं।

  2. आपकी सेवा स्थान प्रबंधक के साथ onCreate() में पंजीकृत होगी, इसे onDestroy() में से पंजीकृत करें। अपने onBind() में यह Messenger ऑब्जेक्ट लौटाएगा। और, onLocationChanged() में इसे अपने साझा Messenger के माध्यम से एक संदेश भेजना चाहिए। START_STICKY का उपयोग करने की आवश्यकता नहीं है क्योंकि आप नहीं चाहते कि सेवा हर समय चल रही हो।

  3. गतिविधि (App में किसी भी गतिविधि हो सकता है) बस इसके onStart() में bindService() कॉल करने के लिए की जरूरत है, सेवा पहले से ही नहीं तो शुरू कर देंगे, और गतिविधि सेवा से Messenger मिल जाएगा। साथ ही, गतिविधि को से unbindService() पर कॉल करना चाहिए। जब सेवा कुछ भी बाध्य नहीं होती है तो सेवा स्वचालित रूप से रुक जाएगी।

  4. आप ऐप (टास्क) के स्तर पर बिंदु 3 में सामान क्या करने की जरूरत है, तो Application वर्ग को लागू है, और उसके onCreate() और onTerminate() का उपयोग करें। एप्लिकेशन क्लास को गतिविधि की तरह रोका या बंद नहीं किया गया है।

    @Override 
    protected void onResume() { 
        super.onResume(); 
    
        final Intent locationServiceIntent = new Intent(this, LocationService.class); 
        this.startService(locationServiceIntent); 
    } 
    
    @Override 
    protected void onPause() { 
        super.onPause(); 
    
        if (!Utils.isAppInForeground(this)) { 
         final Intent locationServiceIntent = new Intent(this, LocationService.class); 
         this.stopService(locationServiceIntent); 
        } 
    } 
    

    अब, कैसे मैं अपने LocationService काम कर सकते हैं:

+0

मैं कैसे पता लगा सकता हूं कि मेरा आवेदन पृष्ठभूमि में जाता है? मैंने पृष्ठभूमि पर जाने वाली किसी भी गतिविधि के बारे में कभी नहीं कहा। लेकिन वह अब कोई फर्क नहीं पड़ता, क्योंकि मेरी पहली समस्या हल हो गई है। – ffddani

+0

एंड्रॉइड में कोई ** दृश्यमान अनुप्रयोग ** घटक नहीं है। यदि आपकी कोई भी गतिविधि दिखाई दे रही है, तो ऐप चल रहा है, अन्यथा, ऐप बंद हो गया है और यहां तक ​​कि नियत भी हो सकता है royed। फिर भी, आप बिंदु 4 का उपयोग कर सकते हैं। –

0

शाबाशी, मेरी पहली समस्या इस तरह से ऊपर कोड का उपयोग कर हल किया जाता है?

1

मैं आपको Google द्वारा प्रदान की गई नवीनतम स्थान एपीआई (संस्करण 2.2 के अनुकूल भी) का उपयोग करने का सुझाव देता हूं।

यहाँ एक उदाहरण है कि उपयोग करने के लिए कैसे पता चलता है: https://github.com/chenjishi/android_location_demo

अपने ऐप पृष्ठभूमि को चलाने के लिए, आप डिस्कनेक्ट स्थान अद्यतन को रोकने के लिए कह सकते हैं।