Here's a working solution (it has already been tested in production for 2 months or so), and it works on OnePlus2 and Android 6:
Then in your application, try reading an external database, for example the following:
- Find out which binary is working. I tried several methods (for example, when calling
/proc/cpuinfo ), but could not find a reliable solution, so I do this through a trial version and an error, for example:- First, I copy the binary from my resources folder to the
files application folder - Then I try to dump the desired database through
<path_to_SQLite3_bnary> <path_to_database> \.dump '<tablename>'\n and read the result - I check the result if it contains
error: I know that the binary does not work if it starts with INSERT INTO I know that it works - I repeat this with my binaries until I find a working binary
- Then I just read the result. The result will contain an error or look like csv. I either handle the error or convert each row to a valid csv via
row.replace("INSERT INTO \"" + tablename + "\" VALUES(", "").replace(");", "") content in csv format. I use opencsv CSVReader for data analysis, then ...
What is it, it works (not yet known) on all devices without problems
Code - copied from my sources, a little suitable for your needs
public static List<String> readCSVData(String pathDatabase, String tableName) throws InterruptedException, TimeoutException, RootDeniedException, IOException { List<String> res = null; List<String> csvData = null; final String[] architectures = new String[]{ "armv7", "armv7-pie", "armv6", "armv6-nofpu" }; for (int i = 0; i < architectures.length; i++) { res = readDatabase(architectures[i], pathDatabase, tableName, rootMethod); if (res.toString().contains("[error:")) { Ld(RootNetworkUtil.class, "Trial and Error - ERROR: " + architectures[i]); } else { int maxLength = (res.toString().length() < 100) ? res.toString().length() : 100; Ld(RootNetworkUtil.class, "Trial and Error - RESULT: " + res.toString().substring(0, maxLength)); Ld(RootNetworkUtil.class, "Architecture found via trial and error: " + architectures[i]); csvData = res; break; } } return csvData; } private static List<String> readDatabase(String architecture, String pathDB, String tablename) throws InterruptedException, TimeoutException, RootDeniedException, IOException { String sqlite = "sqlite3." + architecture; String pathSQLite3 = getSQLitePath(architecture, tablename); // OWN class, just copy the file from the assets to the sqlite3 path!!! AssetUtil.copyAsset(sqlite, pathSQLite3); String[] cmd = new String[]{ "su\n", //"chown root.root " + pathSQLite3 + "\n", "chmod 777 " + pathSQLite3 + "\n", pathSQLite3 + " " + pathDB + " \".dump '" + tablename + "'\"\n" }; List<String> res = new ArrayList<>(); List<String> temp = RootUtils.execute(cmd); for (int i = 0; i < temp.size(); i++) { // Fehlerzeilen behalten!!! if (temp.get(i).contains("error:")) res.add(temp.get(i)); else if (temp.get(i).startsWith("INSERT INTO \"" + tablename + "\"")) res.add(temp.get(i).replace("INSERT INTO \"" + tablename + "\" VALUES(", "").replace(");", "")); } return res; } public static String getSQLitePath(String architecture, String addon) { String sqlite = "sqlite3." + architecture; String pathSQLite3 = "/data/data/" + MainApp.get().getPackageName() + "/files/" + sqlite + addon; return pathSQLite3; }
source share