package de.apps4ics.mountainnavigation;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiManager;
import android.preference.PreferenceManager;
import android.provider.Settings;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.view.GravityCompat;
import android.support.v7.app.ActionBar;
import android.os.Bundle;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.View;
import android.support.v4.widget.DrawerLayout;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;
import android.widget.Toast;
import org.osmdroid.api.IMapController;
import org.osmdroid.bonuspack.overlays.Marker;
import org.osmdroid.tileprovider.tilesource.TileSourceFactory;
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.MapView;
import org.osmdroid.views.overlay.OverlayItem;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import de.apps4ics.mountainnavigation.adapters.ImageListAdapter;
import de.apps4ics.mountainnavigation.handlers.DatabaseHandler;
import de.apps4ics.mountainnavigation.handlers.PoiHandler;
import de.apps4ics.mountainnavigation.handlers.WeatherHandler;
import de.apps4ics.mountainnavigation.pois.DbGeoPoint;
import de.apps4ics.mountainnavigation.pois.Fountain;
import de.apps4ics.mountainnavigation.pois.Poi;
import de.apps4ics.mountainnavigation.pois.Types;
public class MainActivity extends AppCompatActivity implements LocationListener, OnSingleWeatherRetrieved {
public static final String TAG = "MountainNavigation";
/**
* Fragment managing the behaviors, interactions and presentation of the navigation drawer.
*/
private CharSequence mTitle;
private CharSequence mDrawerTitle;
private static final int GPS_MIN_TIME = 5000;
private static final int GPS_MIN_DIST = 5;
private static final int MIN_WEATHER_RELOAD_TIME = 3600000; //1hour, in ms
private static final int MIN_WEATHER_RELOAD_DIST = 5000; //5km, in m
private static final int MIN_POI_RELOAD_TIME = 300000; //5min, in ms
private static final int MIN_POI_RELOAD_DIST = 500; //0.5km, in m
private static int MAX_POIS_AROUND = 20;
public static final int MAX_WIFI_LEVELS = 5;
private static ConnectivityManager cm;
private static TelephonyManager tm;
private static WifiManager wm;
private static NetworkInfo activeNetwork;
private static int networkStrength;
private static SharedPreferences sharedPrefs;
public static SimpleDateFormat df_hm;
public static SimpleDateFormat df_full;
private static Resources res;
private FloatingActionButton fab;
private DatabaseHandler dbHandler;
private PoiHandler poiHandler;
private static WeatherHandler weatherHandler;
private long lastWeatherInformation;
private long lastPoiInformation;
private static MapView mapView;
private IMapController mapController;
public static int ZOOM_LEVEL;
private ActionBarDrawerToggle drawerToggle;
private DrawerLayout drawerLayout;
private ListView poiView;
private ListView menuView;
public static ArrayList<OverlayItem> pathMarkers;
public static OverlayItem imageMarker;
private String provider;
private static Location mLocation;
private LocationManager locationManager;
private static List<Location> foundLocations;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
res = getResources();
pathMarkers = new ArrayList<>();
cm = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
activeNetwork = cm.getActiveNetworkInfo();
networkStrength = 0;
tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
tm.listen(new MyPhoneStateListener(), PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
wm = (WifiManager) getSystemService(WIFI_SERVICE);
sharedPrefs = PreferenceManager.getDefaultSharedPreferences(MainActivity.this);
df_hm = new SimpleDateFormat(res.getString(R.string.date_format_hm));
df_full = new SimpleDateFormat(res.getString(R.string.date_format_full));
RelativeLayout relativeLayout = (RelativeLayout) findViewById(R.id.container);
ZOOM_LEVEL = 18;
mapView = new MapView(getApplicationContext());
mapView.setTileSource(TileSourceFactory.MAPNIK);
mapView.setBuiltInZoomControls(true);
mapView.setMultiTouchControls(true);
mapController = mapView.getController();
mapController.setZoom(ZOOM_LEVEL);
mapController.setCenter(new GeoPoint(48.52, 9.055));
dbHandler = new DatabaseHandler(this);
poiHandler = new PoiHandler(this, res, mapView);
weatherHandler = new WeatherHandler(this);
lastWeatherInformation = lastPoiInformation = 0;
foundLocations = new ArrayList<>();
relativeLayout.addView(mapView);
mTitle = mDrawerTitle = getTitle();
initGps();
fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(mLocation == null){
InformDialog informDialog = new InformDialog(getString(R.string.inform_title), getString(R.string.inform_gps_pos_not_found));
informDialog.show(getFragmentManager(), "Inform Dialog");
return;
}
PoiHandler.AddPoiDialog addPoiDialog = poiHandler.createAddPoiDialog();
addPoiDialog.show(getFragmentManager(), "Add POI Dialog");
}
});
drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
menuView = (ListView) findViewById(R.id.menuList);
poiView = (ListView) findViewById(R.id.poiList);
drawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
// poiView.setItemsCanFocus(false);
ImageListAdapter adapter = new ImageListAdapter(MainActivity.this, PoiHandler.getEntries(), PoiHandler.getEntryImgs(), false);
poiView.setAdapter(adapter);
poiView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
TableLayout layout = (TableLayout) view;
toggleDrawerItems(layout, position);
//drawerLayout.closeDrawers(); //TODO close drawer on click?
}
});
String[] menuEntries = res.getStringArray(R.array.menuEntries);
ArrayAdapter<String> menuAdapter = new ArrayAdapter<>(MainActivity.this, android.R.layout.simple_list_item_1, menuEntries);
menuView.setAdapter(menuAdapter);
menuView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String key = res.getStringArray(R.array.menuEntriesKeys)[position];
if(key.equals(getString(R.string.menu_title_about_key))) {
Intent about = new Intent(MainActivity.this, AboutActivity.class);
startActivity(about);
} else if(key.equals(getString(R.string.menu_title_settings_key))) {
Intent settings = new Intent(MainActivity.this, SettingsActivity.class);
startActivity(settings);
} else if(key.equals(getString(R.string.menu_title_download_key))) {
Intent download = new Intent(MainActivity.this, DownloadActivity.class);
startActivity(download);
}
}
});
drawerLayout.setDrawerListener(drawerToggle);
double _lat = 48.52;
double _lon = 9.055;
double _alt = 350;
long _time = System.currentTimeMillis() / 1000;
DbGeoPoint dbgp = new DbGeoPoint(_lat, _lon, _alt, _time);
long gp_id = dbHandler.addPoi(dbgp);
dbgp.setId(gp_id);
Fountain fountain = new Fountain(0, 2, dbgp);
long f_id = dbHandler.addPoi(fountain);
}
private void toggleDrawerItems(TableLayout layout, int position){
TableRow tr = (TableRow) layout.getChildAt(0); //TODO is tablerow?
TextView tv = null;
ImageView iv = null;
for(int i=0; i<tr.getChildCount(); ++i){
View v = tr.getChildAt(i);
try {
tv = (TextView) v;
} catch(ClassCastException cce){
//Log.e(TAG, "Could not cast " + v.getClass().toString() + " to TextView!");
}
try {
iv = (ImageView) v;
} catch(ClassCastException cce){
//Log.e(TAG, "Could not cast " + v.getClass().toString() + " to ImageView!");
}
}
if(tv == null || iv == null){
Log.e(TAG, "Neither TextView nor ImageView can be null!");
return;
}
int type = getType(position);
if(iv.getTag() == null || iv.getTag() == "disabled"){
iv.setColorFilter(null);
iv.setTag("");
tv.setTextColor(res.getColor(R.color.text_color_selected));
String title = PoiHandler.getEntries()[position];
List<Marker> markers = poiHandler.getPoiIcons(type, title);
mapView.getOverlays().addAll(markers);
mapView.invalidate();
} else {
iv.setColorFilter(res.getColor(R.color.icon_unselected_gray));
iv.setTag("disabled");
tv.setTextColor(res.getColor(R.color.text_color));
Toaster("You disabled " + PoiHandler.getEntries()[position]);
poiHandler.disablePois(type);
mapView.invalidate();
}
}
public static SharedPreferences getSharedPrefs() { return sharedPrefs; }
public static Resources getRes() {
return res;
}
public static boolean showWeatherHints() {
return sharedPrefs.getBoolean(res.getString(R.string.settings_hint_enable_key), true);
}
public static List<Location> getFoundLocations() {
return foundLocations;
}
public static int getPos(int type){
int pos;
switch(type){
case Types.FOUNTAIN:
pos = 0;
break;
case Types.PATH:
pos = 1;
break;
case Types.HUT:
pos = 2;
break;
case Types.PEAK:
pos = 3;
break;
case Types.BREAK_POINT:
pos = 4;
break;
case Types.TRASH_BIN:
pos = 5;
break;
case Types.PIC:
pos = 6;
break;
case Types.CELL_RECEPTION:
pos = 7;
break;
case Types.WIFI:
pos = 8;
break;
case Types.LIFT:
pos = 9;
break;
default:
pos = 0;
break;
}
return pos;
}
public static int getType(int position){
int type;
switch (position){
case 0:
type = Types.FOUNTAIN;
break;
case 1:
type = Types.PATH;
break;
case 2:
type = Types.HUT;
break;
case 3:
type = Types.PEAK;
break;
case 4:
type = Types.BREAK_POINT;
break;
case 5:
type = Types.TRASH_BIN;
break;
case 6:
type = Types.PIC;
break;
case 7:
type = Types.CELL_RECEPTION;
break;
case 8:
type = Types.WIFI;
break;
case 9:
type = Types.LIFT;
break;
case 10:
type = Types.GP;
break;
default:
type = 0;
break;
}
return type;
}
private String getTypeName(int type){
String name = "";
switch(type){
case Types.FOUNTAIN:
name = "fountain";
break;
case Types.PATH:
name = "path";
break;
case Types.HUT:
name = "hut";
break;
case Types.PEAK:
name = "peak";
break;
case Types.BREAK_POINT:
name = "break_point";
break;
case Types.TRASH_BIN:
name = "trash_bin";
break;
case Types.PIC:
name = "image";
break;
case Types.CELL_RECEPTION:
name = "cell_reception";
break;
case Types.WIFI:
name = "wifi";
break;
case Types.LIFT:
name = "lift";
break;
}
return name;
}
private void initGps(){
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
boolean isLocationEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
if(!isLocationEnabled){
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);
}
Criteria criteria = new Criteria();
provider = locationManager.getBestProvider(criteria, false);
mLocation = locationManager.getLastKnownLocation(provider);
}
private void Toaster(String text){
Toaster(text, false);
}
private void Toaster(String text, boolean longDuration){
if(longDuration) Toast.makeText(getApplicationContext(), text, Toast.LENGTH_LONG).show();
else Toast.makeText(getApplicationContext(), text, Toast.LENGTH_SHORT).show();
}
public static void Toaster(String text, Context context){
Toaster(text, false, context);
}
public static void Toaster(String text, boolean longDuration, Context context) {
if(longDuration) Toast.makeText(context, text, Toast.LENGTH_LONG).show();
else Toast.makeText(context, text, Toast.LENGTH_SHORT).show();
}
public static Location getLocation() { return mLocation; }
public static MapView getMapView(){
return mapView;
}
public DatabaseHandler getDbHandler(){
return dbHandler;
}
public static ArrayList<OverlayItem> getPathMarkers(){
return pathMarkers;
}
public static void setPathMarkers(ArrayList<OverlayItem> al){
pathMarkers = al;
}
private static void setActiveNetwork(){
activeNetwork = cm.getActiveNetworkInfo();
}
public static void setNetworkStrength(int strength){
networkStrength = strength;
}
public static int getNetworkStrength() {
return networkStrength;
}
private void addSimpleMarker(GeoPoint gp){
Marker positionMarker = new Marker(mapView);
positionMarker.setPosition(gp);
positionMarker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM);
positionMarker.setTitle(getString(R.string.osm_marker_title));
positionMarker.setSnippet(String.format(getString(R.string.osm_marker_snippet), gp.getLatitude(), gp.getLongitude(), gp.getAltitude(), 0));
mapView.getOverlays().add(positionMarker);
mapView.invalidate();
}
@Override
public void onLocationChanged(Location location) {
if(mLocation != null) {
Location oldLocation = new Location(mLocation);
long currentTime = System.currentTimeMillis();
float distance = mLocation.distanceTo(oldLocation);
if(currentTime - lastWeatherInformation >= MIN_WEATHER_RELOAD_TIME || distance >= MIN_WEATHER_RELOAD_DIST) {
lastWeatherInformation = currentTime;
weatherHandler.getCurrentWeather(location, this);
}
if(currentTime - lastPoiInformation >= MIN_POI_RELOAD_TIME || distance >= MIN_POI_RELOAD_DIST) { //5 minutes
lastPoiInformation = currentTime;
ArrayList<Poi> pois = new ArrayList<>(poiHandler.getPoisAround(location.getLatitude(), location.getLongitude(), MAX_POIS_AROUND));
for(Poi p : pois) {
p.display();
}
}
}
mLocation = location;
if(mLocation == null) return;
foundLocations.add(location);
double lat = location.getLatitude();
double lon = location.getLongitude();
GeoPoint gp = new GeoPoint(lat, lon);
addSimpleMarker(gp);
mapController.setCenter(gp);
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.d(TAG, "onStatusChanged: " + provider + ", " + status);
}
@Override
public void onProviderEnabled(String provider) {
Log.d(TAG, "onProviderEnabled: " + provider);
}
@Override
public void onProviderDisabled(String provider) {
Log.d(TAG, "onProviderDisabled: " + provider);
}
public static WeatherHandler getWeatherHandler() { return weatherHandler; }
public static NetworkInfo getActiveNetwork() {
return activeNetwork;
}
public static WifiManager getWifiManager() {
return wm;
}
public static TelephonyManager getTelephonyManager() {
return tm;
}
public static boolean hasInternet() {
setActiveNetwork();
return activeNetwork != null && activeNetwork.isConnected();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch(requestCode){
case PoiHandler.SELECT_POI_PHOTO:
if(resultCode == RESULT_OK){
poiHandler.addImagePoi(data.getData());
}
break;
}
}
@Override
public void setTitle(CharSequence title){
mTitle = title;
ActionBar actionBar = getSupportActionBar();
if(actionBar != null) actionBar.setTitle(mTitle);
}
@Override
protected void onStart() {
super.onStart();
}
@Override
protected void onResume() {
super.onResume();
locationManager.requestLocationUpdates(provider, GPS_MIN_TIME, GPS_MIN_DIST, this);
}
@Override
protected void onPause() {
super.onPause();
locationManager.removeUpdates(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
}
@Override
public MyWeather postRetrieve(MyWeather weather) {
weatherHandler.displayHints(weather);
weatherHandler.displaySevereWeather(weather);
return null;
}
}