Java tutorial
/* * Copyright (c) 2014 Royer Wang. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.bangz.smartmute.content; import android.content.Context; import android.content.res.Resources; import com.bangz.smartmute.Constants; import com.bangz.smartmute.R; import com.google.android.gms.location.Geofence; import org.json.JSONException; import org.json.JSONObject; import org.json.JSONTokener; import com.bangz.smartmute.util.LogUtils; /** * Created by royerwang on 2014-09-23. */ public class LocationCondition extends Condition { public static final String TAG = LocationCondition.class.getSimpleName(); public static final float DEF_RADIUS = 100.0f; public static final int DEF_LOITERINGDELAY_MS = 1 * 60 * 1000; // we always monitor EXIT transition, user just care about either enter or dwell public static final int DEF_TRANSITIONTYPE = Geofence.GEOFENCE_TRANSITION_ENTER; // The best effort notification responsiveness of the geo fence public static final int DEF_NOTIFYDELAY_MS = 0; public static class TriggerCondition { private int transitionType; private int loiteringDelay; private int notificationDelay; public TriggerCondition(int transtype, int loitering, int notifydelay) { transitionType = transtype; loiteringDelay = loitering; notificationDelay = notifydelay; } public TriggerCondition(int transtype) { this(transtype, DEF_LOITERINGDELAY_MS, DEF_NOTIFYDELAY_MS); } public TriggerCondition() { this(DEF_TRANSITIONTYPE, DEF_LOITERINGDELAY_MS, DEF_NOTIFYDELAY_MS); } public int getTransitionType() { return transitionType; } public int getLoiteringDelay() { return loiteringDelay; } public int getNotificationDelay() { return notificationDelay; } public void setTransitionType(final int transtype) { transitionType = transtype; } public void setLoiteringDelay(final int l) { loiteringDelay = l; } public void setNotificationDelay(final int notifydelay) { notificationDelay = notifydelay; } } //public static final String strMatch = // "(?i)\\s*location\\s*:\\s*[-+]?\\d+(\\.?\\d+)\\s*,\\s*[-+]?\\d+(\\.?\\d+)\\s*(,\\s*\\d+)?"; // The regular string to match, after location: is a JSON string. the whole string example: // location:{"Lat":45.3344, "Lng":-123.56,"radius":100.0,"transitiontype":1,"loitering=60000, // "notifydelay":60000} private static final String strMatch = "(?i)\\s*location\\s*:\\s*\\{.*\\}"; private static final String KEY_LATITUDE = "Lat"; private static final String KEY_LONGITUDE = "Lng"; private static final String KEY_RADIUS = "radius"; private static final String KEY_LOITERINGDELAY = "loitering"; private static final String KEY_TRANSITIONTYPE = "transitiontype"; private static final String KEY_NOTIFYDELAY = "notifydelay"; private double longitude; //? private double latitude; // private float radius; //metter private TriggerCondition triggerCondition; public LocationCondition() { setType(Condition.RT_LOCATION); triggerCondition = new TriggerCondition(); } /** * * @param condition is a string follow this format: * location:JSON string */ public LocationCondition(String condition) { //super(condition); setType(Condition.RT_LOCATION); String strparam = getParamString(condition); try { JSONObject allJson = (JSONObject) new JSONTokener(strparam).nextValue(); latitude = allJson.getDouble(KEY_LATITUDE); longitude = allJson.getDouble(KEY_LONGITUDE); radius = (float) allJson.getDouble(KEY_RADIUS); int tt = allJson.getInt(KEY_TRANSITIONTYPE); int loitering = allJson.getInt(KEY_LOITERINGDELAY); int notifydelay = allJson.getInt(KEY_NOTIFYDELAY); triggerCondition = new TriggerCondition(tt, loitering, notifydelay); setConditionString(BuildConditionString()); } catch (JSONException e) { LogUtils.LOGE(TAG, e.getStackTrace().toString()); } } public LocationCondition(final double lng, final double lat, final float r, final int transitiontype, final int loitering, final int notifydelay) { setType(Condition.RT_LOCATION); longitude = lng; latitude = lat; radius = r; triggerCondition = new TriggerCondition(transitiontype, loitering, notifydelay); setConditionString(BuildConditionString()); } public LocationCondition(final double longitude, final double latitude, final float radius) { this(longitude, latitude, radius, DEF_TRANSITIONTYPE, DEF_LOITERINGDELAY_MS, DEF_NOTIFYDELAY_MS); } public LocationCondition(final double lng, final double lat) { this(lng, lat, DEF_RADIUS); } public LocationCondition(final double lng, final double lat, final float r, final int transtype) { this(lng, lat, r, transtype, DEF_LOITERINGDELAY_MS, DEF_NOTIFYDELAY_MS); } @Override public boolean isValidConditionString(String strCondition) { return checkStringFormat(strCondition); } public static boolean checkStringFormat(String strcondition) { return strcondition.matches(strMatch); } @Override public String getParamString(String strcondition) { return strcondition.replaceAll("(?i)\\s*location\\s*:\\s*", ""); } @Override public String BuildConditionString() { StringBuilder sb = new StringBuilder("location: "); JSONObject json = new JSONObject(); try { json.put(KEY_LATITUDE, latitude).put(KEY_LONGITUDE, longitude).put(KEY_RADIUS, radius) .put(KEY_TRANSITIONTYPE, triggerCondition.getTransitionType()) .put(KEY_LOITERINGDELAY, triggerCondition.getLoiteringDelay()) .put(KEY_NOTIFYDELAY, triggerCondition.getNotificationDelay()); } catch (JSONException e) { LogUtils.LOGE(TAG, e.toString()); } sb.append(json.toString()); return sb.toString(); } @Override public String description(final Context ctx) { Resources res = ctx.getResources(); int transition = getTriggerCondition().getTransitionType(); if (transition == Geofence.GEOFENCE_TRANSITION_ENTER) { return String.format(res.getString(R.string.info_trigger_by_enter), (int) radius); } else { return String.format(res.getString(R.string.info_trigger_by_dwell), (int) radius, getTriggerCondition().getLoiteringDelay() / Constants.ONE_MINUTE_IN_MS); } } public double getLongitude() { return longitude; } public double getLatitude() { return latitude; } public float getRadius() { return radius; } public TriggerCondition getTriggerCondition() { return triggerCondition; } }