1

我在intentservice完成后传回对象时遇到问题。 我的目标是在发送通知之后将currentCharacter对象发送回Mainactivity。我用onResult试了一下,但intentservice没有这个。我也尝试创建一个自己的resultceceiver,但是当我实现这个时,通知甚至没有通过。有没有人知道这个问题的解决方案或解决办法?IntentService不适用于resultreceiver

这是会从在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"); 

     } 
    }); 
} 

}

回答

1

通过您的代码去,你必须通过getParcelableExtra(检索ResultReceiver),但我没有看到你通过它发送一个广播使用rec.send(int,Bundle);

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

0

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

+0

你能告诉我这是如何工作完全是一个具体的例子吗? 我看了文档,但我无法弄清楚(BroadcastReceiver) –