如何让app在后台运行以及时发送通知?

时间:2016-04-12 13:03:15

标签: java android

我正在开发一个应用程序,当用户移动超过300米时发送通知,或者如果2小时后没有移动则发送通知。

然而,问题在于,当我将时间更改为2分钟时,它似乎正在工作,但当我将时间更改为2小时时,它不会向我发送通知。可能是应用程序进入睡眠模式?我不知道,甚至在距离变化时也不会发送通知。

这是我的通知发送代码,TrackMe.Java

package miniandroid.com.services;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Handler;
import android.os.IBinder;

import miniandroid.com.activities.MainActivity;


public class TrackMeService extends Service {

    public int onStartCommand(Intent intent, int flags, int startId) {
        Handler handler = new Handler();
        handler.postDelayed(new Runnable(){
            public void run(){

        SharedPreferences prefs = getSharedPreferences("emood_veriif", MODE_PRIVATE);       
          String mapfirst = prefs.getString("MapFirst", "");
          String mapsecond = prefs.getString("MapSecond", "");
          if (mapfirst != mapsecond){
              NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
                Notification mnotify = new Notification();
                Context context = getApplicationContext();
                Intent intent = new Intent(context,MainActivity.class);
                PendingIntent pending = PendingIntent.getActivity(context, 0, intent, 0);
                Notification.Builder builder = new Notification.Builder(context);
                builder.setDefaults(Notification.DEFAULT_SOUND);
                builder.setAutoCancel(false);
                builder.setTicker("This is important. You have unanswered questions in Smood App.");
                builder.setContentTitle("sMood");
                builder.setContentText("Please describe your mood at this location.");
                builder.setSmallIcon(android.R.drawable.stat_notify_more);
                builder.setContentIntent(pending);
                builder.setOngoing(true);
                builder.setNumber(100);
                builder.build();
              mnotify= builder.getNotification();
              nm.notify(11,mnotify);
            SharedPreferences prefsy = getSharedPreferences("emood_veriif", MODE_PRIVATE);
            SharedPreferences.Editor editor = prefsy.edit();
            editor.putString("MapSecond", mapfirst);
            editor.commit();
          }
          else{

          }

            }
        }, 1);


    return super.onStartCommand(intent, flags, startId);

    }


    public void onDestroy() {

    super.onDestroy();
    }


    public IBinder onBind(Intent arg0) {

    return null;
    }


}

这是位置服务的代码,LocationService.Java

package miniandroid.com.services;

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;
import android.util.Log;
import android.widget.Toast;

import miniandroid.com.helpers.UserPreference;

public class LocationService extends Service {
    public static final String BROADCAST_ACTION = "Hello World";
    //private static final int TIME_DIFF = 1000 * 60 * 2; // 2 minutes
    private static final int TIME_DIFF = 1000 * 60 * 60 * 2;  //2 hours
    private static final int DISTANCE_DIFF = 300;
    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();
        float distanceDelta = location.distanceTo(currentBestLocation);


        boolean isSignificantlyNewer = timeDelta > TIME_DIFF;

        Log.d("MyLocationListener","onLocationChanged: Time Delta: "+ timeDelta+" Distance Delta: "+distanceDelta);

        // If it's been more than two minutes since the current location, use the new location
        // because the user has likely moved
        if (isSignificantlyNewer) {

            Log.d("MyLocationListener","onLocationChanged: Time Delta: is appropriate should show notification Time Delta: "+timeDelta);
            return true;
            // If the new location is more than two minutes older, it must be worse
        }


        if(distanceDelta > DISTANCE_DIFF)
        {
            Log.d("MyLocationListener","onLocationChanged: Distance Delta: is appropriate should show notification Distance Delta: "+distanceDelta);
            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) {
            if (isBetterLocation(loc, previousBestLocation)) {
                previousBestLocation = loc;
                startService(new Intent(LocationService.this,TrackMeService.class));
            }
        }

        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) {

        }

    }
}

另一个类location.java正在使用lat-lng确定位置,并将其地址编码为getAdress,但是,我只使用lat-lng。 我将它设置为每隔两分钟和10米变化后得到位置。那好吗?

// How many Geocoder should return our GPSTracker
    int geocoderMaxResults = 1;

    // The minimum distance to change updates in meters
    private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters

    // The minimum time between updates in milliseconds
    private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 2; // 2 minutes

非常感谢任何sorta帮助。 谢谢。

2 个答案:

答案 0 :(得分:0)

要让应用在未运行时仍然收到通知,请尝试添加 WAKE_LOCK 权限:

<uses-permission android:name="android.permission.WAKE_LOCK" />

答案 1 :(得分:0)

可能你应该使用Foreground服务。 http://developer.android.com/guide/components/services.html#Foreground

操作系统不会杀死前台服务。

另外请增加位置更新最短时间,否则应用程序将在2小时之前释放电池;)因为我看到你发送0作为minTime和minDistance发送到requestLocationUpdates locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, listener);