Как получить данные из службы в действие
В моем приложении у меня есть активность и сервис...
Служба будет транслировать сообщения, собранные из данных GPS...
Активность должна принимать широковещательные сообщения и обновлять пользовательский интерфейс...
мой код
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();
}
};
Ответ 2
Хороший способ иметь использование Handler.
Создайте innerClass в своей деятельности, которая расширяет Handler и переопределяет метод handleMessage
.
Затем в вашем классе ServiceReceiver
создайте переменную обработчика и конструктор, например:
public ServiceReceiver(Handler handler){
this.handler = handler;
}
Итак, в своей деятельности создайте свой собственный обработчик и передайте его службе. Итак, когда вы хотите поместить некоторые данные в свою деятельность, вы можете поместить handler.sendMessage()
в свою службу (она вызовет handleMessage
вашего внутреннего класса).
Ответ 3
Есть три очевидных способа общения с services
- Использование Intents.
- Использование AIDL.
- Использование самого сервисного объекта (как синглтона).
Ответ 4
Как отправить данные в Activity из IntentService?
Вам не нужно связывать услугу, если она предназначена для односторонней связи. Для таких случаев использовать IntentService + BroadcastReceiver довольно просто.
Пример:
У вас есть BackgroundService, который вычисляет уровень сигнала и отправляет данные в Activity каждую секунду. А активность показывает данные в GraphView.
Как это сделать?
![enter image description here]()
Отправить данные из Сервиса
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
вместо BroadcastReceiver. Вы можете просто посмотреть, как конвертировать BroadCastReceiver в LocalBroadcastReceiver.
Соответствующие ссылки
Посмотреть полный проект
Что такое IntentService?
Разница между связанными и несвязанными сервисами