Java tutorial
/* * Copyright (C) 2014 team-cachebox.de * * Licensed under the : GNU General Public License (GPL); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.gnu.org/licenses/gpl.html * * 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.cachebox_test; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import org.mapsforge.map.android.graphics.ext_AndroidGraphicFactory; import org.mapsforge.map.model.DisplayModel; import org.slf4j.LoggerFactory; import com.badlogic.gdx.Files.FileType; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.backends.android.AndroidFiles; import CB_Core.Database; import CB_Core.Database.DatabaseType; import CB_Locator.LocatorSettings; import CB_Translation_Base.TranslationEngine.Translation; import CB_UI.Config; import CB_UI.GlobalCore; import CB_UI_Base.Events.PlatformConnector; import CB_UI_Base.Events.PlatformConnector.IgetFolderReturnListener; import CB_UI_Base.GL_UI.DisplayType; import CB_UI_Base.GL_UI.Controls.MessageBox.MessageBoxButtons; import CB_UI_Base.GL_UI.Controls.MessageBox.MessageBoxIcon; import CB_UI_Base.Math.DevicesSizes; import CB_UI_Base.Math.GL_UISizes; import CB_UI_Base.Math.Size; import CB_UI_Base.Math.UI_Size_Base; import CB_UI_Base.Math.UiSizes; import CB_UI_Base.graphics.GL_RenderType; import CB_Utils.Log.CB_SLF4J; import CB_Utils.Log.Log; import CB_Utils.Log.LogLevel; import CB_Utils.Settings.PlatformSettings; import CB_Utils.Settings.PlatformSettings.IPlatformSettings; import CB_Utils.Settings.SettingBase; import CB_Utils.Settings.SettingBool; import CB_Utils.Settings.SettingInt; import CB_Utils.Settings.SettingModus; import CB_Utils.Settings.SettingString; import CB_Utils.Util.FileIO; import CB_Utils.Util.IChanged; import CB_Utils.fileProvider.File; import CB_Utils.fileProvider.FileFactory; import android.annotation.TargetApi; import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; import android.app.ProgressDialog; import android.content.ContentResolver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; import android.content.UriPermission; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Color; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.os.StatFs; import android.support.v4.content.ContextCompat; import android.support.v4.os.EnvironmentCompat; import android.util.DisplayMetrics; import android.view.KeyEvent; import android.view.View; import android.view.View.OnClickListener; import android.view.View.OnLongClickListener; import android.view.Window; import android.widget.Button; import android.widget.CheckBox; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; import de.CB_Utils.fileProvider.AndroidFileFactory; import de.cachebox_test.Components.copyAssetFolder; import de.cachebox_test.Views.Forms.MessageBox; import de.cb.sqlite.AndroidDB; public class splash extends Activity { final static org.slf4j.Logger log = LoggerFactory.getLogger(splash.class); public static Activity splashActivity; final Context context = this; Handler handler; Bitmap bitmap; Dialog pWaitD; String GcCode = null; String guid = null; String name = null; String GpxPath = null; private SharedPreferences androidSetting; private SharedPreferences.Editor androidSettingEditor; String workPath; IgetFolderReturnListener getFolderReturnListener; int AdditionalWorkPathCount; MessageBox msg; ArrayList<String> AdditionalWorkPathArray; private boolean mOriantationRestart = false; private static DevicesSizes ui; private boolean isLandscape = false; private boolean ToastEx = false; private Boolean showSandbox; protected int height; protected int width; private String LolipopworkPath; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (!FileFactory.isInitial()) { new AndroidFileFactory(); } requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.splash); DisplayMetrics displaymetrics = this.getResources().getDisplayMetrics(); GlobalCore.displayDensity = displaymetrics.density; int h = displaymetrics.heightPixels; int w = displaymetrics.widthPixels; int sw = h > w ? w : h; sw /= GlobalCore.displayDensity; // check if tablet GlobalCore.isTab = sw > 400 ? true : false; int dpH = (int) (h / GlobalCore.displayDensity + 0.5); int dpW = (int) (w / GlobalCore.displayDensity + 0.5); if (dpH * dpW >= 960 * 720) GlobalCore.displayType = DisplayType.xLarge; else if (dpH * dpW >= 640 * 480) GlobalCore.displayType = DisplayType.Large; else if (dpH * dpW >= 470 * 320) GlobalCore.displayType = DisplayType.Normal; else GlobalCore.displayType = DisplayType.Small; // berprfen, ob ACB im Hochformat oder Querformat gestartet wurde. // Hochformat -> Handymodus // Querformat -> Tablet-Modus if (w > h) isLandscape = true; // Portrt erzwingen wenn Normal oder Small display if (isLandscape && (GlobalCore.displayType == DisplayType.Normal || GlobalCore.displayType == DisplayType.Small)) { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } // chek if use small skin GlobalCore.useSmallSkin = GlobalCore.displayType == DisplayType.Small ? true : false; // chk if tabletLayout posible GlobalCore.posibleTabletLayout = (GlobalCore.displayType == DisplayType.xLarge || GlobalCore.displayType == DisplayType.Large); // get parameters final Bundle extras = getIntent().getExtras(); final Uri uri = getIntent().getData(); // try to get data from extras if (extras != null) { GcCode = extras.getString("geocode"); name = extras.getString("name"); guid = extras.getString("guid"); } // try to get data from URI if (GcCode == null && guid == null && uri != null) { String uriHost = uri.getHost().toLowerCase(); String uriPath = uri.getPath().toLowerCase(); // String uriQuery = uri.getQuery(); if (uriHost.contains("geocaching.com")) { GcCode = uri.getQueryParameter("wp"); guid = uri.getQueryParameter("guid"); if (GcCode != null && GcCode.length() > 0) { GcCode = GcCode.toUpperCase(); guid = null; } else if (guid != null && guid.length() > 0) { GcCode = null; guid = guid.toLowerCase(); } else { // warning.showToast(res.getString(R.string.err_detail_open)); finish(); return; } } else if (uriHost.contains("coord.info")) { if (uriPath != null && uriPath.startsWith("/gc")) { GcCode = uriPath.substring(1).toUpperCase(); } else { // warning.showToast(res.getString(R.string.err_detail_open)); finish(); return; } } } if (uri != null) { if (uri.getEncodedPath().endsWith(".gpx")) { GpxPath = uri.getEncodedPath(); } } // if ACB running, call this instance if (main.mainActivity != null) { Bundle b = new Bundle(); if (GcCode != null) { b.putSerializable("GcCode", GcCode); b.putSerializable("name", name); b.putSerializable("guid", guid); } if (GpxPath != null) { b.putSerializable("GpxPath", GpxPath); } Intent mainIntent = main.mainActivity.getIntent(); mainIntent.putExtras(b); startActivity(mainIntent); finish(); } splashActivity = this; LoadImages(); if (savedInstanceState != null) { mSelectDbIsStartet = savedInstanceState.getBoolean("SelectDbIsStartet"); mOriantationRestart = savedInstanceState.getBoolean("OriantationRestart"); } if (mOriantationRestart) return; // wait for result } @SuppressWarnings("deprecation") @Override protected void onStart() { super.onStart(); Log.debug(log, "onStart"); if (android.os.Build.VERSION.SDK_INT >= 23) { PermissionCheck.checkNeededPermissions(this); } // initial GDX Gdx.files = new AndroidFiles(this.getAssets(), this.getFilesDir().getAbsolutePath()); // first, try to find stored preferences of workPath androidSetting = this.getSharedPreferences(Global.PREFS_NAME, 0); workPath = androidSetting.getString("WorkPath", Environment.getDataDirectory() + "/cachebox"); boolean askAgain = androidSetting.getBoolean("AskAgain", true); showSandbox = androidSetting.getBoolean("showSandbox", false); Global.initTheme(this); Global.InitIcons(this); CB_Android_FileExplorer fileExplorer = new CB_Android_FileExplorer(this); PlatformConnector.setGetFileListener(fileExplorer); PlatformConnector.setGetFolderListener(fileExplorer); String LangPath = androidSetting.getString("Sel_LanguagePath", ""); if (LangPath.length() == 0) { // set default lang String locale = Locale.getDefault().getLanguage(); if (locale.contains("de")) { LangPath = "data/lang/de/strings.ini"; } else if (locale.contains("cs")) { LangPath = "data/lang/cs/strings.ini"; } else if (locale.contains("cs")) { LangPath = "data/lang/cs/strings.ini"; } else if (locale.contains("fr")) { LangPath = "data/lang/fr/strings.ini"; } else if (locale.contains("nl")) { LangPath = "data/lang/nl/strings.ini"; } else if (locale.contains("pl")) { LangPath = "data/lang/pl/strings.ini"; } else if (locale.contains("pt")) { LangPath = "data/lang/pt/strings.ini"; } else if (locale.contains("hu")) { LangPath = "data/lang/hu/strings.ini"; } else { LangPath = "data/lang/en-GB/strings.ini"; } } new Translation(workPath, FileType.Internal); try { Translation.LoadTranslation(LangPath); } catch (Exception e) { e.printStackTrace(); } // check Write permission if (!askAgain) { if (!FileIO.checkWritePermission(workPath)) { askAgain = true; if (!ToastEx) { ToastEx = true; String WriteProtectionMsg = Translation.Get("NoWriteAcces"); Toast.makeText(splash.this, WriteProtectionMsg, Toast.LENGTH_LONG).show(); } } } if ((askAgain)) { // no saved workPath found -> search sd-cards and if more than 1 is found give the user the possibility to select one String externalSd = getExternalSdPath("/CacheBox"); boolean hasExtSd; final String externalSd2 = externalSd; if (externalSd != null) { hasExtSd = (externalSd.length() > 0) && (!externalSd.equalsIgnoreCase(workPath)); } else { hasExtSd = false; } // externe SD wurde gefunden != internal // oder Tablet Layout mglich // -> Auswahldialog anzeigen try { final Dialog dialog = new Dialog(context) { @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { splash.this.finish(); } return super.onKeyDown(keyCode, event); } }; dialog.setContentView(R.layout.sdselectdialog); TextView title = (TextView) dialog.findViewById(R.id.select_sd_title); title.setText(Translation.Get("selectWorkSpace") + "\n\n"); /* * TextView tbLayout = (TextView) dialog.findViewById(R.id.select_sd_layout); tbLayout.setText("\nLayout"); final RadioGroup * rgLayout = (RadioGroup) dialog.findViewById(R.id.select_sd_radiogroup); final RadioButton rbHandyLayout = (RadioButton) * dialog.findViewById(R.id.select_sd_handylayout); final RadioButton rbTabletLayout = (RadioButton) * dialog.findViewById(R.id.select_sd_tabletlayout); rbHandyLayout.setText("Handy-Layout"); * rbTabletLayout.setText("Tablet-Layout"); if (!GlobalCore.posibleTabletLayout) { * rgLayout.setVisibility(RadioGroup.INVISIBLE); rbHandyLayout.setChecked(true); } else { if (GlobalCore.isTab) { * rbTabletLayout.setChecked(true); } else { rbHandyLayout.setChecked(true); } } */ final CheckBox cbAskAgain = (CheckBox) dialog.findViewById(R.id.select_sd_askagain); cbAskAgain.setText(Translation.Get("AskAgain")); cbAskAgain.setChecked(askAgain); Button buttonI = (Button) dialog.findViewById(R.id.button1); buttonI.setText("Internal SD\n\n" + workPath); buttonI.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // close select dialog dialog.dismiss(); // show please wait dialog showPleaseWaitDialog(); // use internal SD -> nothing to change Thread thread = new Thread() { @Override public void run() { boolean askAgain = cbAskAgain.isChecked(); // boolean useTabletLayout = rbTabletLayout.isChecked(); saveWorkPath(askAgain/* , useTabletLayout */); dialog.dismiss(); startInitial(); } }; thread.start(); } }); Button buttonE = (Button) dialog.findViewById(R.id.button2); final boolean isSandbox = externalSd == null ? false : externalSd.contains("Android/data/de.cachebox_test"); if (!hasExtSd) { buttonE.setVisibility(Button.INVISIBLE); } else { String extSdText = isSandbox ? "External SD SandBox\n\n" : "External SD\n\n"; buttonE.setText(extSdText + externalSd); } buttonE.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // show KitKat Massage? if (isSandbox && !showSandbox) { AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context); // set title alertDialogBuilder.setTitle("KitKat Sandbox"); // set dialog message alertDialogBuilder.setMessage(Translation.Get("Desc_Sandbox")).setCancelable(false) .setPositiveButton(Translation.Get("yes"), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int id) { // if this button is clicked, run Sandbox Path showSandbox = true; Config.AcceptChanges(); // close select dialog dialog.dismiss(); // show please wait dialog showPleaseWaitDialog(); // use external SD -> change workPath Thread thread = new Thread() { @Override public void run() { workPath = externalSd2; boolean askAgain = cbAskAgain.isChecked(); // boolean useTabletLayout = rbTabletLayout.isChecked(); saveWorkPath(askAgain/* , useTabletLayout */); startInitial(); } }; thread.start(); } }) .setNegativeButton(Translation.Get("no"), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int id) { // if this button is clicked, just close // the dialog box and do nothing dialog.cancel(); } }); // create alert dialog AlertDialog alertDialog = alertDialogBuilder.create(); // show it alertDialog.show(); } else { // close select dialog dialog.dismiss(); // show please wait dialog showPleaseWaitDialog(); // use external SD -> change workPath Thread thread = new Thread() { @Override public void run() { workPath = externalSd2; boolean askAgain = cbAskAgain.isChecked(); // boolean useTabletLayout = rbTabletLayout.isChecked(); saveWorkPath(askAgain/* , useTabletLayout */); startInitial(); } }; thread.start(); } } }); LinearLayout ll = (LinearLayout) dialog.findViewById(R.id.scrollViewLinearLayout); // add all Buttons for created Workspaces AdditionalWorkPathArray = getAdditionalWorkPathArray(); for (final String AddWorkPath : AdditionalWorkPathArray) { final String Name = FileIO.GetFileNameWithoutExtension(AddWorkPath); if (!FileIO.checkWritePermission(AddWorkPath)) { // delete this Work Path deleteWorkPath(AddWorkPath); continue; } Button buttonW = new Button(context); buttonW.setText(Name + "\n\n" + AddWorkPath); buttonW.setOnLongClickListener(new OnLongClickListener() { @Override public boolean onLongClick(View v) { // setting the MassageBox then the UI_sizes are not initial in this moment Resources res = splash.this.getResources(); float scale = res.getDisplayMetrics().density; float calcBase = 533.333f * scale; FrameLayout frame = (FrameLayout) findViewById(R.id.frameLayout1); int width = frame.getMeasuredWidth(); int height = frame.getMeasuredHeight(); MessageBox.Builder.WindowWidth = width; MessageBox.Builder.WindowHeight = height; MessageBox.Builder.textSize = (calcBase / res.getDimensionPixelSize(R.dimen.BtnTextSize)) * scale; MessageBox.Builder.ButtonHeight = (int) (50 * scale); // Ask before delete msg = (MessageBox) MessageBox.Show(Translation.Get("shuredeleteWorkspace", Name), Translation.Get("deleteWorkspace"), MessageBoxButtons.YesNo, MessageBoxIcon.Question, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { if (which == MessageBox.BUTTON_POSITIVE) { // Delete this Workpath only from Settings don't delete any File deleteWorkPath(AddWorkPath); } // Start again to exclude the old Folder msg.dismiss(); onStart(); } }); dialog.dismiss(); return true; } }); buttonW.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // close select dialog dialog.dismiss(); // show please wait dialog showPleaseWaitDialog(); // use external SD -> change workPath Thread thread = new Thread() { @Override public void run() { workPath = AddWorkPath; boolean askAgain = cbAskAgain.isChecked(); // boolean useTabletLayout = rbTabletLayout.isChecked(); saveWorkPath(askAgain/* , useTabletLayout */); startInitial(); } }; thread.start(); } }); ll.addView(buttonW); } Button buttonC = (Button) dialog.findViewById(R.id.buttonCreateWorkspace); buttonC.setText(Translation.Get("createWorkSpace")); buttonC.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // close select dialog dialog.dismiss(); getFolderReturnListener = new IgetFolderReturnListener() { @Override public void getFolderReturn(String Path) { if (FileIO.checkWritePermission(Path)) { AdditionalWorkPathArray.add(Path); writeAdditionalWorkPathArray(AdditionalWorkPathArray); // Start again to include the new Folder onStart(); } else { String WriteProtectionMsg = Translation.Get("NoWriteAcces"); Toast.makeText(splash.this, WriteProtectionMsg, Toast.LENGTH_LONG).show(); } } }; PlatformConnector.getFolder("", Translation.Get("select_folder"), Translation.Get("select"), getFolderReturnListener); } }); dialog.show(); } catch (Exception ex) { ex.printStackTrace(); } } else { if (GlobalCore.displayType == DisplayType.Large || GlobalCore.displayType == DisplayType.xLarge) GlobalCore.isTab = isLandscape; // restore the saved workPath // test whether workPath is available by checking the free size on the SD String workPathToTest = workPath.substring(0, workPath.lastIndexOf("/")); long bytesAvailable = 0; try { StatFs stat = new StatFs(workPathToTest); bytesAvailable = (long) stat.getBlockSize() * (long) stat.getBlockCount(); } catch (Exception ex) { bytesAvailable = 0; } if (bytesAvailable == 0) { // there is a workPath stored but this workPath is not available at the moment (maybe SD is removed) Toast.makeText(splashActivity, "WorkPath " + workPath + " is not available!\nMaybe SD-Card is removed?", Toast.LENGTH_LONG) .show(); finish(); return; } startInitial(); } } private String getExternalSdPath(String Folder) { // check if Layout forced from User workPath = Environment.getExternalStorageDirectory() + Folder; // extract first part of path ("/mnt/" or "/storage/" ...) int pos = workPath.indexOf("/", 2); // search for the second / String prev = "/mnt"; if (pos > 0) { prev = workPath.substring(0, pos); } // search for an external SD-Card String externalSd = ""; // search for an external sd card on different devices if ((externalSd = testExtSdPath(prev + "/extSdCard")) != null) { externalSd += Folder; } else if ((externalSd = testExtSdPath(prev + "/MicroSD")) != null) { externalSd += Folder; } else if ((externalSd = testExtSdPath(prev + "/ext_sdcard")) != null) { externalSd += Folder; } else if ((externalSd = testExtSdPath(prev + "/sdcard/ext_sd")) != null) { externalSd += Folder; } else if ((externalSd = testExtSdPath(prev + "/ext_card")) != null) { // Sony Xperia sola externalSd += Folder; } else if ((externalSd = testExtSdPath(prev + "/external")) != null) { externalSd += Folder; } else if ((externalSd = testExtSdPath(prev + "/sdcard2")) != null) { externalSd += Folder; } else if ((externalSd = testExtSdPath(prev + "/sdcard1")) != null) { externalSd += Folder; } else if ((externalSd = testExtSdPath(prev + "/sdcard/_ExternalSD")) != null) { externalSd += Folder; } else if ((externalSd = testExtSdPath(prev + "/sdcard-ext")) != null) { externalSd += Folder; } else if ((externalSd = testExtSdPath(prev + "/external1")) != null) { externalSd += Folder; } else if ((externalSd = testExtSdPath(prev + "/sdcard/external_sd")) != null) { externalSd += Folder; } else if ((externalSd = testExtSdPath(prev + "/emmc")) != null) { // for CM9 externalSd += Folder; } else if ((externalSd = testExtSdPath("/Removable/MicroSD")) != null) { // Asus Transformer externalSd += Folder; } else if ((externalSd = testExtSdPath("/mnt/ext_sd")) != null) { // ODYS Motion externalSd += Folder; } else if ((externalSd = testExtSdPath("/sdcard/tflash")) != null) { // Car Radio externalSd += Folder; } else if ((externalSd = testExtSdPath(prev + "/sdcard")) != null) { // on some devices it is possible that the SD-Card reported by getExternalStorageDirectory() is the extSd and the real // external SD is /mnt/sdcard (Faktor2 Tablet!!!) externalSd += Folder; } else if ((externalSd = testExtSdPath("/mnt/shared/ExtSD")) != null) { // GinyMotion Emulator externalSd += Folder; } final java.io.File[] externalCacheDirs = ContextCompat.getExternalCacheDirs(context); final List<String> result = new ArrayList<String>(); for (int i = 1; i < externalCacheDirs.length; ++i) { final java.io.File file = externalCacheDirs[i]; if (file == null) continue; final String storageState = EnvironmentCompat.getStorageState(file); if (Environment.MEDIA_MOUNTED.equals(storageState)) result.add(getRootOfInnerSdCardFolder(externalCacheDirs[i])); } if (!result.isEmpty()) { externalSd = result.get(0) + Folder; } if (android.os.Build.VERSION.SDK_INT >= 19) { // check for Root permission File sandboxPath = null; String sandboxParentPath = ""; try { String testFolderName = externalSd + "/Test"; File testFolder = FileFactory.createFile(testFolderName); sandboxParentPath = FileFactory.createFile(externalSd).getParent() + "/Android/data/" + getPackageName(); sandboxPath = FileFactory.createFile(sandboxParentPath + "/files"); File test = FileFactory.createFile(testFolder + "/Test.txt"); testFolder.mkdirs(); test.createNewFile(); if (!test.exists()) { externalSd = null; } test.delete(); testFolder.delete(); } catch (Exception e) { externalSd = null; } if (externalSd == null && sandboxPath != null) { // Check Sandbox Path try { // create Sandbox folder with getExternalFilesDir(null); getExternalFilesDir(null); // FileFactory.createFile(sandboxParentPath).mkdirs(); dosen't work String testFolderName = sandboxPath.getAbsolutePath() + File.separator + "Test"; File testFolder = FileFactory.createFile(testFolderName); File test = FileFactory.createFile(testFolderName + File.separator + "Test.txt"); testFolder.mkdirs(); test.createNewFile(); if (!test.exists()) { externalSd = null; } test.delete(); testFolder.delete(); externalSd = sandboxPath.getAbsolutePath(); } catch (Exception e) { e.printStackTrace(); externalSd = null; } } } return externalSd; } /** Given any file/folder inside an sd card, this will return the path of the sd card */ private static String getRootOfInnerSdCardFolder(java.io.File file) { if (file == null) return null; final long totalSpace = file.getTotalSpace(); while (true) { final java.io.File parentFile = file.getParentFile(); if (parentFile == null || parentFile.getTotalSpace() != totalSpace) return file.getAbsolutePath(); file = parentFile; } } private ArrayList<String> getAdditionalWorkPathArray() { ArrayList<String> retList = new ArrayList<String>(); AdditionalWorkPathCount = androidSetting.getInt("AdditionalWorkPathCount", 0); for (int i = 0; i < AdditionalWorkPathCount; i++) { retList.add(androidSetting.getString("AdditionalWorkPath" + String.valueOf(i), "")); } return retList; } private void writeAdditionalWorkPathArray(ArrayList<String> list) { Editor editor = androidSetting.edit(); // first remove all for (int i = 0; i < AdditionalWorkPathCount; i++) { String delWorkPath = "AdditionalWorkPath" + String.valueOf(i); editor.remove(delWorkPath); } editor.commit(); int index = 0; for (String workpath : list) { String addWorkPath = "AdditionalWorkPath" + String.valueOf(index); editor.putString(addWorkPath, workpath); index++; } AdditionalWorkPathCount = index; editor.putInt("AdditionalWorkPathCount", AdditionalWorkPathCount); editor.commit(); } private void deleteWorkPath(String addWorkPath) { int index = AdditionalWorkPathArray.indexOf(addWorkPath); if (index >= 0) AdditionalWorkPathArray.remove(index); writeAdditionalWorkPathArray(AdditionalWorkPathArray); } private static final String PATH_DOCUMENT = "document"; @TargetApi(Build.VERSION_CODES.KITKAT) @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode == RESULT_OK && requestCode == Global.REQUEST_CODE_GET_WRITE_PERMISSION_ANDROID_5) { Uri treeUri = data.getData(); Intent intent = new Intent(Intent.ACTION_GET_CONTENT); final int takeFlags = intent.getFlags() & (Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); // Check for the freshest data. // Uri workPathUri = Uri.parse(workPath); ContentResolver cr = getContentResolver(); grantUriPermission(getPackageName(), treeUri, Intent.FLAG_GRANT_READ_URI_PERMISSION); cr.takePersistableUriPermission(treeUri, takeFlags); List<UriPermission> permissionlist = cr.getPersistedUriPermissions(); LolipopworkPath = "content://com.android.externalstorage.documents/tree/B8C5-760B%3A";// treeUri.getPath(); Thread th = new Thread(new Runnable() { @Override public void run() { Initial(width, height); } }); th.start(); } if (resultCode == RESULT_OK && requestCode == Global.REQUEST_CODE_PICK_FILE_OR_DIRECTORY_FROM_PLATFORM_CONECTOR) { if (resultCode == android.app.Activity.RESULT_OK && data != null) { // obtain the filename Uri fileUri = data.getData(); if (fileUri != null) { String filePath = fileUri.getPath(); if (filePath != null) { if (getFolderReturnListener != null) getFolderReturnListener.getFolderReturn(filePath); } } } return; } } private void showPleaseWaitDialog() { pWaitD = ProgressDialog.show(splash.this, "In progress", "Copy resources"); pWaitD.show(); TextView tv1 = (TextView) pWaitD.findViewById(android.R.id.message); tv1.setTextColor(Color.WHITE); } // this will test whether the extPath is an existing path to an external sd card private String testExtSdPath(String extPath) { if (extPath.equalsIgnoreCase(workPath)) return null; // if this extPath is the same than the actual workPath -> this is the // internal SD, not // the external!!! try { if (FileIO.FileExists(extPath)) { StatFs stat = new StatFs(extPath); @SuppressWarnings("deprecation") long bytesAvailable = (long) stat.getBlockSize() * (long) stat.getBlockCount(); if (bytesAvailable == 0) { return null; // ext SD-Card is not plugged in -> do not use it } else { // Check can Read/Write File f = FileFactory.createFile(extPath); if (f.canWrite()) { if (f.canRead()) { return f.getAbsolutePath(); // ext SD-Card is plugged in } } // Check can Read/Write on Application Storage String appPath = this.getApplication().getApplicationContext().getExternalFilesDir(null) .getAbsolutePath(); int Pos = appPath.indexOf("/Android/data/"); String p = appPath.substring(Pos); File fi = FileFactory.createFile(extPath + p);// "/Android/data/de.cachebox_test/files"); fi.mkdirs(); if (fi.canWrite()) { if (fi.canRead()) { return fi.getAbsolutePath(); } } return null; } } } catch (Exception e) { e.printStackTrace(); } return null; } private void saveWorkPath(boolean askAgain/* , boolean useTabletLayout */) { if (GlobalCore.displayType == DisplayType.Large || GlobalCore.displayType == DisplayType.xLarge) GlobalCore.isTab = isLandscape; SharedPreferences settings = this.getSharedPreferences(Global.PREFS_NAME, 0); // We need an Editor object to make preference changes. // All objects are from android.context.Context SharedPreferences.Editor editor = settings.edit(); editor.putString("WorkPath", workPath); editor.putBoolean("AskAgain", askAgain); // editor.putBoolean("UseTabletLayout", isLandscape); // Commit the edits! editor.commit(); } @Override public void onDestroy() { Log.debug(log, "onDestroy"); if (isFinishing()) { ReleaseImages(); // versionTextView = null; // myTextView = null; // descTextView = null; splashActivity = null; } super.onDestroy(); if (pWaitD != null && pWaitD.isShowing()) { pWaitD.dismiss(); pWaitD = null; } ui = null; } private void startInitial() { // show wait dialog if not running if (pWaitD == null) showPleaseWaitDialog(); // saved workPath found -> use this Thread thread = new Thread() { @Override public void run() { // wait for measure layout final FrameLayout frame = (FrameLayout) findViewById(R.id.frameLayout1); width = frame.getMeasuredWidth(); height = frame.getMeasuredHeight(); while (width == 0 || height == 0) { splash.this.runOnUiThread(new Runnable() { @Override public void run() { frame.forceLayout(); } }); try { Thread.sleep(100); } catch (InterruptedException e) { } width = frame.getMeasuredWidth(); height = frame.getMeasuredHeight(); } // lolipop ask write permission if (android.os.Build.VERSION.SDK_INT > 20) { Initial(width, height); // Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE); // startActivityForResult(intent, 42); } else { Initial(width, height); } } }; thread.start(); } // Here are some examples of how you might call this method. // The first parameter is the MIME type, and the second parameter is the name // of the file you are creating: // // createFile("text/plain", "foobar.txt"); // createFile("image/png", "mypicture.png"); // Unique request code. private static final int WRITE_REQUEST_CODE = 43; private void Initial(int width, int height) { // Jetzt ist der workPath erstmal festgelegt. Log.debug(log, "Initial()"); // lolipop ask write permission if (android.os.Build.VERSION.SDK_INT > 20) { // if (LolipopworkPath != null) workPath = LolipopworkPath + "/cachebox"; } // Zur Kompatibilitt mit lteren Installationen wird hier noch die redirection.txt abgefragt if (FileIO.FileExists(workPath + "/redirection.txt")) { BufferedReader Filereader; try { Filereader = new BufferedReader(new FileReader(workPath + "/redirection.txt")); String line; while ((line = Filereader.readLine()) != null) { // chk ob der umleitungs Ordner existiert if (FileIO.FileExists(line)) { workPath = line; } } Filereader.close(); } catch (IOException e) { Log.err(log, "read redirection", e); } } new Config(workPath); // Read Config Config.Initialize(workPath, workPath + "/cachebox.config"); // hier muss die Config Db initialisiert werden Database.Settings = new AndroidDB(DatabaseType.Settings, this); boolean userFolderExists = FileIO.createDirectory(Config.mWorkPath + "/User"); if (!userFolderExists) return; Database.Settings.StartUp(Config.mWorkPath + "/User/Config.db3"); // initialisieren der PlattformSettings PlatformSettings.setPlatformSettings(new IPlatformSettings() { @Override public void Write(SettingBase<?> setting) { if (androidSetting == null) androidSetting = splash.this.getSharedPreferences(Global.PREFS_NAME, 0); if (androidSettingEditor == null) androidSettingEditor = androidSetting.edit(); if (setting instanceof SettingBool) { androidSettingEditor.putBoolean(setting.getName(), ((SettingBool) setting).getValue()); } else if (setting instanceof SettingString) { androidSettingEditor.putString(setting.getName(), ((SettingString) setting).getValue()); } else if (setting instanceof SettingInt) { androidSettingEditor.putInt(setting.getName(), ((SettingInt) setting).getValue()); } // Commit the edits! androidSettingEditor.commit(); } @Override public SettingBase<?> Read(SettingBase<?> setting) { if (androidSetting == null) androidSetting = splash.this.getSharedPreferences(Global.PREFS_NAME, 0); if (setting instanceof SettingString) { String value = androidSetting.getString(setting.getName(), ""); ((SettingString) setting).setValue(value); } else if (setting instanceof SettingBool) { boolean value = androidSetting.getBoolean(setting.getName(), ((SettingBool) setting).getDefaultValue()); ((SettingBool) setting).setValue(value); } else if (setting instanceof SettingInt) { int value = androidSetting.getInt(setting.getName(), ((SettingInt) setting).getDefaultValue()); ((SettingInt) setting).setValue(value); } setting.clearDirty(); return setting; } }); // wenn die Settings DB neu Erstellt wurde, mssen die Default werte // geschrieben werden. if (Database.Settings.isDbNew()) { Config.settings.LoadAllDefaultValues(); Config.settings.WriteToDB(); } else { Config.settings.ReadFromDB(); } // Add Android Only Settings AndroidSettings.addToSettiongsList(); new CB_SLF4J(workPath); CB_SLF4J.setLogLevel((LogLevel) Config.AktLogLevel.getEnumValue()); Config.AktLogLevel.addChangedEventListener(new IChanged() { @Override public void isChanged() { CB_SLF4J.setLogLevel((LogLevel) Config.AktLogLevel.getEnumValue()); } }); if (GlobalCore.isTab) { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); Log.debug(log, "setRequestedOrientation SCREEN_ORIENTATION_LANDSCAPE"); } else { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); Log.debug(log, "setRequestedOrientation SCREEN_ORIENTATION_PORTRAIT"); } Database.Data = new AndroidDB(DatabaseType.CacheBox, this); // copy AssetFolder only if Rev-Number changed, like at new installation try { if (Config.installRev.getValue() < GlobalCore.CurrentRevision) { String[] exclude = new String[] { "webkit", "sound", "sounds", "images", "skins", "lang", "kioskmode", "string-files", "" }; copyAssetFolder myCopie = new copyAssetFolder(); myCopie.copyAll(getAssets(), Config.mWorkPath, exclude); Config.installRev.setValue(GlobalCore.CurrentRevision); Config.newInstall.setValue(true); Config.AcceptChanges(); File CreateFile; // create .nomedia Files try { CreateFile = FileFactory.createFile(workPath + "/data/.nomedia"); CreateFile.getParentFile().mkdirs(); CreateFile.createNewFile(); } catch (IOException e) { e.printStackTrace(); } try { CreateFile = FileFactory.createFile(workPath + "/skins/.nomedia"); CreateFile.getParentFile().mkdirs(); CreateFile.createNewFile(); } catch (IOException e) { e.printStackTrace(); } try { CreateFile = FileFactory.createFile(workPath + "/repository/.nomedia"); CreateFile.getParentFile().mkdirs(); CreateFile.createNewFile(); } catch (IOException e) { e.printStackTrace(); } try { CreateFile = FileFactory.createFile(workPath + "/Repositories/.nomedia"); CreateFile.getParentFile().mkdirs(); CreateFile.createNewFile(); } catch (IOException e) { e.printStackTrace(); } try { CreateFile = FileFactory.createFile(workPath + "/cache/.nomedia"); CreateFile.getParentFile().mkdirs(); CreateFile.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } else { Config.newInstall.setValue(false); } } catch (Exception e) { Log.err(log, "Copy Asset", e); } // save askAgain for show SandboxMsg Config.showSandbox.setValue(showSandbox); Config.AcceptChanges(); // UiSize Structur fr die Berechnung der Gren zusammen stellen! Log.debug(log, GlobalCore.getVersionString()); Log.debug(log, "Screen width/height:" + width + "/" + height); if (ui == null) { Resources res = splash.this.getResources(); Log.debug(log, "create new devices-sizes"); ui = new DevicesSizes(); ui.Window = new Size(width, height); ui.Density = res.getDisplayMetrics().density; ui.isLandscape = false; // Log Size values Log.debug(log, "UI-Sizes"); Log.debug(log, "ui.Window: " + ui.Window.toString()); Log.debug(log, "ui.Density: " + ui.Density); Log.debug(log, "ui.isLandscape: " + ui.isLandscape); } new UiSizes(); UI_Size_Base.that.initial(ui); GL_UISizes.defaultDPI = ui.Density; Global.Paints.init(this); {// restrict MapsforgeScaleFactor to max 1.0f (TileSize 256x256) ext_AndroidGraphicFactory.createInstance(this.getApplication()); float restrictedScaleFactor = 1f; DisplayModel.setDeviceScaleFactor(restrictedScaleFactor); new de.cachebox_test.Map.AndroidManager(new DisplayModel()); } Initial2(); } private boolean mSelectDbIsStartet = false; private void Initial2() { // initialize Database Database.Data = new AndroidDB(DatabaseType.CacheBox, this); Database.FieldNotes = new AndroidDB(DatabaseType.FieldNotes, this); Config.AcceptChanges(); // Initial Ready Show main finish(); Intent mainIntent = new Intent().setClass(splash.this, main.class); Bundle b = new Bundle(); if (GcCode != null) { b.putSerializable("GcCode", GcCode); b.putSerializable("name", name); b.putSerializable("guid", guid); } if (GpxPath != null) { b.putSerializable("GpxPath", GpxPath); } if (pWaitD != null) { pWaitD.dismiss(); pWaitD = null; } b.putSerializable("UI", ui); GlobalCore.RunFromSplash = true; mainIntent.putExtras(b); Log.info(log, "Splash start Main Intent"); startActivity(mainIntent); finish(); } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putBoolean("SelectDbIsStartet", mSelectDbIsStartet); outState.putBoolean("OriantationRestart", true); } private void LoadImages() { ((TextView) findViewById(R.id.splash_textViewDesc)).setVisibility(View.INVISIBLE); ((TextView) findViewById(R.id.splash_textViewVersion)).setVisibility(View.INVISIBLE); ((TextView) findViewById(R.id.splash_TextView)).setVisibility(View.INVISIBLE); } private void ReleaseImages() { ((ImageView) findViewById(R.id.splash_BackImage)).setImageResource(0); if (bitmap != null) { bitmap.recycle(); bitmap = null; } } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { this.finish(); } return super.onKeyDown(keyCode, event); } //############################################################################## // Implementation of Permission check with Android Version >23 //############################################################################## @TargetApi(23) @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { switch (requestCode) { case PermissionCheck.MY_PERMISSIONS_REQUEST: { Map<String, Integer> perms = new HashMap<String, Integer>(); // Initial for (String permission : PermissionCheck.NEEDED_PERMISSIONS) { perms.put(permission, PackageManager.PERMISSION_GRANTED); } // Fill with results for (int i = 0; i < permissions.length; i++) perms.put(permissions[i], grantResults[i]); // check all ArrayList<String> deniedList = new ArrayList<String>(); for (String permission : PermissionCheck.NEEDED_PERMISSIONS) { if (perms.get(permission) != PackageManager.PERMISSION_GRANTED) deniedList.add(permission); } if (!deniedList.isEmpty()) { // Permission Denied String br = System.getProperty("line.separator"); StringBuilder sb = new StringBuilder(); sb.append("Some Permission is Denied"); sb.append(br); for (String denied : deniedList) { sb.append(denied); sb.append(br); } sb.append(br); sb.append("Cachbox will close"); Toast.makeText(this, sb.toString(), Toast.LENGTH_LONG).show(); // close this.finish(); } } break; default: super.onRequestPermissionsResult(requestCode, permissions, grantResults); } } }