我想在收到短信时使用后台服务和接收器自动发送位置。 İ认为该服务可以获取位置,但是我没有成功。 Iam初学者android开发人员,所以我需要您的帮助
我在github中找到的服务类:
公共类LocationUpdatesService扩展了服务{
private static final String PACKAGE_NAME ="com.contacttofile.smslocation.service";
private static final String TAG = LocationUpdatesService.class.getSimpleName();
private static final String CHANNEL_ID = "channel_01";
public static final String ACTION_BROADCAST = PACKAGE_NAME + ".broadcast";
public static final String EXTRA_LOCATION = PACKAGE_NAME + ".location";
public static final String EXTRA_STARTED_FROM_NOTIFICATION = PACKAGE_NAME + ".started_from_notification";
public final IBinder mBinder = new LocalBinder();
/**
* The desired interval for location updates. Inexact. Updates may be more or less frequent.
*/
private static final long UPDATE_INTERVAL_IN_MILLISECONDS = 10000;
/**
* The fastest rate for active location updates. Updates will never be more frequent
* than this value.
*/
private static final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS =
UPDATE_INTERVAL_IN_MILLISECONDS / 2;
/**
* The identifier for the notification displayed for the foreground service.
*/
private static final int NOTIFICATION_ID = 12345678;
private boolean mChangingConfiguration = false;
private NotificationManager mNotificationManager;
/**
* Contains parameters used by {@link com.google.android.gms.location.FusedLocationProviderApi}.
*/
private LocationRequest mLocationRequest;
/**
* Provides access to the Fused Location Provider API.
*/
private FusedLocationProviderClient mFusedLocationClient;
/**
* Callback for changes in location.
*/
private LocationCallback mLocationCallback;
private Handler mServiceHandler;
/**
* The current location.
*/
private Location mLocation;
public LocationUpdatesService() {
}
@Override
public void onCreate() {
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
mLocationCallback = new LocationCallback() {
@Override
public void onLocationResult(LocationResult locationResult) {
super.onLocationResult(locationResult);
onNewLocation(locationResult.getLastLocation());
}
};
createLocationRequest();
getLastLocation();
HandlerThread handlerThread = new HandlerThread(TAG);
handlerThread.start();
mServiceHandler = new Handler(handlerThread.getLooper());
mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
// Android O requires a Notification Channel.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = getString(R.string.app_name);
// Create the channel for the notification
NotificationChannel mChannel =
new NotificationChannel(CHANNEL_ID, name, NotificationManager.IMPORTANCE_DEFAULT);
// Set the Notification Channel for the Notification Manager.
mNotificationManager.createNotificationChannel(mChannel);
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "Service started");
boolean startedFromNotification = intent.getBooleanExtra(EXTRA_STARTED_FROM_NOTIFICATION,
false);
// We got here because the user decided to remove location updates from the notification.
if (startedFromNotification) {
removeLocationUpdates();
stopSelf();
}
// Tells the system to not try to recreate the service after it has been killed.
return START_NOT_STICKY;
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mChangingConfiguration = true;
}
@Override
public IBinder onBind(Intent intent) {
// Called when a client (MainActivity in case of this sample) comes to the foreground
// and binds with this service. The service should cease to be a foreground service
// when that happens.
Log.i(TAG, "in onBind()");
stopForeground(true);
mChangingConfiguration = false;
return mBinder;
}
@Override
public void onRebind(Intent intent) {
// Called when a client (MainActivity in case of this sample) returns to the foreground
// and binds once again with this service. The service should cease to be a foreground
// service when that happens.
Log.i(TAG, "in onRebind()");
stopForeground(true);
mChangingConfiguration = false;
super.onRebind(intent);
}
@Override
public boolean onUnbind(Intent intent) {
Log.i(TAG, "Last client unbound from service");
// Called when the last client (MainActivity in case of this sample) unbinds from this
// service. If this method is called due to a configuration change in MainActivity, we
// do nothing. Otherwise, we make this service a foreground service.
if (!mChangingConfiguration && Utils.requestingLocationUpdates(this)) {
Log.i(TAG, "Starting foreground service");
/*
// TODO(developer). If targeting O, use the following code.
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.O) {
mNotificationManager.startServiceInForeground(new Intent(this,
LocationUpdatesService.class), NOTIFICATION_ID, getNotification());
} else {
startForeground(NOTIFICATION_ID, getNotification());
}
*/
//startForeground(NOTIFICATION_ID, getNotification());
}
return true; // Ensures onRebind() is called when a client re-binds.
}
@Override
public void onDestroy() {
mServiceHandler.removeCallbacksAndMessages(null);
}
/**
* Makes a request for location updates. Note that in this sample we merely log the
* {@link SecurityException}.
*/
public void requestLocationUpdates() {
Log.i(TAG, "Requesting location updates");
Utils.setRequestingLocationUpdates(this, true);
startService(new Intent(getApplicationContext(), LocationUpdatesService.class));
try {
mFusedLocationClient.requestLocationUpdates(mLocationRequest,
mLocationCallback, Looper.myLooper());
} catch (SecurityException unlikely) {
Utils.setRequestingLocationUpdates(this, false);
Log.e(TAG, "Lost location permission. Could not request updates. " + unlikely);
}
}
/**
* Removes location updates. Note that in this sample we merely log the
* {@link SecurityException}.
*/
public void removeLocationUpdates() {
Log.i(TAG, "Removing location updates");
try {
mFusedLocationClient.removeLocationUpdates(mLocationCallback);
Utils.setRequestingLocationUpdates(this, false);
stopSelf();
} catch (SecurityException unlikely) {
Utils.setRequestingLocationUpdates(this, true);
Log.e(TAG, "Lost location permission. Could not remove updates. " + unlikely);
}
}
/**
* Returns the {@link NotificationCompat} used as part of the foreground service.
*/
public Notification getNotification() {
Intent intent = new Intent(this, LocationUpdatesService.class);
CharSequence text =Utils.getLocationText(mLocation);
// Extra to help us figure out if we arrived in onStartCommand via the notification or not.
intent.putExtra(EXTRA_STARTED_FROM_NOTIFICATION, true);
// The PendingIntent that leads to a call to onStartCommand() in this service.
PendingIntent servicePendingIntent = PendingIntent.getService(this, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
// The PendingIntent to launch activity.
PendingIntent activityPendingIntent = PendingIntent.getActivity(this, 0,
new Intent(this, MainActivity.class), 0);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.addAction(R.drawable.ic_delete, "launch",
activityPendingIntent)
.addAction(R.drawable.cast_ic_notification_small_icon,"removelocation update",
servicePendingIntent)
.setContentText(text)
.setContentTitle(Utils.getLocationTitle(this))
.setOngoing(true)
.setPriority(Notification.PRIORITY_HIGH)
.setSmallIcon(R.mipmap.ic_launcher)
.setTicker(text)
.setWhen(System.currentTimeMillis());
// Set the Channel ID for Android O.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
builder.setChannelId(CHANNEL_ID); // Channel ID
}
return builder.build();
}
public void getLastLocation() {
try {
mFusedLocationClient.getLastLocation()
.addOnCompleteListener(new OnCompleteListener<Location>() {
@Override
public void onComplete(@NonNull Task<Location> task) {
if (task.isSuccessful() && task.getResult() != null) {
mLocation = task.getResult();
} else {
Log.w(TAG, "Failed to get location.");
}
}
});
} catch (SecurityException unlikely) {
Log.e(TAG, "Lost location permission." + unlikely);
}
}
public void onNewLocation(Location location) {
Log.i(TAG, "New location: " + location);
mLocation = location;
// Notify anyone listening for broadcasts about the new location.
Intent intent = new Intent(ACTION_BROADCAST);
intent.putExtra(EXTRA_LOCATION, location);
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);
// Update notification content if running as a foreground service.
if (serviceIsRunningInForeground(this)) {
// mNotificationManager.notify(NOTIFICATION_ID, getNotification());
}
}
/**
* Sets the location request parameters.
*/
public void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
/**
* Class used for the client Binder. Since this service runs in the same process as its
* clients, we don't need to deal with IPC.
*/
public class LocalBinder extends Binder {
public LocationUpdatesService getService() {
return LocationUpdatesService.this;
}
}
/**
* Returns true if this is a foreground service.
*
* @param context The {@link Context}.
*/
public boolean serviceIsRunningInForeground(Context context) {
ActivityManager manager = (ActivityManager) context.getSystemService(
Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(
Integer.MAX_VALUE)) {
if (getClass().getName().equals(service.service.getClassName())) {
if (service.foreground) {
return true;
}
}
}
return false;
}
和我的接收者:
公共类SReceiver扩展了BroadcastReceiver {
Context mContext;
private String smsNumber;
private String smsMessage;
private String smsPersonName;
private kisiler_list[] kisilerLists;
private kisiler_list_DB db;
// Used in checking for runtime permissions.
private static final int REQUEST_PERMISSIONS_REQUEST_CODE = 34;
// The BroadcastReceiver used to listen from broadcasts from the service.
private SReceiver.MyReceiver myReceiver;
// A reference to the service used to get location updates.
private LocationUpdatesService mService = null;
// Tracks the bound state of the service.
private boolean mBound = false;
private static final String TAG = "SReceiver";
@Override
public void onReceive(Context context, Intent intent) {
// Used in checking for runtime permissions.
final int REQUEST_PERMISSIONS_REQUEST_CODE = 34;
// The BroadcastReceiver used to listen from broadcasts from the service.
SReceiver.MyReceiver myReceiver;
// A reference to the service used to get location updates.
LocationUpdatesService mService = null;
// Tracks the bound state of the service.
boolean mBound = false;
mContext = context;
//requestPermission();
Bundle bundle = intent.getExtras();
if (bundle != null) {
Object[] pdus = (Object[]) bundle.get("pdus");
for (Object pdu : pdus) {
SmsMessage sms = SmsMessage.createFromPdu((byte[]) pdu);
smsNumber = sms.getOriginatingAddress();
Uri lookupUri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(smsNumber));
Cursor cursor = context.getContentResolver().query(lookupUri, new String[]{ContactsContract.Data.DISPLAY_NAME},
null, null, null);
try {
cursor.moveToFirst();
smsPersonName = cursor.getString(0);
} catch (Exception e) {
e.printStackTrace();
} finally {
cursor.close();
}
}
}
//myReceiver = new SReceiver.MyReceiver();
//LocalBroadcastManager.getInstance(context).registerReceiver(myReceiver, new IntentFilter(LocationUpdatesService.ACTION_BROADCAST));
// context.bindService(new Intent(context, LocationUpdatesService.class), mServiceConnection, Context.BIND_AUTO_CREATE);
Intent service_intent=new Intent(context,LocationUpdatesService.class);
context.startService(service_intent);
IBinder binder = peekService(context, new Intent(context, LocationUpdatesService.class));
SmsManager smsManager = SmsManager.getDefault();
if(binder!=null){
mService=((LocationUpdatesService.LocalBinder)binder).getService();
if (!checkPermissions()) {
requestPermissions();
} else {
mService.requestLocationUpdates();
Location location = intent.getParcelableExtra(LocationUpdatesService.EXTRA_LOCATION);
smsManager.sendTextMessage(smsNumber, null, location.toString(),null, null);
if (location != null) {
String latitude=String.valueOf(location.getLatitude());
String longitude=String.valueOf(location.getLongitude());
Log.d(TAG, "onReceive: "+longitude+"-"+latitude);
smsManager.sendTextMessage(smsNumber, null, "longitude: "+longitude+"\nlatitude: "
+latitude,null, null);
Toast.makeText(mContext, Utils.getLocationText(location),
Toast.LENGTH_SHORT).show();
mService.removeLocationUpdates();
Intent stop_intent=new Intent(context,LocationUpdatesService.class);
context.stopService(stop_intent);
}
}
}
}
最终ServiceConnection mServiceConnection =新ServiceConnection(){
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
LocationUpdatesService.LocalBinder binder = (LocationUpdatesService.LocalBinder) service;
mService = binder.getService();
mBound = true;
}
@Override
public void onServiceDisconnected(ComponentName name) {
mService = null;
mBound = false;
}
};
private boolean checkPermissions() {
return PackageManager.PERMISSION_GRANTED == ActivityCompat.checkSelfPermission(mContext,
android.Manifest.permission.ACCESS_FINE_LOCATION);
}
private void requestPermissions() {
boolean shouldProvideRationale =
ActivityCompat.shouldShowRequestPermissionRationale((Activity)mContext,
android.Manifest.permission.ACCESS_FINE_LOCATION);
// Provide an additional rationale to the user. This would happen if the user denied the
// request previously, but didn't check the "Don't ask again" checkbox.
if (shouldProvideRationale) {
} else {
// Request permission. It's possible this can be auto answered if device policy
// sets the permission in a given state or the user denied the permission
// previously and checked "Never ask again".
ActivityCompat.requestPermissions((Activity) mContext,
new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION},
REQUEST_PERMISSIONS_REQUEST_CODE);
}
}
/**
* Callback received when a permissions request has been completed.
*/
private class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Location location = intent.getParcelableExtra(LocationUpdatesService.EXTRA_LOCATION);
if (location != null) {
String latitude=String.valueOf(location.getLatitude());
String longitude=String.valueOf(location.getLongitude());
Log.d(TAG, "onReceive: "+longitude+"-"+latitude);
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(smsNumber, null, "longitude: "+longitude+"\nlatitude: "
+latitude,null, null);
Toast.makeText(mContext, Utils.getLocationText(location),
Toast.LENGTH_SHORT).show();
mService.removeLocationUpdates();
}
}
}
}