我正在开发一个使用Google地图更新位置的应用程序。到目前为止,我只有一个问题,那就是获得精确的位置许可。 这是我的清单文件。
<uses-sdk
android:minSdkVersion="16"
android:targetSdkVersion="23" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<!-- Network State Permissions -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- <android:uses-permission android:name="android.permission.READ_PHONE_STATE" /> -->
<!-- <android:uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> -->
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="@string/google_maps_key" />
<activity
android:name=".MapsActivity"
android:label="@string/title_activity_maps" >
</activity>
<activity
android:name=".HelpMe"
android:label="@string/title_activity_help_me"
android:theme="@style/AppTheme" >
</activity>
<service
android:name=".MyLocationUpdate"
android:exported="false" >
</service>
</application>
这是我的IntentService,通过它我可以将控制传递给我的服务类。
public class MyLocationUpdate extends IntentService {
double latitude,longitude;
AppLogic app = new AppLogic();
HelpMe activity;
IETrackerDTO iedto= new IETrackerDTO();
public MyLocationUpdate() {
super("MyLocationUpdate");
}
@Override
protected void onHandleIntent(Intent intent) {
Log.d("Inside", "Intent Service");
/*IETrackerDTO ide = intent.getExtras().("currentUser");*/
ScheduledThreadPoolExecutor s = new ScheduledThreadPoolExecutor(1);
s.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
LocationFinder gps;
Log.d("Calling other service", "Calling other service");
gps = new LocationFinder(MyLocationUpdate.this);
latitude = gps.getLatitude();
longitude = gps.getLongitude();
Log.d("Location", latitude + " " + longitude);
updateLocation();
toast();
}
}, 0, 10, TimeUnit.SECONDS);
}
public void toast() {
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), "Lat: " + latitude + " long:" + longitude, Toast.LENGTH_SHORT).show();
}
});
}
这是我的Service类,可以及时更新用户的lat长度
public class LocationFinder extends Service implements LocationListener {
private final Context mContext;
static Class<? extends Context> activity;
// flag for GPS status
// boolean isGPSEnabled = false;
boolean canGetLocation = false;
// flag for network status
// boolean isNetworkEnabled = false;
// flag for GPS status
Location location; // location
double latitude; // latitude
double longitude; // longitude
// The minimum distance to change Updates in meters
boolean isGPSEnabled = false;
boolean isNetworkEnabled = false;
static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters
// The minimum time between updates in milliseconds
static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 1 minute
// Declaring a Location Manager
protected LocationManager locationManager;
public LocationFinder(Context context) {
Log.d("Inside constructor", "Inside Constructor");
this.mContext = context;
Log.d("After setting context", "After setting context");
getLocation();
}
public Location getLocation() {
Log.d("Inside getLocation", "Inside getLocation");
Log.d("Inside doInBackground", "Inside doInBackground");
try {
locationManager = (LocationManager) mContext
.getSystemService(LOCATION_SERVICE);
// getting GPS status
isGPSEnabled = locationManager
.isProviderEnabled(LocationManager.GPS_PROVIDER);
// getting network status
isNetworkEnabled = locationManager
.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!isGPSEnabled && !isNetworkEnabled) {
// no network provider is enabled
} else {
Log.d("Inside enabled", "Inside enabled");
this.canGetLocation = true;
if (isNetworkEnabled) {
Log.d("Inside networ enabled", "Inside network enabled");
if (locationManager != null) {
new Thread(){
public Handler mHandler;
public void run() {
Looper.prepare();
mHandler = new Handler()
{
public void handleMessage(Message msg) {
if (ActivityCompat.checkSelfPermission(mContext,Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && mContext.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// public void requestPermissions(@NonNull String[] permissions, int requestCode)
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for Activity#requestPermissions for more details.
return;
}
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, new LocationListener() {
@Override
public void onLocationChanged(Location location) {
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
});
}
};
Looper.loop();
}
}.start();
}/**/
/*locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, (LocationListener) this);*/
Log.d("Network", "Network");
if (locationManager != null) {
location = locationManager
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
// if GPS Enabled get lat/long using GPS Services
if (isGPSEnabled) {
Log.d("Inside gps enabled", "Inside gps enabled");
if (location == null) {
new Thread(){
public Handler mHandler;
public void run() {
Looper.prepare();
mHandler = new Handler()
{
public void handleMessage(Message msg) {
if (ActivityCompat.checkSelfPermission(mContext,Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && mContext.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// public void requestPermissions(@NonNull String[] permissions, int requestCode)
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for Activity#requestPermissions for more details.
return;
}
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, new LocationListener() {
@Override
public void onLocationChanged(Location location) {
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
});
}
};
Looper.loop();
}
}.start();
/* locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);*/
Log.d("GPS Enabled", "GPS Enabled");
if (locationManager != null) {
location = locationManager
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return location;
}
/**
* Stop using GPS listener
* Calling this function will stop using GPS in your app
* */
public void stopUsingGPS() {
if (locationManager != null) {
if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// public void requestPermissions(@NonNull String[] permissions, int requestCode)
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for Activity#requestPermissions for more details.
return;
}
locationManager.removeUpdates(LocationFinder.this);
}
}
/**
* Function to get latitude
* */
public double getLatitude(){
if(location != null){
latitude = location.getLatitude();
}
// return latitude
return latitude;
}
/**
* Function to get longitude
* */
public double getLongitude(){
if(location != null){
longitude = location.getLongitude();
}
// return longitude
return longitude;
}
/**
* Function to check GPS/wifi enabled
* @return boolean
* */
public boolean canGetLocation() {
return this.canGetLocation;
}
/**
* Function to show settings alert dialog
* On pressing Settings button will lauch Settings Options
* */
public void showSettingsAlert(){
AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);
// Setting Dialog Title
alertDialog.setTitle("GPS is settings");
// Setting Dialog Message
alertDialog.setMessage("GPS is not enabled. Do you want to go to settings menu?");
// On pressing Settings button
alertDialog.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
mContext.startActivity(intent);
}
});
// on pressing cancel button
alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
// Showing Alert Message
alertDialog.show();
}
@Override
public void onLocationChanged(Location location) {
getLocation();
}
@Override
public void onProviderDisabled(String provider) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public IBinder onBind(Intent arg0) {
return null;
}
}
除了编译器要求位置权限而没有控件没有传递给服务类方法的事实外,一切运行得很好
这是我的logcat
02-11 11:05:56.980 2114-2779/com.mindtree.igxbridge.getuseraddress D/Calling other service﹕ Calling other service
02-11 11:05:56.980 2114-2779/com.mindtree.igxbridge.getuseraddress D/Inside constructor﹕ Inside Constructor
02-11 11:05:56.980 2114-2779/com.mindtree.igxbridge.getuseraddress D/After setting context﹕ After setting context
02-11 11:05:56.980 2114-2779/com.mindtree.igxbridge.getuseraddress D/Inside getLocation﹕ Inside getLocation
02-11 11:05:56.980 2114-2779/com.mindtree.igxbridge.getuseraddress D/Inside doInBackground﹕ Inside doInBackground
02-11 11:05:56.980 2114-2779/com.mindtree.igxbridge.getuseraddress D/Inside enabled﹕ Inside enabled
02-11 11:05:56.980 2114-2779/com.mindtree.igxbridge.getuseraddress D/Inside gps enabled﹕ Inside gps enabled
02-11 11:05:56.980 2114-2779/com.mindtree.igxbridge.getuseraddress D/GPS Enabled﹕ GPS Enabled
02-11 11:05:56.980 2114-2779/com.mindtree.igxbridge.getuseraddress W/System.err﹕ java.lang.SecurityException: "gps" location provider requires ACCESS_FINE_LOCATION permission.
02-11 11:05:56.980 2114-2779/com.mindtree.igxbridge.getuseraddress W/System.err﹕ at android.os.Parcel.readException(Parcel.java:1599)
02-11 11:05:56.980 2114-2779/com.mindtree.igxbridge.getuseraddress W/System.err﹕ at android.os.Parcel.readException(Parcel.java:1552)
02-11 11:05:56.980 2114-2779/com.mindtree.igxbridge.getuseraddress W/System.err﹕ at android.location.ILocationManager$Stub$Proxy.getLastLocation(ILocationManager.java:717)
02-11 11:05:56.980 2114-2779/com.mindtree.igxbridge.getuseraddress W/System.err﹕ at android.location.LocationManager.getLastKnownLocation(LocationManager.java:1200)
02-11 11:05:56.980 2114-2779/com.mindtree.igxbridge.getuseraddress W/System.err﹕ at com.mindtree.igxbridge.getuseraddress.LocationFinder.getLocation(LocationFinder.java:206)
02-11 11:05:56.980 2114-2779/com.mindtree.igxbridge.getuseraddress W/System.err﹕ at com.mindtree.igxbridge.getuseraddress.LocationFinder.<init>(LocationFinder.java:59)
02-11 11:05:56.980 2114-2779/com.mindtree.igxbridge.getuseraddress W/System.err﹕ at com.mindtree.igxbridge.getuseraddress.MyLocationUpdate$1.run(MyLocationUpdate.java:56)
02-11 11:05:56.980 2114-2779/com.mindtree.igxbridge.getuseraddress W/System.err﹕ at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:423)
02-11 11:05:56.980 2114-2779/com.mindtree.igxbridge.getuseraddress W/System.err﹕ at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:278)
02-11 11:05:56.980 2114-2779/com.mindtree.igxbridge.getuseraddress W/System.err﹕ at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:270)
02-11 11:05:56.980 2114-2779/com.mindtree.igxbridge.getuseraddress W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
02-11 11:05:56.980 2114-2779/com.mindtree.igxbridge.getuseraddress W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
02-11 11:05:56.980 2114-2779/com.mindtree.igxbridge.getuseraddress W/System.err﹕ at java.lang.Thread.run(Thread.java:818)
02-11 11:05:56.980 2114-2779/com.mindtree.igxbridge.getuseraddress D/Location﹕ 0.0 0.0
02-11 11:05:56.980 2114-2779/com.mindtree.igxbridge.getuseraddress D/Inside updateLocatiion﹕ Inside UpdateLocation
02-11 11:05:57.050 2114-2131/com.mindtree.igxbridge.getuseraddress W/EGL_emulation﹕ eglSurfaceAttrib not implemented
02-11 11:05:57.050 2114-2131/com.mindtree.igxbridge.getuseraddress W/OpenGLRenderer﹕ Failed to set EGL_SWAP_BEHAVIOR on surface 0x7f4e5aaabf40, error=EGL_SUCCESS
02-11 11:05:59.000 2114-2131/com.mindtree.igxbridge.getuseraddress E/Surface﹕ getSlotFromBufferLocked: unknown buffer: 0x7f4e5a8b93f0
答案 0 :(得分:0)
简短的回答是你需要清单中的清单块
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.mycompany"
android:versionCode="1"
android:versionName="1.0" >
包名必须是唯一的,因此按照惯例,您拥有的后向域名。这有助于将您识别为供应商,并授予对具有相同包名称(或供应商ID,如果您愿意)的任何服务,其他活动,应用程序,等等的访问权限。由于android是个人设备,因此没有用户授予权限。此外还列出了任何外国特权 uses-permission android:name =&#34; android.permission.ACCESS_FINE_LOCATION&#34; 将被授予供应商,假设他们被用户/运营商接受。