package net.osmand.plus.activities; import java.io.BufferedWriter; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileWriter; import java.io.PrintStream; import java.lang.Thread.UncaughtExceptionHandler; import java.util.List; import net.osmand.Algoritms; import net.osmand.LogUtil; import net.osmand.plus.FavouritesDbHelper; import net.osmand.plus.NavigationService; import net.osmand.plus.OsmandSettings; import net.osmand.plus.PoiFiltersHelper; import net.osmand.plus.ProgressDialogImplementation; import net.osmand.plus.R; import net.osmand.plus.ResourceManager; import net.osmand.plus.voice.CommandPlayer; import pl.edu.agh.adhoc.AdHocModule; import pl.edu.agh.logic.TrafficDataProvider; import android.app.AlertDialog; import android.app.AlertDialog.Builder; import android.app.Application; import android.app.ProgressDialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.os.Handler; import android.text.format.DateFormat; import android.util.Log; import android.widget.Toast; public class OsmandApplication extends Application { public static final String EXCEPTION_PATH = ResourceManager.APP_DIR + "exception.log"; //$NON-NLS-1$ ResourceManager manager = null; PoiFiltersHelper poiFilters = null; RoutingHelper routingHelper = null; FavouritesDbHelper favorites = null; CommandPlayer player = null; TrafficDataProvider trafficDataProvider; AdHocModule adHocModule; // start variables private ProgressDialogImplementation startDialog; private List<String> startingWarnings; private ProgressDialog progressDlg; private Handler uiHandler; private DayNightHelper daynightHelper; private NavigationService navigationService; public void onCreate(){ super.onCreate(); routingHelper = new RoutingHelper(OsmandSettings.getApplicationMode(OsmandSettings.getPrefs(OsmandApplication.this)), OsmandApplication.this, player); adHocModule = new AdHocModule(this); adHocModule.init(); trafficDataProvider = new TrafficDataProvider(adHocModule); adHocModule.setTrafficDataProvider(trafficDataProvider); manager = new ResourceManager(this); daynightHelper = new DayNightHelper(this); uiHandler = new Handler(); startApplication(); } @Override public void onTerminate() { adHocModule.finish(); } public AdHocModule getAdHocModule() { return adHocModule; } public PoiFiltersHelper getPoiFilters() { if(poiFilters == null){ poiFilters = new PoiFiltersHelper(this); } return poiFilters; } public FavouritesDbHelper getFavorites() { if(favorites == null) { favorites = new FavouritesDbHelper(this); } return favorites; } public ResourceManager getResourceManager() { return manager; } public DayNightHelper getDaynightHelper() { return daynightHelper; } @Override public void onLowMemory() { super.onLowMemory(); manager.onLowMemory(); } public ProgressDialog checkApplicationIsBeingInitialized(Context uiContext){ synchronized (OsmandApplication.this) { if(startDialog != null){ progressDlg = ProgressDialog.show(uiContext, getString(R.string.loading_data), getString(R.string.reading_indexes), true); startDialog.setDialog(progressDlg); return progressDlg; } else if(startingWarnings != null){ showWarnings(startingWarnings, uiContext); } } return null; } public boolean isApplicationInitializing(){ return startDialog != null; } public RoutingHelper getRoutingHelper() { return routingHelper; } public TrafficDataProvider getTrafficDataProvider() { return trafficDataProvider; } public CommandPlayer getPlayer() { return player; } public void showDialogInitializingCommandPlayer(final Context uiContext){ String voiceProvider = OsmandSettings.getVoiceProvider(OsmandSettings.getPrefs(this)); if(voiceProvider == null){ Builder builder = new AlertDialog.Builder(uiContext); builder.setCancelable(true); builder.setNegativeButton(R.string.default_buttons_cancel, null); builder.setPositiveButton(R.string.default_buttons_ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { uiContext.startActivity(new Intent(uiContext, SettingsActivity.class)); } }); builder.setTitle(R.string.voice_is_not_available_title); builder.setMessage(R.string.voice_is_not_available_msg); builder.show(); } if(player == null || !Algoritms.objectEquals(voiceProvider, player.getCurrentVoice())){ initVoiceDataInDifferentThread(uiContext); } } private void initVoiceDataInDifferentThread(Context uiContext) { final ProgressDialog dlg = ProgressDialog.show(uiContext, getString(R.string.loading_data), getString(R.string.voice_data_initializing)); new Thread(new Runnable() { @Override public void run() { String w = null; try { w = initCommandPlayer(); } finally { dlg.dismiss(); } if(w != null){ showWarning(dlg.getContext(), w); } } }).start(); } public String initCommandPlayer() { if (player == null) { player = new CommandPlayer(OsmandApplication.this); routingHelper.getVoiceRouter().setPlayer(player); } return player.init(OsmandSettings.getVoiceProvider(OsmandSettings.getPrefs(this))); } public NavigationService getNavigationService() { return navigationService; } public void setNavigationService(NavigationService navigationService) { this.navigationService = navigationService; } public void startApplication() { startDialog = new ProgressDialogImplementation(this, null, false); startDialog.setRunnable("Initializing app", new Runnable() { //$NON-NLS-1$ @Override public void run() { List<String> warnings = null; try { warnings = manager.reloadIndexes(startDialog); player = null; SavingTrackHelper helper = new SavingTrackHelper(OsmandApplication.this); if (helper.hasDataToSave()) { startDialog.startTask(getString(R.string.saving_gpx_tracks), -1); warnings.addAll(helper.saveDataToGpx()); } helper.close(); } finally { synchronized (OsmandApplication.this) { startDialog = null; if (progressDlg != null) { progressDlg.dismiss(); showWarnings(warnings, progressDlg.getContext()); progressDlg = null; } else { startingWarnings = warnings; } } } } }); startDialog.run(); Thread.setDefaultUncaughtExceptionHandler(new DefaultExceptionHandler()); } protected void showWarnings(List<String> warnings, final Context uiContext) { if (warnings != null && !warnings.isEmpty()) { final StringBuilder b = new StringBuilder(); boolean f = true; for (String w : warnings) { if(f){ f = false; } else { b.append('\n'); } b.append(w); } showWarning(uiContext, b.toString()); } } private void showWarning(final Context uiContext, final String b) { uiHandler.post(new Runnable() { @Override public void run() { Toast.makeText(uiContext, b.toString(), Toast.LENGTH_LONG).show(); } }); } private class DefaultExceptionHandler implements UncaughtExceptionHandler { private UncaughtExceptionHandler defaultHandler; public DefaultExceptionHandler() { defaultHandler = Thread.getDefaultUncaughtExceptionHandler(); } @Override public void uncaughtException(final Thread thread, final Throwable ex) { File file = OsmandSettings.extendOsmandPath(getApplicationContext(), EXCEPTION_PATH); try { ByteArrayOutputStream out = new ByteArrayOutputStream(); PrintStream printStream = new PrintStream(out); ex.printStackTrace(printStream); StringBuilder msg = new StringBuilder(); msg.append("Exception occured in thread " + thread.toString() + " : "). //$NON-NLS-1$ //$NON-NLS-2$ append(DateFormat.format("MMMM dd, yyyy h:mm:ss", System.currentTimeMillis())).append("\n"). //$NON-NLS-1$//$NON-NLS-2$ append(new String(out.toByteArray())); if (file.getParentFile().canWrite()) { BufferedWriter writer = new BufferedWriter(new FileWriter(file, true)); writer.write(msg.toString()); writer.close(); } defaultHandler.uncaughtException(thread, ex); } catch (Exception e) { // swallow all exceptions Log.e(LogUtil.TAG, "Exception while handle other exception", e); //$NON-NLS-1$ } } } }