ektorp couchDB to android replication - android

I am trying to synchronize my CouchDB with my android in a way that it works as good offline as online and as far as I understand the .continues(true/false) is the way to go for this. But is there some way to actually change it on runtime some way? I am thinking of having a BroadcastReciever listening to if there is any CONNECTIVITY_SERVICE and set the value of .continues() accordingly but I can't get it to work... any suggestions?
protected void startEktorp() {
httpClient = new TouchDBHttpClient(server);
dbInstance = new StdCouchDbInstance(httpClient);
HamsterSyncEktorpAsyncTask startupTask = new HamsterSyncEktorpAsyncTask() {
#Override
protected void doInBackground() {
// create a local database
dbConnector = dbInstance.createConnector(DATABASE_NAME, true);
}
#Override
protected void onSuccess() {
// Create the query and get the results
queryDB();
// Start doing the replications!
startReplications();
}
};
startupTask.execute();
}
public synchronized void queryDB() {
ViewQuery viewQuery = new ViewQuery()
.designDocId("_design/" + dDocName).viewName(viewName)
.reduce(false).includeDocs(true);
ViewResult viewResult = dbConnector.queryView(viewQuery);
Log.v("SUCCESS", viewResult.getRows().toString());
notifyHandlers(viewResult);
}
/**
* Replicates the database from server to the phone and vice versa.
*/
public void startReplications() {
// pull this database to the test replication server
pullCommand = new ReplicationCommand.Builder().source(DATABASE_PATH)
.target(DATABASE_NAME).continuous(true).build();
pushCommand = new ReplicationCommand.Builder().source(DATABASE_NAME)
.target(DATABASE_PATH).continuous(true).build();
HamsterSyncEktorpAsyncTask pushReplicaton = new HamsterSyncEktorpAsyncTask() {
#Override
protected void doInBackground() {
dbInstance.replicate(pullCommand);
ReplicationStatus status = dbInstance.replicate(pushCommand);
Log.e(TAG, status.getSessionId().toString());
}
};
pushReplicaton.execute();
}
I am also wondering if there are any way to know if and when the replication actually sent/got something new and update my listview in the app showing all the documents in my database (the queryDB() function)?

Related

Mutliplayer sync on Mirror and unity

I'm trying to make an app where I send the input from my android device to the server i.e. my pc where Arduino is connected. So the Pc(server) sends the input to the Arduino. But using Mirror, i am having slight difficulties regarding the syncing of data. I'm able to connect both the server and the client but I'm not able to send the data from client to server or from server to client.
I have tried the YouTube tutorials and the [Command] too but I think I'm missing something.
I just want to send command from the client to server so it sends to Arduino. If anyone can help, it will be a great deal.
The code for script is as
using System.Collections.Generic;
using UnityEngine;
using Mirror;
using TMPro;
public class syncData : NetworkBehaviour
{
public GameObject DFA;
public TMP_Text data1;
public TMP_Text data2;
public TMP_Text data3;
[SyncVar]
string receivedString;
public delegate void StringChangedDelegate(string receivedString);
/*[SyncEvent]*/
public event StringChangedDelegate EventStringChanged;
private void SetString(string receivedString)
{
receivedString = DFA.GetComponent<Comunicacion>().receivedstring;
}
public override void OnStartServer()
{
SetString(receivedString);
}
// Start is called before the first frame update
void Start()
{
// DFA = GameObject.FindWithTag("dfa"); // tag, not name
}
/* [Command]
private void changeString() => SetString(receivedString);
*/
// Update is called once per frame
// [ClientCallBack]
void Update()
{
// Debug.Log("Client is sending information.");
// receivedString = DFA.GetComponent<Comunicacion>().receivedstring;
refresh(receivedString);
}
[Server]
void FunctionServer()
{
Debug.Log("Running the program in Server mode.");
}
[ClientRpc]
void refresh(string receivedString)
{
// receivedString = DFA.GetComponent<Comunicacion>().receivedstring;
if (Input.GetKeyDown(KeyCode.RightArrow) || Input.GetKeyDown(KeyCode.B))
{
Debug.Log(" Right Arrow Button was pressed on Vuzix");
}
else if (Input.GetKeyDown(KeyCode.LeftArrow) || Input.GetKeyDown(KeyCode.X))
{
Debug.Log(" Left Arrow Button was pressed on Vuzix");
}
refresher();
// string[] datos = receivedString.Split(':'); //My arduino script returns a 3 part value (IE: 12,30,18)
//// data1.SetText(datos[0]);// Try to forcefully re-enter values from DFA
// data2.SetText(datos[1]);
// data3.SetText(datos[2]);
}
[Command]
void refresher()
{
// receivedString = DFA.GetComponent<Comunicacion>().receivedstring;
refresh(receivedString);
Debug.Log("A command has been sent");
// gm.Update()
}
}

How to update all live data the same time?

I want to update my live data(s) in my ViewModel when the app detects the user's filters changed on a drawer layout close listener. I have created an update all live data method in my ViewModel, but it doesn't seem to work.
Here's my ViewModel:
public class ReleasesViewModel extends ViewModel {
private HashMap<String, MutableLiveData<List<_Release>>> upcomingReleasesListMap = new HashMap<>();
private ReleasesRepository releasesRepository;
private ArrayList<Integer> platforms;
private ArrayList<Integer> platformsCopy;
private String region;
public ReleasesViewModel() {
upcomingReleasesListMap = new HashMap<>();
// Shared to all fragments : User settings region & platforms
region = SharedPrefManager.read(SharedPrefManager.KEY_PREF_REGION, "North America");
Set<String> defaultPlatformsSet = new HashSet<>();
platforms = SharedPrefManager.read(SharedPrefManager.PLATFORM_IDS);
if (platformsCopy == null) {
// Set only once [past copy of platforms]
platformsCopy = SharedPrefManager.read(SharedPrefManager.PLATFORM_IDS);
}
}
public MutableLiveData<List<_Release>> getUpcomingReleases(String filter) {
// ReleasesRepository takes a different monthly filter
if (upcomingReleasesListMap.get(filter) == null) {
// we don't have a mapping for this filter so create one in the map
MutableLiveData<List<_Release>> releases = new MutableLiveData<>();
upcomingReleasesListMap.put(filter, releases);
// also call this method to update the LiveData
loadReleases(filter);
} else if (upcomingReleasesListMap.containsKey(filter)) {
// Double check if it isn't null, just in case
if (upcomingReleasesListMap.get(filter) == null || isPlatformsUpdated()) {
// if null; try again to update the live data or if platforms filter changed
loadReleases(filter);
} // else just don't do anything, the list is already in the Map
}
return upcomingReleasesListMap.get(filter);
}
private void loadReleases(final String filter) {
releasesRepository = new ReleasesRepository(region, filter, platforms);
releasesRepository.addListener(new FirebaseDatabaseRepository.FirebaseDatabaseRepositoryCallback<_Release>() {
#Override
public void onSuccess(List<_Release> result) {
// sort by release date
if (platforms.size() > 1) {
// Will only sort for multiple platforms filter
Collections.sort(result);
}
// just use the previous created LiveData, this time with the data we got
MutableLiveData<List<_Release>> releases = upcomingReleasesListMap.get(filter);
releases.setValue(result);
}
#Override
public void onError(Exception e) {
// Log.e(TAG, e.getMessage());
MutableLiveData<List<_Release>> releases = upcomingReleasesListMap.get(filter);
releases.setValue(null);
}
});
}
// Detects when user added/removed platform to update lists based on platforms
private boolean isPlatformsUpdated() {
Collections.sort(platforms);
Collections.sort(platformsCopy);
if (platforms.equals(platformsCopy)) {
// nothing new added since past update
return false;
}
// something new added or removed, change
platformsCopy = SharedPrefManager.read(SharedPrefManager.PLATFORM_IDS);
return true;
}
public void updateAllReleasesList() {
// update all releases live data lists
for (String filter : upcomingReleasesListMap.keySet()) {
loadReleases(filter);
}
}
}
The updateAllReleasesList is the method I created to update all my livedata lists, but in calling this method it will call the loadReleases method again and inside this method, it will skip the entire listener addListener code for some reason.
In my fragments where I listen to the data changes I have this following simple observer:
mReleasesViewModel = ViewModelProviders.of(getActivity()).get(ReleasesViewModel.class);
mReleasesViewModel.getUpcomingReleases(filter).observe(this, new Observer<List<_Release>>() {
#Override
public void onChanged(#Nullable List<_Release> releases) {
// whenever the list is changed
if (releases != null) {
mUpcomingGamesAdapter.setData(releases);
mUpcomingGamesAdapter.notifyDataSetChanged();
Toast.makeText(getContext(), "Updated", Toast.LENGTH_SHORT).show();
}
mDatabaseLoading.setVisibility(View.GONE);
}
});
And when I call my update all method in my ViewModel on drawer close, the code inside the observer in my fragment gets called (the list returned is empty), but I want it to call getUpcomingReleases to update everything.. Any ideas on how to update all my current livedatas at the same time and reflect it on the UI?

android Twillio video call network issue

friends I had implemented Twillio Video call in my Android application its working fine in the availability of the network.But I am facing an issue in case of network lost.
Test Cases:-
Device A call to Device B.
Both connected to Room successfully.and video call working fine.
Sudden Device B lost the network connection at this time the call is continuous this is a bug.
Expected :- Both have to disconnect from the room.
Actual:- they are still in connection
Please help if anybody implement this.
While initializing Room, we are providing listeners to it.
ConnectOptions.Builder connectOptionsBuilder = new ConnectOptions.Builder(mAccessToken);
Room mRoom = Video.connect(this, connectOptionsBuilder.build(), new Room.Listener() {
#Override
public void onConnected(Room room) {
}
#Override
public void onConnectFailure(Room room, TwilioException twilioException) {
}
#Override
public void onDisconnected(Room room, TwilioException twilioException) {
String leftParticipantName = room.getName();// name of participant who has left
// Here you can end/disconnect your conversation.
}
#Override
public void onParticipantConnected(Room room, Participant participant) {
}
#Override
public void onParticipantDisconnected(Room room, Participant participant) {
}
#Override
public void onRecordingStarted(Room room) {
}
#Override
public void onRecordingStopped(Room room) {
}
});
From this method you can disconnect your video-conversation.
For disconnect:
if (mRoom != null) {
mRoom.disconnect();
}
Use connection check method in your class detect app have connection or not if doesnt have connnection you can call the method of call disconnect.
If twillio is not disconnecting the call you can disconnect the call by yourself.

Connect a client app Android to a server written with Sails.js using socket.io

Here's my situation: i have a server written with sails.js where i have a user model. I have a dashboard where i can see all the users, create new, delete them and so on...Now i want to create an android app where i can get, using socket.io, notification about the events that occour to the user model.
Example: if i delete a user from my dashboard i want the app to recive a notification from the server that the user has been deleted.
Here's my code for the app:
public class MainActivity extends Activity {
//socket instance
private Socket mSocket;
{
try {
mSocket = IO.socket("http://server_url:port/user");
} catch (URISyntaxException e) {
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); //set the layout for this activity
final TextView tv = (TextView) findViewById(R.id.textView);
mSocket.on("user", new Emitter.Listener() {
#Override
public void call(Object... args) {
tv.setVisibility(View.INVISIBLE);
}
});
mSocket.connect();
final Button btn_createUser = (Button)findViewById(R.id.button);
btn_createUser.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mSocket.connected()) {
//tv.setVisibility(View.INVISIBLE);
}
}
});
}
}
Like i did with the dashboard to connect the socket to the server i did the same thing here, but it seems like the socket doesn't connect, in fact, when i delete a user from the dashboard i get no notification.
Here's the code (that works) i used in my dashboard to connect my socket to the server and listen to updates from the user model:
//connect to the server and listen to updates from user model
io.socket.get('/user', function(data, jwres) {
$scope.users = data;
$scope.$apply(); //write users in the table...
});
//wait for updates...
io.socket.on('user', function serverResponded (data) {
if(data.verb == "updated")
{
//get the user index in the array and update it
var index = getIndex(data.id, $scope.users);
$scope.users[index].online = data.data.online;
$scope.$apply();
}
if(data.verb == "destroyed")
{
//get the user index in the array and remove it
var index = getIndex(data.id, $scope.users);
$scope.users.splice(index, 1);
$scope.$apply();
}
if(data.verb == "created")
{
//simply update the array
$scope.users.push(data.data);
$scope.$apply();
}
});
Now, i think all i'm missing out in the android app is the GET request which automatically subscribe my socket to the model and get notified if something happen...but i don't know hot to do it.
I hope i was clear enough...thank to everyone who will answer me!
PS: i don't want to use AndroidAsync because i need the ultimate version of socket.io!
In case someone need it, i found the solution: https://github.com/balderdashy/sails/issues/2640 here you can find out how to solve the issue! :)

Unable to both start and discover a specific service with Wifi Direct

I'm pretty new with Android programming. But I have been working on this for over a week now, and it starts to get booooring.
My idea is that I want to connect two devices using Wifi Direct. But I only want to connect to those which are running my application. Besides, I want the users to be able to see some information of the other devices (such as user name), not just the MAC or the Android_XXXX name included in the WifiP2pDevice. That's why I decided that a device looking for other devices, should both start the application service and search for peers which are also broadcasting this service.
The problem (I'm testing with two real devices) is that, even though they are running exactly the same code, only one of them is getting the service discovery callbacks (the onDnsSd... listeners below). So, one side acts in the proper way, but not the other. Moreover I'm getting "old" services, meaning that apparently each time I start de service (even though I cancel previously started services), that service seems to be still broadcast during at least some minutes.
I include a shortened version of my code:
public class MoveFlufietsDialogFragment extends DialogFragment implements ChannelListener, DeviceActionListener {
public final HashMap<String, FlufietsPeer> mBuddies = new HashMap<String, FlufietsPeer>();
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
...
mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
mManager = (WifiP2pManager) getActivity().getSystemService(Context.WIFI_P2P_SERVICE);
mChannel = mManager.initialize(getActivity(), getActivity().getMainLooper(), null);
...
startRegistration();
discoverFlufietsService();
...
}
public void discoverFlufietsService() {
DnsSdTxtRecordListener txtListener = new DnsSdTxtRecordListener() {
#Override
public void onDnsSdTxtRecordAvailable(String fullDomain, Map record, WifiP2pDevice device) {
// This and the next listener are only called in one of the devices.
String serviceName = (String) record.get("serviceName");
if ((serviceName != null) && (serviceName.equals("flufiets")) {
// I put the record data in the mBuddies HashMap.
...
mBuddies.put(device.deviceAddress, myPeerDataStructure);
}
}
};
DnsSdServiceResponseListener servListener = new DnsSdServiceResponseListener() {
#Override
public void onDnsSdServiceAvailable(String instanceName, String registrationType, WifiP2pDevice resourceType) {
if (mBuddies.containsKey(resourceType.deviceAddress)) {
FlufietsPeer flufietsPeer = mBuddies.get(resourceType.deviceAddress);
WiFiPeerListAdapter adapter = ((WiFiPeerListAdapter) mFragmentList.getListAdapter());
adapter.add(flufietsPeer);
adapter.notifyDataSetChanged();
}
}
};
mManager.setDnsSdResponseListeners(mChannel, servListener, txtListener);
WifiP2pDnsSdServiceRequest serviceRequest = WifiP2pDnsSdServiceRequest.newInstance();
mManager.addServiceRequest(mChannel, serviceRequest, new ActionListener() {
// onSuccess/onFailure toasts.
});
mManager.discoverServices(mChannel, new WifiP2pManager.ActionListener() {
// onSuccess/onFailure toasts.
});
}
public void startRegistration() {
mManager.clearLocalServices(mChannel, new ActionListener() {
// onSuccess/onFailure toasts.
});
Map record = new HashMap();
record.put("serviceName", "flufiets");
...
WifiP2pDnsSdServiceInfo serviceInfo = WifiP2pDnsSdServiceInfo.newInstance(flufietsService, "_tcp", record);
mManager.addLocalService(mChannel, serviceInfo, new ActionListener() {
// onSuccess/onFailure toasts.
});
}
#Override
public void onResume() {
super.onResume();
mReceiver = new WiFiDirectBroadcastReceiver(mManager, mChannel, this);
getActivity().registerReceiver(mReceiver, mIntentFilter);
}
#Override
public void onPause() {
super.onPause();
getActivity().unregisterReceiver(mReceiver);
}
#Override
public void onStop() {
super.onStop();
mManager.clearLocalServices(mChannel, new ActionListener() {
// onSuccess/onFailure toasts.
});
}
...
}
The problem doesn't seem to be related with the device itself (sometimes it works, sometimes it doesn't, but always only in one of them). I suspect it has to do with either trying to discover a service that we ourselves are broadcasting, or having the same service being offered by two devices. I have tried changing the names of the service, so each device would offer either a "send" or "receive" service, but it doesn't work. I only get the callbacks called (onDnsSd...) in one of the devices.
And that thing about getting old services, when I always clear them, is weird (I do include a timestamp in the service record data, and I could always discard all but the last, but doesn't seem to be logical).
Any ideas? ANY help would be VERY appreciated, because writing the application is not funny any more (:-)=
Thanks a lot!
You need to wait until the clearLocalService call succeeds before adding the local service later. So put the addLocalService call into the onSuccess callback of the clearLocalServices.

Categories

Resources