代码之家  ›  专栏  ›  技术社区  ›  rosu alin

地理围栏不再适用于工作强度服务

  •  0
  • rosu alin  · 技术社区  · 6 年前

    我对地理围栏有一种强烈的服务,我只需要开始。但它必须在后台运行,所以在Android8中,它有时会被列入白名单。 所以我很难使用工作意向服务: https://developer.android.com/reference/android/support/v4/app/JobIntentService 还查看了以下内容: Android 8.0: java.lang.IllegalStateException: Not allowed to start service Intent

    这是我的onhandleIntent(),在这里我将得到我的地理围栏调用:

      //HANDLING INTENTS
    protected void onHandleIntent(Intent intent) {
        GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent);
        if (geofencingEvent != null) {
            int transitionType = geofencingEvent.getGeofenceTransition();
            if (transitionType == Geofence.GEOFENCE_TRANSITION_EXIT) {
                Location triggering = geofencingEvent.getTriggeringLocation();
                if (triggering != null) {
                    Utils.appendLog("GEOFENCE onHandleIntent got an EXIT transition: " + triggering.getLatitude() + ", " + triggering.getLongitude() + " / accuracy: " + triggering.getAccuracy(), "D", "#updategeo " + Constants.GEOFENCE);
                } else
                    Utils.appendLog("GEOFENCE onHandleIntent got an EXIT transition null", "D", "#updategeo " + Constants.GEOFENCE);
                Utils.appendLog("removing geofence after exit", "I", Constants.TRACKER + "#updategeo");
                removeGeofencesAndStartTracking();
            }
        }
    }
    

    这是我的意向服务代码,添加地理围栏逻辑:

      //ADDING/REMOVING GEOFENCES
    public void addGeofence(final Context context, final Location location, float radius) {
        if (!isSettingGeofence) {
            isSettingGeofence = true;
            ArrayList geofences = new ArrayList<>();
            geofences.add(new Geofence.Builder()
                    .setRequestId(geofenceRequestID)
                    .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_EXIT)
                    .setCircularRegion(
                            location.getLatitude(), location.getLongitude(), radius)
                    .setExpirationDuration(Geofence.NEVER_EXPIRE)
                    .build());
    
            if (geofences.size() > 0) {
                if (mGeofencingClient == null)
                    mGeofencingClient = LocationServices.getGeofencingClient(this);
    
                if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                    Utils.appendLog("Geofence Transitions Service addGeofence checkSelfPermission ERROR", "E", Constants.GEOFENCE);
                    return;
                }
    
                Utils.appendLog("addGeofences is being called, wait for success or failure callbacks", "I", Constants.TRACKER + "#updategeo");
                mGeofencingClient.addGeofences(getGeofencingRequest(location, geofences), getGeofencePendingIntent(context)).addOnSuccessListener(new OnSuccessListener<Void>() {
                    @Override
                    public void onSuccess(Void aVoid) {
                        PSLocationService.getInstance(context).lastTimeDidExitRegion = null;
                        isSettingGeofence = false;
                        final RealmLocation realmLocation = new RealmLocation(location.getLatitude(), location.getLongitude(), location.getTime(), null, true);
                        Log.i("#geofenceRequestID", "addGeofence geofence realm location: " + realmLocation.getLocation());
                        final GeofenceRealmLocation geofenceRealmLocation = new GeofenceRealmLocation(geofenceRequestID, realmLocation);
                        Log.i("#geofenceRequestID", "addGeofence geofence geofence location: " + geofenceRealmLocation.getRealmLocation().getLocation());
                        realmLocation.setAccuracy(location.getAccuracy());
                        realmLocation.setSpeed(location.getSpeed());
                        Log.i("", "GLOBAL intances  before addGeofences:" + Realm.getGlobalInstanceCount(PSApplicationClass.Config));
                        Realm realm = Realm.getInstance(PSApplicationClass.Config);
                        realm.executeTransaction(new Realm.Transaction() {
                            @Override
                            public void execute(Realm realm) {
                                realm.copyToRealmOrUpdate(geofenceRealmLocation);
                            }
                        });
                        realm.close();
                        try {
                            final NotificationManager notifManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
                            notifManager.cancel(1010);
                        } catch (Exception e) {
                            Utils.appendLog("Error removing notification: " + e.getMessage(), "I", Constants.GEOFENCE);
                        }
    
                        Log.i("", "GEOFENCETEST addGeofences SUCCESSS");
                        Utils.appendLog("Geofence Transitions Service setGeofenceRequest Success adding geofences!" +
                                        location.getLatitude() +
                                        " , " + location.getLongitude() + " / accuracy: " + location.getAccuracy(),
                                "I",
                                "#updategeo " + Constants.GEOFENCE);
                    }
                }).addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                        Log.i("", "GEOFENCETEST addGeofences FAILURE: " + e.getMessage());
                        isSettingGeofence = false;
                        try {
                            LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
                            boolean networkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
                            if (!networkEnabled) {
                                new Handler(Looper.getMainLooper()).post(new Runnable() {
                                    @Override
                                    public void run() {
                                        MyFirebaseMessagingService.generateNotificationStandard(context, null, context.getString(R.string.Error) + ": " + context.getString(R.string.geofence_error), null, null, false, false, MyFirebaseMessagingService.NETWORK_ERROR_NOTIFICATION);
                                    }
                                });
                            }
                        } catch (Exception ex) {
                            Log.e("", "");
                            // catch Exception
                        }
                        Utils.appendLog("Geofence Transitions Service setGeofenceRequest FAILURE adding geofences!" +
                                        e.getMessage(),
                                "E",
                                "#updategeo " + Constants.GEOFENCE);
                    }
                });
            } else {
                Utils.appendLog("Geofence Transitions Service geofences size Error: " + geofences.size(), "E", Constants.GEOFENCE);
            }
        } else
            Utils.appendLog("Geofence Transitions Service setGeofenceRequest is already setting a geofence", "I", Constants.GEOFENCE);
    }
    

    现在我换了一个工作岗位。

    我这样运行服务:

       Intent bindIntent = new Intent(context, PSGeofenceTransitionsIntentService.class);
            enqueueWork(context, bindIntent);
    
      public static final int JOB_ID = 1;
    
    public static void enqueueWork(Context context, Intent work) {
        enqueueWork(context, PSGeofenceTransitionsIntentService.class, JOB_ID, work);
    }
    

    我还将此添加到我的Android清单中:

      <service android:name=".core.tracking.PSGeofenceTransitionsIntentService"
            android:permission="android.permission.BIND_JOB_SERVICE"/>
    

    我在新的工作中处理OnHandleIntent的内容

      @Override
    protected void onHandleWork(@NonNull Intent intent) {
        GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent);
        if (geofencingEvent != null) {
            int transitionType = geofencingEvent.getGeofenceTransition();
            if (transitionType == Geofence.GEOFENCE_TRANSITION_EXIT) {
                Location triggering = geofencingEvent.getTriggeringLocation();
                if (triggering != null) {
                    Utils.appendLog("GEOFENCE onHandleIntent got an EXIT transition: " + triggering.getLatitude() + ", " + triggering.getLongitude() + " / accuracy: " + triggering.getAccuracy(), "D", "#updategeo " + Constants.GEOFENCE);
                } else
                    Utils.appendLog("GEOFENCE onHandleIntent got an EXIT transition null", "D", "#updategeo " + Constants.GEOFENCE);
                Utils.appendLog("removing geofence after exit", "I", Constants.TRACKER + "#updategeo");
                removeGeofencesAndStartTracking();
            }
        }
    }
    

    现在,我从geofraince中获得了有关手工工作的事件,但仅使用transition type=-1。所以我不会得到进入或退出事件。为什么,或者我如何修复这个地理围栏服务?

    2 回复  |  直到 6 年前
        1
  •  1
  •   ArtÅ«ras Stifanovičius    6 年前

    有同样的问题。因为安卓8的后台工作比较有限。有一种新的呼叫方式 PendingIntent 。你不需要把它改成 JobIntentService . 查看最新的Android指南,了解如何实现地理围栏侦听器:

    https://developer.android.com/training/location/geofencing

    简而言之,你只需要使用 GeofencingClient 用于呼叫 处理意图 .

    private PendingIntent getGeofencePendingIntent() {
        // Reuse the PendingIntent if we already have it.
        if (mGeofencePendingIntent != null) {
            return mGeofencePendingIntent;
        }
        Intent intent = new Intent(this, GeofenceTransitionsIntentService.class);
        // We use FLAG_UPDATE_CURRENT so that we get the same pending intent back when
        // calling addGeofences() and removeGeofences().
        mGeofencePendingIntent = PendingIntent.getService(this, 0, intent, PendingIntent.
                FLAG_UPDATE_CURRENT);
        return mGeofencePendingIntent;
    }
    

    请使用上面提供的链接作为完整示例。

        2
  •  0
  •   mechdon    6 年前

    首先,您需要设置一个广播接收器,在您的onReceive方法中,您需要排队为您的工作意向服务工作。所以,你不是直接启动你的意图服务,而是在你的悬而未决的内容中调用广播接收器。

    推荐文章