/* * Androzic - android navigation client that uses OziExplorer maps (ozf2, ozfx3). * Copyright (C) 2010-2012 Andrey Novikov <http://andreynovikov.info/> * * This file is part of Androzic application. * * Androzic is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Androzic is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Androzic. If not, see <http://www.gnu.org/licenses/>. */ package com.androzic; import java.io.File; import java.io.IOException; import java.util.List; import java.util.Locale; import android.annotation.SuppressLint; import android.app.Activity; import android.app.Dialog; import android.content.DialogInterface; import android.content.DialogInterface.OnKeyListener; import android.content.Intent; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; import android.content.res.Resources; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.os.Message; import android.preference.PreferenceManager; import android.support.v7.app.AlertDialog; import android.text.Html; import android.text.SpannableString; import android.text.method.LinkMovementMethod; import android.text.util.Linkify; import android.util.DisplayMetrics; import android.util.Log; import android.view.KeyEvent; import android.view.View; import android.view.View.OnClickListener; import android.view.Window; import android.widget.Button; import android.widget.ProgressBar; import android.widget.TextView; import com.androzic.data.Route; import com.androzic.data.Track; import com.androzic.overlay.CurrentTrackOverlay; import com.androzic.util.AutoloadedRouteFilenameFilter; import com.androzic.util.FileList; import com.androzic.util.GpxFiles; import com.androzic.util.KmlFiles; import com.androzic.util.OziExplorerFiles; public class Splash extends Activity implements OnClickListener { private static final int MSG_FINISH = 1; private static final int MSG_ERROR = 2; private static final int MSG_STATUS = 3; private static final int MSG_PROGRESS = 4; private static final int MSG_ASK = 5; private static final int MSG_SAY = 6; private static final int RES_YES = 1; private static final int RES_NO = 2; private static final int PROGRESS_STEP = 10000; @SuppressWarnings("unused") private int result; private boolean wait; protected String savedMessage; private ProgressBar progress; private TextView message; private Button gotit; private Button yes; private Button no; private Button quit; protected Androzic application; @SuppressLint("NewApi") @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); application = (Androzic) getApplication(); application.onCreateEx(); PreferenceManager.setDefaultValues(this, R.xml.pref_behavior, true); PreferenceManager.setDefaultValues(this, R.xml.pref_folder, true); PreferenceManager.setDefaultValues(this, R.xml.pref_location, true); PreferenceManager.setDefaultValues(this, R.xml.pref_display, true); PreferenceManager.setDefaultValues(this, R.xml.pref_unit, true); PreferenceManager.setDefaultValues(this, R.xml.pref_tracking, true); PreferenceManager.setDefaultValues(this, R.xml.pref_waypoint, true); PreferenceManager.setDefaultValues(this, R.xml.pref_route, true); PreferenceManager.setDefaultValues(this, R.xml.pref_navigation, true); PreferenceManager.setDefaultValues(this, R.xml.pref_general, true); setContentView(R.layout.act_splash); if (application.isPaid) { findViewById(R.id.paid).setVisibility(View.VISIBLE); } progress = (ProgressBar) findViewById(R.id.progress); message = (TextView) findViewById(R.id.message); message.setText(getString(R.string.msg_wait)); progress.setMax(PROGRESS_STEP * 4); yes = (Button) findViewById(R.id.yes); yes.setOnClickListener(this); no = (Button) findViewById(R.id.no); no.setOnClickListener(this); gotit = (Button) findViewById(R.id.gotit); gotit.setOnClickListener(this); quit = (Button) findViewById(R.id.quit); quit.setOnClickListener(this); wait = true; showEula(); if (!application.mapsInited) { new InitializationThread(progressHandler).start(); } else { progressHandler.sendEmptyMessage(MSG_FINISH); } } private void showEula() { final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); boolean hasBeenShown = prefs.getBoolean(getString(R.string.app_eulaaccepted), false); if (hasBeenShown == false) { final SpannableString message = new SpannableString(Html.fromHtml(getString(R.string.app_eula).replace("/n", "<br/>"))); Linkify.addLinks(message, Linkify.WEB_URLS); AlertDialog.Builder builder = new AlertDialog.Builder(this).setTitle(getString(R.string.app_name)).setIcon(R.drawable.icon).setMessage(message) .setPositiveButton(android.R.string.ok, new Dialog.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { prefs.edit().putBoolean(getString(R.string.app_eulaaccepted), true).commit(); wait = false; dialogInterface.dismiss(); } }).setOnKeyListener(new OnKeyListener() { @Override public boolean onKey(DialogInterface dialoginterface, int keyCode, KeyEvent event) { return !(keyCode == KeyEvent.KEYCODE_HOME); } }).setCancelable(false); AlertDialog d = builder.create(); d.show(); // Make the textview clickable. Must be called after show() ((TextView) d.findViewById(android.R.id.message)).setMovementMethod(LinkMovementMethod.getInstance()); } else { wait = false; } } final Handler progressHandler = new Handler() { public void handleMessage(Message msg) { switch (msg.what) { case MSG_STATUS: message.setText(msg.getData().getString("message")); break; case MSG_PROGRESS: int total = msg.getData().getInt("total"); progress.setProgress(total); break; case MSG_ASK: progress.setVisibility(View.GONE); savedMessage = message.getText().toString(); message.setText(msg.getData().getString("message")); result = 0; yes.setVisibility(View.VISIBLE); no.setVisibility(View.VISIBLE); break; case MSG_SAY: progress.setVisibility(View.GONE); savedMessage = message.getText().toString(); message.setText(msg.getData().getString("message")); result = 0; gotit.setVisibility(View.VISIBLE); break; case MSG_FINISH: startActivity(new Intent(Splash.this, MainActivity.class).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK).putExtras(getIntent())); finish(); break; case MSG_ERROR: progress.setVisibility(View.INVISIBLE); message.setText(msg.getData().getString("message")); quit.setVisibility(View.VISIBLE); break; } } }; private class InitializationThread extends Thread { Handler mHandler; int total; InitializationThread(Handler h) { mHandler = h; } public void run() { while (wait) { try { sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } total = 0; Message msg = mHandler.obtainMessage(MSG_STATUS); Bundle b = new Bundle(); b.putString("message", getString(R.string.msg_initializingdata)); msg.setData(b); mHandler.sendMessage(msg); Resources resources = getResources(); SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(Splash.this); // start location service application.enableLocating(settings.getBoolean(getString(R.string.lc_locate), true)); // set root folder and check if it has to be created String rootPath = settings.getString(getString(R.string.pref_folder_root), Environment.getExternalStorageDirectory() + File.separator + resources.getString(R.string.def_folder_prefix)); File root = new File(rootPath); if (!root.exists()) { try { root.mkdirs(); File nomedia = new File(root, ".nomedia"); nomedia.createNewFile(); } catch (IOException e) { msg = mHandler.obtainMessage(MSG_ERROR); b = new Bundle(); b.putString("message", getString(R.string.err_nosdcard)); msg.setData(b); mHandler.sendMessage(msg); return; } } // check maps folder existence File mapdir = new File(settings.getString(getString(R.string.pref_folder_map), Environment.getExternalStorageDirectory() + File.separator + resources.getString(R.string.def_folder_map))); String oldmap = settings.getString(getString(R.string.pref_folder_map_old), null); if (oldmap != null) { File oldmapdir = new File(root, oldmap); if (!oldmapdir.equals(mapdir)) { mapdir = oldmapdir; Editor editor = settings.edit(); editor.putString(getString(R.string.pref_folder_map), mapdir.getAbsolutePath()); editor.putString(getString(R.string.pref_folder_map_old), null); editor.commit(); } } if (!mapdir.exists()) { mapdir.mkdirs(); } // check data folder existence File datadir = new File(settings.getString(getString(R.string.pref_folder_data), Environment.getExternalStorageDirectory() + File.separator + resources.getString(R.string.def_folder_data))); if (!datadir.exists()) { // check if there was an old data structure String wptdir = settings.getString(getString(R.string.pref_folder_waypoint), null); System.err.println("wpt: " + wptdir); if (wptdir != null) { wait = true; msg = mHandler.obtainMessage(MSG_SAY); b = new Bundle(); b.putString("message", getString(R.string.msg_newdatafolder, datadir.getAbsolutePath())); msg.setData(b); mHandler.sendMessage(msg); while (wait) { try { sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } } datadir.mkdirs(); } // old icons are used by plugins so far File iconsdir = new File(settings.getString(getString(R.string.pref_folder_icon), Environment.getExternalStorageDirectory() + File.separator + resources.getString(R.string.def_folder_icon))); // check marker icons folder existence File markericonsdir = new File(settings.getString(getString(R.string.pref_folder_markericon), Environment.getExternalStorageDirectory() + File.separator + resources.getString(R.string.def_folder_markericon))); if (!markericonsdir.exists()) { try { markericonsdir.mkdirs(); int dpi = resources.getDisplayMetrics().densityDpi; String dpiEx = "xxxhdpi"; if (dpi <= DisplayMetrics.DENSITY_XXHIGH) dpiEx = "xxhdpi"; if (dpi <= DisplayMetrics.DENSITY_XHIGH) dpiEx = "xhdpi"; if (dpi <= DisplayMetrics.DENSITY_HIGH) dpiEx = "hdpi"; if (dpi <= DisplayMetrics.DENSITY_MEDIUM) dpiEx = "mdpi"; File nomedia = new File(markericonsdir, ".nomedia"); nomedia.createNewFile(); application.copyAssets("icons-" + dpiEx, markericonsdir); } catch (IOException e) { e.printStackTrace(); } } // initialize paths application.setRootPath(root.getAbsolutePath()); application.setMapPath(mapdir.getAbsolutePath()); application.setDataPath(Androzic.PATH_DATA, datadir.getAbsolutePath()); application.setDataPath(Androzic.PATH_ICONS, iconsdir.getAbsolutePath()); application.setDataPath(Androzic.PATH_MARKERICONS, markericonsdir.getAbsolutePath()); // initialize data application.installData(); // start tracking service application.enableTracking(settings.getBoolean(getString(R.string.lc_track), true)); // read waypoints application.initializeWaypoints(); // read track tail if (settings.getBoolean(getString(R.string.pref_showcurrenttrack), true)) { application.overlayManager.currentTrackOverlay = new CurrentTrackOverlay(); if (settings.getBoolean(getString(R.string.pref_tracking_currentload), resources.getBoolean(R.bool.def_tracking_currentload))) { int length = Integer.parseInt(settings.getString(getString(R.string.pref_tracking_currentlength), getString(R.string.def_tracking_currentlength))); // TODO Move this to proper class File path = new File(application.dataPath, "myTrack.db"); try { SQLiteDatabase trackDB = SQLiteDatabase.openDatabase(path.getAbsolutePath(), null, SQLiteDatabase.OPEN_READONLY | SQLiteDatabase.NO_LOCALIZED_COLLATORS); Cursor cursor = trackDB.rawQuery("SELECT * FROM track ORDER BY _id DESC LIMIT " + length, null); if (cursor.getCount() > 0) { Track track = new Track(); for (boolean hasItem = cursor.moveToLast(); hasItem; hasItem = cursor.moveToPrevious()) { double latitude = cursor.getDouble(cursor.getColumnIndex("latitude")); double longitude = cursor.getDouble(cursor.getColumnIndex("longitude")); double altitude = cursor.getDouble(cursor.getColumnIndex("elevation")); double speed = cursor.getDouble(cursor.getColumnIndex("speed")); double bearing = cursor.getDouble(cursor.getColumnIndex("track")); double accuracy = cursor.getDouble(cursor.getColumnIndex("accuracy")); int code = cursor.getInt(cursor.getColumnIndex("code")); long time = cursor.getLong(cursor.getColumnIndex("datetime")); boolean continous = cursor.isFirst() || cursor.isLast() ? false : code == 0; track.addPoint(continous, latitude, longitude, altitude, speed, bearing, accuracy, time); } track.show = true; application.overlayManager.currentTrackOverlay.setTrack(track); } cursor.close(); trackDB.close(); } catch (Exception e) { Log.e("Splash", "Read track tail", e); } } } // load routes if (settings.getBoolean(getString(R.string.pref_route_preload), resources.getBoolean(R.bool.def_route_preload))) { boolean hide = settings.getBoolean(getString(R.string.pref_route_preload_hidden), resources.getBoolean(R.bool.def_route_preload_hidden)); List<File> files = FileList.getFileListing(new File(application.dataPath), new AutoloadedRouteFilenameFilter()); for (File file : files) { List<Route> routes = null; try { String lc = file.getName().toLowerCase(Locale.getDefault()); if (lc.endsWith(".rt2") || lc.endsWith(".rte")) { routes = OziExplorerFiles.loadRoutesFromFile(file, application.charset); } else if (lc.endsWith(".kml")) { routes = KmlFiles.loadRoutesFromFile(file); } else if (lc.endsWith(".gpx")) { routes = GpxFiles.loadRoutesFromFile(file); } for (Route route : routes) { route.show = !hide; application.addRoute(route); } } catch (Exception e) { e.printStackTrace(); } } } application.overlayManager.init(); total += PROGRESS_STEP; msg = mHandler.obtainMessage(MSG_PROGRESS); b = new Bundle(); b.putInt("total", total); msg.setData(b); mHandler.sendMessage(msg); // put world map if no any found String[] mapfiles = mapdir.list(); if (Variants.ALWAYS_WRITE_MAP_ASSETS || mapfiles != null && mapfiles.length == 0) application.copyAssets("maps", mapdir); msg = mHandler.obtainMessage(MSG_STATUS); b = new Bundle(); b.putString("message", getString(R.string.msg_initializingmaps)); msg.setData(b); mHandler.sendMessage(msg); // initialize maps application.initializeMaps(); application.moveTileCache(); total += PROGRESS_STEP; msg = mHandler.obtainMessage(MSG_PROGRESS); b = new Bundle(); b.putInt("total", total); msg.setData(b); mHandler.sendMessage(msg); msg = mHandler.obtainMessage(MSG_STATUS); b = new Bundle(); b.putString("message", getString(R.string.msg_initializingplugins)); msg.setData(b); mHandler.sendMessage(msg); // initialize plugins application.initializePlugins(); total += PROGRESS_STEP; msg = mHandler.obtainMessage(MSG_PROGRESS); b = new Bundle(); b.putInt("total", total); msg.setData(b); mHandler.sendMessage(msg); msg = mHandler.obtainMessage(MSG_STATUS); b = new Bundle(); b.putString("message", getString(R.string.msg_initializingview)); msg.setData(b); mHandler.sendMessage(msg); // initialize current map application.initializeMapCenter(); // initialize navigation application.initializeNavigation(); total += PROGRESS_STEP; msg = mHandler.obtainMessage(MSG_PROGRESS); b = new Bundle(); b.putInt("total", total); msg.setData(b); mHandler.sendMessage(msg); mHandler.sendEmptyMessage(MSG_FINISH); } } @Override public void onClick(View v) { switch (v.getId()) { case R.id.yes: result = RES_YES; break; case R.id.no: result = RES_NO; break; case R.id.quit: finish(); break; } gotit.setVisibility(View.GONE); yes.setVisibility(View.GONE); no.setVisibility(View.GONE); progress.setVisibility(View.VISIBLE); message.setText(savedMessage); wait = false; } }