IntentService不适用于resultreceiver

时间:2017-02-10 11:02:28

标签: android intentservice android-geofence custom-receiver

在intentservice完成后,我无法将对象传回。 我的目标是在发送通知后将currentCharacter对象发送回Mainactivity。我用onResult尝试了它,但intentservice没有这个。我也试过创建一个自己的结果收发器但是当我实现它时,通知甚至都没有通过。有没有人知道这个问题的解决方案或解决方法?

当我进入特定区域时,这是从MainActivity调用的GeofenceTransitionIntentService。我有一个currentCharacter对象,我想发送回MainActivity,我也有一个currentCharacter,但这需要更新。

public class GeofenceTransitionIntentService extends IntentService {
protected static final String TAG = "MainActivity";
private boolean checkedIn = false;
private List<Store> stores;
private Store rightStore;
private Character currentCharacter;
private ResultReceiver rec;

/**
 * This constructor is required, and calls the super IntentService(String)
 * constructor with the name for a worker thread.
 */
public GeofenceTransitionIntentService() {
    // Use the TAG to name the worker thread.
    super(TAG);
}

@Override
public void onCreate() {
    super.onCreate();
    Log.d(TAG, "onCreate: geofencetransition");
}

/**
 * Handles incoming intents.
 *
 * @param intent sent by Location Services. This Intent is provided to Location
 *               Services (inside a PendingIntent) when addGeofences() is called.
 */
@Override
protected void onHandleIntent(Intent intent) {
    GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent);
    if (geofencingEvent.hasError()) {
        String errorMessage = "err";
        Log.e(TAG, errorMessage);
        return;
    }

    // Get the transition type.
    int geofenceTransition = geofencingEvent.getGeofenceTransition();

    if(!checkedIn) {
        // 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<Geofence> triggeringGeofences = geofencingEvent.getTriggeringGeofences();

            // Get the transition details as a String.
            String geofenceTransitionDetails = getGeofenceTransitionDetails(
                    geofenceTransition,
                    triggeringGeofences
            );

            stores = new Gson().fromJson(intent.getStringExtra("stores"),
                    new TypeToken<ArrayList<Store>>() {
                    }.getType());

            // Send notification and log the transition details.
            sendNotification(geofenceTransitionDetails);
            currentCharacter = new Gson().fromJson(intent.getStringExtra("char"),
                    Character.class);
            rec = intent.getParcelableExtra("receiverTag");
            String date = new SimpleDateFormat("dd/MM/yyyy", Locale.ENGLISH).format(Calendar.getInstance().getTime());
            Checkin checkin = new Checkin(rightStore, date, 10);
            currentCharacter.getCheckins().add(checkin);
            currentCharacter.setCurrentExp(currentCharacter.getCurrentExp() + checkin.getReceivedExp());
            putCharacter();

            Log.d(TAG, geofenceTransitionDetails);
        } else {
            // Log the error.
            Log.d(TAG, "error");
        }
    }
}

/**
 * Gets transition details and returns them as a formatted string.
 *
 * @param geofenceTransition  The ID of the geofence transition.
 * @param triggeringGeofences The geofence(s) triggered.
 * @return The transition details formatted as String.
 */
private String getGeofenceTransitionDetails(
        int geofenceTransition,
        List<Geofence> triggeringGeofences) {

    String geofenceTransitionString = getTransitionString(geofenceTransition);

    // Get the Ids of each geofence that was triggered.
    ArrayList<String> triggeringGeofencesIdsList = new ArrayList<>();
    for (Geofence geofence : triggeringGeofences) {
        triggeringGeofencesIdsList.add(geofence.getRequestId());
    }
    String triggeringGeofencesIdsString = TextUtils.join(", ", triggeringGeofencesIdsList);

    return geofenceTransitionString + triggeringGeofencesIdsString;
}

/**
 * Posts a notification in the notification bar when a transition is detected.
 * If the user clicks the notification, control goes to the MainActivity.
 */
private void sendNotification(String notificationDetails) {
    Intent notifyIntent;
    notifyIntent = new Intent(getApplicationContext(),  StoresDetail.class);
    for(Store store : stores){
        if(notificationDetails.contains(store.getName())){
            rightStore = store;
        }
    }

    notifyIntent.putExtra("store", rightStore);
    notifyIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

    PendingIntent pendingIntent = PendingIntent.getActivities(getApplicationContext(), 1234,
            new Intent[] { notifyIntent }, PendingIntent.FLAG_UPDATE_CURRENT);
    Notification notification = new Notification.Builder(this)
            .setSmallIcon(R.drawable.logo)
            .setContentTitle(notificationDetails)
            .setContentText("Gamification")
            .setAutoCancel(true)
            .setContentIntent(pendingIntent)
            .build();
    notification.defaults |= Notification.DEFAULT_SOUND;
    NotificationManager notificationManager =
            (NotificationManager) this.getSystemService(this.NOTIFICATION_SERVICE);
    notificationManager.notify(5678, notification);
}

/**
 * Maps geofence transition types to their human-readable equivalents.
 *
 * @param transitionType A transition type constant defined in Geofence
 * @return A String indicating the type of transition
 */
private String getTransitionString(int transitionType) {
    switch (transitionType) {
        case Geofence.GEOFENCE_TRANSITION_ENTER:
            checkedIn = true;
            return "Entered geofence: ";
        case Geofence.GEOFENCE_TRANSITION_EXIT:
            checkedIn = false;
            return "Exited geofence: ";
        default:
            return "default";
    }
}

private void putCharacter(){
    RequestQueue queue = Volley.newRequestQueue(getApplicationContext());
    Gson gson = new Gson();

    APIService caller = new APIService();
    caller.put(queue, "character/", gson.toJson(currentCharacter), new VolleyCallback() {
        @Override
        public void onSuccess(String result) {
            Log.d("GeofenceTransitionSer", "onSuccess of VolleyCallback, Method: putCharacter");
        }

        @Override
        public void onFailed(String result) {
            Log.d("GeofenceTransitionSer", "onFailed of VolleyCallback, Method: putCharacter");

        }
    });
}

}

2 个答案:

答案 0 :(得分:1)

通过您的代码,您确实通过getParcelableExtra()检索了 ResultReceiver ,但我没有看到您使用rec.send(int,Bundle);

在任何地方通过它发送广播

MainActivity永远不会收到通知。 这就是为什么通知可能不会像你所说的那样通过。

答案 1 :(得分:0)

首先,您必须了解Service和IntentService之间的区别。每次启动IntentService时,它都会通过使用工作线程依次处理每个Intent。这与服务的主要区别在于主要在主线程上运行。话虽这么说,你必须找到一种方法将工作请求的状态发送到活动组件。为此,您可以将包含currentCharacter的广播发送到应该存在于Activity中的BroadcastReceiver。请查看官方Android开发人员文档中的以下链接:https://developer.android.com/training/run-background-service/report-status.html