如何从服务获取数据到活动
Posted
技术标签:
【中文标题】如何从服务获取数据到活动【英文标题】:How to get data from service to activity 【发布时间】:2013-08-10 02:52:17 【问题描述】:在我的应用中,我有一个活动和一个服务...... 该服务将广播从 GPS 数据收集的消息... Activity 应该接收广播消息并更新 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);
当我使用此代码时,它无法正常工作... 我在单独的文件中使用 ServiceReceiver 类工作正常.... 请告诉我...!!
【问题讨论】:
【参考方案1】:在我的服务类中我写了这个
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);
而在 Activity 端,我们必须接收此广播消息
LocalBroadcastManager.getInstance(getActivity()).registerReceiver(
mMessageReceiver, new IntentFilter("GPSLocationUpdates"));
通过这种方式,您可以向 Activity 发送消息。 这里 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();
;
【讨论】:
永远不要忘记在 onPause 中取消注册接收者 @FaisalNaseer 如何注销你能提供一些示例代码吗 只需unregisterReceiver(mMessageReceiver );
在“onDestroy”方法上注销接收器:)
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);这是活动上下文还是服务上下文?【参考方案2】:
使用 Handler 是一个好方法。
在您的 Activity 中创建一个扩展 Handler 的 innerClass 并覆盖 handleMessage
方法。
然后,在您的 ServiceReceiver
类中,创建一个处理程序变量和一个构造函数,例如:
public ServiceReceiver(Handler handler)
this.handler = handler;
因此,在您的活动中,创建您的自定义处理程序并将其传递给您的服务。因此,当您想将一些数据放入您的活动时,您可以将handler.sendMessage()
放入您的服务中(它将调用您的内部类的handleMessage
)。
【讨论】:
【参考方案3】:如何从 IntentService 向 Activity 发送数据?
如果服务仅用于一种方式,则无需绑定服务 沟通。对于这种情况,使用 IntentService + BroadcastReceiver 很容易。
示例:
你有一个 BackgroundService 计算信号强度并将数据发送回活动每个 第二。 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);
从服务接收数据
为此,您的 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
注意:
如果您想使用LocalBroadcastReceiver
而不是广播接收器。你可以看看How to convert BroadCastReceiver to LocalBroadcastReceiver
相关链接
See Full projectWhat is an IntentService?Difference between Bound and Unbound Services
【讨论】:
如果用户最小化应用程序,它将取消注册接收器。所以最好在onStart()
注册。
取决于用例是否需要数据,即使您的应用程序在后台,然后在 onCreate() 中的 bindService() 和 onDestroy() 中的 unbindService() 中注册和取消注册 阅读更多 ***.com/questions/8614335/…在官方文档中阅读更多信息developer.android.com/guide/components/…【参考方案4】:
与services
交流的三种明显方式
使用 Intent。 使用 AIDL。 使用服务对象本身(作为单例)。
【讨论】:
【参考方案5】:class MainActivity : AppCompatActivity()
private val sb = object :SerToBroad()
override fun broadcastResult(connected: String?)
t(connected)
override fun onCreate(savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
fun t(connected: String?)
Toast.makeText(MainActivity@this, connected, Toast.LENGTH_SHORT).show()
override fun onStart()
super.onStart()
startService(Intent(MainActivity@ this, MService::class.java))
val inf = IntentFilter()
inf.addAction(MService.ACTION)
registerReceiver(sb, inf)
override fun onStop()
super.onStop()
unregisterReceiver(sb)
-------------------------------------
//Service class
class MService : Service()
companion object const val ACTION = "MY_ACTION"
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int
val intent = Intent()
intent.action = ACTION
intent.putExtra("DATA", "10")
sendBroadcast(intent)
return super.onStartCommand(intent, flags, startId)
--------------------------------------------------
broadcast
abstract class SerToBroad : BroadcastReceiver()
override fun onReceive(p0: Context?, p1: Intent?)
val rec = p1?.getStringExtra("DATA")
broadcastResult(rec)
abstract fun broadcastResult(connected: String?)
【讨论】:
以上是关于如何从服务获取数据到活动的主要内容,如果未能解决你的问题,请参考以下文章