您好,Stackoverflow社区,我是android新手,正在学习如何实现基于位置的服务。
我能够成功实现一个测速仪应用程序,该应用程序可以测量当前速度,总距离和总行驶时间。
现在,我想添加一个附加功能,即当速度增加40 km / h时,我将打开图片并使用前置摄像头拍照。
由于将位置作为单独的LocationService类提供,因此我对实现此方法感到困惑。我看了很多示例,但无法将其应用于我的代码。
我尝试使用Intent将速度变量传递回主要活动,但由于速度变量会不断变化,因此无法继续进行。
我还尝试为文本字段放置一个侦听器,以便可以对其进行监视,但是这样做效率极低。
这是我的MainActivity.java
package com.example.location;
public class MainActivity extends AppCompatActivity {
LocationService myService;
static boolean status;
LocationManager locationManager;
static TextView dist, time, speed, satellite;
Button start, pause, stop;
static long startTime, endTime;
static ImageView image,imageView;
static ProgressDialog locate;
static int p = 0;
private static final int REQUEST_CODE_PERMISSION = 2;
String mPermission = Manifest.permission.ACCESS_FINE_LOCATION;
private Uri file;
private ServiceConnection sc = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
LocationService.LocalBinder binder = (LocationService.LocalBinder) service;
myService = binder.getService();
status = true;
}
@Override
public void onServiceDisconnected(ComponentName name) {
status = false;
}
};
void bindService() {
if (status == true)
return;
Intent i = new Intent(getApplicationContext(), LocationService.class);
bindService(i, sc, BIND_AUTO_CREATE);
status = true;
startTime = System.currentTimeMillis();
}
void unbindService() {
if (status == false)
return;
Intent i = new Intent(getApplicationContext(), LocationService.class);
unbindService(sc);
status = false;
}
@Override
protected void onResume() {
super.onResume();
}
@Override
protected void onStart() {
super.onStart();
}
@Override
protected void onDestroy() {
super.onDestroy();
if (status == true)
unbindService();
}
@Override
public void onBackPressed() {
if (status == false)
super.onBackPressed();
else
moveTaskToBack(true);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dist = (TextView) findViewById(R.id.distancetext);
time = (TextView) findViewById(R.id.timetext);
speed = (TextView) findViewById(R.id.speedtext);
start = (Button) findViewById(R.id.start);
pause = (Button) findViewById(R.id.pause);
stop = (Button) findViewById(R.id.stop);
image = (ImageView) findViewById(R.id.image);
imageView = (ImageView)this.findViewById(R.id.imageView1);
start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//The method below checks if Location is enabled on device or not. If not, then an alert dialog box appears with option
//to enable gps.
if (checkGPS() == false){
requestGPS();
}
requestcamera();
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
return;
}
if (status == false)
//Here, the Location Service gets bound and the GPS Speedometer gets Active.
bindService();
locate = new ProgressDialog(MainActivity.this);
locate.setIndeterminate(true);
locate.setCancelable(false);
locate.setMessage("Getting Location...");
locate.show();
start.setVisibility(View.GONE);
pause.setVisibility(View.VISIBLE);
pause.setText("Pause");
stop.setVisibility(View.VISIBLE);
}
});
pause.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (pause.getText().toString().equalsIgnoreCase("pause")) {
pause.setText("Resume");
p = 1;
} else if (pause.getText().toString().equalsIgnoreCase("Resume")) {
if (checkGPS() == false){
requestGPS();
}
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
//Toast.makeText(this, "GPS is Enabled in your devide", Toast.LENGTH_SHORT).show();
return;
}
pause.setText("Pause");
p = 0;
}
}
});
stop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (status == true)
unbindService();
start.setVisibility(View.VISIBLE);
pause.setText("Pause");
pause.setVisibility(View.GONE);
stop.setVisibility(View.GONE);
p = 0;
}
});
}
private boolean checkGPS() {
int result = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION);
//If permission is granted returning true
if (result == PackageManager.PERMISSION_GRANTED)
return true;
//If permission is not granted returning false
return false;
}
private void requestcamera(){
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[] { Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE }, 0);
}
}
private void requestGPS() {
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_CODE_PERMISSION);
if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission
(MainActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_CODE_PERMISSION);
}
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
showGPSDisabledAlertToUser();
}
}
private void showGPSDisabledAlertToUser() {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setMessage("Enable GPS to use application")
.setCancelable(false)
.setPositiveButton("Enable GPS",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Intent callGPSSettingIntent = new Intent(
android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(callGPSSettingIntent);
}
});
alertDialogBuilder.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert = alertDialogBuilder.create();
alert.show();
}
}
这是我的LocationService.java
public class LocationService extends Service implements
LocationListener,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
private static final long INTERVAL = 1000 * 2;
private static final long FASTEST_INTERVAL = 1000 * 1;
LocationRequest mLocationRequest;
GoogleApiClient mGoogleApiClient;
Location mCurrentLocation, lStart, lEnd;
static double distance = 0;
double speed;
int data;
private static final int CAMERA_REQUEST = 1888;
private static final int MY_CAMERA_PERMISSION_CODE = 100;
private final IBinder mBinder = new LocalBinder();
@Nullable
@Override
public IBinder onBind(Intent intent) {
createLocationRequest();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
mGoogleApiClient.connect();
return mBinder;
}
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(INTERVAL);
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onConnected(Bundle bundle) {
try {
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
} catch (SecurityException e) {
}
}
protected void stopLocationUpdates() {
LocationServices.FusedLocationApi.removeLocationUpdates(
mGoogleApiClient, this);
distance = 0;
}
@Override
public void onConnectionSuspended(int i) {
}
@Override
public void onLocationChanged(Location location) {
MainActivity.locate.dismiss();
mCurrentLocation = location;
if (lStart == null) {
lStart = mCurrentLocation;
lEnd = mCurrentLocation;
} else
lEnd = mCurrentLocation;
//Calling the method below updates the live values of distance and speed to the TextViews.
speed = location.getSpeed() * 18 / 5;
updateUI();
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
public class LocalBinder extends Binder {
public LocationService getService() {
return LocationService.this;
}
}
//The live feed of Distance and Speed are being set in the method below .
private void updateUI() {
if (MainActivity.p == 0) {
distance = distance + (lStart.distanceTo(lEnd) / 1000.00);
MainActivity.endTime = System.currentTimeMillis();
long diff = MainActivity.endTime - MainActivity.startTime;
diff = TimeUnit.MILLISECONDS.toMinutes(diff);
MainActivity.time.setText("Total Time: " + diff + " minutes");
if (speed > 0.0)
MainActivity.speed.setText("Current speed: " + new DecimalFormat("#.##").format(speed) + " km/hr");
else
MainActivity.speed.setText(".......");
MainActivity.dist.setText(new DecimalFormat("#.###").format(distance) + " Km's.");
MainActivity.satellite.setText(" Satellites in use: "+ data);
lStart = lEnd;
}
}
@Override
public boolean onUnbind(Intent intent) {
stopLocationUpdates();
if (mGoogleApiClient.isConnected())
mGoogleApiClient.disconnect();
lStart = null;
lEnd = null;
distance = 0;
return super.onUnbind(intent);
}
}
任何想法都会受到赞赏。
答案 0 :(得分:1)
我认为您应该在IBinder
类中拥有Messenger
,Handler
,service
实例,以便能够通过Verce与activity
进行通信
我建议您阅读此博客以更好地理解。
https://medium.com/@ankit_aggarwal/ways-to-communicate-between-activity-and-service-6a8f07275297