I made a geotagged social report application to report broken streets on Android. It requires location data to post a report. Either from photo's Exif, Gps sensor or set it manually from MapsPickerActivity.
I managed to make the location request using RxLocation library. There's a button that's being made enabled when the app is still getting the location from Gps. Since getting a location data from Gps might take a while, I let the user to just set a location manually at the same time. I want to stop the getGpsLocationObservable if the user pressed the button. If I don't stop the getGpsLocationObservable, I'm afraid the process would still be running and come after setting a custom location. That would be annoying.
How could I achieve that?
Here's snippets of the simplified code
Main disposable :
Disposable myDisposable = imageProcessingObservable()
.compose(getExifLocationTransformer()) //custom location button enabled here
.filter(isLocationSet -> isLocationSet)
.flatmap(x->getGpsLocationObservable());
RxLocation getGpsLocationObservable :
private Observable<String> getGpsLocationObservable(){
locationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setNumUpdates(1)
.setInterval(3000);
rxLocation = new RxLocation(PostActivity.this);
rxLocation.setDefaultTimeout(10, TimeUnit.SECONDS);
return rxLocation.settings()
.checkAndHandleResolution(locationRequest)
.flatMapObservable(isActivated->{
if (isActivated) {
return locationSettingsActivatedObservable();
}
else locationNotFoundObservable();
});
}
#SuppressLint("MissingPermission")
private Observable<String> locationSettingsActivatedObservable(){
return rxLocation.location().updates(locationRequest)
.map(location -> {
LatLng latLng = new LatLng(location.getLatitude(),location.getLongitude());
String street = getStreetName(latLng);
return street;
})
.doOnNext(street->{
updateUI(street);
});
}
I guess it's a great use case for .amb() operator which only takes output of the observable which started emitting first and ignores all others. See http://reactivex.io/RxJava/javadoc/rx/Observable.html#amb-rx.Observable-rx.Observable-
Related
I am trying to implement the ad in my app with Custom Native Ad Format - https://developers.google.com/ad-manager/mobile-ads-sdk/android/native/custom-formats#java_1
So, according to the documentation I am going with the approach described there and creating the ad
...
private void setListeners() {
...
imageView.setOnClickListener(v -> {
nativeCustomFormatAd.performClick("IMAGE");
});
...
}
private NativeCustomFormatAd nativeCustomFormatAd;
AdLoader adLoader = new AdLoader.Builder(context, "/6499/example/native")
.forCustomFormatAd("10063170",
new NativeCustomFormatAd.OnCustomFormatAdLoadedListener() {
#Override
public void onCustomFormatAdLoaded(NativeCustomFormatAd ad) {
// Show the custom format and record an impression.
nativeCustomFormatAd = ad;
Drawable drawable = vm.nativeCustomFormatAd.getImage("IMAGE").getDrawable();
imageView.setDrawable(drawable);
}
},
new NativeCustomFormatAd.OnCustomClickListener() {
#Override
public void onCustomClick(NativeCustomFormatAd ad, String s) {
// Handle the click action
}
})
.withAdListener( ... )
.withNativeAdOptions( ... )
.build();
#SuppressLint("VisibleForTests")
AdManagerAdRequest adManagerAdRequest = new AdManagerAdRequest.Builder().build();
adLoader.loadAd(adManagerAdRequest);
...
So, it looks pretty simple I try to make a request for the ad then I got (in a callback) NativeCustomFormatAd, save it as a class member, and along with it get drawable and set it to the imageView (to present it in the UI). Once a user clicks on the imageView I get an event in the click listener and invoke nativeCustomFormatAd.performClick("IMAGE");.
The problem is that I expect that once I transfer the ad click to the SDK (by nativeCustomFormatAd.performClick("IMAGE");) SDK is supposed to open the external browser, but instead nothing happens.
P.S. I am sure that nativeCustomFormatAd.performClick("IMAGE"); getting invoked and also I see that SDK gets the click as I got a callback event here:
...
new NativeCustomFormatAd.OnCustomClickListener() {
#Override
public void onCustomClick(NativeCustomFormatAd ad, String s) {
// Handle the click action
}
})
...
What am I missing here?
According to the docs you linked:
When a click is performed on a custom format ad, there are three possible responses from the SDK, attempted in this order:
Invoke the OnCustomClickListener from AdLoader, if one was provided.
For each of the ad's deep link URLs, attempt to locate a content resolver and start the first one that resolves.
Open a browser and navigate to the ad's traditional Destination URL.
Also:
If you pass a listener object in, the SDK instead invokes its onCustomClick method and takes no further action.
Therefore, it seems you have to pass a null OnCustomClickListener.
I am trying to get a fake location using a mock location whenever my application running in background service and at that time I am moving to google maps and I am trying to get the current location at that time already GPS enable than asking multi-time enable GPS dialog. here upload the image which repeatedly shown.
I have already tried but whenever Moke location is enabled that time this problem is detected.
here is the java code
LocationRequest request = LocationRequest.create()
.setInterval(2000)
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder().addLocationRequest(request);
SettingsClient client = LocationServices.getSettingsClient(this);
Task<LocationSettingsResponse> task = client.checkLocationSettings(builder.build());
task.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
if (e instanceof ResolvableApiException) {
ResolvableApiException exc = ((ResolvableApiException) e);
IntentSenderRequest intentSenderRequest = new IntentSenderRequest.Builder(exc.getResolution().getIntentSender()).build();
locationDialogLauncher.launch(intentSenderRequest);
}
}
})
I use mapbox for android (java), when it tries to access the device location it gives me an error and closes the application. This problem does not occur when I try to use the app by simulating it.
It seems that this code doesn't work.
private void enableLocationComponent(#NonNull Style loadedMapStyle) {
if (PermissionsManager.areLocationPermissionsGranted(this)) {
locationComponent = mapboxMap.getLocationComponent();
LocationComponentActivationOptions locationComponentActivationOptions =
LocationComponentActivationOptions.builder(this, loadedMapStyle)
.useDefaultLocationEngine(false)
.build();
locationComponent.activateLocationComponent(locationComponentActivationOptions);
locationComponent.setLocationComponentEnabled(true);
locationComponent.setCameraMode(CameraMode.TRACKING);
locationComponent.setRenderMode(RenderMode.COMPASS);
initLocationEngine();
} else {
permissionsManager = new PermissionsManager(this);
permissionsManager.requestLocationPermissions(this);
}
}
What is the crash message in the logcat?
Are you passing a fully loaded map style through to enableLocationComponent()?
You might have already seen them, but fyi about https://docs.mapbox.com/help/tutorials/android-location-listening/ and https://docs.mapbox.com/android/maps/examples/#device-location
I have launched application in google play store, for that application i need to implement Immediate In app update, in order to fix the issue who are already using my application
I already tried Github examples those are Flexible updates not immediate updates.
In android developers site also i have gone through i didnt get proper example
Try below method for in-app-update for IMMEDIATE update of android app.
add below line in apps build gradle file.
implementation 'com.google.android.play:core:1.6.3'
for a better way, place this single method code in your MainActivity and call inside onCreate() method.
AppUpdateManager appUpdateManager;
private void inAppUpdate() {
// Creates instance of the manager.
appUpdateManager = AppUpdateManagerFactory.create(this);
// Returns an intent object that you use to check for an update.
Task<AppUpdateInfo> appUpdateInfoTask = appUpdateManager.getAppUpdateInfo();
// Checks that the platform will allow the specified type of update.
appUpdateInfoTask.addOnSuccessListener(new OnSuccessListener<AppUpdateInfo>() {
#Override
public void onSuccess(AppUpdateInfo appUpdateInfo) {
Log.e("AVAILABLE_VERSION_CODE", appUpdateInfo.availableVersionCode()+"");
if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE
// For a flexible update, use AppUpdateType.FLEXIBLE
&& appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.IMMEDIATE)) {
// Request the update.
try {
appUpdateManager.startUpdateFlowForResult(
// Pass the intent that is returned by 'getAppUpdateInfo()'.
appUpdateInfo,
// Or 'AppUpdateType.FLEXIBLE' for flexible updates.
AppUpdateType.IMMEDIATE,
// The current activity making the update request.
HomeActivity.this,
// Include a request code to later monitor this update request.
UPDATE_REQUEST_CODE);
} catch (IntentSender.SendIntentException ignored) {
}
}
}
});
appUpdateManager.registerListener(installStateUpdatedListener);
}
//lambda operation used for below listener
InstallStateUpdatedListener installStateUpdatedListener = installState -> {
if (installState.installStatus() == InstallStatus.DOWNLOADED) {
popupSnackbarForCompleteUpdate();
} else
Log.e("UPDATE", "Not downloaded yet");
};
private void popupSnackbarForCompleteUpdate() {
Snackbar snackbar =
Snackbar.make(
findViewById(android.R.id.content),
"Update almost finished!",
Snackbar.LENGTH_INDEFINITE);
//lambda operation used for below action
snackbar.setAction(this.getString(R.string.restart), view ->
appUpdateManager.completeUpdate());
snackbar.setActionTextColor(getResources().getColor(R.color.your_color));
snackbar.show();
}
courtsey here
We are using below scenario in our app for Mandatory updates.
We are maintain Current version code and latest version code in our backend database.
In Splash screen, I am calling that API to check latest version code.
Get current version code from APP.
Get latest version code from API.
If latest version code is incremental then current. We Display Update Dialog.
You have to make sure that, Once new update rollout you need to change version in backend database.
I've an app which allows usage if user is in certain area, meaning I don't need to track the user, but I need to make sure location that's received is fresh (even if it requires waiting).
What's the best way to do this? Currently using:
getLastLocation()
but it can sometimes get previous location, understandably.
You can register a location listener and proceed to the code if the location condition is met:
locationCallback = new LocationCallback() {
#Override
public void onLocationResult(LocationResult locationResult) {
if (locationResult == null) {
return;
}
for (Location location : locationResult.getLocations()) {
//if(this is the location) jump to the code which makes the app usable
}
//stay unusable
};
};
getting the location might take some time. If by force you mean holding the ui thread until the precise-enough location is available then force getting the location is a bad but feasible idea.