diff --git a/app/build.gradle b/app/build.gradle index b9402d19a3c203eca248a46c6b1df15ce5a1c81f..76d627b1a1889e0ef5719eee5715c13359aa0af6 100755 --- a/app/build.gradle +++ b/app/build.gradle @@ -6,9 +6,9 @@ android { defaultConfig { applicationId "ohi.andre.consolelauncher" minSdkVersion 8 - targetSdkVersion 23 - versionCode 78 - versionName "4.8" + targetSdkVersion 25 + versionCode 81 + versionName "4.10" } buildTypes { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 7d098eebda50f1b87b1adb237764503d1457dc62..1a00f156062bda1000300347526a59cbc32f16b9 100755 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -23,6 +23,12 @@ <uses-permission android:name="android.permission.GET_ACCOUNTS" /> <uses-permission android:name="android.permission.WRITE_SETTINGS" /> + <permission android:name="android.permission.FLASHLIGHT" + android:permissionGroup="android.permission-group.HARDWARE_CONTROLS" + android:protectionLevel="normal" + android:label="@string/help_flash" + android:description="@string/help_flash" /> + <!-- features --> <uses-feature android:name="android.hardware.camera" @@ -50,16 +56,13 @@ <activity android:name=".LauncherActivity" android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize" - android:launchMode="singleTask" + android:launchMode="singleInstance" android:stateNotNeeded="true" - android:excludeFromRecents="true" android:windowSoftInputMode="stateAlwaysVisible|adjustResize"> <intent-filter> <action android:name="android.intent.action.MAIN" /> - <category android:name="android.intent.category.HOME" /> <category android:name="android.intent.category.DEFAULT" /> - <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> @@ -99,6 +102,17 @@ android:value=".tuils.tutorial.TutorialIndexActivity" /> </activity> + + <provider + android:name="android.support.v4.content.FileProvider" + android:authorities="${applicationId}.provider" + android:exported="false" + android:grantUriPermissions="true"> + <meta-data + android:name="android.support.FILE_PROVIDER_PATHS" + android:resource="@xml/provider_paths"/> + </provider> + </application> </manifest> \ No newline at end of file diff --git a/app/src/main/java/ohi/andre/consolelauncher/LauncherActivity.java b/app/src/main/java/ohi/andre/consolelauncher/LauncherActivity.java index a1ebd2cbcba73f3dddbd9ceecb30db234ade4fd7..a65f3ff822598ee2b8edd4e02f951836d2c25ac0 100755 --- a/app/src/main/java/ohi/andre/consolelauncher/LauncherActivity.java +++ b/app/src/main/java/ohi/andre/consolelauncher/LauncherActivity.java @@ -1,6 +1,7 @@ package ohi.andre.consolelauncher; import android.Manifest; +import android.annotation.TargetApi; import android.app.Activity; import android.app.admin.DevicePolicyManager; import android.content.ComponentName; @@ -49,6 +50,8 @@ public class LauncherActivity extends Activity implements Reloadable { private PreferencesManager preferencesManager; + private Intent starterIntent; + private CommandExecuter ex = new CommandExecuter() { @Override @@ -126,6 +129,7 @@ public class LauncherActivity extends Activity implements Reloadable { private void finishOnCreate() { File tuiFolder = getFolder(); Resources res = getResources(); + starterIntent = getIntent(); DevicePolicyManager policy = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE); ComponentName component = new ComponentName(this, PolicyReceiver.class); @@ -245,9 +249,17 @@ public class LauncherActivity extends Activity implements Reloadable { @Override public void reload() { - Intent intent = getIntent(); - startActivity(intent); - finish(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { + reloadOver11(); + } else { + finish(); + startActivity(starterIntent); + } + } + + @TargetApi(Build.VERSION_CODES.HONEYCOMB) + private void reloadOver11() { + recreate(); } @Override @@ -256,7 +268,9 @@ public class LauncherActivity extends Activity implements Reloadable { if (hasFocus) { hideStatusBar(); - ui.focusTerminal(); + if (ui != null) { + ui.focusTerminal(); + } } } diff --git a/app/src/main/java/ohi/andre/consolelauncher/UIManager.java b/app/src/main/java/ohi/andre/consolelauncher/UIManager.java index 877cf049297021d5fd41a7585d4f64bc27debe17..d030c2d7850be6f9cc93641fb7d5eb3a4508a380 100755 --- a/app/src/main/java/ohi/andre/consolelauncher/UIManager.java +++ b/app/src/main/java/ohi/andre/consolelauncher/UIManager.java @@ -5,6 +5,7 @@ import android.app.ActivityManager; import android.app.admin.DevicePolicyManager; import android.content.ComponentName; import android.content.Context; +import android.content.Intent; import android.graphics.Typeface; import android.os.Build; import android.os.Handler; @@ -98,6 +99,8 @@ public class UIManager implements OnTouchListener { } }; + boolean doubleTapSU = false; + protected TextWatcher textWatcher = new TextWatcher() { @Override @@ -417,8 +420,10 @@ public class UIManager implements OnTouchListener { policy = null; component = null; det = null; - } else + } else { + doubleTapSU = Boolean.parseBoolean(prefsMgr.getValue(PreferencesManager.DOUBLETAP_SU)); initDetector(); + } mTerminalAdapter = new TerminalManager(terminalView, inputView, prefixView, submitView, skinManager, getHint(prefsMgr), inputBottom); mTerminalAdapter.setInputListener(new OnNewInputListener() { @@ -530,6 +535,8 @@ public class UIManager implements OnTouchListener { det.setOnDoubleTapListener(new OnDoubleTapListener() { + boolean hadSU = false; + @Override public boolean onSingleTapConfirmed(MotionEvent e) { return false; @@ -542,9 +549,13 @@ public class UIManager implements OnTouchListener { @Override public boolean onDoubleTap(MotionEvent e) { - if(Tuils.verifyRoot()) { + if(doubleTapSU) { + hadSU = Tuils.verifyRoot(); + doubleTapSU = hadSU; + } + + if(hadSU) { ShellUtils.execCommand("input keyevent 26", true, null); - return true; } else { boolean admin = policy.isAdminActive(component); @@ -552,9 +563,9 @@ public class UIManager implements OnTouchListener { Tuils.requestAdmin((Activity) mContext, component, mContext.getString(R.string.adminrequest_label)); else policy.lockNow(); - - return true; } + + return true; } }); } diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/raw/airplane.java b/app/src/main/java/ohi/andre/consolelauncher/commands/raw/airplane.java index 5a124f3903bf3229d34dba76cd924431d5b89ecf..1bf6343651f7ac800562f9ce64af0eac9ffcdb9f 100755 --- a/app/src/main/java/ohi/andre/consolelauncher/commands/raw/airplane.java +++ b/app/src/main/java/ohi/andre/consolelauncher/commands/raw/airplane.java @@ -27,7 +27,7 @@ public class airplane implements CommandAbstraction { return info.res.getString(R.string.output_airplane) + !isEnabled; } else - return info.res.getString(R.string.output_noairplane); + return info.res.getString(R.string.output_nofeature); } private boolean isEnabled(Context context) { diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/raw/data.java b/app/src/main/java/ohi/andre/consolelauncher/commands/raw/data.java index efd1f994fd213d6ea91cefbe89f1f173265f5b90..c458151ebb2251f89a365138888d70a99f79a038 100755 --- a/app/src/main/java/ohi/andre/consolelauncher/commands/raw/data.java +++ b/app/src/main/java/ohi/andre/consolelauncher/commands/raw/data.java @@ -1,16 +1,24 @@ package ohi.andre.consolelauncher.commands.raw; +import android.annotation.TargetApi; import android.content.Context; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.NetworkInfo.State; import android.net.wifi.WifiManager; +import android.os.Build; +import android.provider.Settings; +import android.telephony.SubscriptionManager; +import android.telephony.TelephonyManager; +import android.widget.Toast; import java.lang.reflect.Field; +import java.lang.reflect.Method; import ohi.andre.consolelauncher.R; import ohi.andre.consolelauncher.commands.CommandAbstraction; import ohi.andre.consolelauncher.commands.ExecInfo; +import ohi.andre.consolelauncher.tuils.Tuils; public class data implements CommandAbstraction { @@ -22,34 +30,128 @@ public class data implements CommandAbstraction { } private boolean toggle(ExecInfo info) { - if (info.connectivityMgr == null) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { + if (info.connectivityMgr == null) { + try { + init(info); + } catch (Exception e) { + e.printStackTrace(); + } + } + + boolean mobileConnected; + + if (info.wifi == null) + info.wifi = (WifiManager) info.context.getSystemService(Context.WIFI_SERVICE); + + if (info.wifi.isWifiEnabled()) + mobileConnected = true; + else { + NetworkInfo mobileInfo = info.connectivityMgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE); + State state = mobileInfo.getState(); + mobileConnected = state == NetworkInfo.State.CONNECTED || state == NetworkInfo.State.CONNECTING; + } + try { - init(info); + info.setMobileDataEnabledMethod.invoke(info.connectMgr, !mobileConnected); } catch (Exception e) { e.printStackTrace(); } - } - boolean mobileConnected; + return !mobileConnected; + } else { + if (!Tuils.verifyRoot()) { + Toast.makeText(info.context, R.string.output_nofeature, Toast.LENGTH_SHORT).show(); + return false; + } - if (info.wifi == null) - info.wifi = (WifiManager) info.context.getSystemService(Context.WIFI_SERVICE); + if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP) { + try { + return toggleDataLollipop(info.context); + } catch (Exception e) { + e.printStackTrace(); + } + } else { + try { + return toggleDataAboveLollipop(info.context); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + return false; + } - if (info.wifi.isWifiEnabled()) - mobileConnected = true; - else { - NetworkInfo mobileInfo = info.connectivityMgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE); - State state = mobileInfo.getState(); - mobileConnected = state == NetworkInfo.State.CONNECTED || state == NetworkInfo.State.CONNECTING; + private boolean toggleDataLollipop(Context context) throws Exception { + String command = null; + int state = isMobileDataEnabledFromLollipop(context) ? 0 : 1; + String transactionCode = getTransactionCode(context); + if (transactionCode != null && transactionCode.length() > 0) { + command = "service call phone " + transactionCode + " i32 " + state; + return executeCommandViaSu("-c", command); } + return false; + } + private static String getTransactionCode(Context context) throws Exception { try { - info.setMobileDataEnabledMethod.invoke(info.connectMgr, !mobileConnected); + final TelephonyManager mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); + final Class<?> mTelephonyClass = Class.forName(mTelephonyManager.getClass().getName()); + final Method mTelephonyMethod = mTelephonyClass.getDeclaredMethod("getITelephony"); + mTelephonyMethod.setAccessible(true); + final Object mTelephonyStub = mTelephonyMethod.invoke(mTelephonyManager); + final Class<?> mTelephonyStubClass = Class.forName(mTelephonyStub.getClass().getName()); + final Class<?> mClass = mTelephonyStubClass.getDeclaringClass(); + final Field field = mClass.getDeclaredField("TRANSACTION_setDataEnabled"); + field.setAccessible(true); + return String.valueOf(field.getInt(null)); } catch (Exception e) { - e.printStackTrace(); + throw e; + } + } + + private static boolean isMobileDataEnabledFromLollipop(Context context) { + boolean state = false; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + state = Settings.Global.getInt(context.getContentResolver(), "mobile_data", 0) == 1; } + return state; + } - return !mobileConnected; + private static boolean executeCommandViaSu(String option, String command) { + String su = "su"; + for (int i=0; i < 3; i++) { + if (i == 1) { + su = "/system/xbin/su"; + } else if (i == 2) { + su = "/system/bin/su"; + } + try { + Runtime.getRuntime().exec(new String[]{su, option, command}); + } catch (Exception e) { + return false; + } finally { + return true; + } + } + + return false; + } + + @TargetApi(Build.VERSION_CODES.LOLLIPOP_MR1) + private boolean toggleDataAboveLollipop(Context context) throws Exception { + SubscriptionManager mSubscriptionManager = (SubscriptionManager) context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE); + String command = null; + int state = isMobileDataEnabledFromLollipop(context) ? 0 : 1; + String transactionCode = getTransactionCode(context); + for (int i = 0; i < mSubscriptionManager.getActiveSubscriptionInfoCountMax(); i++) { + if (transactionCode != null && transactionCode.length() > 0) { + int subscriptionId = mSubscriptionManager.getActiveSubscriptionInfoList().get(i).getSubscriptionId(); + command = "service call phone " + transactionCode + " i32 " + subscriptionId + " i32 " + state; + return executeCommandViaSu("-c", command); + } + } + return false; } private void init(ExecInfo info) throws Exception { diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/raw/share.java b/app/src/main/java/ohi/andre/consolelauncher/commands/raw/share.java index 8bde354fc5dfd72f9bb8063797f1be9e6a19d979..80fc6b5cc7dfedc965546685a9e7c56bf63fb3af 100755 --- a/app/src/main/java/ohi/andre/consolelauncher/commands/raw/share.java +++ b/app/src/main/java/ohi/andre/consolelauncher/commands/raw/share.java @@ -8,6 +8,7 @@ import java.io.File; import ohi.andre.consolelauncher.R; import ohi.andre.consolelauncher.commands.CommandAbstraction; import ohi.andre.consolelauncher.commands.ExecInfo; +import ohi.andre.consolelauncher.tuils.Tuils; public class share implements CommandAbstraction { @@ -17,12 +18,8 @@ public class share implements CommandAbstraction { if (f.isDirectory()) return info.res.getString(R.string.output_isdirectory); - Intent sharingIntent = new Intent(Intent.ACTION_SEND); - Uri uri = Uri.fromFile(f); - sharingIntent.setType("*/*"); - sharingIntent.putExtra(Intent.EXTRA_STREAM, uri); - info.context.startActivity(Intent.createChooser(sharingIntent, - info.res.getString(R.string.share_label))); + Intent sharingIntent = Tuils.shareFile(info.context, f); + info.context.startActivity(Intent.createChooser(sharingIntent, info.res.getString(R.string.share_label))); return info.res.getString(R.string.sharing) + " " + f.getName(); } diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/raw/status.java b/app/src/main/java/ohi/andre/consolelauncher/commands/raw/status.java index edc7f5f152953e18fadfa9f543ca6d6700a643f4..f0822c3edcdd66417cc625f030ed544500ab0a27 100644 --- a/app/src/main/java/ohi/andre/consolelauncher/commands/raw/status.java +++ b/app/src/main/java/ohi/andre/consolelauncher/commands/raw/status.java @@ -5,6 +5,8 @@ import android.content.Intent; import android.content.IntentFilter; import android.net.ConnectivityManager; import android.net.NetworkInfo; +import android.os.Build; +import android.provider.Settings; import ohi.andre.consolelauncher.R; import ohi.andre.consolelauncher.commands.CommandAbstraction; @@ -33,13 +35,20 @@ public class status implements CommandAbstraction { } level *= 100; - ConnectivityManager cm = (ConnectivityManager) info.context.getSystemService(Context.CONNECTIVITY_SERVICE); - NetworkInfo activeNetwork = cm.getActiveNetworkInfo(); - boolean isMobile = activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE; + boolean connected = false; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + connected = Settings.Global.getInt(info.context.getContentResolver(), "mobile_data", 0) == 1; + } + } else { + ConnectivityManager cm = (ConnectivityManager) info.context.getSystemService(Context.CONNECTIVITY_SERVICE); + NetworkInfo activeNetwork = cm.getActiveNetworkInfo(); + boolean isMobile = activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE; + } return info.res.getString(R.string.battery_charge) + Tuils.SPACE + (int) level + PERCENTAGE + Tuils.NEWLINE + info.res.getString(R.string.wifi) + Tuils.SPACE + wifiConnected + Tuils.NEWLINE + - info.res.getString(R.string.mobile_data) + Tuils.SPACE + isMobile; + info.res.getString(R.string.mobile_data) + Tuils.SPACE + connected; } @Override diff --git a/app/src/main/java/ohi/andre/consolelauncher/managers/AppsManager.java b/app/src/main/java/ohi/andre/consolelauncher/managers/AppsManager.java index 7f46d96e24fe1397f7f172aca5b6a45245953f48..d9a789138c10f53ae8c9a42295d1587f2f0b7dbd 100755 --- a/app/src/main/java/ohi/andre/consolelauncher/managers/AppsManager.java +++ b/app/src/main/java/ohi/andre/consolelauncher/managers/AppsManager.java @@ -11,6 +11,7 @@ import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ResolveInfo; import android.os.Build; +import android.util.Log; import java.util.ArrayList; import java.util.Collections; @@ -443,9 +444,22 @@ public class AppsManager { private static class AppUtils { public static void checkEquality(List<AppInfo> list) { + + First: for (AppInfo info : list) { + + Second: for (int count = 0; count < list.size(); count++) { AppInfo info2 = list.get(count); + + if(info == null || info.publicLabel == null) { + continue First; + } + + if(info2 == null || info2.publicLabel == null) { + continue Second; + } + if (!info.equals(info2) && info.publicLabel.equals(info2.publicLabel)) { list.set(count, new AppInfo(info2.packageName, getNewLabel(info2.publicLabel, info2.packageName), info2.launchedTimes)); @@ -456,27 +470,55 @@ public class AppsManager { public static String getNewLabel(String oldLabel, String packageName) { try { - int firstDot = packageName.indexOf(Tuils.DOT) + 1; - int secondDot = packageName.substring(firstDot).indexOf(Tuils.DOT) + firstDot; - - StringBuilder newLabel = new StringBuilder(); - if (firstDot == -1) { - newLabel.append(packageName); - newLabel.append(Tuils.SPACE); - newLabel.append(oldLabel); - } else if (secondDot == -1) { - newLabel.append(packageName.substring(firstDot, packageName.length())); - newLabel.append(Tuils.SPACE); - newLabel.append(oldLabel); + +// OLD VERSION OF this method +// +// int firstDot = packageName.indexOf(Tuils.DOT) + 1; +// int secondDot = packageName.substring(firstDot).indexOf(Tuils.DOT) + firstDot; +// +// StringBuilder newLabel = new StringBuilder(); +// if (firstDot == -1) { +// newLabel.append(packageName); +// newLabel.append(Tuils.SPACE); +// newLabel.append(oldLabel); +// } else if (secondDot == -1) { +// newLabel.append(packageName.substring(firstDot, packageName.length())); +// newLabel.append(Tuils.SPACE); +// newLabel.append(oldLabel); +// } else { +// newLabel.append(packageName.substring(firstDot, secondDot)); +// newLabel.append(Tuils.SPACE); +// newLabel.append(oldLabel); +// } +// +// String label = newLabel.toString(); +// return label.substring(0, 1).toUpperCase() + label.substring(1); + + int firstDot = packageName.indexOf(Tuils.DOT); + if(firstDot == -1) { +// no dots in package name (nearly impossible) + return packageName; + } + firstDot++; + + int secondDot = packageName.substring(firstDot).indexOf(Tuils.DOT); + String prefix; + if(secondDot == -1) { +// only one dot, so two words. The first is most likely to be the company name +// facebook.messenger +// is better than +// messenger.facebook + prefix = packageName.substring(0, firstDot - 1); + prefix = prefix.substring(0,1).toUpperCase() + prefix.substring(1).toLowerCase(); + return prefix + Tuils.SPACE + oldLabel; } else { - newLabel.append(packageName.substring(firstDot, secondDot)); - newLabel.append(Tuils.SPACE); - newLabel.append(oldLabel); +// two dots or more, the second word is the company name + prefix = packageName.substring(firstDot, secondDot + firstDot); + prefix = prefix.substring(0,1).toUpperCase() + prefix.substring(1).toLowerCase(); + return prefix + Tuils.SPACE + oldLabel; } - String label = newLabel.toString(); - return label.substring(0, 1).toUpperCase() + label.substring(1); - } catch (IndexOutOfBoundsException e) { + } catch (Exception e) { return packageName; } } diff --git a/app/src/main/java/ohi/andre/consolelauncher/managers/FileManager.java b/app/src/main/java/ohi/andre/consolelauncher/managers/FileManager.java index dae35564cad907342e30994720998b546e02d031..56a544cd4138d86d85e78ada9b1ad42c125ce121 100755 --- a/app/src/main/java/ohi/andre/consolelauncher/managers/FileManager.java +++ b/app/src/main/java/ohi/andre/consolelauncher/managers/FileManager.java @@ -192,7 +192,7 @@ public class FileManager { if (file.isDirectory()) return FileManager.ISDIRECTORY; - Intent intent = Tuils.openFile(file); + Intent intent = Tuils.openFile(c, file); c.startActivity(intent); return 0; diff --git a/app/src/main/java/ohi/andre/consolelauncher/managers/PreferencesManager.java b/app/src/main/java/ohi/andre/consolelauncher/managers/PreferencesManager.java index 5575e48f8c69ffc93704238919b0a9a466fed838..fc433cbbd9e7dbc80065f540df364fe2512d1196 100755 --- a/app/src/main/java/ohi/andre/consolelauncher/managers/PreferencesManager.java +++ b/app/src/main/java/ohi/andre/consolelauncher/managers/PreferencesManager.java @@ -13,6 +13,7 @@ import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; +import ohi.andre.consolelauncher.tuils.ShellUtils; import ohi.andre.consolelauncher.tuils.Tuils; public class PreferencesManager { @@ -47,6 +48,7 @@ public class PreferencesManager { public static final String FILE_SUGGESTION_BG = "fileSuggestionBg"; public static final String DOUBLETAP = "closeOnDbTap"; + public static final String DOUBLETAP_SU = "doubleTapSU"; public static final String SHOWSUGGESTIONS = "showSuggestions"; public static final String EXECUTE_ON_SUGGESTION_CLICK = "executeOnSuggestionClick"; @@ -165,6 +167,7 @@ public class PreferencesManager { } else { // settings.txt doesn't exist file.createNewFile(); } + ShellUtils.execCommand("chmod 666 " + file.getAbsolutePath(), false, null); } else return false; @@ -181,6 +184,8 @@ public class PreferencesManager { stream.flush(); stream.close(); + ShellUtils.execCommand("chmod 666 " + file.getAbsolutePath(), false, null); + return true; } catch (Exception e) { return false; diff --git a/app/src/main/java/ohi/andre/consolelauncher/managers/SkinManager.java b/app/src/main/java/ohi/andre/consolelauncher/managers/SkinManager.java index 15b5aa51ca63a41a7296baebd1bb53d7fa8e4d6f..ffeaf83115b1112c35e6a3192b2f3e5911f66a3a 100755 --- a/app/src/main/java/ohi/andre/consolelauncher/managers/SkinManager.java +++ b/app/src/main/java/ohi/andre/consolelauncher/managers/SkinManager.java @@ -4,6 +4,7 @@ import android.graphics.Color; import android.graphics.Typeface; import android.graphics.drawable.ColorDrawable; import android.util.Log; +import android.util.SparseIntArray; import java.util.HashMap; @@ -48,15 +49,20 @@ public class SkinManager { private boolean useSystemWp; private boolean showSuggestions; - private HashMap<Integer, Integer> suggestionBgs = new HashMap<>(); - private int suggestionTextColor; + private int defaulSuggestionColor; + private int appSuggestionColor; + private int aliasSuggestionColor; + private int musicSuggestionColor; + private int contactsSuggestionColor; + private int commandSuggestionColor; + private int fileSuggestionColor; + private boolean multicolorSuggestions; private boolean transparentSuggestions; public SkinManager(PreferencesManager prefs, Typeface lucidaConsole) { - boolean systemFont = Boolean.parseBoolean(prefs.getValue(PreferencesManager.USE_SYSTEMFONT)); globalTypeface = systemFont ? Typeface.DEFAULT : lucidaConsole; @@ -125,71 +131,51 @@ public class SkinManager { transparentSuggestions = false; } - if(transparentSuggestions) { - suggestionBgs.put(0, Color.TRANSPARENT); - - if(suggestionTextColor == bgColor) { - suggestionTextColor = Color.GREEN; - } + if(transparentSuggestions && suggestionTextColor == bgColor) { + suggestionTextColor = Color.GREEN; } else { - int defaultSuggestionBg; try { - defaultSuggestionBg = Color.parseColor(prefs.getValue(PreferencesManager.DEFAULT_SUGGESTION_BG)); + defaulSuggestionColor = Color.parseColor(prefs.getValue(PreferencesManager.DEFAULT_SUGGESTION_BG)); } catch (Exception e) { - defaultSuggestionBg = defaultSuggestionBgDefault; + defaulSuggestionColor = defaultSuggestionBgDefault; } - suggestionBgs.put(0, defaultSuggestionBg); - if(multicolorSuggestions) { - - int appSuggestionBg; try { - appSuggestionBg = Color.parseColor(prefs.getValue(PreferencesManager.APP_SUGGESTION_BG)); + appSuggestionColor = Color.parseColor(prefs.getValue(PreferencesManager.APP_SUGGESTION_BG)); } catch (Exception e) { - appSuggestionBg = appSuggestionBgDefault; + appSuggestionColor = appSuggestionBgDefault; } - suggestionBgs.put(SuggestionsManager.Suggestion.TYPE_APP, appSuggestionBg); - int contactSuggestionBg; try { - contactSuggestionBg = Color.parseColor(prefs.getValue(PreferencesManager.CONTACT_SUGGESTION_BG)); + contactsSuggestionColor = Color.parseColor(prefs.getValue(PreferencesManager.CONTACT_SUGGESTION_BG)); } catch (Exception e) { - contactSuggestionBg = contactSuggestionBgDefault; + contactsSuggestionColor = contactSuggestionBgDefault; } - suggestionBgs.put(SuggestionsManager.Suggestion.TYPE_CONTACT, contactSuggestionBg); - int commandSuggestionsBg; try { - commandSuggestionsBg = Color.parseColor(prefs.getValue(PreferencesManager.COMMAND_SUGGESTION_BG)); + commandSuggestionColor = Color.parseColor(prefs.getValue(PreferencesManager.COMMAND_SUGGESTION_BG)); } catch (Exception e) { - commandSuggestionsBg = commandSuggestionsBgDefault; + commandSuggestionColor = commandSuggestionsBgDefault; } - suggestionBgs.put(SuggestionsManager.Suggestion.TYPE_COMMAND, commandSuggestionsBg); - int songSuggestionBg; try { - songSuggestionBg = Color.parseColor(prefs.getValue(PreferencesManager.SONG_SUGGESTION_BG)); + musicSuggestionColor = Color.parseColor(prefs.getValue(PreferencesManager.SONG_SUGGESTION_BG)); } catch (Exception e) { - songSuggestionBg = songSuggestionBgDefault; + musicSuggestionColor = songSuggestionBgDefault; } - suggestionBgs.put(SuggestionsManager.Suggestion.TYPE_SONG, songSuggestionBg); - int fileSuggestionBg; try { - fileSuggestionBg = Color.parseColor(prefs.getValue(PreferencesManager.FILE_SUGGESTION_BG)); + fileSuggestionColor = Color.parseColor(prefs.getValue(PreferencesManager.FILE_SUGGESTION_BG)); } catch (Exception e) { - fileSuggestionBg = fileSuggestionBgDeafult; + fileSuggestionColor = fileSuggestionBgDeafult; } - suggestionBgs.put(SuggestionsManager.Suggestion.TYPE_FILE, fileSuggestionBg); - int aliasSuggestionBg; try { - aliasSuggestionBg = Color.parseColor(prefs.getValue(PreferencesManager.ALIAS_SIGGESTION_BG)); + aliasSuggestionColor = Color.parseColor(prefs.getValue(PreferencesManager.ALIAS_SIGGESTION_BG)); } catch (Exception e) { - aliasSuggestionBg = aliasSuggestionBgDefault; + aliasSuggestionColor = aliasSuggestionBgDefault; } - suggestionBgs.put(SuggestionsManager.Suggestion.TYPE_ALIAS, aliasSuggestionBg); } } } @@ -199,10 +185,6 @@ public class SkinManager { return globalTypeface; } - public int getGlobalFontSize() { - return globalFontSize; - } - public int getDeviceColor() { return deviceColor; } @@ -236,7 +218,28 @@ public class SkinManager { type = 0; } - return new ColorDrawable(suggestionBgs.get(type)); + if(transparentSuggestions) { + return new ColorDrawable(Color.TRANSPARENT); + } else if(!multicolorSuggestions) { + return new ColorDrawable(defaulSuggestionColor); + } else { + switch (type) { + case SuggestionsManager.Suggestion.TYPE_APP: + return new ColorDrawable(appSuggestionColor); + case SuggestionsManager.Suggestion.TYPE_ALIAS: + return new ColorDrawable(aliasSuggestionColor); + case SuggestionsManager.Suggestion.TYPE_COMMAND: + return new ColorDrawable(commandSuggestionColor); + case SuggestionsManager.Suggestion.TYPE_CONTACT: + return new ColorDrawable(contactsSuggestionColor); + case SuggestionsManager.Suggestion.TYPE_FILE: + return new ColorDrawable(fileSuggestionColor); + case SuggestionsManager.Suggestion.TYPE_SONG: + return new ColorDrawable(musicSuggestionColor); + default: + return new ColorDrawable(defaulSuggestionColor); + } + } } public int getSuggestionTextColor() { diff --git a/app/src/main/java/ohi/andre/consolelauncher/managers/SuggestionsManager.java b/app/src/main/java/ohi/andre/consolelauncher/managers/SuggestionsManager.java index 43fe6692fc91fd5e0aae62553b9247bc4a405bfd..b67c94886cb1e16d2f2e978f69225d03ca0c99d6 100644 --- a/app/src/main/java/ohi/andre/consolelauncher/managers/SuggestionsManager.java +++ b/app/src/main/java/ohi/andre/consolelauncher/managers/SuggestionsManager.java @@ -46,16 +46,19 @@ public class SuggestionsManager { // lastword = 0 && before = 0 if (before.length() == 0) { String[] apps = info.appsManager.getSuggestedApps(); - for(int count = 0; count < apps.length; count++) { - if(apps[count] == null) { - continue; + if (apps != null) { + for(int count = 0; count < apps.length; count++) { + if(apps[count] == null) { + continue; + } + + float shift = count + 1; + float rate = 1f / shift; + suggestionList.add(new Suggestion(apps[count], true, (int) Math.ceil(rate), Suggestion.TYPE_APP)); } - float shift = count + 1; - float rate = 1f / shift; - suggestionList.add(new Suggestion(apps[count], true, (int) Math.ceil(rate), Suggestion.TYPE_APP)); + return suggestionList.toArray(new Suggestion[suggestionList.size()]); } - return suggestionList.toArray(new Suggestion[suggestionList.size()]); } // lastword = 0 && before > 0 else { @@ -123,7 +126,7 @@ public class SuggestionsManager { } int[] args = cmd.argType(); - boolean exec = args[args.length - 1] == CommandAbstraction.PARAM; + boolean exec = args == null || (args[args.length - 1] == CommandAbstraction.PARAM); for (String s : cmd.parameters()) { suggestions.add(new Suggestion(s, exec, NO_RATE, 0)); } diff --git a/app/src/main/java/ohi/andre/consolelauncher/tuils/Tuils.java b/app/src/main/java/ohi/andre/consolelauncher/tuils/Tuils.java index c376ca3f40a9979a1be5ac4a1db6745d2948ca15..c3923edef208a9706fb630d30bc4517cad6a4572 100755 --- a/app/src/main/java/ohi/andre/consolelauncher/tuils/Tuils.java +++ b/app/src/main/java/ohi/andre/consolelauncher/tuils/Tuils.java @@ -17,6 +17,7 @@ import android.os.Build; import android.os.Environment; import android.provider.MediaStore; import android.provider.Settings; +import android.support.v4.content.FileProvider; import android.text.TextUtils; import android.util.Patterns; import android.widget.Toast; @@ -32,6 +33,7 @@ import java.util.List; import java.util.regex.Pattern; import dalvik.system.DexFile; +import ohi.andre.consolelauncher.BuildConfig; import ohi.andre.consolelauncher.managers.MusicManager; import ohi.andre.consolelauncher.tuils.tutorial.TutorialIndexActivity; @@ -103,6 +105,7 @@ public class Tuils { Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN); intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, component); intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, label); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); a.startActivityForResult(intent, 0); } @@ -320,18 +323,85 @@ public class Tuils { } public static String getUsername(Context context) { - Pattern email = Patterns.EMAIL_ADDRESS; - Account[] accs = AccountManager.get(context).getAccounts(); - for (Account a : accs) - if (email.matcher(a.name).matches()) - return a.name; + try { + Pattern email = Patterns.EMAIL_ADDRESS; + Account[] accs = AccountManager.get(context).getAccounts(); + for (Account a : accs) + if (email.matcher(a.name).matches()) + return a.name; + } catch (Exception e) { + return null; + } return null; } - public static Intent openFile(File url) { - Uri uri = Uri.fromFile(url); + public static Intent openFile(Context context, File url) { + Uri uri = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".provider", url); + + Intent intent = new Intent(Intent.ACTION_VIEW); + if (url.toString().contains(".doc") || url.toString().contains(".docx")) { + // Word document + intent.setDataAndType(uri, "application/msword"); + } else if (url.toString().contains(".apk")) { + // apk + intent.setDataAndType(uri, + "application/vnd.android.package-archive"); + } else if (url.toString().contains(".pdf")) { + // PDF file + intent.setDataAndType(uri, "application/pdf"); + } else if (url.toString().contains(".ppt") + || url.toString().contains(".pptx")) { + // Powerpoint file + intent.setDataAndType(uri, "application/vnd.ms-powerpoint"); + } else if (url.toString().contains(".xls") + || url.toString().contains(".xlsx")) { + // Excel file + intent.setDataAndType(uri, "application/vnd.ms-excel"); + } else if (url.toString().contains(".zip") + || url.toString().contains(".rar")) { + // ZIP Files + intent.setDataAndType(uri, "application/zip"); + } else if (url.toString().contains(".rtf")) { + // RTF file + intent.setDataAndType(uri, "application/rtf"); + } else if (url.toString().contains(".wav") + || url.toString().contains(".mp3")) { + // WAV audio file + intent.setDataAndType(uri, "audio/x-wav"); + } else if (url.toString().contains(".gif")) { + // GIF file + intent.setDataAndType(uri, "image/gif"); + } else if (url.toString().contains(".jpg") + || url.toString().contains(".jpeg") + || url.toString().contains(".png")) { + // JPG file + intent.setDataAndType(uri, "image/jpeg"); + } else if (url.toString().contains(".txt")) { + // Text file + intent.setDataAndType(uri, "text/plain"); + } else if (url.toString().contains(".3gp") + || url.toString().contains(".mpg") + || url.toString().contains(".mpeg") + || url.toString().contains(".mpe") + || url.toString().contains(".mp4") + || url.toString().contains(".avi")) { + // Video files + intent.setDataAndType(uri, "video/*"); + } else { + intent.setDataAndType(uri, "*/*"); + } + + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + return intent; + } + + public static Intent shareFile(Context c, File url) { + Uri uri = FileProvider.getUriForFile(c, BuildConfig.APPLICATION_ID + ".provider", url); Intent intent = new Intent(Intent.ACTION_VIEW); + if (url.toString().contains(".doc") || url.toString().contains(".docx")) { // Word document intent.setDataAndType(uri, "application/msword"); @@ -384,8 +454,12 @@ public class Tuils { intent.setDataAndType(uri, "*/*"); } + intent.putExtra(Intent.EXTRA_STREAM, uri); + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); return intent; + } public static String getInternalDirectoryPath() { diff --git a/app/src/main/res/raw/settings.txt b/app/src/main/res/raw/settings.txt index e3bf1421a81e747379036c1a7fc974a197739368..e27a0c403050ed7dede0fab01bd0e5a74ab22d8b 100755 --- a/app/src/main/res/raw/settings.txt +++ b/app/src/main/res/raw/settings.txt @@ -1,5 +1,5 @@ // do not edit the settingsVersion property! -settingsVersion=4.8 +settingsVersion=4.11 // when you are ready go back to t-ui and type "restart" to see changes @@ -45,6 +45,7 @@ songsFolder=/sdcard/Music // others closeOnDbTap=true +doubleTapSU=true showSuggestions=true enableEnterInPhysicalKeyboard=false compareStringForApps=false diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 43b7139fd70d4e571a865f68ae5f019769767b64..d6002921d941941679be1426b61835fec5e273a7 100755 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -43,7 +43,7 @@ <string name="output_wifi">WiFi active:</string> <string name="output_data">Mobile Data active:</string> <string name="output_numbernotfound">Contact not found</string> - <string name="output_noairplane">Can\'t toggle Airplane Mode on 4.2+ Android Version</string> + <string name="output_nofeature">Can\'t use this feature on your Android version</string> <string name="output_airplane">Airplane Mode active:</string> <!-- files --> @@ -129,10 +129,6 @@ \n\nExample: \nhelp search </string> - <string name="help_kill">Kill an application - \nUsage: kill [appName] - \n\nExample: - \nkill Settings</string> <string name="help_mv">Move one or more files to a folder \nUsage: [su] mv [files] [folder] \n\nsu mv fool.txt fool2.png myFolder diff --git a/app/src/main/res/xml/provider_paths.xml b/app/src/main/res/xml/provider_paths.xml new file mode 100644 index 0000000000000000000000000000000000000000..fafa14f895ed086ac360cb4e194562535204a22a --- /dev/null +++ b/app/src/main/res/xml/provider_paths.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8"?> +<paths> + <external-path + name="external_files" + path="." /> +</paths> \ No newline at end of file