我正在创建一个跑步应用程序,用户可以在其中跟踪他的跑步时间和路线。在点击START时,相机应该聚焦到当前位置,计时器文本视图应该开始更新,经过的时间是秒。此外,随着用户的移动,google地图应该开始根据用户的当前位置绘制标记。
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类的扩展线程),这段代码似乎工作得很好。照相机聚焦到当前用户位置,当用户移动时,标记将放置在地图上
然而,在编写定时器代码后,相机在启动时完全停止移动。
此外,计时器文本视图不会使用while循环中的计时器值进行更新,尽管从日志中的消息可以看出,getTime()方法返回了应该向上添加的正确值
while循环似乎也没有在并行主线程中运行,因为在用户位置更改时,我看不到新的标记被放置在地图上。
有没有人可以建议一下如何在我的代码中添加秒表功能
秒表代码:
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;
}
}发布于 2015-04-17 07:46:03
我浏览了一下代码,但似乎你的秒表实现并不存在
但是,当您单击start按钮时,每次都会初始化int的新实例,然后调用这个不祥的start thread方法
然后进入一个在主线程上运行的无限循环,实际上是在没有if子句的情况下阻塞其他操作,顺便说一句,每次一个新的int数组用回调gettime ()填充它时,也会进行初始化。
这不应该在UI线程上处理,而应该在单独的线程中处理,可能是内部类线程,这样您就可以轻松地访问activity类的成员和方法
你的应用程序应该只是冻结,等待你的while循环结束,这就是为什么没有绘制,没有更新,等等
由于您的实现,您的文本视图将会更新,但根本不会绘制
发布于 2015-04-17 09:06:59
好的,开始:(我没有看到代码按钮) delTime是经过的时间oldTime是开始时间tv是文本视图的引用
public void run ()
{
oldTime=System.cur...;
while (running)
{
setDeltaTime (); //computes the time went by.
int hours=(int)(delTime/3600000);
int minutes=(int)((delTime-hours*3600000)/60000);
int seconds=(int)((delTime-hours*3600000- minutes*6000)/1000);
String s="" +(hours <10?"0":"")
+hours
+":"
+(minutes<10?"0":"")
+minutes
+":"
+(second <10?"0":"")
+seconds;
tv.setText (s);
relax ()//give the thread some relaxation (sleep ());
}
}因此,您可以将文本视图更新为00:00:00格式,并且它已脱离UI线程...这样你就不会阻止它了
(我知道你也想要mills,然后扩展这个example...and,不需要创建返回数组的方法,也不需要布尔值来检查线程是否正在运行,因为线程类对它有一个回调...isAlive ()...and在线程启动之前设置它并不好实际上在start ()时可能已经抛出了运行时异常,也许try catch也是合适的)
https://stackoverflow.com/questions/29687616
复制相似问题