Recognizing when the user is driving, walking, biking - java

I am trying to find the most reliable way to identify if the user is driving, walking, biking or is stationary. I am going to use this in an Android application. I would prefer to avoid GPS as much as possible.
Please let me know what algorithms worked for you, their advantages and disadvatages. Thanks!

Google has an API for this in Google Play Services. Check out https://developer.android.com/reference/com/google/android/gms/location/ActivityRecognitionApi.html
I wouldn't suggest coding it on your own, its not easy (I had a version about a year before Google did, it was buggy and battery draining).

You probably will never get a completely accurate result, but a reasonable estimate could be determined using
- GPS to identify speed
- Is the charger plugged in
- is the phone off, or on screensaver
- is the movement detector going off a lot - likely walking but may be driving on dirt road
I was playing with a simplistic version of this as follows (sorry code is in Python)
def inspect_phone(self):
self.phone_gps_lat = 137.0000 # get from phone
self.phone_gps_lng = 100.0000 # get from phone
self.phone_moving = False # get from phone
self.phone_move_dist_2_mn = 4
self.phone_on_charge = True
self.screen_saver = False
#-------------------------------
phone_status = ''
if self.phone_on_charge == True:
phone_status += 'Phone is charging'
if self.phone_moving == True:
phone_status += ', driving in Car'
else:
phone_status += ', sitting still'
else:
if self.screen_saver == False:
phone_status += 'Phone is being used'
else:
phone_status += 'Phone is off'
if self.phone_moving == True:
if self.phone_move_dist_2_mn < 5:
phone_status += ', going for Walk'
elif self.phone_move_dist_2_mn > 500:
phone_status += ', flying on Plane'
else:
phone_status += ', riding on ' + transport['Public']
return phone_status

I have made a small logic to get the best polylines for each activity and optimize the draw, since we need certain quantity of latitudes and longitudes in order to draw the best track that the user has made.
Lets say when the user press to start a new activity it will prompt 3 options, run, walk or biking.
This method takes what the user has selected and updates the locationRequest for each one.
public void setTrackActivity(long interval, long fastInterval) {
//Update the locationRequest intervals for each different Activity
mLocationRequest.setInterval(interval);
mLocationRequest.setFastestInterval(fastInterval);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
For walking I set the locationRequest intervals within 6 seconds
delay for each request.
For runing I set the locationRequest intervals within 2 seconds delay
for each request.
For runing I set the locationRequest intervals within 1 second delay
for each request.
Then, to save up more polylines when drawing the map, I take the same concept. If an user is walking it will trace a polyline each 30 polylines that have been made
public void drawTrack(GoogleMap googleMap) {
googleMap.clear(); //Clearing markers and polylines
PolylineOptions polyline_options = new PolylineOptions().addAll(mLinkedList)
.color(ContextCompat.getColor(mContext, R.color.colorAccent)).width(Constants.POLYLINE_WIDTH).geodesic(true);
// Adding the polyline to the map
Polyline polyline = googleMap.addPolyline(polyline_options);
// set the zindex so that the poly line stays on top of my tile overlays
polyline.setZIndex(1000);
// we add each polyline to an array of polylines
mPolylinesArray.add(polyline);
// We add the latest latlang points we got
mLatLngArray.add(mLinkedList.getLast());
//If we have made 30 polylines we store 1 line starting from that first point to the last, so we can save 28 polylines and draw one instead of having so many points for lets say 10 meters, this value must change depending on the activity, if biking, runing or walking
if (mLatLngArray.size() % 30 == 0) {
// First we delete all polylines saved at the array
for (Polyline pline : mPolylinesArray) {
pline.remove();
}
// We create a new polyline based on the first and last latlang from the 30 we took
Polyline routeSoFar = googleMap.addPolyline(new PolylineOptions().color(Color.GREEN).width(Constants.POLYLINE_WIDTH).geodesic(true));
// Draw the polyline
routeSoFar.setPoints(mLatLngArray);
// set the zindex so that the poly line stays on top of my tile overlays
routeSoFar.setZIndex(1000);
// Clear polyline array
mPolylinesArray.clear();
// Add polyline to array
mPolylinesArray.add(routeSoFar);
}
}
Where mLinkedList is an LinkedList<LatLng> so we can have the first and last element (if you want to draw a custom marker when activity starts and when activity finish )
mPolylinesArray is an array of Polylines ArrayList<Polyline>

Related

Can not remove Polyline from Google Map, Android SDK

I have a problem removing a single polyline from my Google Map in Android.
There were other Users with similar questions but not many answers and none of them where helpful.
Inside the google dock, it's explained that you can remove a polyline with the .remove() function.
But in my case this does not work. Maybe the problem lays within the scope.
In my class I have defined:
Polyline polyline = null;
Then I have an OnClick Listener for my Map and two arrays. One with 2 Locations in it (for my polyline) and one that adds Markers when I click on the map.
if(test.size() == 2 && pol == false)
{
polylineOptions.color(Color.BLUE);
polylineOptions.addAll(test);
polyline = m_map.addPolyline(polylineOptions);
//polygonOptions.fillColor(Color.BLUE).addAll(test);
}
if(markerList.size() == 2)
{
pol = true;
polyline.remove();
}
When I click on the Map a polyline is drawn. Then I click again, and the markerList is now equal 2, it goes into the function but the polyline is not removed. Why? What can I do?

Obstacles are removed faster than the bullet animation passes

Situation: The tank has a Shot() method and a code that checks if the bullet hits the obstacle after being fired. The bullet flies up the X-coordinate. The do...while loop checks how far the bullet can travel without obstacles. After that, the animation of the bullet flight itself takes place through TranslateTransition. And the last loop goes through all the game obstacles and checks for contact through intersects and, if successful, removes the obstacle.
do {
y = (int) (bulletObj.getImageBullet().getTranslateX() + register) / PlayField.BRICK_SIZE;
x = (int) bulletObj.getImageBullet().getTranslateY() / PlayField.BRICK_SIZE;
line = LevelData.LevelOne[x][y];
register += 1;
} while (line.equals("0"));
System.out.println(System.currentTimeMillis()); // 1643642047472 ms.
bulletTranslate = new TranslateTransition();
bulletTranslate.setFromX(bulletObj.getImageBullet().getTranslateX());
bulletTranslate.setToX(bulletObj.getImageBullet().getTranslateX() + register - 18);
bulletTranslate.setNode(bulletObj.getImageBullet());
bulletTranslate.setDuration(Duration.millis(register)); // Let register = 300 мs.
bulletTranslate.play();
System.out.println(System.currentTimeMillis()); // 1643642047474 ms.
bulletObj.getImageBullet().setTranslateX(bulletObj.getImageBullet().getTranslateX() + register - 18);
for (GameObject platform: PlayField.platforms) {
if (platform.getImage().getBoundsInParent().intersects(bulletObj.getImageBullet().getBoundsInParent()))
{
System.out.println(System.currentTimeMillis()); // 1643642047474 ms.
tankRoot.getChildren().remove(platform.getImage());
PlayField.platforms.remove(platform);
LevelData.LevelOne[x][y] = "0";
break;
}
}
Everything works as expected, but there is only one problem.
The problem is that the obstacle objects are removed faster than the animation bullets pass.
And it is necessary that after contact they are deleted simultaneously.
How to solve the problem?
Before the shot
After the shot, the object disappeared during the flight of the bullet
P.S Sorry, I used google translate.
As #jewelsea suggested, you need to supply a minimal reproducible example to get some proper help.
Having said that, based on the code you provided, below is my initial analysis. Note that this is a rough analysis by reading the code.. so everything is just an assumption ;)
The first part of the code (do-while) is to determine the distance the bullet needs to travel (determining the value of register)
The second part is to initiate animation of bullet to translate from its current position (using the register value).
The third part is to set the final translate value to the bullet and the final part is to check if the bounds are intersected and delete the node.
I think the thrid part (below line of code) is not needed and could be the cause for your issue. You are updating the value to the end value and immediately checking if it is intersected.. which will be true and will delete instantly.
bulletObj.getImageBullet().setTranslateX(bulletObj.getImageBullet().getTranslateX() + register - 18);
Try moving your 'for' loop code to onFinished of translation. Something like..
bulletTranslate = new TranslateTransition();
bulletTranslate.setFromX(bulletObj.getImageBullet().getTranslateX());
bulletTranslate.setToX(bulletObj.getImageBullet().getTranslateX() + register - 18);
bulletTranslate.setNode(bulletObj.getImageBullet());
bulletTranslate.setDuration(Duration.millis(register)); // Let register = 300 мs.
bulletTranslate.setOnFinished(e->{
for (GameObject platform: PlayField.platforms) {
if (platform.getImage().getBoundsInParent().intersects(bulletObj.getImageBullet().getBoundsInParent()))
{
tankRoot.getChildren().remove(platform.getImage());
PlayField.platforms.remove(platform);
LevelData.LevelOne[x][y] = "0";
break;
}
}
});
bulletTranslate.play();

Want to know about google map pop ups or snippet upon exact location

I want to develop an app on google map that could notify me with some information set by the user when I am close to the exact location. So can I get a link for this that How can I get pop-ups when I am at the exact(user) location?
You'll first need to enable a location manager to start getting the user's current location. Then, every time the user's location updates, the location manager calls the onLocationChanged() method. Here, you would want to check the distance between the user's current location and the destination location. If they are within whatever distance you choose, then you can display your map marker. Here is a little example of how to do that:
#Override
public void onLocationChanged(Location location) {
float distanceInMeters = destLocation.distanceTo(location);
// Distance in miles
double distance_to_dest = (distanceInMeters/1609.344);
int distance_to_dest_int = (int)(distance_to_dest * 100);
distance_to_dest = ((double)distance_to_dest_int/100.00);
tvMilesToGo.setText(String.format("%.2f", distance_to_dest) + "mi");
// About 1/10th of a mile
if ((distanceInMeters > 149) && (distanceInMeters < 176)) {
// I played an alarm sound when close to the target destination
//if (alarmPlayer.isPlaying()) {
// alarmPlayer.stop();
//}
//alarmPlayer.start();
Marker marker = mMap.addMarker(new MarkerOptions()
.position(new LatLng(destLocation.getLatitude(), destLocation.getLongitude()))
.title(“Arrived”)
.snippet(“You have arrived at your destination!”)
.icon(red_descriptor));
Marker.showInfoWindow;
}
}
Note, in your case, you would probably only ever want to add a marker once, so, you would probably want to set a flag such as markerIsVisible = true once you add it to the map, and then check before adding the marker if (markerIsVisible == false) {add the marker, markerIsVisible = true}

How to make my app delay and update the layout's components in every iteration of a loop

I am making a board game were I have 3 AI players and a user playing. When the user presses a Button to give its turn up to the AI's I want to add a delay so the user can see every move each AI makes.
I have tried a thread sleep and handler but it seems they are unable to update the board and add a delay with each iteration of the while loop. The code without any attempt to add a delay can be found below. I would need to add a delay after the inner while loop terminates.
public void onClickNextTurn(View view){
boolean turnFinished;
findViewById(R.id.btnChangeTurn).setVisibility(View.INVISIBLE);
while (this.playerTurn<4) {
this.playerTurn++;
turnFinished=false;
while (!turnFinished) {
diceRoll();
MoveTriplet result = ai[playerTurn-2].aiTurn(this.boardPieceLocations, this.homeLocations, this.finishLocations, this.roll, playerTurn);
if (result != null) {
if (result.getMoveType() == 'b') { //The Artificial Opponent is moving from one home location to the board AND gets to roll again
this.homeLocations[playerTurn - 1][result.getPreviousIndex()] = 0;
if (this.boardPieceLocations[result.getNextIndex()] != 0)
returnPieceHome(this.boardPieceLocations[result.getNextIndex()]);
this.boardPieceLocations[result.getNextIndex()] = this.playerTurn;
this.homeButtons[playerTurn - 1][result.getPreviousIndex()].setBackgroundColor(getResources().getColor(R.color.colorHoles));
this.buttons[result.getNextIndex()].setBackgroundColor(colors[playerTurn - 1]);
}
So if anyone could point me in the right direction on how I could add an delay between iterations of the outer while loop and at the same time updating the my board. Thanks in advance!
Try looking at the standard Android animation APIs. Those should handle the timing for you and be smoother anyways -- plus, they'll use the GPU more efficiently for you.

how do i organise this function so it works as i intend it to

im new to android studio and i want this function to loop and create an infinite ball falling loop which will be scored until the two integers do not match but when i try to run it, it will only loop once and if i change streak = 2 in the else statement the app crashes
public void mainGameLoop(){
do {
//sets Balls integer
setColourint();
ball.setVisibility(View.VISIBLE);
//ball fall
float bottomOfScreen = getResources().getDisplayMetrics()
.heightPixels - (ball.getHeight() * 4);
//fall animation
ball.animate()
.translationY(bottomOfScreen)
.setInterpolator(new AccelerateInterpolator())
.setInterpolator(new BounceInterpolator())
.setDuration(9000);
//once animation is complete compares balls variable with current variable
if (colourint == ranint){
//if they are same then +1 score
score = score+1;
scr.setText(Integer.parseInt(String.valueOf(score)));
} else {
//else game is over
streak = 2;
}
//repeat until game is over
} while (streak == 1);
}
once the balls reached the bottom of the relative layout i want the function to check if the setcoulour int and the ran int are the same and then if the are score = score + 1, ball goes back to the top, the setColourInt function is called and the ball falls again(and so on and so on) but if not loop ends and it's game over...i apologise for my blatant incompetence but I can't imagine you guys don't remember when you too, were this naive when it came to coding. many thanks Tom
You have to give the UI a chance to draw what you're doing. The way you have it coded, whichever method (onStart, onCreate, etc) that calls your mainGameLoop will never return because it's stuck in an infinite loop. This is an error.
One way to do this is to create a View and implement your game draw logic in the onDraw method. The UI thread will call your onDraw method when it is time to draw. Here's an article that talks about this approach: http://cjds.github.io/2014/04/28/Creating-a-simple-android-game/

Categories

Resources