如何从服务获取数据到活动

bGo*_*rle 21 android

在我的应用程序中,我有一个活动和服务...该服务将广播从GPS数据收集的消息...活动应该接收广播消息并更新UI ...

我的代码

public class LocationPollerDemo extends Activity {
    private static final int PERIOD = 10000; // 30 minutes
    private PendingIntent pi = null;
    private AlarmManager mgr = null;
    private double lati;
    private double longi;
    private ServiceReceiver serviceReceiver;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mgr = (AlarmManager) getSystemService(ALARM_SERVICE);

        Intent i = new Intent(this, LocationPoller.class);

        i.putExtra(LocationPoller.EXTRA_INTENT, new Intent(this, ServiceReceiver.class));
        i.putExtra(LocationPoller.EXTRA_PROVIDER, LocationManager.GPS_PROVIDER);

        pi = PendingIntent.getBroadcast(this, 0, i, 0);
        mgr.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(), PERIOD, pi);

        DebugLog.logTrace("On Create Demo");
        Toast.makeText(this, "Location polling every 30 minutes begun", Toast.LENGTH_LONG).show();
        serviceReceiver = new ServiceReceiver();
        IntentFilter filter = new IntentFilter("me");
        this.registerReceiver(serviceReceiver, filter);
    }

    class ServiceReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            File log = new File(Environment.getExternalStorageDirectory(), "Location2.txt");
            DebugLog.logTrace(Environment.getExternalStorageDirectory().getAbsolutePath());

            try {
                BufferedWriter out = new BufferedWriter(new FileWriter(log.getAbsolutePath(), log.exists()));

                out.write(new Date().toString());
                out.write(" : ");

                Bundle b = intent.getExtras();
                Location loc = (Location) b.get(LocationPoller.EXTRA_LOCATION);
                String msg;

                if (loc == null) {
                    loc = (Location) b.get(LocationPoller.EXTRA_LASTKNOWN);

                    if (loc == null) {
                        msg = intent.getStringExtra(LocationPoller.EXTRA_ERROR);
                    } else {
                        msg = "TIMEOUT, lastKnown=" + loc.toString();
                    }
                } else {
                    msg = loc.toString();
                }

                if (msg == null) {
                    msg = "Invalid broadcast received!";
                }

                out.write(msg);
                out.write("\n");
                out.close();
            } catch (IOException e) {
                Log.e(getClass().getName(), "Exception appending to log file", e);
                DebugLog.logException(e);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

当我使用此代码时,它无法正常工作...我在单独的文件中使用ServiceReceiver类工作正常....请告诉我... !!

bGo*_*rle 43

在我的Service类中,我写了这个

private static void sendMessageToActivity(Location l, String msg) {
    Intent intent = new Intent("GPSLocationUpdates");
    // You can also include some extra data.
    intent.putExtra("Status", msg);
    Bundle b = new Bundle();
    b.putParcelable("Location", l);
    intent.putExtra("Location", b);
    LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
}
Run Code Online (Sandbox Code Playgroud)

在活动方面,我们必须收到此广播消息

LocalBroadcastManager.getInstance(getActivity()).registerReceiver(
            mMessageReceiver, new IntentFilter("GPSLocationUpdates"));
Run Code Online (Sandbox Code Playgroud)

通过这种方式,您可以向活动发送消息.这里的mMessageReceiver是那个类中你将要执行任何你想要的类....

在我的代码中我做了这个....

private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        // Get extra data included in the Intent
        String message = intent.getStringExtra("Status");
        Bundle b = intent.getBundleExtra("Location");
        lastKnownLoc = (Location) b.getParcelable("Location");
        if (lastKnownLoc != null) {
            tvLatitude.setText(String.valueOf(lastKnownLoc.getLatitude()));
            tvLongitude
                    .setText(String.valueOf(lastKnownLoc.getLongitude()));
            tvAccuracy.setText(String.valueOf(lastKnownLoc.getAccuracy()));
            tvTimestamp.setText((new Date(lastKnownLoc.getTime())
                    .toString()));
            tvProvider.setText(lastKnownLoc.getProvider());
        }
        tvStatus.setText(message);
        // Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
    }
};
Run Code Online (Sandbox Code Playgroud)

  • 并且永远不要忘记在onPause中取消注册接收者 (3认同)
  • LocalBroadcastManager.getInstance(上下文).sendBroadcast(意向); 这是活动上下文还是服务上下文? (2认同)

Roh*_*ngh 7

如何从 IntentService 向 Activity 发送数据?

如果服务用于单向通信,则不需要绑定服务。对于这种情况,使用 IntentService + BroadcastReceiver 非常容易。

例子:

您有一个 BackgroundService,它计算信号强度并每秒将数据发送回 Activity。Activity 在 GraphView 中显示数据。

怎么做?

在此处输入图片说明

从服务发送数据

public class TrackWifiService extends IntentService {

    public TrackWifiService() {
        super("wifiService");
    }

    protected void onHandleIntent(@Nullable Intent intent) {

        sendDataToActivity()
    }

   private void sendDataToActivity()
   {
        Intent sendLevel = new Intent();
        sendLevel.setAction("GET_SIGNAL_STRENGTH");
        sendLevel.putExtra( "LEVEL_DATA","Strength_Value");
        sendBroadcast(sendLevel);

   }


}
Run Code Online (Sandbox Code Playgroud)

从服务接收数据
为此,您Activity应该注册一个BroadcastReceiver

public class TrackWifiActivity extends AppCompatActivity {

   WifiLevelReceiver receiver;

   @Override
   public void onCreate(Bundle savedInstanceState)
   {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.track_wifi_activity_layout);
      receiver = new WifiLevelReceiver();
      registerReceiver(receiver, new IntentFilter("GET_SIGNAL_STRENGTH"));  //<----Register
   }


   @Override
   public void onStop()
   {
       super.onStop();
       unregisterReceiver(receiver);           //<-- Unregister to avoid memoryleak
   }

   class WifiLevelReceiver extends BroadcastReceiver {

       @Override
       public void onReceive(Context context, Intent intent) {

           if(intent.getAction().equals("GET_SIGNAL_STRENGTH"))
           {
              int level = intent.getIntExtra("LEVEL_DATA",0);

              // Show it in GraphView
           }
       }

   }

}
Run Code Online (Sandbox Code Playgroud)

笔记:

如果你想用LocalBroadcastReceiver一个 BroadcastReceiver 代替。您可以查看如何将 BroadCastReceiver 转换为 LocalBroadcastReceiver

相关链接

查看完整项目
什么是 IntentService?
绑定服务和非绑定服务的区别


Ren*_*ira 6

获得它的好方法是使用Handler.在您的活动中创建一个扩展Handler和Override handleMessage方法的innerClass .

然后,在您的ServiceReceiver类中,创建一个处理程序变量和一个构造函数,如:

public ServiceReceiver(Handler handler){
   this.handler = handler;
}
Run Code Online (Sandbox Code Playgroud)

因此,在您的活动中,创建自定义处理程序并将其传递给您的服务.因此,当您想要将某些数据添加到您的活动中时,您可以放入handler.sendMessage()您的服务(它将调用handleMessage您的innerClass).