Java tutorial
/* Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 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 com.ideateam.plugin; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLConnection; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import org.apache.cordova.CallbackContext; import org.apache.cordova.CordovaActivity; import org.apache.cordova.CordovaPlugin; import org.apache.cordova.PluginResult; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import android.annotation.SuppressLint; import android.app.Activity; import android.app.ProgressDialog; import android.content.ContentValues; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.os.AsyncTask; import android.util.Log; /** * This class exposes methods in Cordova that can be called from JavaScript. */ public class DownloadDB extends CordovaPlugin { final private String TAG = "CordovaPlugin"; private String zipPath; private String cordovaDBPath; private String cordovaDBName; private String url; private String dbName; private ProgressDialog mProgressDialog; private Activity activity; private CallbackContext callbackContext; private PluginResult result; /** * Executes the request and returns PluginResult. * * @param action * The action to execute. * @param args * JSONArry of arguments for the plugin. * @param callbackContext * The callback context from which we were invoked. */ @SuppressLint("NewApi") public boolean execute(String action, final JSONArray args, final CallbackContext callbackContext) throws JSONException { if (action.equals("downloadDB")) { activity = this.cordova.getActivity(); JSONObject obj = new JSONObject(args.getString(0)); dbName = obj.getString("nameDB"); url = obj.getString("url"); Log.d(TAG, "!!! download zip DB from url: " + url); zipPath = activity.getApplicationContext().getFilesDir().getPath(); zipPath = zipPath.substring(0, zipPath.lastIndexOf("/")) + "/databases"; Log.d(TAG, ".. !!! DB path: " + zipPath); this.callbackContext = callbackContext; isDownloaded = false; URL uri; try { uri = new URL(url); HttpURLConnection httpConnection = (HttpURLConnection) uri.openConnection(); httpConnection.setDoInput(true); httpConnection.setDoOutput(true); httpConnection.setRequestMethod("GET"); httpConnection.connect(); if (httpConnection.getResponseCode() != 200) { Log.d(TAG, "..callbackContext.error "); callbackContext.error("Zip don't exists"); ((CordovaActivity) this.cordova.getActivity()) .sendJavascript("UART.system.Helper.downloadDB('error')"); Log.d(TAG, "..callbackContext.error "); callbackContext.error("Zip don't exists"); ((CordovaActivity) this.cordova.getActivity()) .sendJavascript("UART.system.Helper.downloadDB('error')"); } else { DownloadFile(); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } else if (action.equals("removeDB")) { cordova.getActivity().runOnUiThread(new Runnable() { public void run() { Log.d(TAG, "... removeDB name " + dbName); try { JSONObject obj = new JSONObject(args.getString(0)); String dbName = obj.getString("nameDB"); DeviceDB dDB = GetDeviceDB(dbName); int deletedRows = dDB.master_db.delete("Databases", "name='" + dbName + "'", null); dDB.master_db.close(); File file = new File(dDB.cordovaDBPath + dDB.cordovaDBName); Boolean isDeleted = file.delete(); Log.d(TAG, "..removeDB path " + dDB.cordovaDBPath + dDB.cordovaDBName + " isDeleted " + isDeleted + " del rows " + deletedRows); callbackContext .sendPluginResult(new PluginResult(PluginResult.Status.OK, args.optString(0))); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }); } else if (action.equals("sizeDB")) { cordova.getActivity().runOnUiThread(new Runnable() { JSONObject obj = new JSONObject(args.getString(0)); String dbName = obj.getString("nameDB"); DeviceDB dDB = GetDeviceDB(dbName); File file = new File(dDB.cordovaDBPath + dDB.cordovaDBName); public void run() { Log.d(TAG, ".. sizeDB dbName " + dbName); try { CallbackResult(true, "" + file.length()); callbackContext.success("" + file.length()); } catch (Exception e) { // Log.d(TAG, e.getMessage()); } } }); } else { return false; } Log.d(TAG, "..return from plugin"); return true; } private void CallbackResult(Boolean success, String msg) { Log.d(TAG, " ..CallbackResult " + success + " " + msg); final CordovaActivity activity = (CordovaActivity) this.cordova.getActivity(); if (success) { //activity.sendJavascript("UART.system.Helper.downloadDB('ok')"); callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, msg)); } else { //activity.sendJavascript("UART.system.Helper.downloadDB('error')"); callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, msg)); } } private void DownloadFile() { activity.runOnUiThread(new Runnable() { @Override public void run() { new DownloadFileAsync().execute(url); } }); } private DeviceDB GetDeviceDB(String dbName) { DeviceDB dDB = new DeviceDB(); String path = cordova.getActivity().getApplicationContext().getFilesDir().getPath(); String dbPath = path.substring(0, path.lastIndexOf("/")) + "/app_database/"; Log.d(TAG, dbPath); File file = new File(dbPath + "Databases.db"); if (!file.exists()) { Log.d(TAG, "Databases.db not found"); dbPath = path.substring(0, path.lastIndexOf("/")) + "/app_webview/databases/"; } dDB.master_db = SQLiteDatabase.openDatabase(dbPath + "Databases.db", null, SQLiteDatabase.OPEN_READWRITE); try { Cursor c = dDB.master_db.rawQuery("SELECT origin, path FROM Databases WHERE name='" + dbName + "'", null); c.moveToFirst(); dDB.cordovaDBPath = dbPath + c.getString(0) + "/"; dDB.cordovaDBName = c.getString(1); c.close(); } catch (Exception e) { Log.d(TAG, "Can not found fields ORIGIN, PATH"); Cursor c = dDB.master_db.rawQuery("SELECT origin, id FROM Databases WHERE name='" + dbName + "'", null); c.moveToFirst(); dDB.cordovaDBPath = dbPath + c.getString(0) + "/"; dDB.cordovaDBName = c.getString(1) + ".db"; c.close(); } return dDB; } boolean isDownloaded = false; class DownloadFileAsync extends AsyncTask<String, String, String> { @Override protected void onPreExecute() { super.onPreExecute(); mProgressDialog = new ProgressDialog(activity); mProgressDialog.setMessage("Downloading file.."); mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); mProgressDialog.setCancelable(false); mProgressDialog.show(); Log.d(TAG, "mProgressDialog.show"); } @Override protected String doInBackground(String... aurl) { int count; try { URL url = new URL(aurl[0]); URLConnection conexion = url.openConnection(); conexion.connect(); int lenghtOfFile = conexion.getContentLength(); if (lenghtOfFile > 0) { ReplaceDB(); String path = String.format("%s/%s.zip", zipPath, dbName); mProgressDialog.setMax(lenghtOfFile / 1024); InputStream input = new BufferedInputStream(url.openStream()); Log.d(TAG, "zip path:" + path); File zip = new File(zipPath); zip.mkdirs(); zip = new File(path); zip.createNewFile(); FileOutputStream output = new FileOutputStream(path); // activity.openFileOutput(String.format("%s.zip", // dbName), // Context.MODE_PRIVATE); Log.d(TAG, "zip path 2"); byte data[] = new byte[1024]; long total = 0; while ((count = input.read(data)) != -1) { total += count; publishProgress("" + (int) (total / 1024)); output.write(data, 0, count); } output.flush(); output.close(); input.close(); isDownloaded = true; } } catch (Exception e) { Log.e(TAG, e.getMessage()); CallbackResult(false, e.getMessage()); } return null; } protected void onProgressUpdate(String... progress) { mProgressDialog.setProgress(Integer.parseInt(progress[0])); } @Override protected void onPostExecute(String unused) { mProgressDialog.dismiss(); UnzipUtility unzipper = new UnzipUtility(); if (isDownloaded) { try { //Log.d(TAG, "unzip"); String zipFile = String.format("%s/%s.zip", zipPath, dbName); unzipper.unzip(zipFile, cordovaDBPath); /*SQLiteDatabase master_db = SQLiteDatabase.openDatabase(cordovaDBPath + cordovaDBName, null, SQLiteDatabase.OPEN_READWRITE); master_db.execSQL("CREATE TABLE \"__WebKitDatabaseInfoTable__\" (\"key\" TEXT, \"value\" TEXT)"); ContentValues values = new ContentValues(); values.put("key", "WebKitDatabaseVersionKey"); master_db.insert("__WebKitDatabaseInfoTable__", null, values); master_db.close(); */ callbackContext.success("db imported"); CallbackResult(true, "db imported_"); callbackContext.success("db imported"); CallbackResult(true, "db imported"); Log.d(TAG, "unziped"); } catch (Exception ex) { // some errors occurred ex.printStackTrace(); CallbackResult(false, ex.getMessage()); } } else { CallbackResult(false, "Can not find a zip with DB"); } } } public class UnzipUtility { /** * Size of the buffer to read/write data */ private static final int BUFFER_SIZE = 4096; /** * Extracts a zip file specified by the zipFilePath to a directory * specified by destDirectory (will be created if does not exists) * * @param zipFilePath * @param destDirectory * @throws IOException */ public void unzip(String zipFilePath, String destDirectory) throws IOException { File destDir = new File(destDirectory); if (!destDir.exists()) { destDir.mkdir(); } ZipInputStream zipIn = new ZipInputStream(new FileInputStream(zipFilePath)); ZipEntry entry = zipIn.getNextEntry(); // iterates over entries in the zip file //Log.d(TAG, "..unzip" + entry.getName()); while (entry != null) { String filePath = destDirectory + File.separator + cordovaDBName; if (!entry.isDirectory()) { // if the entry is a file, extracts it extractFile(zipIn, filePath); } else { // if the entry is a directory, make the directory File dir = new File(filePath); dir.mkdir(); } zipIn.closeEntry(); entry = zipIn.getNextEntry(); } zipIn.close(); } /** * Extracts a zip entry (file entry) * * @param zipIn * @param filePath * @throws IOException */ private void extractFile(ZipInputStream zipIn, String filePath) throws IOException { BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filePath)); byte[] bytesIn = new byte[BUFFER_SIZE]; int read = 0; while ((read = zipIn.read(bytesIn)) != -1) { bos.write(bytesIn, 0, read); } bos.close(); } } private void ReplaceDB() { Log.d(TAG, "..Get physical DB name and path. zipPath " + zipPath); String dbPath = zipPath.substring(0, zipPath.lastIndexOf("/")) + "/app_database/"; SQLiteDatabase master_db = null; String field = "path"; Log.d(TAG, dbPath + "Databases.db"); File file = new File(dbPath + "Databases.db"); if (!file.exists()) { Log.d(TAG, "Databases.db not found"); field = "id"; dbPath = zipPath.substring(0, zipPath.lastIndexOf("/")) + "/app_webview/databases/"; } try { master_db = SQLiteDatabase.openDatabase(dbPath + "Databases.db", null, SQLiteDatabase.OPEN_READONLY); } catch (Exception e) { } if (master_db != null) { Cursor c = master_db.rawQuery("SELECT origin, " + field + " FROM Databases WHERE name='" + dbName + "'", null); c.moveToFirst(); cordovaDBPath = dbPath + c.getString(0) + "/"; cordovaDBName = c.getString(1); if (field == "id") { field += ".db"; } c.close(); master_db.close(); Log.d(TAG, ": " + cordovaDBPath + cordovaDBName); } } class DeviceDB { SQLiteDatabase master_db; String cordovaDBPath; String cordovaDBName; } class CheckZip extends AsyncTask<Void, Void, Void> { @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected Void doInBackground(Void... params) { URL uri; try { uri = new URL(url); HttpURLConnection httpCon = (HttpURLConnection) uri.openConnection(); if (httpCon.getResponseCode() != 200) { //throw new Exception("Failed to connect"); CallbackResult(false, "Zip don't exists"); } else { DownloadFile(); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } @Override protected void onPostExecute(Void result) { super.onPostExecute(result); } } }