From b74d9f1825dd43a040c408fa89dbe8ea121040e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Katzer?= Date: Sun, 15 Dec 2013 11:09:02 +0100 Subject: [PATCH] Add KitKat support - requires Android SDK 19 or higher --- README.md | 25 +-- plugin.xml | 5 +- src/android/KitKatPrinter.java | 142 ---------------- src/android/Printer.java | 293 ++++++--------------------------- www/printer.js | 12 +- 5 files changed, 52 insertions(+), 425 deletions(-) delete mode 100644 src/android/KitKatPrinter.java diff --git a/README.md b/README.md index b800d67..d2e5da5 100644 --- a/README.md +++ b/README.md @@ -9,11 +9,7 @@ by Sebastián Katzer ([github.com/katzer](https://github.com/katzer)) - **iOS** *(Print from iOS devices to AirPrint compatible printers)*
See [Drawing and Printing Guide for iOS](http://developer.apple.com/library/ios/documentation/2ddrawing/conceptual/drawingprintingios/Printing/Printing.html) for detailed informations and screenshots. -- **Android** *(Print through 3rd party printing apps on SDK <= 18)* - -## Dependencies -Cordova will check all dependencies and install them if they are missing. -- [org.apache.cordova.device](https://github.com/apache/cordova-plugin-device) *(since v0.5.0)* +- **Android** *(SDK 19)* ## Adding the Plugin to your project Through the [Command-line Interface](http://cordova.apache.org/docs/en/3.0.0/guide_cli_index.md.html#The%20Command-line%20Interface): @@ -29,7 +25,7 @@ cordova plugin rm de.appplant.cordova.plugin.printer ``` ## Release Notes -#### Version 0.5.0 (not yet released) +#### Version 0.5.0 (11.12.2013) - Release under the Apache 2.0 license. - [***change:***] Removed the `callback` property from the `print` interface. - [enhancement:] Added Android KitKat support
@@ -79,23 +75,6 @@ var page = document.body.innerHTML; window.plugin.printer.print(page); ``` -## Platform specifics - -### Get all available printing apps on Android <= 4.3 -The callback function will be called with a second argument which is an array, indicating which printer apps are available for printing. -```javascript -window.plugin.printer.isServiceAvailable( - function (isAvailable, installedAppIds) { - alert('The following print apps are installed on your device: ' + installedAppIds.join(', ')); - } -); -``` - -### Specify printing app on Android <= 4.3 -An App-ID can be assigned as a platform configuration to indicate which 3rd party printing app shall be used. Otherwise the first found application will be used. -```javascript -window.plugin.printer.print(page, { appId: 'epson.print' }); -``` ## Quirks diff --git a/plugin.xml b/plugin.xml index fbe0ca3..3200a63 100644 --- a/plugin.xml +++ b/plugin.xml @@ -9,7 +9,7 @@ A bunch of printig plugins for Cordova 3.x.x https://github.com/katzer/cordova-plugin-printer.git - print, printer, ios, android + print, printer, ios, android, kitkat Apache 2.0 Sebastián Katzer @@ -50,8 +50,7 @@ - - + diff --git a/src/android/KitKatPrinter.java b/src/android/KitKatPrinter.java deleted file mode 100644 index 75805d5..0000000 --- a/src/android/KitKatPrinter.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - Copyright 2013 appPlant UG - - 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 de.appplant.cordova.plugin.printer; - -import org.apache.cordova.CallbackContext; -import org.apache.cordova.CordovaPlugin; -import org.apache.cordova.PluginResult; - -import org.json.JSONArray; -import org.json.JSONException; - -import android.annotation.TargetApi; -import android.content.Context; -import android.os.Build; -import android.print.PrintAttributes; -import android.print.PrintDocumentAdapter; -import android.print.PrintManager; -import android.view.View; -import android.webkit.WebView; -import android.webkit.WebViewClient; - -@TargetApi(19) -public class KitKatPrinter extends CordovaPlugin { - - @Override - public boolean execute (String action, JSONArray args, CallbackContext callbackContext) throws JSONException { - // Es soll überprüft werden, ob ein Dienst zum Ausdrucken von Inhalten zur Verfügung steht - if (action.equalsIgnoreCase("isServiceAvailable")) { - isServiceAvailable(callbackContext); - - return true; - } - - // Etwas soll ausgedruckt werden - if (action.equalsIgnoreCase("print")) { - print(args, callbackContext); - - return true; - } - - // Returning false results in a "MethodNotFound" error. - return false; - } - - /** - * Überprüft, ob ein Drucker zur Verfügung steht. - */ - private void isServiceAvailable (CallbackContext ctx) { - Boolean supported = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; - PluginResult result = new PluginResult(PluginResult.Status.OK, supported); - - ctx.sendPluginResult(result); - } - - /** - * Druckt den HTML Content aus. - */ - private void print (final JSONArray args, CallbackContext ctx) { - final KitKatPrinter self = this; - - cordova.getActivity().runOnUiThread( new Runnable() { - public void run() { - String content = args.optString(0, ""); - WebView controller = self.getPrintController(); - - self.loadContentIntoPrintController(content, controller); - - self.startPrinterApp(controller); - } - }); - } - - /** - * Erstellt den Print-View. - */ - private WebView getPrintController () { - WebView webview = new WebView(cordova.getActivity()); - - webview.setVisibility(View.INVISIBLE); - webview.getSettings().setJavaScriptEnabled(false); - - return webview; - } - - /** - * Lädt den zu druckenden Content in ein WebView, welcher vom Drucker ausgedruckt werden soll. - */ - private void loadContentIntoPrintController (String content, WebView webview) { - //Set base URI to the assets/www folder - String baseURL = webView.getUrl(); - baseURL = baseURL.substring(0, baseURL.lastIndexOf('/') + 1); - - webview.loadDataWithBaseURL(baseURL, content, "text/html", "UTF-8", null); - } - - /** - * Öffnet die Printer App, damit der Content ausgedruckt werden kann. - */ - private void startPrinterApp (WebView webview) { - webview.setWebViewClient (new WebViewClient() { - public boolean shouldOverrideUrlLoading (WebView view, String url) { - return false; - } - - public void onPageFinished (WebView webview, String url) { - // Get a PrintManager instance - PrintManager printManager = (PrintManager) cordova.getActivity() - .getSystemService(Context.PRINT_SERVICE); - - // Get a print adapter instance - PrintDocumentAdapter printAdapter = webView.createPrintDocumentAdapter(); - - // Get a print builder instance - PrintAttributes.Builder builder = new PrintAttributes.Builder(); - - builder.setMinMargins(PrintAttributes.Margins.NO_MARGINS); - - // Create a print job with name and adapter instance - printManager.print("Print Document", printAdapter, builder.build()); - } - }); - } -} diff --git a/src/android/Printer.java b/src/android/Printer.java index 7c6d1b4..15fae6a 100644 --- a/src/android/Printer.java +++ b/src/android/Printer.java @@ -21,81 +21,38 @@ package de.appplant.cordova.plugin.printer; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; +import org.apache.cordova.CallbackContext; +import org.apache.cordova.CordovaPlugin; +import org.apache.cordova.PluginResult; import org.json.JSONArray; import org.json.JSONException; -import org.json.JSONObject; -import android.app.Activity; -import android.content.Intent; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.Picture; -import android.net.Uri; -import android.os.Handler; +import android.annotation.TargetApi; +import android.content.Context; +import android.os.Build; +import android.print.PrintAttributes; +import android.print.PrintDocumentAdapter; +import android.print.PrintManager; import android.view.View; -import android.view.ViewGroup; import android.webkit.WebView; import android.webkit.WebViewClient; -import org.apache.cordova.CordovaPlugin; -import org.apache.cordova.CallbackContext; -import org.apache.cordova.PluginResult; - +@TargetApi(19) public class Printer extends CordovaPlugin { - private CallbackContext ctx; - - /** - * Auflistung von App-IDs, welche den Content ausdrucken können - */ - private String printAppIds[] = { - "kr.co.iconlab.BasicPrintingProfile", // Bluetooth Smart Printing - "com.blueslib.android.app", // Bluetooth SPP Printer API - "com.brother.mfc.brprint", // Brother iPrint&Scan - "com.brother.ptouch.sdk", // Brother Print Library - "jp.co.canon.bsd.android.aepp.activity", // Canon Easy-PhotoPrint - "com.pauloslf.cloudprint", // Cloud Print - "com.dlnapr1.printer", // CMC DLNA Print Client - "com.dell.mobileprint", // Dell Mobile Print - "com.printjinni.app.print", // PrintJinni - "epson.print", // Epson iPrint - "jp.co.fujixerox.prt.PrintUtil.PCL", // Fuji Xerox Print Utility - "jp.co.fujixerox.prt.PrintUtil.Karin", // Fuji Xeros Print&Scan (S) - "com.hp.android.print", // HP ePrint" "com.hp.android.print - "com.blackspruce.lpd", // Let's Print Droid - "com.threebirds.notesprint", // NotesPrint print your notes - "com.xerox.mobileprint", // Print Portal (Xerox) - "com.zebra.kdu", // Print Station (Zebra) - "net.jsecurity.printbot", // PrintBot - "com.dynamixsoftware.printhand", // PrintHand Mobile Print - "com.dynamixsoftware.printhand.premium", // PrintHand Mobile Print Premium - "com.sec.print.mobileprint", // Samsung Mobile Print - "com.rcreations.send2printer", // Send 2 Printer - "com.ivc.starprint", // StarPrint - "com.threebirds.easyviewer", // WiFi Print - "com.woosim.android.print", // Woosim BT printer - "com.woosim.bt.app", // WoosimPrinter - "com.zebra.android.zebrautilities", // Zebra Utilities - }; - @Override public boolean execute (String action, JSONArray args, CallbackContext callbackContext) throws JSONException { - // Etwas soll ausgedruckt werden - if ("print".equals(action)) { - print(args, callbackContext); + // Es soll überprüft werden, ob ein Dienst zum Ausdrucken von Inhalten zur Verfügung steht + if (action.equalsIgnoreCase("isServiceAvailable")) { + isServiceAvailable(callbackContext); return true; } - // Es soll überprüft werden, ob ein Dienst zum Ausdrucken von Inhalten zur Verfügung steht - if ("isServiceAvailable".equals(action)) { - isServiceAvailable(callbackContext); + // Etwas soll ausgedruckt werden + if (action.equalsIgnoreCase("print")) { + print(args, callbackContext); return true; } @@ -108,9 +65,8 @@ public class Printer extends CordovaPlugin { * Überprüft, ob ein Drucker zur Verfügung steht. */ private void isServiceAvailable (CallbackContext ctx) { - JSONArray appIds = this.getInstalledAppIds(); - Boolean available = appIds.length() > 0; - PluginResult result = new PluginResult(PluginResult.Status.OK, available); + Boolean supported = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; + PluginResult result = new PluginResult(PluginResult.Status.OK, supported); ctx.sendPluginResult(result); } @@ -119,24 +75,13 @@ public class Printer extends CordovaPlugin { * Druckt den HTML Content aus. */ private void print (final JSONArray args, CallbackContext ctx) { - final Printer self = this; - - this.ctx = ctx; + final KitKatPrinter self = this; cordova.getActivity().runOnUiThread( new Runnable() { public void run() { - JSONObject platformConfig = args.optJSONObject(1); - String appId = self.getPrintAppId(platformConfig); + String content = args.optString(0, ""); + WebView controller = self.getPrintController(); - if (appId == null) { - self.ctx.success(4); - return; - }; - - String content = args.optString(0, ""); - Intent controller = self.getPrintController(appId); - - self.adjustSettingsForPrintController(controller); self.loadContentIntoPrintController(content, controller); self.startPrinterApp(controller); @@ -144,200 +89,54 @@ public class Printer extends CordovaPlugin { }); } - /** - * Gibt die zu verwendende App-ID an. - */ - private String getPrintAppId (JSONObject platformConfig) { - String appId = platformConfig.optString("appId", null); - - if (appId != null) { - return (this.isAppInstalled(appId)) ? appId : null; - } else { - return this.getFirstInstalledAppId(); - } - } - /** * Erstellt den Print-View. */ - private Intent getPrintController (String appId) { - String intentId = "android.intent.action.SEND"; + private WebView getPrintController () { + WebView webview = new WebView(cordova.getActivity()); - if (appId.equals("com.rcreations.send2printer")) { - intentId = "com.rcreations.send2printer.print"; - } else if (appId.equals("com.dynamixsoftware.printershare")) { - intentId = "android.intent.action.VIEW"; - } else if (appId.equals("com.hp.android.print")) { - intentId = "org.androidprinting.intent.action.PRINT"; - } + webview.setVisibility(View.INVISIBLE); + webview.getSettings().setJavaScriptEnabled(false); - Intent intent = new Intent(intentId); - - if (appId != null) - intent.setPackage(appId); - - return intent; - } - - /** - * Stellt die Eigenschaften des Druckers ein. - */ - private void adjustSettingsForPrintController (Intent intent) { - String mimeType = "image/png"; - String appId = intent.getPackage(); - - // Check for special cases that can receive HTML - if (appId.equals("com.rcreations.send2printer") || appId.equals("com.dynamixsoftware.printershare")) { - mimeType = "text/html"; - } - - intent.setType(mimeType); + return webview; } /** * Lädt den zu druckenden Content in ein WebView, welcher vom Drucker ausgedruckt werden soll. */ - private void loadContentIntoPrintController (String content, Intent intent) { - String mimeType = intent.getType(); - - if (mimeType.equals("text/html")) { - loadContentAsHtmlIntoPrintController(content, intent); - } else { - loadContentAsBitmapIntoPrintController(content, intent); - } - } - - /** - * Lädt den zu druckenden Content als HTML in ein WebView, welcher vom Drucker ausgedruckt werden soll. - */ - private void loadContentAsHtmlIntoPrintController (String content, Intent intent) { - intent.putExtra(Intent.EXTRA_TEXT, content); - } - - /** - * Lädt den zu druckenden Content als BMP in ein WebView, welcher vom Drucker ausgedruckt werden soll. - */ - private void loadContentAsBitmapIntoPrintController (String content, final Intent intent) { - Activity ctx = cordova.getActivity(); - final WebView page = new WebView(ctx); - final Printer self = this; - - page.setVisibility(View.INVISIBLE); - page.getSettings().setJavaScriptEnabled(false); - - page.setWebViewClient( new WebViewClient() { - @Override - public void onPageFinished(final WebView page, String url) { - new Handler().postDelayed( new Runnable() { - @Override - public void run() { - Bitmap screenshot = self.takeScreenshot(page); - File tmpFile = self.saveScreenshotToTmpFile(screenshot); - ViewGroup vg = (ViewGroup)(page.getParent()); - - intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(tmpFile)); - - vg.removeView(page); - } - }, 1000); - } - }); - + private void loadContentIntoPrintController (String content, WebView webview) { //Set base URI to the assets/www folder String baseURL = webView.getUrl(); - baseURL = baseURL.substring(0, baseURL.lastIndexOf('/') + 1); + baseURL = baseURL.substring(0, baseURL.lastIndexOf('/') + 1); - ctx.addContentView(page, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)); - page.loadDataWithBaseURL(baseURL, content, "text/html", "UTF-8", null); - } - - /** - * Nimmt einen Screenshot der Seite auf. - */ - private Bitmap takeScreenshot (WebView page) { - Picture picture = page.capturePicture(); - Bitmap bitmap = Bitmap.createBitmap(picture.getWidth(), picture.getHeight(), Bitmap.Config.ARGB_8888); - Canvas canvas = new Canvas(bitmap); - - picture.draw(canvas); - - return bitmap; - } - - /** - * Speichert den Screenshot der Seite in einer tmp. Datei ab. - */ - private File saveScreenshotToTmpFile (Bitmap screenshot) { - try { - File tmpFile = File.createTempFile("screenshot", ".tmp"); - FileOutputStream stream = new FileOutputStream(tmpFile); - - screenshot.compress(Bitmap.CompressFormat.PNG, 100, stream); - stream.close(); - - return tmpFile; - } catch (IOException e) { - e.printStackTrace(); - } - - return null; + webview.loadDataWithBaseURL(baseURL, content, "text/html", "UTF-8", null); } /** * Öffnet die Printer App, damit der Content ausgedruckt werden kann. */ - private void startPrinterApp (Intent intent) { - cordova.startActivityForResult(this, intent, 0); - } - - /** - * Findet heraus, ob die Anwendung installiert ist. - */ - private boolean isAppInstalled (String appId) { - PackageManager pm = cordova.getActivity().getPackageManager(); - - try { - PackageInfo pi = pm.getPackageInfo(appId, 0); - - if (pi != null){ - return true; + private void startPrinterApp (WebView webview) { + webview.setWebViewClient (new WebViewClient() { + public boolean shouldOverrideUrlLoading (WebView view, String url) { + return false; } - } catch (PackageManager.NameNotFoundException e) {} - return false; - } + public void onPageFinished (WebView webview, String url) { + // Get a PrintManager instance + PrintManager printManager = (PrintManager) cordova.getActivity() + .getSystemService(Context.PRINT_SERVICE); - /** - * Die IDs aller verfügbaren Drucker-Apps. - */ - private JSONArray getInstalledAppIds () { - JSONArray appIds = new JSONArray(); + // Get a print adapter instance + PrintDocumentAdapter printAdapter = webView.createPrintDocumentAdapter(); - for (int i = 0; i < printAppIds.length; i++) { - String appId = printAppIds[i]; - Boolean isInstalled = this.isAppInstalled(appId); + // Get a print builder instance + PrintAttributes.Builder builder = new PrintAttributes.Builder(); - if (isInstalled){ - appIds.put(appId); + builder.setMinMargins(PrintAttributes.Margins.NO_MARGINS); + + // Create a print job with name and adapter instance + printManager.print("Print Document", printAdapter, builder.build()); } - } - - return appIds; - } - - /** - * Die erste ID in der Liste, deren App installiert ist. - */ - private String getFirstInstalledAppId () { - for (int i = 0; i < printAppIds.length; i++) { - String appId = printAppIds[i]; - Boolean isInstalled = this.isAppInstalled(appId); - - if (isInstalled){ - return appId; - } - } - - return null; + }); } } diff --git a/www/printer.js b/www/printer.js index 0df05dd..7b8d6e9 100755 --- a/www/printer.js +++ b/www/printer.js @@ -39,11 +39,7 @@ Printer.prototype = { callback.apply(scope || window, args); }; - if (device.platform == 'Android' && device.version >= '4.4') { - cordova.exec(callbackFn, null, 'KitKatPrinter', 'isServiceAvailable', []); - } else { - cordova.exec(callbackFn, null, 'Printer', 'isServiceAvailable', []); - }; + cordova.exec(callbackFn, null, 'Printer', 'isServiceAvailable', []); }, /** @@ -61,11 +57,7 @@ Printer.prototype = { return; } - if (device.platform == 'Android' && device.version >= '4.4') { - cordova.exec(null, null, 'KitKatPrinter', 'print', [page, options]); - } else { - cordova.exec(null, null, 'Printer', 'print', [page, options]); - }; + cordova.exec(null, null, 'Printer', 'print', [page, options]); } };