/* * Copyright 2015 Thomas Hoffmann * * 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 de.j4velin.wifiAutoOff; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import com.google.android.gms.maps.model.LatLng; import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; public class Database extends SQLiteOpenHelper { private static final int DATABASE_VERSION = 1; private static Database instance; private static final AtomicInteger openCounter = new AtomicInteger(); private Database(final Context context) { super(context, "wifiautomatic", null, DATABASE_VERSION); } public static synchronized Database getInstance(final Context c) { if (instance == null) { instance = new Database(c.getApplicationContext()); } openCounter.incrementAndGet(); return instance; } @Override public void close() { if (openCounter.decrementAndGet() == 0) { super.close(); } } @Override public void onCreate(final SQLiteDatabase db) { db.execSQL("CREATE TABLE IF NOT EXISTS locations (name TEXT, lat DOUBLE, lon DOUBLE);"); } @Override public void onUpgrade(final SQLiteDatabase db, int oldVersion, int newVersion) { } /** * Gets a list of saved locations * * @return the list of locations, might be empty */ public List<Location> getLocations() { Cursor c = getReadableDatabase() .query("locations", new String[]{"name", "lat", "lon"}, null, null, null, null, null); c.moveToFirst(); List<Location> re = new ArrayList<>(c.getCount()); while (!c.isAfterLast()) { if (BuildConfig.DEBUG) Logger.log("added location: " + c.getString(0) + " " + c.getDouble(1) + " " + c.getDouble(2)); re.add(new Location(c.getString(0), new LatLng(c.getDouble(1), c.getDouble(2)))); c.moveToNext(); } c.close(); return re; } /** * Saves a location * * @param name the name (e.g. address or thelike) * @param coords the latitude, longitude coordinate */ public void addLocation(final String name, final LatLng coords) { ContentValues values = new ContentValues(); values.put("name", name); values.put("lat", coords.latitude); values.put("lon", coords.longitude); getWritableDatabase().insert("locations", null, values); } /** * Deletes a location * * @param coords the coordinates of the location to delete */ public void deleteLocation(final LatLng coords) { if (BuildConfig.DEBUG) Logger.log("deleting " + coords.toString() + " contained? " + (getNameForLocation(coords) != null)); getWritableDatabase().delete("locations", "lat LIKE ? AND lon LIKE ?", new String[]{String.valueOf(coords.latitude).substring(0, 8) + "%", String.valueOf(coords.longitude).substring(0, 8) + "%"}); } /** * Gets the saved name for the given coordinates * * @param coords the location to check * @return the name for the given locaiton or null, if that location is not a saved location */ public String getNameForLocation(final LatLng coords) { String lat = String.valueOf(coords.latitude); String lon = String.valueOf(coords.longitude); if (lat.length() > 9) lat = lat.substring(0, 8); if (lon.length() > 9) lon = lon.substring(0, 8); Cursor c = getReadableDatabase() .query("locations", new String[]{"name"}, "lat LIKE ? AND lon LIKE ?", new String[]{lat + "%", lon + "%"}, null, null, null); String result; if (c.moveToFirst()) { result = c.getString(0); } else { result = null; if (BuildConfig.DEBUG) Logger.log("location not in database: " + coords.latitude + "," + coords.longitude); } c.close(); return result; } /** * Checks if the given location is within the given range of any saved location * * @param current the location to test * @return true, if 'current' is within range of any saved location */ public boolean inRangeOfLocation(final android.location.Location current) { String lat = String.valueOf(current.getLatitude()); String lon = String.valueOf(current.getLongitude()); Cursor c = getReadableDatabase().query("locations", new String[]{"lat", "lon"}, "ABS(lat - ?) < 0.1 AND ABS(lon - ?) < 0.1", new String[]{lat, lon}, null, null, null); if (BuildConfig.DEBUG) Logger.log(c.getCount() + " locations found which might be in range"); boolean inRange = false; if (c.moveToFirst()) { android.location.Location location = new android.location.Location("tester"); while (!inRange && !c.isAfterLast()) { location.setLatitude(c.getDouble(0)); location.setLongitude(c.getDouble(1)); inRange = location.distanceTo(current) < current.getAccuracy(); if (BuildConfig.DEBUG) Logger.log("distance to " + location + ": " + location.distanceTo(current)); c.moveToNext(); } } c.close(); return inRange; } }