How can I cross platform with Android and IOS - android

I have created an app in both Android & IOS. I am on the last hurdle of the app. I was able to get Android user working with IOS user whereas the IOS had a tableview.
Now I am faced with a different problem. If the "rider" on the iOS app is requesting a ride and the Android driver is available - how can I finish this use case?
If the iOS user makes a request, this is the process:
func requestPressed(_ sender: Any) {
print("... requestPressed")
let dict = selectedPin!.addressDictionary
if dict?.count == 0 {
// this isn't shown to the user, just in your debug window
print("no addresses available, try again in a few seconds")
return
}
destAddress = selectedPin!.addressDictionary!["Street"] as? String ?? "None"
if destAddress == "None" {
print("no valid address available, try again in a few seconds")
return
}
if userLocation != nil {
print("my userLocation: \(userLocation!)")
if canRequestRyde { // if true ...
// get the destination area name, and the price
areaNameDestination = DriveHandler.Instance.getAreaName(latitude: destLat, longitude: destLong)
print("destination area \(areaNameDestination)")
requestFarePrice()
rRideHandler.Instance.requestRide(latitude: Double(userLocation!.latitude), longitude: Double(userLocation!.longitude), destLat: Double(destLat), destLong: Double(destLong), currentAddress: self.currentAddress, destAddress: destAddress, farePrice: farePrice)
// reset the driver message
driverMessage = ""
canRequestRide(delegateCalled: true, request: nil)
} else {
riderCancelled()
}
}
}
The Firebase entry would look like this:
What I need to do from this is for the online Android Driver to either accept/decline the request and follow the steps as if it was Android Rider vs Android Driver.
Below are the steps if Android requests a ride and press "Request" btn:
private void requestPickupHere(String uid) {
Log.e(TAG, "requestPickupHere");
DatabaseReference dbRequest = FirebaseDatabase.getInstance().getReference(Common
.request_tbl); // "RideRequests"
GeoFire mGeoFire = new GeoFire(dbRequest);
mGeoFire.setLocation(uid, new GeoLocation(Common.mLastLocation.getLatitude(),
Common.mLastLocation.getLongitude()));
// write to db
if (search_bar_destination != null) {
dbRequest.child(uid).child("destination").setValue(search_bar_destination);
} else if (tap_on_map_destination != null) {
dbRequest.child(uid).child("destination").setValue(tap_on_map_destination);
}
dbRequest.child(riderId).child("status").setValue("");
if (mUserMarker.isVisible()) {
mUserMarker.remove();
}
// Add a new marker
mUserMarker = mMap.addMarker(new MarkerOptions()
.title("Pickup Here")
.snippet("")
.position(new LatLng(Common.mLastLocation.getLatitude(), Common.mLastLocation.getLongitude()))
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED)));
mUserMarker.showInfoWindow();
btnRequest.setText("Getting your DRIVER ...");
location = getCompleteAddressString(Common.mLastLocation.getLatitude(), Common.mLastLocation.getLongitude());
Log.e(TAG, "riders location = " + location);
findDriver();
}
When the above code is run, it open an activity "Customer Call" located within the Driver Application, where the driver can either Accept / Deny the request.
How can I get the request to be sent from IOS Rider to the Android Driver in the same way it would work for Android to Android?

Using different platforms shouldn't be an issue, when a user requests a ride then you can add an attribute under the driver in the database for example:
DriverRides
DriverId
Name: peter
purpose: needs a ride
Then you can retrieve all the requests to be appear for that driver in a recyclerview. It shouldn't matter what phone the user is using, except if you want the android user to take requests and the ios user to send requests.
You are using the same database for both platforms, so when an ios user or android user store data it will go to the same place. For example if user x uses an iPhone and user y uses a Samsung, you would do the following in the database:
Users
UserId1
name: userx
age: 100
UserId2
name: usery
age: 120

Related

Flutter HEALTH package get steps from user returns always null?

I am working on a personal project and I am using flutter to develop an app (cross platform) that reads in the user's health data from google fit (Android) or Apple Health. I am using this package and even the EXACT same code like in the documentation (I am currently only testing on Android):
Future fetchStepData() async {
int? steps;
// get steps for today (i.e., since midnight)
final now = DateTime.now();
final midnight = DateTime(now.year, now.month, now.day);
bool requested = await health.requestAuthorization([HealthDataType.STEPS]);
if (requested) {
try {
steps = await health.getTotalStepsInInterval(midnight, now);
} catch (error) {
print("Caught exception in getTotalStepsInInterval: $error");
}
print('Total number of steps: $steps');
setState(() {
_nofSteps = (steps == null) ? 0 : steps;
_state = (steps == null) ? AppState.NO_DATA : AppState.STEPS_READY;
});
} else {
print("Authorization not granted - error in authorization");
setState(() => _state = AppState.DATA_NOT_FETCHED);
}
}
Then I am calling this function with await and I also have inserted the correct permission in all Android Manifest files:
Also I set up an OAuth2 Client ID for the project and added my google account as a test user.
BUT THE FUNCTION SETS THE VARIABLE STEPS ALWAYS TO NULL? The boolean variable "requested" is true, so it seems like the actual connection is working?
I am really disappointed by myself guys and I really need help - THANK YOU!
I tried adding the correct android permissions, asking for permissions explicitly, different time intervalls but nothing worked for me, I always got a null value back.

Mongodb- How to get data from a partition that was created by other user?

I am using Realm MongoDB for my android app, and I have a problem:
I have different users in my app, and each user has his "cards". The partition of each user's cards is:
"Card=userID".
So, I want to be able to send a card from one user to the other. I do it via a link that includes userID and specific cardID.
So my code looks something like:
Realm.init(this);
mainApp = new App(new AppConfiguration.Builder(APP_ID).defaultSyncErrorHandler((session, error) ->
Log.e("TAG()", "Sync error: ${error.errorMessage}")
).build());
//TEMP CODE
String partition = "Card=611d7n582w36796ce34af106"; //test partition of another user
if(mainApp.currentUser() != null) {
SyncConfiguration config = new SyncConfiguration.Builder(
mainApp.currentUser(),
partition)
.build();
Realm realmLinkCard = Realm.getInstance(config);
Log.d(TAG, "onCreate: cards found- " + realmLinkCard.where(Card.class).findAll().size());
}
The last log always shows 0. I know there are cards for sure because if the user that created the corresponding partition is signed in then it does find the cards.
permissions are set to true for both read and write for the whole sync.
What can the problem be?
You cannot access a Realm by a user who has a different partition.
Instead you can create a mongodb function and call it from your user.
Make your function here:
Check here on How to create a function
And call it by checking here on How to call a function from client
Quick example of a realm function:
exports = async function funcName(partition) {
const cluster = context.services.get('myclustername');
const mycollection = cluster.db('mydbname').collection('mycollectionname');
let result = [];
try {
result = mycollection.findOne({
_partition: partition,
});
} catch (e) {
result.push(e);
return result;
}
return result;
};
To call it, please see above for the documentation as I'm not an Android developper.

Xamarin Forms Android: map.Pins.Clear() issue

my development team and I have run into an issue on our Android distribution of our Xamarin project. The issue is as such: The application uses an observable collection of objects and represents these objects in the form of a list view and a map view with pins representing the objects. In the map view, our code is designed to subscribe to a messaging center call that periodically updates the observable collection of objects from our API (other part of project). The issue we are having is that when we call PlotPins method in the messaging center code block, the application should first retrieve the updated list and then access that list to plot pins on the map. Every time an update is received, the application will clear all pins from the map and then replot the pins based on the updated list (inefficient we know, but this is a temporary solution). However, the pins are never updated. Through the use of the debugger we have discovered that once map.Pins.Clear() within PlotPins() is called, the application jumps to the end of the RequestUpdatedListAsync method (which occurs periodically to retrieve the updated list and which triggers the Messaging Center) and then halts.
Our solution works for our GTK build, with the pins being cleared and redrawn on the map as intended, so this seems to be an Android specific issue.
Any help would be appreciated, thank you.
Relevant code located below:
MESSAGING CENTER:
MessagingCenter.Subscribe<object, ObservableCollection<MyObject>>(Application.Current, Constants.ListUpdateContract, (sender, newList) =>
{
//update list
listUpdater.UpdateList(newList);
//call method to plot pins again
PlotPins(map);
});
PLOTPINS:
private void PlotPins(Map map)
{
map.Pins.Clear();
foreach (MyObject in MyObjects)
{
var pin = new Pin
{
Label = MyObject.ID,
Address = "Latitude: " + MyObject.Latitude + " " + "Longitude: " + MyObject.Longitude,
Type = PinType.Place,
Position = new Position(Convert.ToDouble(MyObject.Latitude), Convert.ToDouble(MyObject.Longitude))
};
//event handler for when user clicks on pin's info window
pin.InfoWindowClicked += async (s, args) =>
{
//opens up detail page for pin associated with myObject
await Navigation.PushAsync(new DetailPage(MyObject));
};
map.Pins.Add(pin);
}
}
REQUEST UPDATED LIST ASYNC:
public static async System.Threading.Tasks.Task<bool> RequestUpdatedListAsync()
{
if (!_tokenIsGood)
return false;
var success = false;
var response = new HttpResponseMessage();
try
{
response = await _client.GetAsync(Constants. MyObjectDisplayUrl);
}
catch (Exception e)
{
System.Diagnostics.Debug.WriteLine("Error requesting updated list.");
System.Diagnostics.Debug.WriteLine(e.Message);
System.Diagnostics.Debug.WriteLine(e.StackTrace);
return success;
}
response.EnsureSuccessStatusCode();
success = true;
var responseBody = await response.Content.ReadAsStringAsync();
// Update list
MyObjects.Clear();
MyObjects = JsonConvert.DeserializeObject<ObservableCollection< MyObject >>(responseBody);
//Alert subscribed ViewModels to update list
MessagingCenter.Send<object, ObservableCollection< MyObject >>(Application.Current, Constants.ListUpdateContract, units);
return success;
}
Since maps.Pins is UI related it has to be run in main UI thread.
MessagingCenter doesnt always publish/subscribe in main threads .
So to fix this issue call the maps.Pins.Clear() in main thread.
Device.BeginInvokeOnMainThread(()=> maps.Pins.Clear());
Credits: #shanranm for mentioning limitation of MessagingCenter for using main threads.

Ionic 2 / Ionic 3 : How to get current location of a device

None of the answers on stackoverflow worked for me. A lot of them are for Ionic 1 or those answers are deprecated or they are not working for android device.
I have seen a lot of solutions on stackoverflow about getting current location of device but non of them seems to be working for Android .
what i have tried:-
using geolocation.getCurrentPosition() , which is working for IOS and browser but not for Android.
using this.geolocation.watchPosition() , which is working for IOS and browser but not for Android.
using navigator.geolocation.getCurrentPosition(),which is working for IOS and browser but not for Android.
using fiddle solution provided by this question getCurrentPosition() and watchPosition() are deprecated on insecure origins
Anyway , all of these are deprecated by google due to :-
getCurrentPosition() and watchPosition() are deprecated on insecure
origins, and support will be removed in the future. You should
consider switching your application to a secure origin, such as HTTPS.
See goo.gl/rStTGz for more details.
what worked for me is (https://ionicframework.com/docs/native/background-geolocation/ ) & (https://www.joshmorony.com/adding-background-geolocation-to-an-ionic-2-application/ ) both of these are based on background-geolocation plugin but,it's taking almost 50-55 sec on Android device, again it's working fine for ios
The problem with joshmorony(https://www.joshmorony.com/adding-background-geolocation-to-an-ionic-2-application/ ) solution is foreground is not working for Android physical devices but working fine for browser and ios. Background tracking is working fine , which is taking almost 50 sec to give lat & lng for the first time.
Please help me with this. I want a way to get current location in minimum time. For your info, I am using google javascript map sdk / api .
I tried every solution provided by all of you and others also on internet. Finally i found a solution.You can try this plugin cordova-plugin-advanced-geolocation (https://github.com/Esri/cordova-plugin-advanced-geolocation ) from ESRI . But this plugin will work for Android not IOS. For ios you can go with same old approach . i.e - using this.geolocation.getCurrentPosition(...) or this.geolocation.watchPosition(..).
Add cordova-plugin-advanced-geolocation Plugin Like this :-
cordova plugin add https://github.com/esri/cordova-plugin-advanced-geolocation.git
then Add below line at the top of Class / Component
declare var AdvancedGeolocation:any; //at the top of class
Now add these lines inside relevant function of component ( P.S. - I have included code for both Android & IOS)
//**For Android**
if (this.platform.is('android')) {
this.platform.ready().then(() => {
AdvancedGeolocation.start((success) => {
//loading.dismiss();
// this.refreshCurrentUserLocation();
try {
var jsonObject = JSON.parse(success);
console.log("Provider " + JSON.stringify(jsonObject));
switch (jsonObject.provider) {
case "gps":
console.log("setting gps ====<<>>" + jsonObject.latitude);
this.currentLat = jsonObject.latitude;
this.currentLng = jsonObject.longitude;
break;
case "network":
console.log("setting network ====<<>>" + jsonObject.latitude);
this.currentLat = jsonObject.latitude;
this.currentLng = jsonObject.longitude;
break;
case "satellite":
//TODO
break;
case "cell_info":
//TODO
break;
case "cell_location":
//TODO
break;
case "signal_strength":
//TODO
break;
}
}
catch (exc) {
console.log("Invalid JSON: " + exc);
}
},
function (error) {
console.log("ERROR! " + JSON.stringify(error));
},
{
"minTime": 500, // Min time interval between updates (ms)
"minDistance": 1, // Min distance between updates (meters)
"noWarn": true, // Native location provider warnings
"providers": "all", // Return GPS, NETWORK and CELL locations
"useCache": true, // Return GPS and NETWORK cached locations
"satelliteData": false, // Return of GPS satellite info
"buffer": false, // Buffer location data
"bufferSize": 0, // Max elements in buffer
"signalStrength": false // Return cell signal strength data
});
});
} else {
// **For IOS**
let options = {
frequency: 1000,
enableHighAccuracy: false
};
this.watch = this.geolocation.watchPosition(options).filter((p: any) => p.code === undefined).subscribe((position: Geoposition) => {
// loading.dismiss();
console.log("current location at login" + JSON.stringify(position));
// Run update inside of Angular's zone
this.zone.run(() => {
this.currentLat = position.coords.latitude;
this.currentLng = position.coords.longitude;
});
});
}
EDIT : First installation is always going fine. But Sometimes you might get errors for no reason in subsequent installations. To make this error (any error with this plugin ) go away.Follow these steps :
1. Remove this plugin from your project (including config.xml and package.json).
2. Delete/Remove android platform.
3. Delete plugins folder.
4. Now reinstall this plugin again, following the steps above.
I have gone through the problem and find the solution.
the best way to get geolocation of the user is to use this plugin https://ionicframework.com/docs/native/geolocation/
do not forget to add this is app.moudle.ts as its a provider.
by simply adding this code in app component i was able to get location( do not forget to import and add in constructor)
this.geolocation.getCurrentPosition({ enableHighAccuracy: true }).then((resp) => {
console.log(resp);
}, Error => {
console.log(Error);
}).catch(Error => {
console.log(Error);
})
i only have the same error while i was using ionic cordova run
android --livereload that is insecure origin
but when i use ionic serve i can see the response in browser and also after
using ionic cordova run android
just to confirm response in android i check the chrome debugger.
It works for me
import { Geolocation } from '#ionic-native/geolocation/ngx';
import { NativeGeocoder, NativeGeocoderOptions, NativeGeocoderResult } from '#ionic-native/native-geocoder/ngx';
geoencoderOptions: NativeGeocoderOptions = {
useLocale: true,
maxResults: 5
};
constructor(
private geolocation: Geolocation,
private nativeGeocoder: NativeGeocoder
) {
getCurrentLocation() {
this.geolocation.getCurrentPosition()
.then((resp) => {
this.getGeoencoder(resp.coords.latitude, resp.coords.longitude);
}).catch((error) => {
console.log('Error getting location', error);
});
}
//geocoder method to fetch address from coordinates passed as arguments
getGeoencoder(latitude, longitude) {
this.nativeGeocoder.reverseGeocode(latitude, longitude, this.geoencoderOptions)
.then((result: NativeGeocoderResult[]) => {
const address = this.generateAddress(result[0]);
})
.catch((error: any) => {
// alert('Error getting location' + JSON.stringify(error));
});
}
//Return Comma saperated address
generateAddress(addressObj) {
let obj = [];
let address = "";
for (let key in addressObj) {
obj.push(addressObj[key]);
}
obj.reverse();
for (let val in obj) {
if (obj[val].length)
address += obj[val] + ', ';
}
return address.slice(0, -2);
}
you need to provide the permission for Android app as follows:
<feature name="Geolocation">
<param name="android-package" value="org.apache.cordova.GeoBroker" />
</feature>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
I ran into a similar problem. When I build from the terminal with the --prod flag, I no longer see this error since it is now requesting position over https.
Built without --prod flag
Built using the --prod flag
Edit: Sorry for the format, I hope that this makes a little more sense. I used the following function in a service that I could call from anywhere to get the latitude, longitude, accuracy, and timestamp. The key though is using the --prod flag in the terminal when building the app.
this.geolocation.getCurrentPosition().then(position => {
let locationObj = {
lat: position.coords.latitude,
lon: position.coords.longitude,
timestamp: position.timestamp,
accuracy: position.coords.accuracy
};
resolve(locationObj);
})
this method is working for bot android and browser
watchLocation() {
this.watchLocationUpdates = this.geolocation.watchPosition({ maximumAge: 60000, timeout: 25000, enableHighAccuracy: true })
.subscribe(resp => {
this.latitude = resp.coords.latitude;
this.longitude = resp.coords.longitude;
this.altitude = resp.coords.altitude;
this.accuracy = resp.coords.accuracy;
this.altAccuracy = resp.coords.altitudeAccuracy;
this.heading = resp.coords.heading;
this.speed = resp.coords.speed;
this.timestamp = new Date(resp.timestamp);
});
}
I found solution for me: use google api https://www.googleapis.com/geolocation/v1/geolocate?key={API_KEY}
If platform Android I use google api.

Uber API => ETA is not updated in sandbox mode (accepted)

Well, I am making android and iOS app and integrating the Uber Api for taxi request. I am using the Uber-API in sand-box mode
I want to impelement this
If in status ACCEPTED and ETA <=2 min:
show message Your Personal Driver will arrive in less than 2 minutes.
If status ACCEPTED and ETA == 0:
Show message Your Personal Driver has arrived.
Problem
I am using the sandbox mode, the ETA is not changing.
Here is the out put
{
driver = {
name = John;
"phone_number" = "(555)555-5555";
"picture_url" = "https://d1a3f4spazzrp4.cloudfront.net/uberex-sandbox/images/driver.jpg";
rating = "4.9";
};
eta = 7; // Note: this ETA, This always remains 7 not changing
location = {
bearing = "-122";
latitude = "47.36758";
longitude = "8.54552";
};
"request_id" = "40edd821-e87a-4401-866a-126e15e1dce1";
status = accepted;
"surge_multiplier" = 1;
vehicle = {
"license_plate" = "UBER-PLATE";
make = Toyota;
model = Prius;
"picture_url" = "https://d1a3f4spazzrp4.cloudfront.net/uberex-sandbox/images/prius.jpg";
};}
Uber App
In the uber app the arriving ETA is accurate
10min
then 9,8,7...1,0
is this a sandbox restriciton or an uber-api Bug.?

Categories

Resources