我正在为跑步者创建简单的位置/间隔训练应用程序。 在我的主要活动(MapsActivity)中,我正在创建我创建的另一个类的对象(GPSImplementation)。它正在获取当前位置并为跑步者计算一些东西(速度,行进距离等)。然后我创建了另一个活动“SettingsActivity”,用户可以在其中更改某些设置。在更改设置期间,我不想停止主要活动的数据收入(跑步者可以在训练期间更改某些选项,我不想重置数据,我希望在更改选项期间仍然可以收集它们,例如距离应该不断补充)。所以我想我会将我创建的类对象(gps)传递给另一个带有“Parcelable”方法的活动。当我添加它时,程序拒绝打开SettingsActivity。它会自动关闭并出现很多错误。我使用Parcelable错了吗?一开始的应用程序运行良好,它显示位置数据等。只有当我尝试输入设置(通过onSettingsClick方法)时,它才会崩溃。
MapsActivity(主要活动):
public class MapsActivity extends AppCompatActivity {
private TextView tvDistanceOverall;
private TextView tvTime;
private TextView tvTimeOverall;
private TextView tvSpeed;
private TextView tvSpeedOverall;
private GPSImplementation gps;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
gps = new GPSImplementation(this);
tvDistanceOverall = (TextView) findViewById(R.id.textViewDistance);
tvSpeed = (TextView) findViewById(R.id.textViewSpeed);
tvSpeedOverall = (TextView) findViewById(R.id.textViewSpeedOverall);
tvTime = (TextView) findViewById(R.id.textViewTime);
tvTimeOverall = (TextView) findViewById(R.id.textViewTimeOverall);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_menu, menu);
return true;
}
public void onExitClose(MenuItem item) {
System.exit(0);
}
public void onSettingsClick(MenuItem item) {
Intent settingsIntent = new Intent(this, SettingsActivity.class);
settingsIntent.putExtra("GPS", (Parcelable) gps);
startActivity(settingsIntent);
}
public void onProgramClick(MenuItem item) {
}
public void fillingData() {
tvDistanceOverall.setText("Overall Distance: " + Double.toString(gps.getOverallDistance()));
tvDistanceOverall.invalidate();
if (gps.getDistance() != 0 && gps.getTime() != 0) {
double tempo = gps.getTime() / gps.getDistance() * 100 / 6;
double speed = gps.getDistance() / gps.getTime() * 3.6;
gps.setOverallDistance(gps.getOverallDistance()+gps.getDistance());
tvSpeed.setText("Tempo: " + String.format("%.2f", tempo));
tvSpeed.invalidate();
tvSpeedOverall.setText("Speed km/h: " + String.format("%.2f", speed));
tvSpeedOverall.invalidate();
} else {
tvSpeed.setText("Tempo: 0,00");
tvSpeed.invalidate();
tvSpeedOverall.setText("Speed km/h: 0,00");
tvSpeedOverall.invalidate();
}
tvTime.setText("Time: " + Double.toString(gps.getTime()));
tvTime.invalidate();
tvTimeOverall.setText("Time Overall: " + Double.toString(gps.getTimeOverall()));
tvTimeOverall.invalidate();
}
@Override
public void onStart(){
gps.getmGoogleApiClient().connect();
super.onStart();
}
@Override
public void onResume(){
super.onResume();
fillingData();
}
SettingsActivity:
public class SettingsActivity extends AppCompatActivity {
private GPSImplementation gps;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent i = getIntent();
Parcelable myParcelableObject = i.getParcelableExtra("GPS");
gps = (GPSImplementation) myParcelableObject;
setContentView(R.layout.activity_settings);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_menu, menu);
return true;
}
public void onExitClose(MenuItem item) {
System.exit(0);
}
public void onSettingsClick(MenuItem item) {
}
public void onProgramClick(MenuItem item){
Intent programIntent = new Intent(this, MapsActivity.class);
startActivity(programIntent);
}
GPSImplementation(位置跟踪类):
public class GPSImplementation implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener, LocationListener {
private Context context;
private TextView tvDistanceOverall;
private TextView tvTime;
private TextView tvTimeOverall;
private TextView tvSpeed;
private TextView tvSpeedOverall;
private double startTime;
private double endTime;
private double overallDistance;
private double timeOverall;
private double distance;
private double time;
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;
private Location mLastLocation;
private Location myCurrentLocation;
private boolean mRequestingLocationUpdates;
public GPSImplementation(Context c) {
this.context=c;
mGoogleApiClient = new GoogleApiClient.Builder(context)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
timeOverall = overallDistance = distance = time = 0;
mRequestingLocationUpdates = true;
mLocationRequest = new LocationRequest();
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setInterval(3000);
mLocationRequest.setFastestInterval(1000);
tvDistanceOverall = (TextView) ((Activity)context).findViewById(R.id.textViewDistance);
tvSpeed = (TextView) ((Activity)context).findViewById(R.id.textViewSpeed);
tvSpeedOverall = (TextView) ((Activity)context).findViewById(R.id.textViewSpeedOverall);
tvTime = (TextView) ((Activity)context).findViewById(R.id.textViewTime);
tvTimeOverall = (TextView) ((Activity)context).findViewById(R.id.textViewTimeOverall);
}
public Context getContext() {
return context;
}
public void setContext(Context context) {
this.context = context;
}
public double getStartTime() {
return startTime;
}
public void setStartTime(double startTime) {
this.startTime = startTime;
}
public double getEndTime() {
return endTime;
}
public void setEndTime(double endTime) {
this.endTime = endTime;
}
public double getOverallDistance() {
return overallDistance;
}
public void setOverallDistance(double overallDistance) {
this.overallDistance = overallDistance;
}
public double getTimeOverall() {
return timeOverall;
}
public void setTimeOverall(double timeOverall) {
this.timeOverall = timeOverall;
}
public double getDistance() {
return distance;
}
public void setDistance(double distance) {
this.distance = distance;
}
public double getTime() {
return time;
}
public void setTime(double time) {
this.time = time;
}
public GoogleApiClient getmGoogleApiClient() {
return mGoogleApiClient;
}
public void setmGoogleApiClient(GoogleApiClient mGoogleApiClient) {
this.mGoogleApiClient = mGoogleApiClient;
}
public LocationRequest getmLocationRequest() {
return mLocationRequest;
}
public void setmLocationRequest(LocationRequest mLocationRequest) {
this.mLocationRequest = mLocationRequest;
}
public Location getmLastLocation() {
return mLastLocation;
}
public void setmLastLocation(Location mLastLocation) {
this.mLastLocation = mLastLocation;
}
public Location getMyCurrentLocation() {
return myCurrentLocation;
}
public void setMyCurrentLocation(Location myCurrentLocation) {
this.myCurrentLocation = myCurrentLocation;
}
public boolean ismRequestingLocationUpdates() {
return mRequestingLocationUpdates;
}
public void setmRequestingLocationUpdates(boolean mRequestingLocationUpdates) {
this.mRequestingLocationUpdates = mRequestingLocationUpdates;
}
@Override
public void onLocationChanged(Location location) {
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
myCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
endTime = SystemClock.elapsedRealtime();
distance = getDistance(mLastLocation.getLatitude(), mLastLocation.getLongitude(), myCurrentLocation.getLatitude(), myCurrentLocation.getLongitude());
time = (endTime - startTime) / 1000;
startTime = endTime;
timeOverall += time;
mLastLocation = myCurrentLocation;
fillingData();
}
@Override
public void onConnected(@Nullable Bundle bundle) {
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
mGoogleApiClient);
if (mRequestingLocationUpdates) {
startTime = SystemClock.elapsedRealtime();
startLocationUpdates();
}
}
private void startLocationUpdates() {
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
private double 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 dist;
}
private void fillingData() {
tvDistanceOverall.setText("Overall Distance: " + Double.toString(overallDistance));
tvDistanceOverall.invalidate();
if (distance != 0 && time != 0) {
double tempo = time / distance * 100 / 6;
double speed = distance / time * 3.6;
overallDistance+=distance;
tvSpeed.setText("Tempo: " + String.format("%.2f", tempo));
tvSpeed.invalidate();
tvSpeedOverall.setText("Speed km/h: " + String.format("%.2f", speed));
tvSpeedOverall.invalidate();
} else {
tvSpeed.setText("Tempo: 0,00");
tvSpeed.invalidate();
tvSpeedOverall.setText("Speed km/h: 0,00");
tvSpeedOverall.invalidate();
}
tvTime.setText("Time: " + Double.toString(time));
tvTime.invalidate();
tvTimeOverall.setText("Time Overall: " + Double.toString(timeOverall));
tvTimeOverall.invalidate();
}
@Override
public void onConnectionSuspended(int i) {
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
}