用于位置的Android后台服务无法在其他手机中使用

时间:2016-11-29 13:30:00

标签: android service location android-pendingintent android-gps

位置检测的后台服务会在一段时间后关闭。我在onTaskRemoved中有代码为pendingIntent撤销设置警报。我仍然无法解决问题。以下是我的后台服务类的代码:

public class MyService extends Service {
    public static final String BROADCAST_ACTION = "Hello World";
    private static final int TWO_MINUTES = 1000 * 60 *5;
    public LocationManager locationManager;
    public MyLocationListener listener;
    public Location previousBestLocation = null;
    double latitude; // latitude
    double longitude; // longitude
    Intent intent;
    private static final String POST_URL = "http://api.url.com/oauth/api/v1/location/update";
    int counter = 0;
    public static boolean isRunning  = false;

    @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();
        if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.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;
        }
        locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 4000, 0, listener);
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 4000, 0, listener);
    }

    @Override
    public IBinder onBind(Intent intent) {
        super.onCreate();

        return (IBinder) intent;
    }




    protected boolean isBetterLocation(Location location, Location currentBestLocation) {
        if (currentBestLocation == null) {
            return true;
        }

        long timeDelta = location.getTime() - currentBestLocation.getTime();
        boolean isSignificantlyNewer = timeDelta > TWO_MINUTES;
        boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;
        boolean isNewer = timeDelta > 0;

        if (isSignificantlyNewer) {
            return true;
        } 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() {

        super.onDestroy();

Toast.makeText(getApplicationContext(),"onDestroy",Toast.LENGTH_LONG).show();
Log.d("onDestroy","onDestroy");

        Intent myIntent = new Intent(getApplicationContext(), MyService.class);

        PendingIntent pendingIntent = PendingIntent.getService(getApplicationContext(), 0, myIntent, 0);

        AlarmManager alarmManager1 = (AlarmManager) getSystemService(ALARM_SERVICE);

        Calendar calendar = Calendar.getInstance();

        calendar.setTimeInMillis(System.currentTimeMillis());

        calendar.add(Calendar.SECOND, 1);

        alarmManager1.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 10, pendingIntent);



    }


    @Override
    public void onTaskRemoved(Intent rootIntent) {
        super.onTaskRemoved(rootIntent);
        Toast.makeText(getApplicationContext(),"onTaskRemoved",Toast.LENGTH_LONG).show();
        Log.d("onTaskRemoved", "onTaskRemoved");
        Intent myIntent = new Intent(getApplicationContext(), MyService.class);

        PendingIntent pendingIntent = PendingIntent.getService(getApplicationContext(), 0, myIntent, 0);

        AlarmManager alarmManager1 = (AlarmManager) getSystemService(ALARM_SERVICE);

        Calendar calendar = Calendar.getInstance();

        calendar.setTimeInMillis(System.currentTimeMillis());

        calendar.add(Calendar.SECOND, 1);

        alarmManager1.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 10, pendingIntent) ;




    }


    public class MyLocationListener implements LocationListener {

        public void onLocationChanged(final Location loc) {
            if (isBetterLocation(loc, previousBestLocation)) {
                latitude = loc.getLatitude();
                longitude = loc.getLongitude();
                intent.putExtra("Latitude", loc.getLatitude());
                intent.putExtra("Longitude", loc.getLongitude());
                intent.putExtra("Provider", loc.getProvider());
                sendBroadcast(intent);


                SharedPreferences check = getApplicationContext().getSharedPreferences("Access_token", Context.MODE_PRIVATE);
                final String access_token = check.getString("access_token", "N/A");

                StringRequest stringRequest = new StringRequest(Request.Method.POST, POST_URL,
                        new Response.Listener<String>() {
                            @Override
                            public void onResponse(String response) {

Toast.makeText(getApplicationContext(),""+response,Toast.LENGTH_LONG).show();
                            }
                        },
                        new Response.ErrorListener() {
                            @Override
                            public void onErrorResponse(VolleyError error) {

                                Toast.makeText(getApplicationContext(),""+error,Toast.LENGTH_LONG).show();

                            }
                        }) {
                    @Override
                    protected Map<String, String> getParams() {
                        Map<String, String> params = new HashMap<String, String>();
                        params.put("access_token", access_token);
                        params.put("latitude", String.valueOf(latitude));
                        params.put("longitude", String.valueOf(longitude));
                        return params;
                    }

                };
                stringRequest.setRetryPolicy(new DefaultRetryPolicy(1 * 500000,
                        DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
                        DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
                RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
                requestQueue.add(stringRequest);
            }


        }

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

        }

        @Override
        public void onProviderEnabled(String provider) {

        }

        @Override
        public void onProviderDisabled(String provider) {

        }
    }

}

1 个答案:

答案 0 :(得分:0)

在onbind方法中返回null,因为返回某些东西意味着你想将它绑定到一个组件,这可能导致在该组件关闭时停止服务。也可以使用onStartCommand而不是onStart。如果你需要OnStartCommand方法中的意图,则返回START_REDELIVER_INTENT标志,否则使用START_STICKY重新启动服务。

public class MyService extends Service {
  public static final String BROADCAST_ACTION = "Hello World";
  private static final int TWO_MINUTES = 1000 * 60 *5;
  public LocationManager locationManager;
  public MyLocationListener listener;
  public Location previousBestLocation = null;
  double latitude; // latitude
  double longitude; // longitude
  Intent intent;
  private static final String POST_URL = "http://api.url.com/oauth/api/v1/location/update";
  int counter = 0;
  public static boolean isRunning  = false;

  @Override
  public int onStartCommand(Intent intent, int flags, int startId) {
    this.intent = new Intent(BROADCAST_ACTION);
    locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    listener = new MyLocationListener();
    if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.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.
    }
    locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 4000, 0, listener);
    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 4000, 0, listener);
    return START_STICKY;
  }

  protected boolean isBetterLocation(Location location, Location currentBestLocation) {
    if (currentBestLocation == null) {
      return true;
    }

    long timeDelta = location.getTime() - currentBestLocation.getTime();
    boolean isSignificantlyNewer = timeDelta > TWO_MINUTES;
    boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;
    boolean isNewer = timeDelta > 0;

    if (isSignificantlyNewer) {
      return true;
    } 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() {

    super.onDestroy();

    Toast.makeText(getApplicationContext(),"onDestroy", Toast.LENGTH_LONG).show();
    Log.d("onDestroy","onDestroy");

    Intent myIntent = new Intent(getApplicationContext(), MyService.class);

    PendingIntent pendingIntent = PendingIntent.getService(getApplicationContext(), 0, myIntent, 0);

    AlarmManager alarmManager1 = (AlarmManager) getSystemService(ALARM_SERVICE);

    Calendar calendar = Calendar.getInstance();

    calendar.setTimeInMillis(System.currentTimeMillis());

    calendar.add(Calendar.SECOND, 1);

    alarmManager1.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 10, pendingIntent);



  }

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


  @Override
  public void onTaskRemoved(Intent rootIntent) {
    super.onTaskRemoved(rootIntent);
    Toast.makeText(getApplicationContext(),"onTaskRemoved",Toast.LENGTH_LONG).show();
    Log.d("onTaskRemoved", "onTaskRemoved");
    Intent myIntent = new Intent(getApplicationContext(), MyService.class);

    PendingIntent pendingIntent = PendingIntent.getService(getApplicationContext(), 0, myIntent, 0);

    AlarmManager alarmManager1 = (AlarmManager) getSystemService(ALARM_SERVICE);

    Calendar calendar = Calendar.getInstance();

    calendar.setTimeInMillis(System.currentTimeMillis());

    calendar.add(Calendar.SECOND, 1);

    alarmManager1.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 10, pendingIntent) ;

  }


  public class MyLocationListener implements LocationListener {

    public void onLocationChanged(final Location loc) {
      if (isBetterLocation(loc, previousBestLocation)) {
        latitude = loc.getLatitude();
        longitude = loc.getLongitude();
        intent.putExtra("Latitude", loc.getLatitude());
        intent.putExtra("Longitude", loc.getLongitude());
        intent.putExtra("Provider", loc.getProvider());
        sendBroadcast(intent);


        SharedPreferences check = getApplicationContext().getSharedPreferences("Access_token", Context.MODE_PRIVATE);
        final String access_token = check.getString("access_token", "N/A");

        StringRequest stringRequest = new StringRequest(Request.Method.POST, POST_URL,
            new Response.Listener<String>() {
              @Override
              public void onResponse(String response) {

                Toast.makeText(getApplicationContext(),""+response,Toast.LENGTH_LONG).show();
              }
            },
            new Response.ErrorListener() {
              @Override
              public void onErrorResponse(VolleyError error) {

                Toast.makeText(getApplicationContext(),""+error,Toast.LENGTH_LONG).show();

              }
            }) {
          @Override
          protected Map<String, String> getParams() {
            Map<String, String> params = new HashMap<String, String>();
            params.put("access_token", access_token);
            params.put("latitude", String.valueOf(latitude));
            params.put("longitude", String.valueOf(longitude));
            return params;
          }

        };
        stringRequest.setRetryPolicy(new DefaultRetryPolicy(1 * 500000,
            DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
            DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
        RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
        requestQueue.add(stringRequest);
      }


    }

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

    }

    @Override
    public void onProviderEnabled(String provider) {

    }

    @Override
    public void onProviderDisabled(String provider) {

    }
  }

}