Я создаю приложение для бегунов, где пользователь может отслеживать время его выполнения и маршрут. При нажатии кнопки START камера должна сфокусироваться на текущее местоположение, а текст таймера должен начало обновления. Истекшее время - секунды. Также, как пользователь перемещает карту google, следует начинать рисовать маркер в соответствии с текущим местоположением пользователей.добавление секундомера к коду, идущему параллельно основному потоку в android
Here is the code I have written so far
package com.example.kanchan.runner7;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.support.*;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.drive.Drive;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.*;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.Polyline;
import com.google.android.gms.maps.model.PolylineOptions;
import com.google.android.gms.plus.Plus;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.concurrent.TimeUnit;
import java.util.logging.Handler;
//1
public class HomeScreen extends FragmentActivity//,GoogleApiClient.ConnectionCallbacks,GoogleApiClient.OnConnectionFailedListener
implements View.OnClickListener,
LocationListener {
private Button buttonstart;
private Button buttonreset;
private GoogleMap mMap;
protected LocationManager locationManager;
protected LocationListener locationListener;
private List<LatLng> routePoints ;
private Marker TP;
private Marker TP1;
private Polyline route1;
private Location loc;
private TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.d("Kimi","onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home_screen);
buttonstart = (Button)findViewById(R.id.button1);
buttonstart.setOnClickListener(this);
buttonreset = (Button)findViewById(R.id.button2);
buttonreset.setOnClickListener(this);
tv = (TextView)findViewById(R.id.timer);
setUpMapIfNeeded();
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
routePoints = new ArrayList<LatLng>();
//route1 = new Polyline();
// TP= new MarkerOptions().position((new LatLng(0,0)));
loc = new Location(LocationManager.GPS_PROVIDER);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_home_screen, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button1:
buttonstartclick();
break;
}
}
private void buttonstartclick() {
Log.d("Kimi..","kimi start button clicked");
mMap.clear();
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(
new LatLng(loc.getLatitude(), loc.getLongitude()), 14));
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(new LatLng(loc.getLatitude(), loc.getLongitude())) // Sets the center of the map to location user
.zoom(17) // Sets the zoom
.bearing(90) // Sets the orientation of the camera to east
.tilt(40) // Sets the tilt of the camera to 30 degrees
.build(); // Creates a CameraPosition from the builder
mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
stopwatch s = new stopwatch();
s.startThread();
while (true)
{
int[] curTime = s.getTime();
Log.d("Kimi result from time", Integer.toString(curTime[2]));
try {
Thread.sleep(2000);
} catch(InterruptedException e){}
tv.setText(Integer.toString(curTime[2]));
}
}
private void setUpMapIfNeeded() {
// Do a null check to confirm that we have not already instantiated the map.
if (mMap == null) {
// Try to obtain the map from the SupportMapFragment.
mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.mapView))
.getMap();
// Check if we were successful in obtaining the map.
if (mMap != null) {
setUpMap();
}
}
}
private void setUpMap() {
mMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
/* mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
TP = mMap.addMarker(new MarkerOptions().
position(new LatLng(0, 0)).title("TutorialsPoint"));*/
}
@Override
public void onLocationChanged(Location location) {
if(TP1 != null)
TP1.remove();
Log.d("Kimi..",Double.toString(location.getLatitude()));
Log.d("Kimi..",Double.toString(location.getLongitude()));
loc = location;
/* mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(
new LatLng(location.getLatitude(), location.getLongitude()), 13));
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(new LatLng(location.getLatitude(), location.getLongitude())) // Sets the center of the map to location user
.zoom(17) // Sets the zoom
.bearing(90) // Sets the orientation of the camera to east
.tilt(40) // Sets the tilt of the camera to 30 degrees
.build(); // Creates a CameraPosition from the builder
mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
*/
TP = mMap.addMarker(new MarkerOptions().position(new LatLng(location.getLatitude(), location.getLongitude()))
.icon(BitmapDescriptorFactory.fromResource(R.drawable.red2)));
TP1 = mMap.addMarker(new MarkerOptions().position(new LatLng(location.getLatitude(), location.getLongitude())));
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.d("Kimi","status");
}
@Override
public void onProviderEnabled(String provider) {
Log.d("Kimi","enable");
}
@Override
public void onProviderDisabled(String provider) {
Log.d("Kimi","disable");
}
}
Этот код, кажется, работает хорошо, если в buttonstartclick() я удалить часть для секундомера (на самом деле раз, как это будет incremantal.stopwatch Class EXTENS Нить в моем коде). Камера фокусируется на текущем местонахождении пользователя и по мере перемещения пользователя маркеры размещаются на карте
Однако после написания кода таймера камера вообще перестает перемещаться по СТАРТ.
Также TextView таймера не обновляется со значениями таймера внутри время цикла, хотя из сообщений в журнале я вижу, что GetTime() метод возвращает правильное значение, которое должно быть upadted
этого времени цикл также делает похоже, не работает в параллельном основном потоке, потому что при изменении местоположения пользователя я не вижу новых маркеров, размещенных на карте.
Может кто-нибудь пожалуйста, предложить способ добавить секундомера функцию в мой код
Секундомер код:
public class stopwatch extends Thread
{
private long startTime;
private boolean started;
public void startThread()
{
this.startTime = System.currentTimeMillis();
this.started = true;
this.start();
}
public void run()
{
while (started)
{
// empty code since currentTimeMillis increases by itself
}
}
public int[] getTime()
{
long milliTime = System.currentTimeMillis() - this.startTime;
int[] out = new int[]{0, 0, 0, 0};
out[0] = (int)(milliTime/3600000 );
out[1] = (int)(milliTime/60000 ) % 60;
out[2] = (int)(milliTime/1000 ) % 60;
out[3] = (int)(milliTime) % 1000;
return out;
}
public void stopThread()
{
this.started = false;
}
}
Трудно сказать, не сказав ваш код секундомера, но у Android есть класс хронометров, который довольно проста в использовании и может служить вам хорошо. И если я могу, ваш класс секундомера должен начинаться с заглавной буквы, я думаю. – JDenais
добавил код секундомера –
Я думаю, что данный ответ правильный, за исключением совета по созданию внутреннего класса. Для меня ваш случай - это учебник, в котором образец Observer был бы идеальным. – JDenais