Apologies for long post:
I am implementing an android SDK that needs to emit data wirelessly without pairing in a background job to nearby "hubs" (which I control). I am using Wi-Fi Direct P2P service discovery and storing my data as an entry in a DNS record that the hub picks up and processes. The value I need to emit it stored in a shared preferences instance, because it is altered by two services that run on a schedule.
Currently, I have the process that advertises the local service in an IntentService
. It gets the value it’s supposed to advertise from its intent:
protected void onHandleIntent(Intent intent) {
val = intent.getStringExtra(AppConstants.EXTRA_VALUE);
mManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
mChannel = mManager.initialize(this, getMainLooper(), null);
mRecord = new HashMap<String, String>();
mRecord.put(AppConstants.RECORD_KEY, val);
mService = WifiP2pDnsSdServiceInfo.newInstance(
AppConstants.SERVICE_INSTANCE, AppConstants.SERVICE_REG_TYPE, mRecord);
mManager.addLocalService(mChannel, mService, addServiceListener);
mManager.setDnsSdResponseListeners(mChannel, dnsSdServiceResponseListener,
dnsSdTxtRecordListener);
mManager.addServiceRequest(mChannel, mRequest, addServiceRequestListener);
mManager.discoverServices(mChannel, serviceDiscoveryListener);
}
And this service is added to the framework (I know this works because I can receive the record on my hub).
The problem comes when the value changes. I cannot simply start another instance of this service because the original channel is still open on the first, and thus two records will be found by my hub (each device should be advertising one instance of my service with one record). I can no longer clear mChannel
because the first IntentService
has already exited/died. Channels persist after the service exists (p2p framework still sees advertisement).
A few things I tried/considered:
- Add a
BroadcastReceiver
to eachIntentService
instance that will receive notification when the value is updated, to either kill itself appropriately (callmChannel.clearLocalServices()
) and start a new service, or just update the value in the original instance by clearing and readvertising service on same channel- Doesn't work because service dies after
discoverServices()
, receiver is not called
- Doesn't work because service dies after
- Foreground service - needs to run in the background, independent of a UI, and is unbeknownst to the user. Don't want to hang up the main thread.
In short, I need an efficient way to prolong the life of the service in the background indefinitely and still be able to respond to broadcasts (so not sure if Thread.sleep
would work), store the mChannel
somewhere that can be picked up the next time the value changes, or use a different design (other than services) completely.