Ionic 使用原生定位功能

咱們在上一篇已經成功建立並編譯了 hello-world 項目。如今增長讀取當前座標的功能。html

新增讀取當前座標的功能

  1. 首先要安裝 geolocation pluginandroid

    npm install --save @ionic-native/geolocation
  2. 將 geolocation plugin 添加到 app.module.ts 的 providers 中:git

    import { Geolocation } from "@ionic-native/geolocation";
    
    @NgModule({
      providers: [
        StatusBar,
        SplashScreen,
        Geolocation,
        { provide: ErrorHandler, useClass: IonicErrorHandler }
      ]
    })
    export class AppModule { }
  3. 在 home.html 中增長一個按鈕,在按鈕的 click 事件中調用 gps 插件獲取當前座標點並顯示在 home.html 中:npm

    import { Geolocation } from '@ionic-native/geolocation';
    
    @Component({
      selector: 'page-home',
      templateUrl: 'home.html'
    })
    export class HomePage {
      constructor(
        public navCtrl: NavController,
        private geolocation: Geolocation
      ) {
      }
      position = "()";
    
      ngOnInit() {
        this.isLoading = "加載完畢";
      }
    
      getPosition() {
        this.geolocation.getCurrentPosition().then((resp) => {
          this.position = `(${resp.coords.latitude}, ${resp.coords.longitude})`;
        }).catch((error) => {
          this.position = 'error:' + error.message;
          console.log('Error getting location', error);
        });
      }
    }
  4. 按上一篇的方法再次編譯 apk。注意編譯以前要把以前生成過的 apk 所有刪除先。由於從此要常常進行編譯 apk 的工做,建議把壓縮未簽名 apk、簽名 apk、驗證簽名這 3 項工做放進一個叫作 「sign.bat」 的批處理文件並放置在項目根目錄下,而後編寫 npm scripts 以下:segmentfault

    "scripts": {
      "prebuild": "del /F /Q C:\\projects\\ionic\\hello-world\\platforms\\android\\app\\build\\outputs\\apk\\release\\*.*",
      "build": "ionic cordova build android --prod --release",
      "postbuild": "sign"
    }

    這樣從此只要執行「npm run build」就會先執行 prebuild 裏面的腳本刪除舊的 apk,而後編譯出新的 apk,再執行簽名腳本。app

在手機上安裝新版 apk 以後會發現獲取不到當前座標,錯誤信息爲「application does not have sufficient geolocation permissions.」,也就是默認是沒有獲取定位的權限的。ionic

請求定位權限

  1. 參考官方文檔,首先要安裝 android-permissions 插件,注意這兩個都要裝,可不是裝一個插件的兩種方法!ide

    ionic cordova plugin add cordova-plugin-android-permissions
    npm install --save @ionic-native/android-permissions
  2. 官方文檔漏了必須的一步,要在post

    C:\projects\ionic\hello-world\platforms\android\app\src\main\AndroidManifest.xml

    中添加要申請的權限:ACCESS_COARSE_LOCATION、ACCESS_FINE_LOCATION 和 ACCESS_LOCATION_EXTRA_COMMANDS:ui

    <?xml version='1.0' encoding='utf-8'?>
    <manifest android:hardwareAccelerated="true" android:versionCode="1" android:versionName="0.0.1" package="io.ionic.starter" xmlns:android="http://schemas.android.com/apk/res/android">
        <supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:resizeable="true" android:smallScreens="true" android:xlargeScreens="true" />
        <uses-permission android:name="android.permission.INTERNET" />
        <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
        <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
        <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
        <application android:hardwareAccelerated="true" android:icon="@mipmap/icon" android:label="@string/app_name" android:supportsRtl="true">
            <activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale" android:label="@string/activity_name" android:launchMode="singleTop" android:name="MainActivity" android:theme="@android:style/Theme.DeviceDefault.NoActionBar" android:windowSoftInputMode="adjustResize">
                <intent-filter android:label="@string/launcher_name">
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
        </application>
        <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="26" />
    </manifest>

    不然根本不會彈出權限請求系統對話框。
    其中權限字符串列表在Manifest.permission.html中能夠查到。

  3. 安裝以後一樣要把它放置到 app.module.ts 的 providers 中,並在 home.ts 中添加請求權限的代碼。值得注意的是 Android 26 以上要求在請求權限以前要有使用該權限的代碼,不然一樣不會彈出權限申請系統對話框,因此 home.ts 代碼像這樣:

    import { Geolocation } from '@ionic-native/geolocation';
    import { AndroidPermissions } from '@ionic-native/android-permissions';
    
    @Component({
      selector: 'page-home',
      templateUrl: 'home.html'
    })
    export class HomePage {
      constructor(
        public navCtrl: NavController,
        private geolocation: Geolocation,
        private androidPermissions: AndroidPermissions
      ) {
      }
    
      position = "()";
    
      getPosition() {
        this.geolocation.getCurrentPosition().then((resp) => {
          this.position = `(${resp.coords.latitude}, ${resp.coords.longitude})`;
        }).catch((error) => {
          this.androidPermissions.requestPermissions([
            this.androidPermissions.PERMISSION.ACCESS_COARSE_LOCATION,
            this.androidPermissions.PERMISSION.ACCESS_FINE_LOCATION,
            this.androidPermissions.PERMISSION.ACCESS_LOCATION_EXTRA_COMMANDS]).then(r => {
              // 申請權限成功
              this.geolocation.getCurrentPosition().then((resp) => {
                this.position = `(${resp.coords.latitude}, ${resp.coords.longitude})`;
              });
            }).catch(err => {
              //申請權限失敗:"
            });
        });
      }
    }
相關文章
相關標籤/搜索