从服务中获取Activity的小部件

时间:2013-02-23 16:47:23

标签: java android service android-activity

主活动有一个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);

2 个答案:

答案 0 :(得分: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);
    }

答案 1 :(得分:0)

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

我使用Service Binding来允许Service向Activity发送一条消息,其中包含加速度计值。

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

我做了以下事情。为清晰起见,我遗漏了世俗的细节(例如同步以避免比赛)。请注意,我使用bind()以及StartService()。 bind()用于在Activity和Service之间发送消息; StartService()是在Activity退出后服务继续运行的。

基本上,活动和服务交换允许每个人向另一个发送消息的信使。活动将自定义消息发送到服务,以便订阅服务消息或取消订阅服务消息。当服务想要将数据发送到活动时,它会向活动的Messenger发送自定义消息。收到此类消息后,活动会向用户显示新值。

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

我为下面的示例代码的长度道歉,但有很多必要的细节要传达。

在我的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;
    }