我正在尝试确定Android用户是否与预定位置列表非常接近.我想用最少量的手机电池消耗来做到这一点.我看到实现此目的的两种机制是接近警报和请求位置更新.这两种方法的优点和缺点是什么?一个人对电池的影响会小于另一个吗?在任何一种情况下,我都会猜测所使用的特定位置管理器会影响功耗(现有的Stack Overflow应答).
我正在构建一个需要用户位置的应用程序.我正在关注此处的Android培训文档,其中说:
shouldShowRequestPermissionRationale返回布尔值,指示我们是否应该显示具有请求权限的理由的UI(危险权限,ACCESS_FINE_LOCATION)
现在在这段代码中(取自文档本身):
if (ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
Manifest.permission.READ_CONTACTS)) {
// Show an explanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(thisActivity,
new String[]{Manifest.permission.READ_CONTACTS},
MY_PERMISSIONS_REQUEST_READ_CONTACTS);
// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
// app-defined int constant. The callback …Run Code Online (Sandbox Code Playgroud) 假设我想构建一个应用程序,它定期请求当前位置(例如,每 10 分钟一次,这个数字应该是可配置的)并提交到服务器。
我知道对于这种情况通常建议使用 Foreground Service 和 WorkManager。然而哪个更适合呢?以下是我的想法和疑问。
WorkManager - 主要用于可延迟的后台工作,其执行是有保证的。但我知道从 Android 8 (API 26) 开始引入了后台位置,并且限制位置每小时只能更新几次https://developer.android.com/about/versions/oreo/background-location-limits。因此,这可能不符合定期更新的要求。
ForegroundService - 非常适合运行并需要让用户意识到的东西。出于隐私目的,建议这种情况(位置跟踪)使用。Google 还创建了一个示例应用程序来推广这种做法https://github.com/android/location-samples/tree/master/LocationUpdatesForegroundService。
从上面的分析来看,似乎ForegroundService是这样的。但是我还发现它WorkManager具有内置支持,可ForegroundService通过androidx.work.impl.foreground.SystemForegroundService https://developer.android.com/topic/libraries/architecture/workmanager/advanced/long-running#long-running-kotlin结合使用 Worker
这让我很困惑,不知道我应该使用什么,以及谷歌针对这个特定场景真正推荐的是什么。
有人有什么想法吗?
android android-location foreground-service android-architecture-components android-workmanager
我需要找到从一个地方到另一个地方的估计开车时间.我有两个地方的纬度和经度,但我不知道该怎么做.是否有任何API.帮助谢谢.
我需要使用共享意图活动从我的应用程序共享位置,我已经通过一些示例并知道如何实现共享意图.但是我被困在setType.我需要我的应用程序在地图上共享位置详细信息以及用户位置.
顺便说一句,我用一个非常相似的问题复制用户代码"没有冒犯"
任何帮助将非常感谢.
Intent intent1 = new Intent(Intent.ACTION_SEND);
intent1.setType("text/plain");
intent1.putExtra(Intent.EXTRA_TEXT, "The status update text");
startActivity(Intent.createChooser(intent1, "Select prefered Service"));
Run Code Online (Sandbox Code Playgroud) 我使用distanceBetween()Location类来计算两点之间的距离,如下所示:
private float getDistanceInMiles(GeoPoint p1, GeoPoint p2) {
double lat1 = ((double)p1.getLatitudeE6()) / 1e6;
double lng1 = ((double)p1.getLongitudeE6()) / 1e6;
double lat2 = ((double)p2.getLatitudeE6()) / 1e6;
double lng2 = ((double)p2.getLongitudeE6()) / 1e6;
float [] dist = new float[1];
Log.i("destination coordinates", "Latitude:" + lat2 + ", Longitude: " + lng2);
Location.distanceBetween(lat1, lng1, lat2, lng2, dist);
return dist[0] * 0.000621371192f;
}
Run Code Online (Sandbox Code Playgroud)
文档说distanceBetween()"计算两个位置之间的近似距离,以及它们之间最短路径的初始和最终方位." 但是,distanceBetween()和真实GPS设备或Google Navigation应用程序返回的结果之间的差异非常大.例如,我的方法将返回6.2英里,而谷歌地图显示相同位置10英里.我仔细检查起点p1和终点p2的坐标,它们似乎是正确的.这是distanceBetween()方法的工作原理还是我做错了什么?顺便说一下,有没有办法使用Google Place API来检索距离作为JSON响应?
Google地图计算的距离:6.1英里

结果
Location.distanceBetween(41.742964, -87.995971, 41.811511, -87.967923, dist) is
Run Code Online (Sandbox Code Playgroud)
4.947700
我希望在用户启用或禁用网络或GPS位置时收到通知,重要的是我希望知道他们更改了哪个以及如何更改.我有android.location.PROVIDERS_CHANGED广播意图的广播接收器,这是接收正确的广播.
我现在需要尝试确定发生了哪个操作,即启用或禁用以及哪个提供程序已更改.我知道我可以保持每个提供商的状态,然后当我收到通知他们已经改变了然后我可以解决已经改变的事情,我正在寻找一个更"标准"的方法来做到这一点.广播意图似乎没有任何额外内容来指示哪个提供商已更改.
这是我目前的代码.
public class LocationProviderChangedReceiver extends BroadcastReceiver {
private final static String TAG = "LocationProviderChangedReceiver";
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().matches("android.location.PROVIDERS_CHANGED"))
{
Log.i(TAG,"Location Providers changed");
Bundle bundle = intent.getExtras();
if (bundle == null) {
Log.d(TAG, "No extras data");
} else {
Log.d(TAG, "Bundle received of size " + bundle.size);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是我Manifest的一个小摘录
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<receiver
android:name=".LocationProviderChangedReceiver"
android:exported="false">
<intent-filter>
<action android:name="android.location.PROVIDERS_CHANGED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
Run Code Online (Sandbox Code Playgroud)
如果广播中有额外的内容声明哪个提供商已更改以及是否已启用或禁用,那么这将是完美的.不幸的是,这种情况并非如此.是否有人知道我可以通过哪种机制来确定哪些状态已经改变而不维护我自己的状态变量. …
我将应用程序设置为每5秒获取一次位置通知.
mLocationRequest = LocationRequest.create();
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setInterval(5000);
mLocationRequest.setFastestInterval(5000/6);
myLocationReq.requestLocationUpdates(mLocationRequest
Run Code Online (Sandbox Code Playgroud)
所以 - 每隔5秒,就会调用onLocationChanged.这工作正常.
现在我想将间隔改为1秒,而不是打电话
requestLocationUpdates
Run Code Online (Sandbox Code Playgroud)
如何才能做到这一点?
我知道以前曾问过类似的问题,但答案并不完美.
我使用Android开发者网站的示例代码创建了一个使用地理围栏的应用程序.我没有使用任何共享首选项来存储地理围栏,因为我没有删除地理围栏.我正在地理围栏中测试应用程序,但我的智能手机每次应用程序运行时都会收到通知,并且在应用程序被杀死时没有观察到任何通知.为什么会这样?我想即使应用程序被杀,我也应该收到通知.
主要活动
public class MainActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.drawer_layout);
.....
GeofencingTask myTask = new GeofencingTask();
myTask.execute();
}
private class GeofencingTask extends AsyncTask<String,Void,String> implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
@Override
protected void onPreExecute() {
}
@Override
protected String doInBackground(String... params) {
mGoogleApiClient = new GoogleApiClient.Builder(MainActivity.this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();
mGeofenceList = new ArrayList<Geofence>();
mGeofenceList.add(new Geofence.Builder()
.setRequestId("1")
.setCircularRegion(
Constants.MyAPP_LOCATION_LATITUDE,
Constants.MyAPP_LOCATION_LONGITUDE,
Constants.MyAPP_RADIUS
)
.setExpirationDuration(Constants.GEOFENCE_EXPIRATION_TIME)
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER |
Geofence.GEOFENCE_TRANSITION_EXIT)
.build());
return null;
}
protected void onPostExecute(String s) { …Run Code Online (Sandbox Code Playgroud) 我需要从纬度和经度获得城市和州.Geocoder执行此功能以获得城市和州.但我java.io.IOException: grpc failed只在Android真实设备上收到错误.它在模拟器中运行良好.
new Geocoder(context).getFromLocation(latLng.latitude, latLng.longitude, 1).get(0);
Run Code Online (Sandbox Code Playgroud)
此外,我一直在使用Asynctask调用此函数,这是在另一篇文章中建议的Geocoder grpc在堆栈溢出失败,但对我没有任何作用.
我也重启了设备但仍然失败了.
需要帮助.提前致谢.
注意:我测试了Google Pixel XL,三星S6边缘,三星S4.
android google-maps latitude-longitude android-location google-geocoder
android ×10
android-location ×10
google-maps ×2
android-architecture-components ×1
battery ×1
distance ×1
geofencing ×1
geolocation ×1
proximity ×1