宁波建设网站多少钱,wordpress怎么改静态,外国企业网站模板免费下载,我的世界做视频封面的网站Github:https://github.com/MADMAX110/Odometer
一、使用位置服务
之前的Odometer应用是显示一个随机数#xff0c;现在要使用Android的位置服务返回走过的距离。 修改getDiatance方法使其返回走过的距离#xff0c;为此要用Android的位置服务。这些服务允许你得到用户的当…Github:https://github.com/MADMAX110/Odometer
一、使用位置服务
之前的Odometer应用是显示一个随机数现在要使用Android的位置服务返回走过的距离。 修改getDiatance方法使其返回走过的距离为此要用Android的位置服务。这些服务允许你得到用户的当前位置请求定期更新并在用户进入一个特定位置指定半径范围内时请求触发一个意图。 步骤 1、声明需要又使用位置服务的权限 2、创建服务时建立一个位置监听器 3、请求位置更新 4、计算走过的距离 5、在撤销服务之前删除位置更新
1、声明你需要的权限
Android默认地允许你完成很多动作不过有些动作需要的得到用户的许可才能完成。这可能是因为它们使用了用户的个人信息或者可能会影响存储的数据也可能会影响其他应用的工作。 位置服务就是需要得到用户授予应用权限才能使用的服务之一。 修改AndroidManifest.xml增加以下声明 分别是请求精确位置和模糊位置
?xml version1.0 encodingutf-8?
manifest xmlns:androidhttp://schemas.android.com/apk/res/androidxmlns:toolshttp://schemas.android.com/toolsuses-permission android:nameandroid.permission.ACCESS_FINE_LOCATION /uses-permission android:nameandroid.permission.ACCESS_COARSE_LOCATION/application......./application/manifest2、为OdometerService增加位置监听器
要实现LocationListener接口来创建位置监听器。 这个接口有4个方法需要你定义 onLocationChanged, onPreviderEnabled, onProviderDisabled, onStatusChanged。 要在第一次创建OdometerService时建立一个位置监听器所以要在OdometerService的onCreate方法中实现这个接口。 将下列代码加入OdometerService private LocationListener listener;Overridepublic void onCreate() {super.onCreate();listener new LocationListener() {Overridepublic void onLocationChanged(NonNull Location location) {}};}3、请求位置更新
要得到位置更新需要做三件事 创建一个位置管理器来访问Android的位置服务 指定一个位置提供器 请求这个位置提供者将用户当前位置的定期更新发送到我们在上一页增加的位置监听器。
创建位置管理器
要使用getSystemService方法来创建
locManager (LocationManager) getSystemService(Context.LOCALE_SERVICE);指定位置提供者
指定位置提供者用来确定用户的位置。有两个主要选项GPS和network。 GPS选项使用设备的GPS传感器确定用户的位置网络选项会利用Wifi、蓝牙或移动网络。 并不是所有设备都同时又这两类位置提供者所以可以使用位置管理器的getBestProvider方法得到设备上最准确的位置提供者这个方法有两个参数一个Criteria对象可以用来指定电量需求之类的标准以及一个标志指示当前是否应当在设备上启用。
String provider locManager.getBestProvider(new Criteria(), true);请求位置更新
要用位置管理器的requestLocationUpdates方法让位置提供者将更新发送到位置监听器。 这个方法有4个参数位置提供者、更新的最小时间间隔位置更新之间的最小距离你希望接收这些更新的位置监听器。
//检查是否有权限
if (ContextCompat.checkSelfPermission(this, PERMISSION_STRIMG) PackageManager.PERMISSION_GRANTED){String provider locManager.getBestProvider(new Criteria(), true);if (provider ! null)locManager.requestLocationUpdates(provider, 1000, 1, listener);}更新的OdometerService代码
package com.hafd.odometer;import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Binder;
import android.os.IBinder;import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import androidx.core.content.PackageManagerCompat;import java.util.Random;public class OdometerService extends Service {private final IBinder binder new OdometerBinder();private final Random random new Random();//创建一个绑定式服务时需要提供一个Binder实现public class OdometerBinder extends Binder {//活动将使用这个方法得到OdometerService的一个引用OdometerService getOdometer() {return OdometerService.this;}}Overridepublic IBinder onBind(Intent intent) {return binder;}public double getDistance() {return random.nextDouble();}private LocationListener listener;private LocationManager locManager;public static final String PERMISSION_STRIMG Manifest.permission.ACCESS_FINE_LOCATION;SuppressLint(ServiceCast)Overridepublic void onCreate() {super.onCreate();listener new LocationListener() {Overridepublic void onLocationChanged(NonNull Location location) {}};locManager (LocationManager) getSystemService(Context.LOCALE_SERVICE);if (ContextCompat.checkSelfPermission(this, PERMISSION_STRIMG) PackageManager.PERMISSION_GRANTED){String provider locManager.getBestProvider(new Criteria(), true);if (provider ! null)locManager.requestLocationUpdates(provider, 1000, 1, listener);}}
}4、计算走过的距离
可以使用Location对象的diatanceTo方法来得到两个位置之间的距离 private static double distanceInMeters;private static Location lastLocation null;public void onCreate() {super.onCreate();listener new LocationListener() {Overridepublic void onLocationChanged(NonNull Location location) {if (location null)lastLocation location;distanceInMeters location.distanceTo(lastLocation);lastLocation location;}};}public double getDistance() {return this.distanceInMeters;}5、停止监听器继续获取位置更新 public void onDestroy() {super.onDestroy();if (locManager ! null listener ! null) {if (ContextCompat.checkSelfPermission(this, PERMISSION_STRIMG) PackageManager.PERMISSION_GRANTED){locManager.removeUpdates(listener);}locManager null;listener null;}}完整的OdometerService.java
package com.hafd.odometer;import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Binder;
import android.os.IBinder;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;public class OdometerService extends Service {private static double distanceInMeters;private static Location lastLocation null;private final IBinder binder new OdometerBinder();private LocationListener listener;private LocationManager locManager;public static final String PERMISSION_STRIMG Manifest.permission.ACCESS_FINE_LOCATION;//创建一个绑定式服务时需要提供一个Binder实现public class OdometerBinder extends Binder {//活动将使用这个方法得到OdometerService的一个引用OdometerService getOdometer() {return OdometerService.this;}}Overridepublic IBinder onBind(Intent intent) {return binder;}public double getDistance() {return this.distanceInMeters;}SuppressLint(ServiceCast)Overridepublic void onCreate() {super.onCreate();listener new LocationListener() {Overridepublic void onLocationChanged(NonNull Location location) {if (location null)lastLocation location;distanceInMeters location.distanceTo(lastLocation);lastLocation location;}};locManager (LocationManager) getSystemService(Context.LOCALE_SERVICE);if (ContextCompat.checkSelfPermission(this, PERMISSION_STRIMG) PackageManager.PERMISSION_GRANTED){String provider locManager.getBestProvider(new Criteria(), true);if (provider ! null)locManager.requestLocationUpdates(provider, 1000, 1, listener);}}Overridepublic void onDestroy() {super.onDestroy();if (locManager ! null listener ! null) {if (ContextCompat.checkSelfPermission(this, PERMISSION_STRIMG) PackageManager.PERMISSION_GRANTED){locManager.removeUpdates(listener);}locManager null;listener null;}}
}二、让应用请求权限
现在的应用必须在系统设置里面手动为这个应用开启位置权限如何要让应用自己请求权限呢
检查并请求权限
修改代码使得只有当用户授予了必要的权限时MainActivity才绑定到这个服务这个权限由OdometerService中定义的PERMISSION_STRING常量指定。如果没有授予权限就请求这个权限。 在MainActivity更新onStart方法。 Overrideprotected void onStart() {super.onStart();//如果没有授权就请求权限if (ContextCompat.checkSelfPermission(this, OdometerService.PERMISSION_STRIMG) ! PackageManager.PERMISSION_GRANTED){ActivityCompat.requestPermissions(this,new String[]{OdometerService.PERMISSION_STRIMG}, PERMISSION_REQUEST_CODE);}else {Intent intent new Intent(this, OdometerService.class);bindService(intent, connection, Context.BIND_AUTO_CREATE); }}检查用户对权限请求的响应
使用requestPermissions方法请求用户授予一个权限时不能通过检查它的返回值来确定是否授予了权限。这是因为权限请求是异步发生的当你等待用户响应时并不会阻塞当前线程。 正确的做法是要检查用户的响应需要覆盖活动的onRequestPermissionsResult方法。这个方法有3个参数 一个标识权限请求的int请求代码、 一个权限String数组、 以及一个对应请求结果的int数组。 使用这个方法时首先检查int请求代码是否与requestPermissions方法中使用的代码一致。如果一致则检查是否已经授予这个权限。 SuppressLint(MissingSuperCall)public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults){switch (requestCode) {case PERMISSION_REQUEST_CODE: {if (grantResults.length 0 grantResults[0] PackageManager.PERMISSION_GRANTED) {Intent intent new Intent(this, OdometerService.class);bindService(intent, connection, Context.BIND_AUTO_CREATE);}else {}}}}如果拒绝授予就发出一个通知
如果用户不授予权限不允许使用他们当前位置OdometerService就无法得出他们走了多远。这里使用通知告知用户。 先增加两个字符串 string nameapp_nameOdometer/stringstring namepermission_deniedLocation permission required/string再将下列代码增加到上一节空白的else语句中
NotificationCompat.Builder builder new NotificationCompat.Builder(this).setSmallIcon(android.R.drawable.ic_menu_compass).setContentTitle(getResources().getString(R.string.app_name)).setContentText(getResources().getString(R.string.permission_denied)).setPriority(NotificationCompat.PRIORITY_HIGH).setVibrate(new long[] {1000, 1000}).setAutoCancel(true);Intent actionIntent new Intent(this, MainActivity.class);PendingIntent actionPendingIntent PendingIntent.getActivity(this,0,actionIntent,PendingIntent.FLAG_UPDATE_CURRENT);builder.setContentIntent(actionPendingIntent);NotificationManager notificationManager (NotificationManager) getSystemService(NOTIFICATION_SERVICE);notificationManager.notify(NOTIFICATION_ID, builder.build());完整的MainActivity
package com.hafd.odometer;import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.app.NotificationCompat;
import androidx.core.content.ContextCompat;import android.annotation.SuppressLint;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.widget.TextView;import java.util.Locale;public class MainActivity extends AppCompatActivity {private OdometerService odometer;private boolean bound false;private final int PERMISSION_REQUEST_CODE 698;private final int NOTIFICATION_ID 423;private ServiceConnection connection new ServiceConnection() {Overridepublic void onServiceConnected(ComponentName componentName, IBinder iBinder) {OdometerService.OdometerBinder odometerBinder (OdometerService.OdometerBinder) iBinder;odometer odometerBinder.getOdometer(); //使用IBinder得到服务的一个引用bound true;}Overridepublic void onServiceDisconnected(ComponentName componentName) {bound false;}};Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);displayDistance();}SuppressLint({MissingSuperCall, NotificationPermission})public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults){switch (requestCode) {case PERMISSION_REQUEST_CODE: {if (grantResults.length 0 grantResults[0] PackageManager.PERMISSION_GRANTED) {Intent intent new Intent(this, OdometerService.class);bindService(intent, connection, Context.BIND_AUTO_CREATE);}else {NotificationCompat.Builder builder new NotificationCompat.Builder(this).setSmallIcon(android.R.drawable.ic_menu_compass).setContentTitle(getResources().getString(R.string.app_name)).setContentText(getResources().getString(R.string.permission_denied)).setPriority(NotificationCompat.PRIORITY_HIGH).setVibrate(new long[] {1000, 1000}).setAutoCancel(true);Intent actionIntent new Intent(this, MainActivity.class);PendingIntent actionPendingIntent PendingIntent.getActivity(this,0,actionIntent,PendingIntent.FLAG_UPDATE_CURRENT);builder.setContentIntent(actionPendingIntent);NotificationManager notificationManager (NotificationManager) getSystemService(NOTIFICATION_SERVICE);notificationManager.notify(NOTIFICATION_ID, builder.build());}}}}Overrideprotected void onStart() {super.onStart();//如果没有授权就请求权限if (ContextCompat.checkSelfPermission(this, OdometerService.PERMISSION_STRIMG) ! PackageManager.PERMISSION_GRANTED){ActivityCompat.requestPermissions(this,new String[]{OdometerService.PERMISSION_STRIMG}, PERMISSION_REQUEST_CODE);}else {Intent intent new Intent(this, OdometerService.class);bindService(intent, connection, Context.BIND_AUTO_CREATE);}}protected void onStop() {super.onStop();if (bound) {unbindService(connection);bound false;}}private void displayDistance() {final TextView distanceView (TextView) findViewById(R.id.distance);final Handler handler new Handler();handler.post(new Runnable() {Overridepublic void run() {double distance 0.0;//如果得到OdometerService的一个引用而且绑定到这个服务则调用getDistance。if (bound odometer ! null)distance odometer.getDistance();String distanceStr String.format(Locale.getDefault(), %1$,.2f miles, distance);distanceView.setText(distanceStr);//每秒运行一次handler.postDelayed(this, 1000);}});}
}试一试