Viết một Ứng dụng NativeScript theo Thời gian thực: Định vị và Google Maps
Vietnamese (Tiếng Việt) translation by Dai Phong (you can also view the original English article)
NativeScript là một framework dùng để xây dựng những ứng dụng di động đa nền tảng sử dụng XML, CSS và JavaScript. Trong loạt bài này, chúng ta sẽ thử một số thứ thú vị mà bạn có thể làm với một ứng dụng NativeScript: định vị và tích hợp Google Maps, cơ sở dữ liệu SQLite, tích hợp Firebase và thông báo đẩy. Cùng với đó, chúng ta sẽ xây dựng một ứng dụng theo dõi hoạt động thể thao với khả năng hoạt động theo thời gian thực, nó sẽ sử dụng từng tính năng này.
Trong hướng dẫn này, bạn sẽ học cách làm việc với định vị và Google Maps trong các ứng dụng NativeScript.
Tôi giả sử rằng bạn đã biết cách tạo ra các ứng dụng trong NativeScript. Nếu bạn là người mới làm quen với NativeScript, tôi khuyên bạn trước tiên hãy tham khảo một trong những hướng dẫn trước về NativeScript trước khi theo dõi hướng dẫn này.
Giới thiệu về NativeScript
Tạo Ứng dụng NativeScript Đầu tiên của Bạn
Tạo một Ứng dụng về Thời tiết bằng TypeScript và NativeScript
Những gì bạn sẽ thực hiện
Bạn sẽ tạo một ứng dụng theo dõi hoạt động đi bộ bằng cách sử dụng định vị và Google Maps. Nó sẽ hiển thị cho người dùng khoảng cách mà họ đã đi được và số bước mà họ đã đi ứng với khoảng cách đó. Ngoài ra còn có một bản đồ sẽ hiển thị vị trí hiện tại của người dùng.
Để cho bạn có được một ý tưởng, kết quả sau cùng sẽ giống như sau:



Thiết lập Dự án
Bắt đầu bằng cách tạo một ứng dụng NativeScript mới:
tns create fitApp --appid "com.yourname.fitApp"
Để dễ dàng thiết lập UI của ứng dụng, tôi đã tạo một repo GitHub bao gồm cả phiên bản bắt đầu và phiên bản sau cùng của dự án. Bạn có thể sao chép nội dung của thư mục app vào trong thư mục app của dự án. Chúng ta sẽ chỉ làm việc với hai tập tin: main-page.xml và main-page.js. Những tập tin còn lại chỉ là sườn từ dự án demo của NativeScript.
Chạy Ứng dụng
Chúng ta sẽ sử dụng emulator của Android được cung cấp bởi Android Studio để chạy thử ứng dụng. Điều này sẽ cho phép chúng ta sử dụng Android GPS Emulator để mô phỏng sự thay đổi vị trí một cách dễ dàng. Tôi không thật sự muốn đi quanh quẩn một cách vô ích ở bên ngoài để kiểm tra vị trí! Nhưng nếu đó là điều bạn muốn thì tôi sẽ không cản bạn.
Nếu bạn chạy lệnh tns run android
, nó sẽ tự động gọi emulator của Android nếu nó đã được cài đặt. Nếu nó chưa được cài đặt, bạn có thể cài đặt nó bằng cách khởi chạy Android Studio, nhấp vào configure (cấu hình) và chọn SDK Manager. Việc này mặc định sẽ mở SDK Platforms. Nhấp vào tab SDK Tools và đảm bảo chọn Android Emulator, và nhấp vào Apply để cài đặt nó.
Để sử dụng GPS emulator, hãy tải nó về từ GitHub và chạy tập tin có thể thực thi war:
java -jar android-gps-emulator-0.2.war
Sau khi hoàn tất, bạn sẽ có thể truy cập vào http://localhost:8080/gpsemulator/
từ trình duyệt của bạn và kết nối đến localhost
. Hãy đảm bảo rằng emulator của Android đang chạy khi bạn thực hiện việc này. Một khi bạn đã kết nối, chỉ cần phóng to bản đồ và nhấp vào bất kỳ vị trí nào mà bạn muốn sử dụng làm vị trí. Ứng dụng sẽ nhận biết vị trí này và sử dụng nó như là vị trí hiện tại của nó.



Làm việc Với Plugin Định vị Geolocation
Geolocation trong NativeScript tương tự như Geolocation API trong JavaScript. Sự khác biệt duy nhất về chức năng đó là việc bổ sung một hàm distance()
được sử dụng để tính toán khoảng cách giữa hai vị trí.
Cài đặt Plugin Geolocation
Để làm việc với định vị, trước tiên bạn cần phải cài đặt plugin Geolocation:
tns plugin add nativescript-geolocation
Sau khi hoàn tất, bây giờ bạn có thể thêm nó từ tập tin script của bạn:
var geolocation = require("nativescript-geolocation");
Lấy Vị trí Hiện tại của Người dùng
Plugin Geolocation của NativeScript bao gồm ba hàm để bạn có thể sử dụng để làm việc với vị trí hiện tại của người dùng. Chúng ta sẽ sử dụng từng hàm trong ứng dụng này:
getCurrentLocation
watchLocation
distance
Mở tập tin main-view-model.js và thêm code sau đây vào bên trong hàm createViewModel()
. Ở đây chúng ta đang khởi tạo các biến mà chúng ta sẽ sử dụng sau này để lưu trữ các giá trị khác nhau cần thiết để theo dõi vị trí của người dùng.
Tôi đã thêm một số comment trong code để bạn biết điều gì đang xảy ra. Ngoài ra còn có một số dòng code đã được chuyển thành comment; những dòng này là dành cho việc tích hợp Google Maps. Tôi đã tạm thời chuyển chúng thành comment để giữ cho mọi thứ đơn giản. Một khi chúng ta đến với phần tích hợp Google Maps, bạn sẽ cần phải bỏ những comment đó.
function createViewModel() { var viewModel = new Observable(); var watchId; // stores the ID of the location watcher so we can stop it later var start_location; // stores the location of the user when they first started tracking var current_location; // stores the current location of the user viewModel.is_tracking = false; // whether the user's location is currently being tracked or not //viewModel.latitude = 15.447819409392789; //viewModel.longitude = 120.93888133764267; //viewModel.zoom = 20; var total_distance = 0; var total_steps = 0; var locations = []; // array which will store the locations //var mapView; //var marker = new mapsModule.Marker(); if (!geolocation.isEnabled()) { // check if geolocation is not enabled geolocation.enableLocationRequest(); // request for the user to enable it } // next: add code for getting the user's current location }
Tiếp theo, thêm code để lấy vị trí hiện tại của người dùng. Code này được thực thi khi người dùng nhấn vào nút để bắt đầu và ngừng việc theo dõi vị trí. Phương thức geolocation.getCurrentLocation()
được sử dụng để lấy vị trí hiện tại.
Ở đây chúng ta đã xác định ba tùy chọn: desiredAccuracy
, updateDistance
và timeout
. desiredAccuracy
cho phép bạn thiết lập độ chính xác theo mét. Nó có thể có hai giá trị: Accuracy.high
, khoảng 3 mét, và Accuracy.any
, khoảng 300 mét. updateDistance
xác định phải cách xa bao nhiêu (tính bằng mét) giữa vị trí trước và vị trí hiện tại trước khi nó cập nhật. Sau cùng, timeout
xác định bao nhiêu mili giây để chờ một vị trí.
Một khi nhận được vị trí, chúng ta thiết lập vị trí đó là start_location
và đẩy nó vào mảng locations
. Sau đó, vị trí này sẽ được sử dụng cùng với vị trí đầu tiên sẽ lấy được từ việc theo dõi vị trí hiện tại của người dùng để xác định khoảng cách di chuyển.
viewModel.toggleTracking = function() { if (geolocation.isEnabled()) { this.set('is_tracking', !viewModel.is_tracking); // flip the toggle for tracking if (viewModel.is_tracking) { geolocation.getCurrentLocation( { desiredAccuracy: Accuracy.high, // 3 meter accuracy updateDistance: 5, // 5 meters timeout: 2000 // 2 seconds } ). then(function(loc) { if (loc) { start_location = loc; locations.push(start_location); //viewModel.set('latitude', loc.latitude); //viewModel.set('longitude', loc.longitude); } }, function(e){ dialogs.alert(e.message); }); // next: add code for watching user's current location } else { // next: add code to stop watching the user's current location } } else { dialogs.alert("Please enable Geolocation"); } }
Theo dõi Vị trí Hiện tại của Người dùng
Để lấy được vị trí hiện tại, chúng ta sử dụng hàm geolocation.watchLocation()
. Hàm này tương tự như hàm setInterval()
trong JavaScript, bởi vì nó cũng thực thi hàm callback liên tục cho đến khi bạn dừng nó bằng hàm geolocation.clearWatch()
. Hàm callback được tự động gọi dựa trên updateDistance
và minimumUpdateTime
.
Trong code ở bên dưới, vị trí sẽ được cập nhật nếu nó cách địa điểm trước đó ít nhất là 5 mét. Nhưng hoạt động cập nhật này sẽ chỉ xảy ra mỗi 5 giây. Điều này có nghĩa là nếu người dùng không đi bộ 5 mét trở lên trong vòng 5 giây, thì vị trí sẽ không cập nhật.
watchId = geolocation.watchLocation( function (loc) { if (loc) { current_location = loc; // next: add code for getting the distance between two locations } }, function(e){ dialogs.alert(e.message); }, { desiredAccuracy: Accuracy.high, updateDistance: 5, // 5 meters minimumUpdateTime : 5000 // update every 5 seconds } );
Một khi người dùng muốn ngừng theo dõi, bạn cần phải gọi hàm geolocation.clearWatch()
. Bạn cũng cần phải thiết lập lại các giá trị còn lại đang được cập nhật mỗi lần vị trí được thay đổi.
geolocation.clearWatch(watchId); // stop watching the user's location total_distance = 0; total_steps = 0; locations = []; viewModel.set('distance', "distance travelled: " + total_distance + " meters"); viewModel.set('steps', "steps: " + total_steps);
Lấy khoảng cách giữa hai điểm
Bây giờ chúng ta đã sẵn sàng để lấy khoảng cách. Điều này có thể được thực hiện bằng cách gọi hàm geolocation.distance()
. Hàm này nhận hai đối tượng location
làm đối số của nó, vì vậy chúng ta sẽ sử dụng hai vị trí sau cùng đã được đẩy vào mảng locations
để xác định khoảng cách (tính bằng mét) di chuyển được bởi người dùng từ một vị trí đã được ghi lại trước đó đến vị trí hiện tại. Từ đó, chúng ta có thể sử dụng một sự chuyển đổi gần đúng từ mét sang số bước - tôi nói là gần đúng bởi vì không phải ai cũng sẽ đi cùng một khoảng cách trong một bước.
Sau đó, chúng ta chỉ cần thêm kết quả distance
và steps
vào total_distance
và total_steps
để chúng ta có thể theo dõi tổng khoảng cách và số bước mà họ đã đi được kể từ khi họ bắt đầu theo dõi vị trí của họ.
locations.push(loc); //viewModel.set('latitude', loc.latitude); //viewModel.set('longitude', loc.longitude); //marker.position = mapsModule.Position.positionFromLatLng(viewModel.latitude, viewModel.longitude); location_count = locations.length; if (location_count >= 2) { var distance = Math.round(geolocation.distance(locations[location_count - 2], locations[location_count - 1])); // get the distance between the last two locations var steps = Math.round(distance * 1.3123); // determine the approximate number of steps // add the current distance to the overall distance travelled total_distance = total_distance + distance; total_steps = total_steps + steps; // update the UI viewModel.set('distance', "distance travelled: " + total_distance + " meters"); viewModel.set('steps', "steps: " + total_steps); }
Tại thời điểm này, bạn có thể bắt đầu chạy thử ứng dụng bằng GPS emulator mà tôi đã đề cập trước đó. Xin hãy lưu ý rằng bạn cần nhấn save trên tập tin main-view-model.js để kích hoạt việc tải lại ứng dụng.
Sau đó, chọn một vị trí trong GPS emulator từ đó một vị trí mới sẽ được lấy về bởi ứng dụng sau khi nó đã được nạp. Nếu bạn không làm điều này, nó sẽ mặc định vị trí Googleplex trong Mountain View, California. Điều này có nghĩa là lần kế tiếp bạn chọn vị trí trên emulator, nó sẽ nhảy từ vị trí này tới vị trí mà bạn đã chọn. Nếu nó cách xa thì bạn sẽ nhận được một con số thật sự lớn cho khoảng cách và số bước.
Ngoài ra, bạn có thể chạy thử trên một thiết bị thật với kết nối internet và GPS đã được kích hoạt. Chỉ bắt buộc phải có GPS ở thời điểm hiện tại, nhưng khi chúng ta thêm Google Maps, ứng dụng sẽ cần kết nối internet.
Làm việc với Google Maps
Bây giờ chúng ta sẽ sử dụng Google Maps để thêm một bản đồ hiển thị vị trí hiện tại của người dùng.
Cài đặt Plugin Google Maps
tns plugin add nativescript-google-maps-sdk
Một khi đã cài đặt, bạn cần phải sao chép các tập tin template cho Android:
cp -r node_modules/nativescript-google-maps-sdk/platforms/android/res/values app/App_Resources/Android/
Tiếp theo, mở tập tin app/App_Resources/Android/values/nativescript_google_maps_api.xml và thêm khoá API Google Maps của bạn (khóa máy chủ):
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="nativescript_google_maps_api_key">YOUR GOOGLE MAPS API KEY HERE</string> </resources>
Hãy đảm bảo rằng bạn đã bật Google Maps Android API từ Google Console trước khi bạn thử dùng nó.
Thêm Bản đồ
Đối với bản đồ, hãy mở tập tin main-page.xml và bạn sẽ thấy những thứ sau đây:
<maps:mapView latitude="{{ latitude }}" longitude="{{ longitude }}" zoom="{{ zoom }}" mapReady="{{ onMapReady }}" />
Ở đây chúng ta đã xác định ba tùy chọn (longitude
, latitude
và zoom
) và một hàm để thực thi khi bản đồ đã sẵn sàng. longitude
và latitude
xác định vị trí mà bạn muốn kết xuất trên bản đồ. zoom
xác định mức phóng to hay thu nhỏ của bản đồ. mapReady
là nơi chúng ta chỉ định hàm để thêm đánh dấu trên bản đồ. Đánh dấu này đại diện cho vị trí hiện tại của người dùng, vì vậy nó sẽ được kết xuất ở ngay giữa bản đồ.
Mặc định, điều này sẽ không hoạt động vì bạn vẫn chưa thêm định nghĩa lược đồ cho bản đồ. Vì vậy bên trong phần tử Page
của bạn, hãy thêm định nghĩa cho phần tử maps
:
<Page xmlns="http://schemas.nativescript.org/tns.xsd" xmlns:maps="nativescript-google-maps-sdk" > </Page>
Sau khi hoàn tất, một đối tượng Google Maps sẽ được kết xuất ngay bên dưới nút để theo dõi vị trí. Nó vẫn chưa có bất kỳ bản đồ nào vì latitude
và longitude
chưa được xác định. Để làm điều đó, hãy quay trở lại tập tin main-view-model.js và bỏ các comment cho các dòng code để làm việc với Google Maps:
// default coordinates viewModel.latitude = 15.447819409392789; viewModel.longitude = 120.93888133764267; viewModel.zoom = 20; // default map zoom level var mapView; // variable for storing the current map instance var marker = new mapsModule.Marker(); // variable for storing the marker instance
Thêm Đánh dấu
Bởi vì chúng ta đã khai báo các tọa độ mặc định cho điểm đánh dấu, chúng ta có thể dựng một điểm đánh dấu khi bản đồ đã sẵn sàng:
viewModel.onMapReady = function(args) { mapView = args.object; // get the map view marker.position = mapsModule.Position.positionFromLatLng(viewModel.latitude, viewModel.longitude); // set the marker's position on the map mapView.addMarker(marker); // add the marker to the map }
Tiếp theo, chúng ta cần phải cập nhật vị trí của điểm đánh dấu một khi người dùng bắt đầu theo dõi vị trí của họ. Bạn có thể làm điều đó bên trong hàm callback thành công cho hàm getCurrentLocation()
:
locations.push(start_location); // remove the comments for these: //viewModel.set('latitude', loc.latitude); //viewModel.set('longitude', loc.longitude); //marker.position = mapsModule.Position.positionFromLatLng(viewModel.latitude, viewModel.longitude);
Chúng ta cũng cần phải cập nhật nó khi vị trí của người dùng được cập nhật (bên trong hàm callback thành công cho hàm watchLocation
):
current_location = loc; locations.push(loc); // remove the comments for these: //viewModel.set('latitude', loc.latitude); //viewModel.set('longitude', loc.longitude); //marker.position = mapsModule.Position.positionFromLatLng(viewModel.latitude, viewModel.longitude);
Sau khi hoàn tất, một bản đồ kết xuất vị trí mặc định sẽ hiển thị trong ứng dụng.
Tóm tắt
Trong bài hướng dẫn này, bạn đã tạo ra một ứng dụng NativeScript cho phép người dùng theo dõi khoảng cách mà họ đã đi được và số bước tương đối ứng với khoảng cách đó. Bạn còn sử dụng Google Maps để cho phép người dùng xem vị trí hiện tại của họ. Bằng cách làm như vậy, bạn đã học được cách sử dụng các plugin Geolocation và Google Maps cho NativeScript.
Đây chỉ mới là sự khởi đầu! Trong các bài viết tiếp theo của loạt bài này, chúng ta sẽ thêm một cơ sở dữ liệu cục bộ, thông báo đẩy và các tính năng tuyệt vời khác vào ứng dụng của chúng ta.
Trong lúc đó, hãy tham khảo một số bài viết khác của chúng tôi về NativeScript và phát triển ứng dụng đa nền tảng.
- Ứng dụng Di độngTạo một Ứng dụng về Thời tiết bằng TypeScript và NativeScriptWernher-Bel Ancheta
- Phát triển Ứng dụng Di độngGiới thiệu về Vue và Weex dành cho Ứng dụng Di động gốcLawrence Turton
- IonicLàm quen với các Dịch vụ của Ionic: AuthWernher-Bel Ancheta
Để tìm hiểu một cách đầy đủ về NativeScript, hãy thử khóa học video của chúng tôi về Viết Ứng dụng Di động Với NativeScript. Trong khóa học này, Keyvan Kasaei sẽ hướng dẫn cho bạn từng bước cách xây dựng một ứng dụng đơn giản. Cùng với đó, bạn sẽ học được cách cài đặt một quy trình phát triển ứng dụng đơn giản với các yêu cầu mạng, kiến trúc MVVM và một số thành phần UI quan trọng nhất của NativeScript. Sau khi kết thúc, bạn sẽ hiểu được tại sao bạn nên cân nhắc NativeScript cho dự án phát triển ứng dụng di động tiếp theo của mình.
