Skip to content

Instantly share code, notes, and snippets.

@tajchert
Last active December 19, 2022 12:30
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save tajchert/dc30560891bc6aee76fb to your computer and use it in GitHub Desktop.
Save tajchert/dc30560891bc6aee76fb to your computer and use it in GitHub Desktop.
Android Wear Realm Database Sync

This short code will show how to sync database file using Realm, but can be used for any file that you need to send to Wear (using Data API). It just takes any file, change it to Asset object and send it over to Wear device. Also it can be used Mobile->Wear, and Wear->Mobile.

When you need to sync database just call FileSender.syncRealm(context);, that is it!

DISCLAIMER "Proper" way would be to synchronize each transaction to DB, but it in most cases Wear is used very rarely comparing to mobile, so it would most likely cause a battery drain. My idea was to synchronize it only whene it is needed (so for example when app closes). If you want to make sure that you are using latest DB, just send trigger data using MessageAPI from Wear to Phone with ask of syncing over its database, or keep some timestapm of last edit and check it.

public class FileSender extends AsyncTask<Void, Void, Void> {
private Asset asset;
private Context context;
private GoogleApiClient mGoogleAppiClient;
private static final String TAG = "AssetsSender";
public FileSender(Asset asset, Context context) {
this.asset = asset;
this.context = context;
}
@Override
protected Void doInBackground(Void... params) {
sendData(asset);
return null;
}
@Override
protected void onPreExecute() {
mGoogleAppiClient = new GoogleApiClient.Builder(context)
.addApi(Wearable.API)
.build();
mGoogleAppiClient.connect();
}
private void sendData(Asset asset) {
if(asset == null){
return;
}
PutDataMapRequest dataMap = PutDataMapRequest.create("/ourAppDatabase");
byte[] arr = asset.getData();
dataMap.getDataMap().putByteArray("realmDatabase", arr);//for some reason .putAsset wasn't working for me in some cases
PutDataRequest request = dataMap.asPutDataRequest();
PendingResult<DataApi.DataItemResult> pendingResult = Wearable.DataApi.putDataItem(mGoogleAppiClient, request);
pendingResult.setResultCallback(new ResultCallback<DataApi.DataItemResult>() {
@Override
public void onResult(DataApi.DataItemResult dataItemResult) {
Log.d(TAG, "onResult result:" + dataItemResult.getStatus());
}
});
}
public static void syncRealm(Context context){
File writableFolder = context.getFilesDir();
File realmFile = new File(writableFolder, Realm.DEFAULT_REALM_NAME);
Asset realAsset = Tools.assetFromFile(realmFile);
new FileSender(realAsset, context).execute();
}
}
public class ListenerService extends WearableListenerService {
//Remember to decler it as well in Manifest.xml
private static final String TAG = ListenerService.class.getSimpleName();
@Override
public void onDataChanged(DataEventBuffer dataEvents) {
Log.d(TAG, "onDataChanged");
final List<DataEvent> events = FreezableUtils.freezeIterable(dataEvents);
dataEvents.close();
for (DataEvent event : events) {
Uri uri = event.getDataItem().getUri();
String path = uri.getPath();
if ("/ourAppDatabase".equals(path)) {
DataMapItem item = DataMapItem.fromDataItem(event.getDataItem());
byte[] realmAsset = item.getDataMap().getByteArray("realmDatabase");
if(realmAsset != null){
toFile(realmAsset);
//I recommend here calling a Broadcast - getBaseContext().sendBroadcast(new Intent(yourbroadcast here));
}
}
}
}
private void toFile(byte [] byteArray){
File writableFolder = ListenerService.this.getFilesDir();
File realmFile = new File(writableFolder, Realm.DEFAULT_REALM_NAME);
if (realmFile.exists()) {
realmFile.delete();
}
try {
FileOutputStream fos=new FileOutputStream(realmFile.getPath());
fos.write(byteArray);
fos.close();
}
catch (java.io.IOException e) {
Log.d(TAG, "toFile exception: " + e.getLocalizedMessage());
}
}
}
@agarwalamit662
Copy link

Hey ... I am getting error when I tried to query the new contents in the realm file. It returns null entry and app crashes. When I again reopen the app, realm return entries for same query. Where is the problem.?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment