1

主要活动有一个 AlarmManager,它每 X 分钟调用一次服务。我需要一种方法,服务类中的方法可以更新主活动中的 TextView,但我不知道如何在服务中获取 TextView 的对象。有什么办法吗?

以下是部分代码:

Intent myIntent = new Intent(MainActivity.this, MyAlarmService.class);
pintent = PendingIntent.getService(MainActivity.this, 0, myIntent, 0);

AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 60000, pintent);
4

2 回答 2

0

我有同样的需求,在一个加速度计读取服务和一个可以启动/停止服务并显示当前平均加速度计幅度的应用程序中。

我使用服务绑定允许服务向活动发送消息,其中包含加速度计值。

有关绑定的背景信息,请参阅http://developer.android.com/guide/components/bound-services.html#Messenger。有关一个很好的示例,请参阅 API 示例的 MessengerServiceActivities 和 MessengerService 类。

我做了以下。为了清楚起见,我省略了平凡的细节(例如同步以避免比赛)。请注意,我使用了 bind() 和 StartService()。bind() 用于在 Activity 和 Service 之间发送消息;StartService() 是这样服务在活动退出后继续运行。

基本上,Activity 和 Service 交换 Messenger,允许彼此向对方发送消息。Activity 向服务发送自定义消息,以便订阅服务消息或取消订阅服务消息。当 Service 要向 Activity 发送数据时,它会向 Activity 的 Messenger 发送自定义消息。Activity 收到这样的消息后,会向用户显示新值。

建议使用通知的答案使用一种简单的方法将数据显示到屏幕上。如果您想在 Activity 中显示数据(相对于通知栏),则需要这种更复杂的消息传递答案。

对于以下示例代码的长度,我深表歉意,但有很多必要的细节需要传达。

在我的 Activity 中,名为 AccelServiceControl:

private FromServiceHandler handler;  // My custom class for Handling Messages from my Service.
private Messenger fromService;  // For receiving messages from our Service
...
public void onCreate(Bundle savedInstanceState) {
    ...
    handler = new FromServiceHandler(this);
    fromService = new Messenger(handler);
    ...
}
protected void onResume() {
    ...
    // While we're in the foreground, we want to be bound to our service.
    // onServiceConnected() will return the IBinder we'll use to communicate back and forth.
    bindService(new Intent(this, AccelService.class), this, Context.BIND_AUTO_CREATE);
}
protected void onPause() {
    ...
    // Note: By itself, this doesn't stop the Service from sending messages to us.
    // We need to send a custom Unsubscribe Message to stop getting messages from the Service.
    unbindService(this);

}
public void onClick(View v) {
    // Send a custom intent to start or stop our Service.
    if (buttonStart == v) {
        startService(new Intent(AccelService.ACTION_START));
    } else if (buttonStop == v) {
        startService(new Intent(AccelService.ACTION_STOP));
    }
    ...
}
public void onServiceConnected(ComponentName name, IBinder service) {
    ...
    // Ask our Service to send us updates.
    toService = new Messenger(service);
    Message msg = Message.obtain(null, FromClientHandler.MSG_SUBSCRIBE);    // our custom Subscribe message
    msg.replyTo = fromService;
    try {
        toService.send(msg);
    } catch (RemoteException e) {
        // Failed because the Service has died.
        // We handle this in onServiceDisconnected().
    }
}

在 Activity 的自定义消息处理程序中:

....
public void handleMessage(Message msg) {
    switch (msg.what) {
    case MSG_ACCEL_UPDATE:
        ...
        Bundle bundle = msg.getData();
        double accelValue = bundle.getDouble(ACCEL_UPDATE_VALUE);
        ...then display the new accelValue in, for example, a TextView.
    ...
    }
}

在名为 AccelService 的服务中:

...
private Messenger fromClient;   // For receiving messages from our Client(s).
private FromClientHandler handler;      // needed just for unlinking at in onDestroy().
// Since we have only one Client, we store only one Activity's Messenger
private Messenger subscribedMessenger;
public void onCreate() {
    ...
    handler = new FromClientHandler(this);
    fromClient = new Messenger(handler);
}
public void onDestroy() {
    // Unlink ourselves from our Handler, so the Garbage Collector can get rid of us.  That's a topic in itself.
    handler.unlink();
    ....
}
public int onStartCommand(Intent intent, int flags, int startId) {
    ...
    int returnValue = START_NOT_STICKY;
    String action = intent.getAction();
    if (ACTION_START.equals(action)) {
        doActionStart();
        returnValue = START_STICKY;
    } else if (ACTION_STOP.equals(action)) {
        ...
        // Our Service is done
        stopSelf();
    }
    ... 
    return returnValue;
}
public IBinder onBind(Intent intent) {
    // Hand back a way to send messages to us.
    return fromClient.getBinder();
}
...when we want to send data to the Activity:
    Message msg = Message.obtain(null, FromServiceHandler.MSG_ACCEL_UPDATE);
    Bundle bundle = new Bundle();
    bundle.putDouble(FromServiceHandler.ACCEL_UPDATE_VALUE,  avgAccel);
    msg.setData(bundle);
    try {
        subscribedMessenger.send(msg);
    } catch (RemoteException e) {
        // Failed because the Client has unbound.
        subscribedMessenger = null;
    }
于 2013-02-23T18:15:16.060 回答
0

在您的警报服务中,您有一个 onReceive 方法

   public void onReceive(Context context, Intent arg1) {

        String data = "haha";
        if (data.isEmpty() == false && data.contentEquals("") == false) {

            nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
            CharSequence from = "sing";
            CharSequence message = data;
                   //get the activity
            PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
                    new Intent(), 0);
            Notification notif = new Notification(R.drawable.icon,
                    data, System.currentTimeMillis());
            notif.defaults |= Notification.DEFAULT_SOUND;
            notif.setLatestEventInfo(context, from, message, contentIntent);
            nm.notify(1, notif);

        }

方法调用:

AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        Intent intent = new Intent(this, ReminderReceiverActivity.class);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0,
                intent, PendingIntent.FLAG_CANCEL_CURRENT);

        am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(),
                100000, pendingIntent);
    }
于 2013-02-23T16:54:56.483 回答