我在我的应用中使用地理围栏并基于地理围栏事件(Enter或Exit)我想执行一些操作。 Geofence documentation表示,一旦设置地理围栏,它将自动触发事件,您可以使用IntentService捕获此事件。为此我做了如下的意图服务:
GeofenceTransitionsIntentService.java
K
现在,问题是当应用程序打开时(无论是前景还是背景)我输入或退出地理围栏它工作正常并向我显示一个toast消息和logcat显示日志但是当我从最近的应用程序中删除应用程序时没有向我显示的toast消息或logcat中没有显示日志。
我试图在谷歌上找到解决方案,但大多数答案建议使用该服务,但如果我没有错,那么IntentService在工作完成后自动停止,并在收到任何意图时自动启动。所以,我认为使用IntentService来完成这项任务会更有效。
更新 我正在使用以下代码行注册地理围栏。
public class GeofenceTransitionsIntentService extends IntentService {
Handler mHandler;
public GeofenceTransitionsIntentService() {
super("GeofenceTransitionsIntentService");
mHandler = new Handler();
}
@Override
public void onCreate() {
super.onCreate();
Log.e("JK-->>","service started!");
}
@Override
protected void onHandleIntent(Intent intent) {
Log.e("JK-->>","onHandel--->>");
GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent);
if (geofencingEvent.hasError()) {
Log.e("JK-->>","geofenceEvent has error!");
return;
}
int geofenceTransitionType = geofencingEvent.getGeofenceTransition();
if (geofenceTransitionType == Geofence.GEOFENCE_TRANSITION_ENTER) {
Log.e("JK-->>","enter!");
mHandler.post(new DisplayToast(this,"Enter"));
} else if (geofenceTransitionType == Geofence.GEOFENCE_TRANSITION_EXIT) {
mHandler.post(new DisplayToast(this,"Exit"));
Log.e("JK-->>","exit");
}
}
public class DisplayToast implements Runnable {
private final Context mContext;
String mText;
public DisplayToast(Context mContext, String text){
this.mContext = mContext;
mText = text;
}
public void run(){
Toast.makeText(mContext, mText, Toast.LENGTH_SHORT).show();
}
}
}
在getGeofencePendingIntent()中,我使用以下代码行启动意向服务。
geofencingClient.addGeofences(getGeofencingRequest(),getGeofencePendingIntent());
答案 0 :(得分:0)
此服务将始终运行:
转到项目java - >右键单击 - >新建> service->服务 将它命名为守望者
watchman.java
Sum of duration for distinct b.activityid
当您将其创建为服务时,它将在清单文件中自动注册,无需更新清单文件。
从主要活动或您想要开始的任何地方,请将其称为
public class watchman extends Service
{
NotificationManager mNotifyManager;
NotificationCompat.Builder mBuilder;
NotificationChannel notificationChannel;
String NOTIFICATION_CHANNEL_ID = "1";
public watchman() { }
@Override
public void onCreate()
{
try
{
mNotifyManager = (NotificationManager) getApplicationContext().getSystemService(NOTIFICATION_SERVICE);
mBuilder = new NotificationCompat.Builder(this, null);
mBuilder.setContentTitle("Insta Promo")
.setContentText("We are ready to help you.")
.setSmallIcon(R.drawable.ic_launcher_background);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "My Notifications", NotificationManager.IMPORTANCE_HIGH);
// Configure the notification channel.
notificationChannel.setDescription("Channel description");
notificationChannel.enableLights(true);
notificationChannel.setLightColor(Color.RED);
notificationChannel.setVibrationPattern(new long[]{0, 1000, 500, 1000});
notificationChannel.enableVibration(true);
notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
mNotifyManager.createNotificationChannel(notificationChannel);
}
else
{
mBuilder.setContentTitle("Insta Promo")
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setColor(ContextCompat.getColor(this, R.color.colorAccent))
.setVibrate(new long[]{100, 250})
.setLights(Color.YELLOW, 500, 5000)
.setAutoCancel(true);
}
mBuilder.setChannelId(NOTIFICATION_CHANNEL_ID);
mNotifyManager.notify(1, mBuilder.build());
startForeground(1, mBuilder.build());
}
catch(Exception e)
{
Log.d(TAG, "EXCEPTION IN SHOWING NOTIFICATION xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx...\n");
Log.e("MY_APP", "exception", e);
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
new Thread(new Runnable()
{
public void run()
{
while (true)
{
try
{
Log.d(TAG, "Thread : Running again...\n");
Thread.sleep(10000);
}
catch (InterruptedException e)
{
Log.d(TAG, "Thread : InterruptedException Error in service...\n");
}
}
}
}).start();
return START_STICKY;
}
@Override
public void onDestroy()
{
super.onDestroy();
}
@Override
public IBinder onBind(Intent intent)
{
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
}
现在你甚至将它从最近删除了...,它将在内存中始终为你运行,要检查它,请继续关注logcat。希望能帮助到你。它的项目从4.1开始到最新的8.0开始
用于显示通知我正在使用振动权限,因此也可以为您提供清单文件。
Log.d(TAG, " Good to Go \n");
Log.d(TAG, "Starting Service from main...\n");
Intent intent = new Intent(MainActivity.this, watchman.class);
startService(intent);
Log.d(TAG, "Main has started the service...\n");
希望它真的能帮助你或其他人。
答案 1 :(得分:0)
但请注意将服务作为前景会影响手机的电池续航时间。并且将服务作为前景也对用户来说是烦人的,因为它始终显示通知并且不能被关闭。
您可以更好地使用JobScheduler或Firebase JobDispatcher来安排后台工作。
答案 2 :(得分:0)
我找到了答案......我的代码没有问题,IntentService也运行良好,但错误在于测试。我在android Oreo运行设备上测试我的应用程序。
在android oreo google已经更新了他们的政策,在前台他们会多次发送位置更新,但在后台他们只会几小时发送位置更新 。 它背后的主要原因是拯救设备的赌博生活。
有关android oreo位置更新的更多信息,您可以查看this文档。