Frequent calls of wechat applet wx.getLocation:fail will increase power loss

Posted by deeppak on Wed, 01 Dec 2021 07:40:08 +0100

Frequent calls of wechat applet getLocation:fail will increase power loss

There was a problem when developing wechat applet yesterday. It is as follows:
I need to get the location information, send it to the back end and get the orders within the scope. Before receiving the order, I also need to get the location again, get the latest location information and pass it along with my own information
The result is this:

I got it! I went to check the official documents:
Official Portal
That's what the document says


Let's see the announcement
Related announcement portal

In short
1. wx.getLocation will be restricted in the basic library above version 2.17.0
2. The call of the development and experience version is valid within 30 seconds, and an error will be returned within 30 seconds
3. No error will be reported for the official version, but the data returned within 30 seconds is still the data obtained for the first time

For the above announcement, it can still be used if you don't need to call wx.getLocatio frequently to obtain the location, such as initialization to obtain the location

This restriction is very unfriendly both in use and testing

So we need to use another official method wx.onLocationChange

Let's look at the documentation

It roughly means that you can monitor the change of geographical location in real time. The data passed is a callback function used to receive the changed geographical information. It also needs to be used in combination with wx.startLocationUpdate.
The simple understanding is that I need to open location monitoring wx.startLocationUpdate first, so that I can listen to the received value of the callback function passed by wx.onLocationChange. If not needed, I can use it
wx.offLocationChange turn off location listening

In order to improve the code reuse rate, let's package the function of obtaining location into modules

First, we need to create a new js file
We'll call it
location.js is where you want to put it
First define a function method
We call it authorization here and export it. A try catch is written in it for error handling (generally speaking, the error here is caused by not opening permission)

export const authorization = () => {
  try{
	//Operation positioning  
  }catch{
	//Processing error processing without open location permission
  }
}

We define a method to get the location (the main function) called getWxLocation

const getWxLocation = () => {
  //Prompt positioning
  wx.showLoading({
    title: 'Positioning...',
    mask: true,
  })
  //Use promise to synchronously receive the obtained value
  return new Promise((resolve, reject) => {
  	//Define the function to receive location information
    let _locationChangeFn = (res) => {
     //When the supervisor hears the data of positioning information
      console.log('location change', res)
      //Return location data
      resolve(res)
      wx.hideLoading()
      //lsnrctl stop 
      wx.offLocationChange(_locationChangeFn)
    }
    //Turn on location service
    wx.startLocationUpdate({
      type: 'gcj02',
      success: (res) => {
		//Start the listening transfer callback function after opening successfully
        wx.onLocationChange(_locationChangeFn)
      },
      fail: (err) => {
        console.log('Failed to get current location', err)
        wx.hideLoading()
        //Return error
        reject()
      }
    })
  })
}

Put this function in the first function
async - await asynchronous to synchronous is used here

export const authorization = async () => {
  try{
	//Run positioning function
	//return the location information
	return await getWxLocation();
  }catch{
	//Processing error processing without open location permission
  }
}

Define functions without open location permission

const toSetting = () => {
  return new Promise((resolve, reject) => {
    //Call up the client applet setting interface to return the operation results set by the user
    wx.openSetting({
      success(res) {
        console.log(res)
        if (res.authSetting["scope.userLocation"]) {
          // res.authSetting["scope.userLocation"] is true, indicating that the user has agreed to obtain the location information. At this time, call getlocation to get the information
          let locationRes = await getlocation()
          resolve(locationRes)
        }
      },
      fail(err) {
        reject()
      }
    })
  })
}

Put it in the main function

export const authorization = async () => {
  try{
	//Run positioning function
	//return the location information
	return await getWxLocation();
  }catch{
	//Processing error processing without open location permission
	wx.showModal({
      title: 'reminder',
      content: 'Failed to obtain permission. You need to obtain your geographic location to provide you with better services! Are you authorized to obtain geographic location?',
      success: function (res) {
        if (res.confirm) {//Here is after clicking OK
          console.log('The user clicks OK')
          toSetting()
        } else {//Here is after clicking cancel
          console.log('The user clicks cancel')
        }
      }
    })
  }
}

Calling is introducing

const { authorization } = require('../../../utils/location')

use

  let res = await authorization()
      console.log(res)

That's OK, no restrictions!!

Complete code

//This function is triggered by the click event at the beginning:
export const authorization = async () => {
  try {
    return await getWxLocation() //wait for

  } catch (error) {
    wx.showModal({
      title: 'reminder',
      content: 'Failed to obtain permission. You need to obtain your geographic location to provide you with better services! Are you authorized to obtain geographic location?',
      success: function (res) {
        if (res.confirm) { //Here is after clicking OK
          console.log('The user clicks OK')
          toSetting()
        } else { //Here is after clicking cancel
          console.log('The user clicks cancel')
        }
      }
    })

    return
  }
}

const getWxLocation = () => {
  wx.showLoading({
    title: 'Positioning...',
    mask: true,
  })
  return new Promise((resolve, reject) => {
    let _locationChangeFn = (res) => {
      console.log('location change', res)
      // Storage.set('userLocation', res)
      resolve(res)
      wx.hideLoading()
      wx.offLocationChange(_locationChangeFn)
    }
    wx.startLocationUpdate({
      type: 'gcj02',
      success: (res) => {
        console.log(res);
        wx.onLocationChange(_locationChangeFn)

      },
      fail: (err) => {
        console.log('Failed to get current location', err)
        wx.hideLoading()
        reject()
      }
    })
  })
}
const toSetting = () => {
  return new Promise((resolve, reject) => {
    //Call up the client applet setting interface to return the operation results set by the user
    wx.openSetting({
      success(res) {
        console.log(res)
        if (res.authSetting["scope.userLocation"]) {
          // res.authSetting["scope.userLocation"] is true, indicating that the user has agreed to obtain the location information. At this time, call getlocation to get the information
          let locationRes = await getlocation()
          resolve(locationRes)
        }
      },
      fail(err) {
        reject()
      }
    })
  })
}


Give me some attention and support

Topics: Javascript Mini Program