我正在编写一个跟踪跑步距离的跑步/健身应用程序。它在Android Studio中看起来很好,但在运行应用程序时会出现一些错误。这是代码:
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener, LocationListener {
private GoogleMap mMap;
private GoogleApiClient mGoogleApiClient;
public static final String TAG = "FitnessApp";
private LocationRequest mLocationRequest;
public LatLng latLng, latLngStart;
public Pair pair;
Handler Handler = new Handler();
private long startTime, elapsedTime;
private final int REFRESH_RATE = 100;
private String hours, minutes, seconds;
private long secs, mins, hrs;
private boolean stopped = false;
public int dist;
public int Speed;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mLocationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(10 * 1000) // 10 seconds, in milliseconds
.setFastestInterval(1 * 1000); // 1 second, in milliseconds
}
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
latLng = new LatLng (1.3263, 103.8026);
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
mMap.animateCamera(CameraUpdateFactory.zoomTo(11));
}
@Override
public void onConnected(@Nullable Bundle bundle) {
Log.i(TAG, "Location services connected.");
Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (location == null) {
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
} else {
handleNewLocation(location);
}
}
@Override
public void onConnectionSuspended(int i) {
Log.i(TAG, "Location services suspended. Please reconnect.");
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
if (connectionResult.hasResolution()) {
try {
// Start an Activity that tries to resolve the error
connectionResult.startResolutionForResult(this, CAUSE_SERVICE_DISCONNECTED);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
} else {
Log.i(TAG, "Location services connection failed with code " + connectionResult.getErrorCode());
}
}
@Override
protected void onResume() {
super.onResume();
mGoogleApiClient.connect();
}
@Override
protected void onPause() {
super.onPause();
if (mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
mGoogleApiClient.disconnect();
}
}
@Override
public void onLocationChanged(Location location) {
handleNewLocation(location);
}
public LatLng handleNewLocation(Location location) {
Log.d(TAG, location.toString());
double currentLatitude = location.getLatitude();
double currentLongitude = location.getLongitude();
latLng = new LatLng(currentLatitude,currentLongitude);
MarkerOptions options = new MarkerOptions()
.position(latLng)
.title("You are here!");
options.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA));
mMap.addMarker(options);
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
mMap.animateCamera(CameraUpdateFactory.zoomTo(11));
return latLng;
}
public void startClick(View view) {
showStopButton();
if(stopped){
startTime = System.currentTimeMillis() - elapsedTime;
}
else{
startTime = System.currentTimeMillis();
}
Handler.removeCallbacks(startTimer);
Handler.postDelayed(startTimer, 0);
h1.removeCallbacks(startCalorieTracker);
h1.postDelayed(startCalorieTracker,0);
latLngStart = new LatLng (latLng.latitude,latLng.longitude);
}
public void stopClick(View view) {
Double lat1 = latLngStart.latitude;
Double lon1 = latLngStart.longitude;
Double lat2 = latLng.latitude;
Double lon2 = latLng.longitude;
getDistance(lat1, lon1, lat2, lon2);
hideStopButton();
Handler.removeCallbacks(startTimer);
h1.removeCallbacks(startCalorieTracker);
stopped = true;
((TextView)findViewById(R.id.distance)).setText(dist);
if (hrs > 0 || mins > 0 || secs >0) {
Speed = dist/(Integer.parseInt(hours)+(Integer.parseInt(minutes)/60)+(Integer.parseInt(seconds)/3600));
((TextView)findViewById(R.id.speed)).setText(Speed + "km/h");
}
else {
((TextView)findViewById(R.id.speed)).setText("0 km/h");
}
}
public void resetClick(View view) {
stopped = false;
((TextView)findViewById(R.id.time)).setText("00:00:00");
((TextView)findViewById(R.id.distance)).setText("0 km");
((TextView)findViewById(R.id.speed)).setText("0 km/h");
((TextView)findViewById(R.id.calories)).setText("0 Cal");
}
public int getDistance(double lat1, double lon1, double lat2, double lon2) {
double latA = Math.toRadians(lat1);
double lonA = Math.toRadians(lon1);
double latB = Math.toRadians(lat2);
double lonB = Math.toRadians(lon2);
double cosAng = (Math.cos(latA) * Math.cos(latB) * Math.cos(lonB - lonA)) +
(Math.sin(latA) * Math.sin(latB));
double ang = Math.acos(cosAng);
double dist = ang * 6371;
return (int) dist;
}
private void showStopButton(){
findViewById(R.id.buttonStart).setVisibility(View.GONE);
findViewById(R.id.buttonReset).setVisibility(View.GONE);
findViewById(R.id.buttonStop).setVisibility(View.VISIBLE);
}
private void hideStopButton(){
findViewById(R.id.buttonStart).setVisibility(View.VISIBLE);
findViewById(R.id.buttonReset).setVisibility(View.VISIBLE);
findViewById(R.id.buttonStop).setVisibility(View.GONE);
}
//Timer
private Runnable startTimer = new Runnable() {
public void run() {
elapsedTime = System.currentTimeMillis() - startTime;
updateTimer(elapsedTime);
Handler.postDelayed(this,REFRESH_RATE);
}
};
private void updateTimer (float time){
secs = (long)(time/1000);
mins = (long)((time/1000)/60);
hrs = (long)(((time/1000)/60)/60);
secs = secs % 60;
seconds=String.valueOf(secs);
if(secs == 0){
seconds = "00";
}
if(secs <10 && secs > 0){
seconds = "0"+seconds;
}
mins = mins % 60;
minutes=String.valueOf(mins);
if(mins == 0){
minutes = "00";
}
if(mins <10 && mins > 0){
minutes = "0"+minutes;
}
hours=String.valueOf(hrs);
if(hrs == 0){
hours = "00";
}
if(hrs <10 && hrs > 0){
hours = "0"+hours;
}
((TextView)findViewById(R.id.time)).setText(hours + ":" + minutes + ":" + seconds);
}
public Handler h1= new Handler ();
public Runnable startCalorieTracker = new Runnable () {
@Override
public void run() {
h1.postDelayed(this, REFRESH_RATE);
int CaloriesBurnt = dist*85;
((TextView)findViewById(R.id.calories)).setText(CaloriesBurnt + "Cal");
}
};
我得到的错误:
FATAL EXCEPTION: main
Process: rainbow.com.fitnessapp3, PID: 3268
java.lang.IllegalStateException: Could not execute method for android:onClick
at android.view.View$DeclaredOnClickListener.onClick(View.java:4452)
at android.view.View.performClick(View.java:5198)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at android.view.View$DeclaredOnClickListener.onClick(View.java:4447)
at android.view.View.performClick(View.java:5198)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: android.content.res.Resources$NotFoundException: String resource ID #0x0
at android.content.res.Resources.getText(Resources.java:312)
at android.widget.TextView.setText(TextView.java:4417)
at rainbow.com.fitnessapp3.MapsActivity.stopClick(MapsActivity.java:175)
at java.lang.reflect.Method.invoke(Native Method)
at android.view.View$DeclaredOnClickListener.onClick(View.java:4447)
at android.view.View.performClick(View.java:5198)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
我认为问题在于以下几行代码:
public void startClick(View view) {
showStopButton();
if(stopped){
startTime = System.currentTimeMillis() - elapsedTime;
}
else{
startTime = System.currentTimeMillis();
}
Handler.removeCallbacks(startTimer);
Handler.postDelayed(startTimer, 0);
h1.removeCallbacks(startCalorieTracker);
h1.postDelayed(startCalorieTracker,0);
latLngStart = new LatLng (latLng.latitude,latLng.longitude);
}
public void stopClick(View view) {
Double lat1 = latLngStart.latitude;
Double lon1 = latLngStart.longitude;
Double lat2 = latLng.latitude;
Double lon2 = latLng.longitude;
getDistance(lat1, lon1, lat2, lon2);
hideStopButton();
Handler.removeCallbacks(startTimer);
h1.removeCallbacks(startCalorieTracker);
stopped = true;
((TextView)findViewById(R.id.distance)).setText(dist);
if (hrs > 0 || mins > 0 || secs >0) {
Speed = dist/(Integer.parseInt(hours)+(Integer.parseInt(minutes)/60)+(Integer.parseInt(seconds)/3600));
((TextView)findViewById(R.id.speed)).setText(Speed + "km/h");
}
else {
((TextView)findViewById(R.id.speed)).setText("0 km/h");
}
}
答案 0 :(得分:1)
问题在于:
public void handleNewLocation(位置位置)
您的方法无效,因此,在执行时不会返回任何值。
最简单的解决方案是使用 Pair 对象,返回两个值,如下所示:
public Pair<String, String> handleNewLocation(Location location){
//do your thing here
[...]
Pair<String, String> pair = new Pair<>();
pair.first = Double.toString(currentLatitude);
pair.second = Double.toString(currentLongitude);
return pair;
}
然后,当您需要使用该方法时,请使用它:
Pair pair = handleNewLocation(Location location);
String firstValue = pair.first; //THIS IS THE FIRST VALUE
String secondValue = pair.second; //THIS IS THE SECOND VALUE
另一种方法是创建一个自定义对象,一个&#34; POJO&#34;,它将保存您的值。查看如何创建POJO,它是有趣的,有用的,并且很好地了解您是否想要进入Java编程。
另请注意,您不应该制作自己的方法&#34; public&#34;除非你需要。如果您只在写入的类中使用该方法,则可以将其设置为“私有”#34;。这是一个很好的做法,以确保您的应用程序是安全和受保护的。