【问题标题】:Android: Stop serviceAndroid:停止服务
【发布时间】:2014-06-22 16:51:56
【问题描述】:

我正在尝试一个演示,在该演示中,我在启动按钮上启动一项服务。该服务在后台运行,获取 GPS 位置并将其发送到服务器。代码如下:

主要活动

public class MainActivity extends Activity implements OnClickListener {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button start = (Button) findViewById(R.id.button_start);
        Button stop = (Button) findViewById(R.id.button_stop);

        start.setOnClickListener(this);
        stop.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        if(v.getId() == R.id.button_start){
            Intent intent = new Intent(this,AndroidLocationServices.class);
        startService(intent);
        } else if(v.getId() == R.id.button_stop){
            Intent intent = new Intent(this,AndroidLocationServices.class);
        stopService(intent);
        }
    }
}

Android 位置监听器

public class AndroidLocationServices extends Service {
WakeLock wakeLock;

private LocationManager locationManager;
String lat,longi;

public AndroidLocationServices() {
}

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

@Override
public void onCreate() {
    super.onCreate();

    PowerManager pm = (PowerManager) getSystemService(this.POWER_SERVICE);

    wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "DoNotSleep");

    Log.e("Google", "Service Created");
}

public void onStart(Intent intent, int startId) {
    Log.e("Google", "Service Started");

    locationManager = (LocationManager) getApplicationContext()
            .getSystemService(Context.LOCATION_SERVICE);

    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
            5000, 5, listener);
}

private LocationListener listener = new LocationListener() {
    @Override
    public void onLocationChanged(Location location) {
        Log.e("Google", "Location Changed");

        if (location == null)
            return;

        if (isConnectingToInternet(getApplicationContext())) {
            JSONArray jsonArray = new JSONArray();
            JSONObject jsonObject = new JSONObject();

            try {
                Log.e("latitude", location.getLatitude() + "");
                Log.e("longitude", location.getLongitude() + "");

                lat = String.valueOf(location.getLatitude());
                longi = String.valueOf(location.getLongitude());

                jsonObject.put("latitude", location.getLatitude());
                jsonObject.put("longitude", location.getLongitude());

                jsonArray.put(jsonObject);

                Log.e("request", jsonArray.toString());

                new LocationWebService().execute();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void onProviderDisabled(String provider) {
    }

    @Override
    public void onProviderEnabled(String provider) {
    }

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

@Override
public void onDestroy() {
    super.onDestroy();
        wakeLock.release();
}

public static boolean isConnectingToInternet(Context _context) {
    ConnectivityManager connectivity = (ConnectivityManager) _context
            .getSystemService(Context.CONNECTIVITY_SERVICE);
    if (connectivity != null) {
        NetworkInfo[] info = connectivity.getAllNetworkInfo();
        if (info != null)
            for (int i = 0; i < info.length; i++)
                if (info[i].getState() == NetworkInfo.State.CONNECTED) {
                    return true;
                }

    }
    return false;
}

public class LocationWebService extends AsyncTask<String, String, Boolean> {

    public LocationWebService() {
    }

    @Override
    protected Boolean doInBackground(String... arg0) {

        ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
        nameValuePairs.add(new BasicNameValuePair("userLang", longi));
        nameValuePairs.add(new BasicNameValuePair("userLat", lat));
        nameValuePairs.add(new BasicNameValuePair("device_type", "Android"));

        Log.d("Lat",lat);
        Log.d("Lan",longi);

        // Service Handler to call PHP URL
        ServiceHandler serviceHandler = new ServiceHandler();

        // Creating service handler class instance
        String jsonStr = serviceHandler.makeHttpRequest("URL", "GET", nameValuePairs);  

        return null;
    }
 }
}

服务处理程序

public class ServiceHandler {
// Global Declaration.
static String json = "";
public final static int GET = 1;
public final static int POST = 2;
/*
 * Constructor.
 */
public ServiceHandler() {
}

/*
 * Making service call
 * @url - url to make request
 * @method - http request method
 * */
public String makeHttpRequest(String url, String method, List<NameValuePair> params) {
    // Making HTTP request
    try {
        // check for request method
        if(method == "POST"){
            // request method is POST
            // defaultHttpClient
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpPost httpPost = new HttpPost(url);
            // adding post params
            if (params != null) {
                httpPost.setEntity(new UrlEncodedFormEntity(params));
            }

            HttpResponse httpResponse = httpClient.execute(httpPost);
            HttpEntity httpEntity = httpResponse.getEntity();
            json = EntityUtils.toString(httpEntity);                
        }else if(method == "GET"){
            // request method is GET
            DefaultHttpClient httpClient = new DefaultHttpClient();
            String paramString = URLEncodedUtils.format(params, "utf-8");
            url += "?" + paramString;
            HttpGet httpGet = new HttpGet(url);

            HttpResponse httpResponse = httpClient.execute(httpGet);
            HttpEntity httpEntity = httpResponse.getEntity();
            json = EntityUtils.toString(httpEntity);
        }           
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    } catch (ClientProtocolException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return json;
}
}

现在我的服务不会在点击停止按钮时停止。我收到以下错误:

05-06 12:51:12.000: D/AndroidRuntime(11736): Shutting down VM
05-06 12:51:12.000: W/dalvikvm(11736): threadid=1: thread exiting with uncaught exception (group=0x416af2a0)
05-06 12:51:12.007: E/AndroidRuntime(11736): FATAL EXCEPTION: main
05-06 12:51:12.007: E/AndroidRuntime(11736): java.lang.RuntimeException: Unable to stop     service com.oi.demointentservice.AndroidLocationServices@41e910f8: java.lang.RuntimeException: WakeLock under-locked DoNotSleep
05-06 12:51:12.007: E/AndroidRuntime(11736):    at android.app.ActivityThread.handleStopService(ActivityThread.java:2575)
05-06 12:51:12.007: E/AndroidRuntime(11736):    at android.app.ActivityThread.access$2000(ActivityThread.java:140)
05-06 12:51:12.007: E/AndroidRuntime(11736):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1330)
05-06 12:51:12.007: E/AndroidRuntime(11736):    at android.os.Handler.dispatchMessage(Handler.java:99)
05-06 12:51:12.007: E/AndroidRuntime(11736):    at android.os.Looper.loop(Looper.java:137)
05-06 12:51:12.007: E/AndroidRuntime(11736):    at android.app.ActivityThread.main(ActivityThread.java:4895)
05-06 12:51:12.007: E/AndroidRuntime(11736):    at java.lang.reflect.Method.invokeNative(Native Method)
05-06 12:51:12.007: E/AndroidRuntime(11736):    at java.lang.reflect.Method.invoke(Method.java:511)
05-06 12:51:12.007: E/AndroidRuntime(11736):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:994)
05-06 12:51:12.007: E/AndroidRuntime(11736):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:761)
05-06 12:51:12.007: E/AndroidRuntime(11736):    at dalvik.system.NativeStart.main(Native Method)
05-06 12:51:12.007: E/AndroidRuntime(11736): Caused by: java.lang.RuntimeException: WakeLock under-locked DoNotSleep
05-06 12:51:12.007: E/AndroidRuntime(11736):    at android.os.PowerManager$WakeLock.release(PowerManager.java:363)
05-06 12:51:12.007: E/AndroidRuntime(11736):    at android.os.PowerManager$WakeLock.release(PowerManager.java:338)
05-06 12:51:12.007: E/AndroidRuntime(11736):    at com.oi.demointentservice.AndroidLocationServices.onDestroy(AndroidLocationServices.java:130)
05-06 12:51:12.007: E/AndroidRuntime(11736):    at android.app.ActivityThread.handleStopService(ActivityThread.java:2558)
05-06 12:51:12.007: E/AndroidRuntime(11736):    ... 10 more

请建议我现在该做什么。

【问题讨论】:

    标签: android service android-service android-location android-wake-lock


    【解决方案1】:

    首先:

    @Override
    public void onDestroy() {
       wakeLock.release();
       stopMyService();
       super.onDestroy();
    }
    

    第二: 在停止服务之前,您必须取消注册侦听器(位置一),然后您可以停止:

    stopSelf();
    

    按如下方式注销监听器是一个好习惯:

    public void closeMyService() {
        context.unregisterReceiver(receiver);
        locationManager.removeUpdates(this);
    }
    

    【讨论】:

      【解决方案2】:

      在destroy方法中检查WakeLock对象为null,因为有时服务没有启动,然后在onDestroy()方法中我们需要检查它。

       if( wakeLock.isHeld())
          {
              wakeLock.release();
          }
      

      onStart() 方法已被弃用,因此您可以使用 onStartCommand() 代替。 希望它能达到你的目的

      【讨论】:

      • 现在检查问题。
      • @ManojFegde 我已经使用 isHeld() 函数在上述模式中编辑了我的答案检查 wakeLock 对象,现在错误已解决
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-14
      • 2018-11-11
      • 2011-11-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多