- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我无法从服务类添加地理围栏。下面是我的代码:
地理围栏服务:
package com.example.admin.reminderapp.services;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.support.annotation.NonNull;
import android.util.Log;
import android.widget.Toast;
import com.example.admin.reminderapp.R;
import com.example.admin.reminderapp.database.model.Reminder;
import com.example.admin.reminderapp.geofencing.Constants;
import com.example.admin.reminderapp.geofencing.GeofenceErrorMessages;
import com.example.admin.reminderapp.geofencing.GeofenceTransitionsIntentService;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.location.Geofence;
import com.google.android.gms.location.GeofencingRequest;
import com.google.android.gms.location.LocationServices;
import java.util.ArrayList;
import java.util.List;
public class GeoFenceService extends Service implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
private Context mContext = this;
private IBinder mIBinder = new LocalBinder();
private GoogleApiClient mGoogleApiClient;
public GeoFenceService() {
Log.i(getClass().getName(), "GeoFenceService()");
}
@Override
public IBinder onBind(Intent intent) {
return mIBinder;
}
protected synchronized void buildGoogleApiClient() {
Log.i("GeoFenceService", "buildGoogleApiClient");
mGoogleApiClient = new GoogleApiClient.Builder(mContext)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();
}
@Override
public void onCreate() {
super.onCreate();
Log.i("GeoFenceService", "onCreate");
buildGoogleApiClient();
}
@Override
public void onConnected(Bundle connectionHint) {
Log.i("GeoFenceService", "Connected to GoogleApiClient");
}
@Override
public void onConnectionFailed(ConnectionResult result) {
Log.e("GeoFenceService", "Connection failed: ConnectionResult.getErrorCode() = " + result.getErrorCode());
}
@Override
public void onConnectionSuspended(int cause) {
Log.i("GeoFenceService", "Connection suspended");
}
private GeofencingRequest getGeofencingRequest(long reminderId) {
GeofencingRequest.Builder builder = new GeofencingRequest.Builder();
builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER);
builder.addGeofences(populateGeofenceList(reminderId));
return builder.build();
}
public List<Geofence> populateGeofenceList(long reminderId) {
List<Geofence> geofenceList = new ArrayList<>();
Reminder reminder = Reminder.load(Reminder.class, reminderId);
Log.i("ReminderService", reminder.getId()+" - "+reminder.toString());
Geofence geofence = new Geofence.Builder()
.setRequestId(String.valueOf(reminderId))
.setCircularRegion(
reminder.getLat(),
reminder.getLat(),
(float) reminder.getKm() * 1000
)
.setExpirationDuration(Geofence.NEVER_EXPIRE)
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER |
Geofence.GEOFENCE_TRANSITION_EXIT)
.build();
geofenceList.add(geofence);
return geofenceList;
}
private PendingIntent getGeofencePendingIntent(long reminderId) {
Intent intent = new Intent(this, GeofenceTransitionsIntentService.class);
Log.i("ReminderService", intent +"");
// intent.putExtra("ReminderId", reminderId);
return PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
public void addGeofence(long reminderId) {
if (!mGoogleApiClient.isConnected()) {
Toast.makeText(this, getString(R.string.not_connected), Toast.LENGTH_SHORT).show();
return;
}
try {
LocationServices.GeofencingApi.addGeofences(
mGoogleApiClient,
getGeofencingRequest(reminderId),
getGeofencePendingIntent(reminderId)
).setResultCallback(new ResultCallback<Status>() {
@Override
public void onResult(@NonNull Status status) {
if (status.isSuccess()) {
Toast.makeText(
mContext,
"Reminder Added.",
Toast.LENGTH_SHORT
).show();
} else {
String errorMessage = GeofenceErrorMessages.getErrorString(GeoFenceService.this, status.getStatusCode());
Log.e(GeoFenceService.this.getClass().getName(), errorMessage);
}
}
});
} catch (SecurityException securityException) {
Log.e(getClass().getName(), "Invalid location permission. You need to use ACCESS_FINE_LOCATION with geofences");
securityException.printStackTrace();
}
}
public void removeGeofence(long reminderId) {
if (!mGoogleApiClient.isConnected()) {
Toast.makeText(this, getString(R.string.not_connected), Toast.LENGTH_SHORT).show();
return;
}
try {
LocationServices.GeofencingApi.removeGeofences(
mGoogleApiClient,
getGeofencePendingIntent(reminderId)
).setResultCallback(new ResultCallback<Status>() {
@Override
public void onResult(@NonNull Status status) {
if (status.isSuccess()) {
Toast.makeText(
mContext,
"Reminder Removed.",
Toast.LENGTH_SHORT
).show();
} else {
String errorMessage = GeofenceErrorMessages.getErrorString(GeoFenceService.this,
status.getStatusCode());
Log.e(GeoFenceService.this.getClass().getName(), errorMessage);
}
}
});
} catch (SecurityException securityException) {
Log.e(getClass().getName(), "Invalid location permission. You need to use ACCESS_FINE_LOCATION with geofences");
securityException.printStackTrace();
}
}
@Override
public void onDestroy() {
super.onDestroy();
mGoogleApiClient.disconnect();
}
public class LocalBinder extends Binder {
public GeoFenceService getService() {
return GeoFenceService.this;
}
}
}
GeoFenceTransitionIntentService:
package com.example.admin.reminderapp.geofencing;
import android.app.IntentService;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.BitmapFactory;
import android.media.RingtoneManager;
import android.net.Uri;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.TaskStackBuilder;
import android.text.TextUtils;
import android.util.Log;
import com.example.admin.reminderapp.R;
import com.example.admin.reminderapp.activity.HomeActivity;
import com.google.android.gms.location.Geofence;
import com.google.android.gms.location.GeofencingEvent;
import java.util.ArrayList;
import java.util.List;
/**
* An {@link IntentService} subclass for handling asynchronous task requests in
* a service on a separate handler thread.
* <p/>
* TODO: Customize class - update intent actions, extra parameters and static
* helper methods.
*/
public class GeofenceTransitionsIntentService extends IntentService {
protected static final String TAG = "GeofenceTransitionsIS";
Boolean isMessageTone, isMessageVibrate;
String messageTone;
public GeofenceTransitionsIntentService() {
super(TAG);
Log.i(TAG, "GeofenceTransitionsIntentService");
}
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "onCreate");
}
// @Override
// protected void onHandleIntent(Intent intent) {
// GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent);
// if (geofencingEvent.hasError()) {
// String errorMessage = GeofenceErrorMessages.getErrorString(this,
// geofencingEvent.getErrorCode());
// Log.e(TAG, errorMessage);
// return;
// }
//
// // Get the transition type.
// int geofenceTransition = geofencingEvent.getGeofenceTransition();
//
// // Test that the reported transition was of interest.
// if (geofenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER ||
// geofenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT) {
//
// // Get the geofences that were triggered. A single event can trigger
// // multiple geofences.
// List triggeringGeofences = geofencingEvent.getTriggeringGeofences();
//
// // Get the transition details as a String.
// String geofenceTransitionDetails = getGeofenceTransitionDetails(
// this,
// geofenceTransition,
// triggeringGeofences
// );
//
// // Send notification and log the transition details.
// sendNotification(geofenceTransitionDetails);
// Log.i(TAG, geofenceTransitionDetails);
// } else {
// // Log the error.
// Log.e(TAG, getString(R.string.geofence_transition_invalid_type,
// geofenceTransition));
// }
// }
@Override
protected void onHandleIntent(Intent intent) {
Log.i(TAG, "Intent");
GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent);
if (geofencingEvent.hasError()) {
String errorMessage = GeofenceErrorMessages.getErrorString(this,
geofencingEvent.getErrorCode());
Log.e(TAG, errorMessage);
return;
}
int geofenceTransition = geofencingEvent.getGeofenceTransition();
if (geofenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER ||
geofenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT) {
List<Geofence> triggeringGeofences = geofencingEvent.getTriggeringGeofences();
String geofenceTransitionDetails = getGeofenceTransitionDetails(
this,
geofenceTransition,
triggeringGeofences
);
sendNotification(geofenceTransitionDetails);
Log.i(TAG, geofenceTransitionDetails);
} else {
// Log the error.
Log.e(TAG, getString(R.string.geofence_transition_invalid_type, geofenceTransition));
}
}
private String getGeofenceTransitionDetails(
Context context,
int geofenceTransition,
List<Geofence> triggeringGeofences) {
String geofenceTransitionString = getTransitionString(geofenceTransition);
ArrayList triggeringGeofencesIdsList = new ArrayList();
for (Geofence geofence : triggeringGeofences) {
triggeringGeofencesIdsList.add(geofence.getRequestId());
}
String triggeringGeofencesIdsString = TextUtils.join(", ", triggeringGeofencesIdsList);
return geofenceTransitionString + ": " + triggeringGeofencesIdsString;
}
private void sendNotification(String notificationDetails) {
int notifyColor = getResources().getColor(R.color.primary);
SharedPreferences prefs = getSharedPreferences("NotificationPrefs", MODE_PRIVATE);
isMessageTone = prefs.getBoolean("is_message_notification", false);
isMessageVibrate = prefs.getBoolean("is_message_vibrate", false);
messageTone = prefs.getString("message_notificationTone", "");
SharedPreferences preferences = getSharedPreferences("Theme", MODE_PRIVATE);
int storedPreference = preferences.getInt("storedInt", 0);
if (storedPreference == 0 || storedPreference == 1) {
notifyColor = getResources().getColor(R.color.primary);
} else if (storedPreference == 2) {
notifyColor = getResources().getColor(R.color.primary_theme2);
} else if (storedPreference == 3) {
notifyColor = getResources().getColor(R.color.primary_theme3);
} else if (storedPreference == 4) {
notifyColor = getResources().getColor(R.color.primary_theme4);
} else if (storedPreference == 5) {
notifyColor = getResources().getColor(R.color.primary_theme5);
}
Intent notificationIntent = new Intent(getApplicationContext(), HomeActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(HomeActivity.class);
stackBuilder.addNextIntent(notificationIntent);
PendingIntent notificationPendingIntent =
stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
// Define the notification settings.
builder.setSmallIcon(R.drawable.ic_directions_black)
.setLargeIcon(BitmapFactory.decodeResource(getResources(),
R.drawable.ic_directions_black))
.setColor(notifyColor)
.setContentTitle(notificationDetails)
.setContentText(getString(R.string.geofence_transition_notification_text))
.setContentIntent(notificationPendingIntent);
if (isMessageTone) {
if (messageTone.equals("")) {
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
builder.setSound(defaultSoundUri);
} else {
builder.setSound(Uri.parse(messageTone));
}
if (isMessageVibrate) {
builder.setVibrate(new long[]{0, 1000});
}
}
builder.setAutoCancel(true);
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(0, builder.build());
}
private String getTransitionString(int transitionType) {
switch (transitionType) {
case Geofence.GEOFENCE_TRANSITION_ENTER:
return getString(R.string.geofence_transition_entered);
case Geofence.GEOFENCE_TRANSITION_EXIT:
return getString(R.string.geofence_transition_exited);
default:
return getString(R.string.unknown_geofence_transition);
}
}
}
问题:
我可以得到“添加了地理围栏”的 toast 。但是当我选择当前位置进行围栏时,它不会触发任何通知。以前,当我从 Activity 中执行此操作时,如果我的设备位置在我添加的围栏中,它会触发通知。
请帮我找出问题。
谢谢。
最佳答案
我是这样做的:
我已经创建了 GeoFenceObserversationService
singleton 类。
GeoFenceObserversationService.java:
public class GeoFenceObserversationService extends Service implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, ResultCallback<Status> {
protected static final String TAG = "GeoFenceObserversationService";
protected GoogleApiClient mGoogleApiClient;
protected ArrayList<Geofence> mGeofenceList;
private boolean mGeofencesAdded;
private SharedPreferences mSharedPreferences;
private static GeoFenceObserversationService mInstant;
public static GeoFenceObserversationService getInstant(){
return mInstant;
}
@Override
public void onCreate() {
super.onCreate();
mInstant = this;
mGeofenceList = new ArrayList<Geofence>();
mSharedPreferences = getSharedPreferences(AppConstants.SHARED_PREFERENCES_NAME, MODE_PRIVATE);
mGeofencesAdded = mSharedPreferences.getBoolean(AppConstants.GEOFENCES_ADDED_KEY, false);
buildGoogleApiClient();
}
@Override
public void onDestroy() {
mGoogleApiClient.disconnect();
super.onDestroy();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
protected void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();
}
@Override
public void onConnected(Bundle connectionHint) {
}
@Override
public void onConnectionFailed(ConnectionResult result) {
}
@Override
public void onConnectionSuspended(int cause) {
}
private GeofencingRequest getGeofencingRequest() {
GeofencingRequest.Builder builder = new GeofencingRequest.Builder();
builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER);
builder.addGeofences(mGeofenceList);
return builder.build();
}
public void addGeofences() {
if (!mGoogleApiClient.isConnected()) {
Toast.makeText(this, getString(R.string.not_connected), Toast.LENGTH_SHORT).show();
return;
}
populateGeofenceList();
if(!mGeofenceList.isEmpty()){
try {
LocationServices.GeofencingApi.addGeofences(mGoogleApiClient, getGeofencingRequest(), getGeofencePendingIntent()).setResultCallback(this);
} catch (SecurityException securityException) {
securityException.printStackTrace();
}
}
}
public void removeGeofences() {
if (!mGoogleApiClient.isConnected()) {
Toast.makeText(this, getString(R.string.not_connected), Toast.LENGTH_SHORT).show();
return;
}
try {
LocationServices.GeofencingApi.removeGeofences(mGoogleApiClient,getGeofencePendingIntent()).setResultCallback(this);
} catch (SecurityException securityException) {
securityException.printStackTrace();
}
}
public void onResult(Status status) {
if (status.isSuccess()) {
mGeofencesAdded = !mGeofencesAdded;
SharedPreferences.Editor editor = mSharedPreferences.edit();
editor.putBoolean(AppConstants.GEOFENCES_ADDED_KEY, mGeofencesAdded);
editor.apply();
} else {
String errorMessage = AppConstants.getErrorString(this,status.getStatusCode());
Log.i("Geofence", errorMessage);
}
}
private PendingIntent getGeofencePendingIntent() {
Intent intent = new Intent(this, GeofenceTransitionsIntentService.class);
return PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
private void populateGeofenceList() {
mGeofenceList.clear();
List<GeoFencingResponce> geoFenceList = getGeofencesList;
if(geoFenceList!=null&&!geoFenceList.isEmpty()){
for (GeoFencingResponce obj : geoFenceList){
mGeofenceList.add(obj.getGeofence());
Log.i(TAG,"Registered Geofences : " + obj.Id+"-"+obj.Name+"-"+obj.Lattitude+"-"+obj.Longitude);
}
}
}
}
AppConstant:
public static final String SHARED_PREFERENCES_NAME = PACKAGE_NAME + ".SHARED_PREFERENCES_NAME";
public static final String GEOFENCES_ADDED_KEY = PACKAGE_NAME + ".GEOFENCES_ADDED_KEY";
public static final String DETECTED_GEOFENCES = "detected_geofences";
public static final String DETECTED_BEACONS = "detected_beacons";
public static String getErrorString(Context context, int errorCode) {
Resources mResources = context.getResources();
switch (errorCode) {
case GeofenceStatusCodes.GEOFENCE_NOT_AVAILABLE:
return mResources.getString(R.string.geofence_not_available);
case GeofenceStatusCodes.GEOFENCE_TOO_MANY_GEOFENCES:
return mResources.getString(R.string.geofence_too_many_geofences);
case GeofenceStatusCodes.GEOFENCE_TOO_MANY_PENDING_INTENTS:
return mResources.getString(R.string.geofence_too_many_pending_intents);
default:
return mResources.getString(R.string.unknown_geofence_error);
}
}
我从哪里开始服务?来自应用类
startService(new Intent(getApplicationContext(),GeoFenceObserversationService.class));
我如何注册地理围栏?
GeoFenceObserversationService.getInstant().addGeofences();
希望对您有所帮助。
关于机器人 : not able to add geofence from service,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35973536/
我正在使用 choronos,它建议使用 start/stop 命令开始停止,如下所示 开始计时 停止计时 但是,我正在编写 puppet manifest,它只适用于下面的服务命令。 服务计时开始
来历及作用 services.exe进程程序文件是由微软公司为其发布的Windows操作系统定义的一个系统进程,常见于Windows 2000/XP/Vista/2007等系统中,被描述为服务和控
我一直在尝试使用installutil:installutil /u GSIS.FileMoverService.exe安装Windows服务。 我得到的输出是: Uninstalling assem
如果一个域有多个团队和多个 Web 应用程序,那么注册 Service Worker 来管理整个站点的最佳建议是什么?具有范围的顶级服务 worker /或子域中的多个服务 worker ?由于一个域
我已经在 eclipse 中创建了企业项目。动态web项目和ejb项目对企业项目有借鉴意义。当我运行管理员(企业项目)运行时选择 wildfly 服务器 18。我收到以下错误。谁能告诉我我错过了什么。
我已经使用 apache-cxf-2.7.4 创建了一个 Web 服务。我进入了我的项目中制作的类(class)。我的项目中的库是: math3-commons-3.2.jar XStream-1.4
我在域中的 Virtual Box 中运行集群计算机,默认情况下服务在 Network 服务下运行,服务一直停止,事件日志中出现以下错误。 请从下面的错误日志中查找错误详细信息。任何帮助都会很棒。 L
在我的应用程序中,用户可以在 map 上发布事件。应用程序的入口点是一个无状态的 web api 服务。为了在内部代表用户,我想要一个用户服务。我应该何时使用 Reliable Stateful Ac
当我尝试运行在WIX中创建的安装程序时,出现以下错误消息: “服务'Report Generator Service'(报告生成器服务)无法启动。请验证您是否具有启动系统服务的足够特权”。 我已经在这
尝试使用 cloudformation 创建 ECS 服务(在 Fargate 上)但出现错误: Invalid service in ARN (Service: AmazonECS; Status
我正在编写一个简单的Windows服务,该服务每个月向所有员工发送一封电子邮件。我的问题是,完成后如何停止自我?我是该领域的新手,请帮帮我。非常感谢。 它将部署在服务器上以每月运行。我没有开始做这件事
有谁知道是否有办法在 service worker 中获取此号码或日期: 将我的服务 worker 缓存命名为 cache-1182 会很方便或 cache-20171127171448 我想在安装事
我想开始使用 Azure Service Fabric 技术。 我按照this document工作并安装最新的SDK。安装后,我打开 PowerShell(“以管理员身份运行”)命令行窗口并写入这些
我在使用 whenever gem 时遇到了一些问题。我创建了一个 rake 任务,当我自己启动它时它工作得很好但是当我在日志中收到以下消息时尝试自动执行它: ActiveRecord::Statem
我想在 service fabric 集群中为两个不同的 web 应用程序(webpi/website)共享 http/80 端口,应用程序必须有 2 个不同的主机名: mywebapi.com 和
我创建了一个使用 MongoDB 实现 hibernate OGM 的应用程序。它在 Eclipse 中运行得很好,但是,当我构建一个 fat jar 并尝试运行它时,出现以下错误: Exceptio
我有一个 Selenium Python 测试套件。它开始运行,但几分钟后抛出以下错误: Exception AttributeError: "'Service' object has no attr
我按照此链接的说明进行操作:https://www.thegeekdiary.com/centos-rhel-7-how-to-make-custom-script-to-run-automatica
我在 ubuntu 下的 jboss 上部署了简单的“HelloWorld”Web 服务。 我创建了简单的客户端,但我无法让它工作。每次运行客户端时,我都会收到 NullPointerExceptio
我正在尝试为我的网站使用后台定期同步。我正在使用 localhost 并在 1*1000 毫秒时注册 periodicsync 事件,但这根本不会触发。 我看过这个demo ,但即使我将该网站安装为应
我是一名优秀的程序员,十分优秀!