我每隔15分钟设置一次警报,但仍然会以随机时间发送数据,而不会在应用程序关闭时显示

时间:2016-10-05 14:05:04

标签: android

每当我开始我的主要活动时,时间就会到来。我希望它每15分钟发生一次。

用于启动服务

public class ConnectivityReceiver extends WakefulBroadcastReceiver
{

    @Override
    public void onReceive(Context context, Intent intent)
    {

        Log.d("hasNetwork","inside");
        final AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        final PendingIntent wakeupIntent = PendingIntent.getService(context, 0, new Intent(context, LocationUpdaterService.class), PendingIntent.FLAG_UPDATE_CURRENT);
        final boolean hasNetwork = !intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
        if (hasNetwork)
        {
之后我试图每隔15分钟设置一次警报

        }
        else
        {
            Log.d("hasNetwork","NO");
            alarmManager.cancel(wakeupIntent);
        }
    }

}

//这里我设置一分钟后重复的时间用于测试目的                alarmManager.setExact(AlarmManager.RTC_WAKEUP,60000,wakeupIntent);

public class LocationUpdaterService extends Service  implements

 GoogleApiClient.ConnectionCallbacks, 

GoogleApiClient.OnConnectionFailedListener,
        com.google.android.gms.location.LocationListener




{


    LocationRequest mLocationRequest;
    GoogleApiClient mGoogleApiClient;
    ProgressDialog progressDialog;
    String lat="",lng="";
    SharedPreferences sp;
    SharedPreferences.Editor editor;


    protected synchronized void buildGoogleApiClient()
    {
        Toast.makeText(this, "buildGoogleApiClient", Toast.LENGTH_SHORT).show();
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
    }
    @Override
    public void onLocationChanged(Location location)
    {
        Log.d("hasNetw1ork", "onlocation???");
        Geocoder geocoder;
        List<Address> addresses;
        geocoder = new Geocoder(this, Locale.getDefault());
        double latitude = location.getLatitude();
        double longitude = location.getLongitude();
        Log.e("latitude", "latitude--" + latitude+"longitude="+longitude);
        lat= String.valueOf(latitude);
        lng= String.valueOf(longitude);
        try
        {
            Log.e("latitude", "inside latitude--" + latitude);
            addresses = geocoder.getFromLocation(latitude, longitude, 1);

        }
        catch (IOException e)
        {
            e.printStackTrace();
        }


        Log.d("hasNetwork",location.getLatitude()+"  "+location.getLongitude());
            sendToServer();

    }

    @Override
    public void onConnected(@Nullable Bundle bundle)
    {
      //  Toast.makeText(this, "onConnected", Toast.LENGTH_SHORT).show();
        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;
        }
          Location mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);

          mLocationRequest = new LocationRequest();
          mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);

          LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,mLocationRequest,this);

    }

    @Override
    public void onConnectionSuspended(int i)
    {

    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {


    }

    private enum State
    {
        IDLE, WORKING;
    }


    private static State state;

    private PowerManager.WakeLock wakeLock;

    static
    {
        state = State.IDLE;
    }

    @Override
    public void onCreate()
    {
        super.onCreate();
        final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
        this.wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "LocationUpdaterService");
        Log.d("hasNetwork", "oncreate");
        buildGoogleApiClient();
        mGoogleApiClient.connect();

        sp= PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
        editor=sp.edit();
    }

    @Override
    public IBinder onBind(Intent arg0)
    {
        Log.d("hasNetwork", "onBind");

        return null;
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId)
    {
        if (state == State.IDLE)
        {
            state = State.WORKING;
            this.wakeLock.acquire();
            // register location updates, not gonna code it you know
            Log.d("hasNetwork", "onStartCommand");
        }

        return START_NOT_STICKY;
    }

    @Override
    public void onDestroy()
    {
        super.onDestroy();
        state = State.IDLE;
        if (this.wakeLock.isHeld())
        {
            Log.d("hasNetwork", "onDestroy");
            this.wakeLock.release();
        }
    }
    private void sendToServer()
    {
        // send to server in background thread. you might want to start AsyncTask here
        vollyRequest_Add_Latlong();

    }

    private void onSendingFinished()
    {
        // call this after sending finished to stop the service
        this.stopSelf(); 
   }

这是获取当前位置并发送到服务器的类

{{1}}

1 个答案:

答案 0 :(得分:0)

您遇到两个不同的问题:

首先,您正在使用setInexactRepeating()。顾名思义,文档明确说明,这些警报是不准确的。 Android会将多个警报捆绑在一起,以最大限度地减少设备唤醒。

如果由于某种原因您认为您的用例需要精确计时,您可以使用setExact()安排一次性警报并继续根据需要安排这些警报。

其次,Android 6.0引入了Doze mode,这有助于在设备不使用时进一步减少设备唤醒。我们的想法是,如果用户没有主动使用他们的设备,那么任何应用都不需要执行定期工作,例如提取新的新闻文章。相反,当用户下一次拿起他们的设备时,警报将触发,您的数据将会更新。

如果您的应用符合打盹文档中的白名单指南,则可以要求您的用户通过电池优化将您的应用列入白名单。