Various android enhancements - see the changelog
This commit is contained in:
parent
f44ed52148
commit
13c9d3dbef
@ -1,4 +1,12 @@
|
|||||||
## ChangeLog
|
## ChangeLog
|
||||||
|
#### Version 0.7.2 (not yet released)
|
||||||
|
- [__change__:] Changed plugin ID to `cordova-plugin-printer`
|
||||||
|
- [__change__:] Plugin requires Android KitKat or newer
|
||||||
|
- [__change__:] `isAvailable` returns false if no enabled print services can be found (Android)
|
||||||
|
- [enhancement:] `isAvailable` returns additional list of available print services (Android)
|
||||||
|
- [enhancement:] Support `duplex` attribute (Android)
|
||||||
|
|
||||||
|
|
||||||
#### Version 0.7.1 (23.04.2015)
|
#### Version 0.7.1 (23.04.2015)
|
||||||
- [bugfix:] `isAvailable` does not block the main thread anymore.
|
- [bugfix:] `isAvailable` does not block the main thread anymore.
|
||||||
- [bugfix:] iPad+iOS8 incompatibility (Thanks to __zmagyar__)
|
- [bugfix:] iPad+iOS8 incompatibility (Thanks to __zmagyar__)
|
||||||
|
@ -42,7 +42,8 @@
|
|||||||
|
|
||||||
<!-- cordova -->
|
<!-- cordova -->
|
||||||
<engines>
|
<engines>
|
||||||
<engine name="cordova" version=">=6.0.0" />
|
<engine name="cordova" version=">=3.0.0" />
|
||||||
|
<engine name="android-sdk" version=">=19" />
|
||||||
</engines>
|
</engines>
|
||||||
|
|
||||||
<!-- interface -->
|
<!-- interface -->
|
||||||
|
@ -21,14 +21,6 @@
|
|||||||
|
|
||||||
package de.appplant.cordova.plugin.printer;
|
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 org.json.JSONObject;
|
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
@ -39,7 +31,20 @@ import android.print.PrintManager;
|
|||||||
import android.webkit.WebView;
|
import android.webkit.WebView;
|
||||||
import android.webkit.WebViewClient;
|
import android.webkit.WebViewClient;
|
||||||
|
|
||||||
@TargetApi(19)
|
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 java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class Printer extends CordovaPlugin {
|
public class Printer extends CordovaPlugin {
|
||||||
|
|
||||||
private WebView view;
|
private WebView view;
|
||||||
@ -71,17 +76,14 @@ public class Printer extends CordovaPlugin {
|
|||||||
|
|
||||||
if (action.equalsIgnoreCase("isAvailable")) {
|
if (action.equalsIgnoreCase("isAvailable")) {
|
||||||
isAvailable();
|
isAvailable();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (action.equalsIgnoreCase("print")) {
|
if (action.equalsIgnoreCase("print")) {
|
||||||
print(args);
|
print(args);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returning false results in a "MethodNotFound" error.
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,10 +95,17 @@ public class Printer extends CordovaPlugin {
|
|||||||
cordova.getThreadPool().execute(new Runnable() {
|
cordova.getThreadPool().execute(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
Boolean supported = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
|
List<String> ids = getEnabledPrintServiceIds();
|
||||||
PluginResult result = new PluginResult(PluginResult.Status.OK, supported);
|
Boolean available = ids.size() > 1;
|
||||||
|
|
||||||
command.sendPluginResult(result);
|
PluginResult res1 = new PluginResult(
|
||||||
|
PluginResult.Status.OK, available);
|
||||||
|
PluginResult res2 = new PluginResult(
|
||||||
|
PluginResult.Status.OK, new JSONArray(ids));
|
||||||
|
PluginResult res = new PluginResult(
|
||||||
|
PluginResult.Status.OK, Arrays.asList(res1, res2));
|
||||||
|
|
||||||
|
command.sendPluginResult(res);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -130,11 +139,12 @@ public class Printer extends CordovaPlugin {
|
|||||||
if (content.startsWith("http") || content.startsWith("file:")) {
|
if (content.startsWith("http") || content.startsWith("file:")) {
|
||||||
view.loadUrl(content);
|
view.loadUrl(content);
|
||||||
} else {
|
} else {
|
||||||
//Set base URI to the assets/www folder
|
|
||||||
String baseURL = webView.getUrl();
|
String baseURL = webView.getUrl();
|
||||||
baseURL = baseURL.substring(0, baseURL.lastIndexOf('/') + 1);
|
baseURL = baseURL.substring(0, baseURL.lastIndexOf('/') + 1);
|
||||||
|
|
||||||
view.loadDataWithBaseURL(baseURL, content, "text/html", "UTF-8", null);
|
// Set base URI to the assets/www folder
|
||||||
|
view.loadDataWithBaseURL(
|
||||||
|
baseURL, content, "text/html", "UTF-8", null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,6 +174,7 @@ public class Printer extends CordovaPlugin {
|
|||||||
final String docName = props.optString("name", DEFAULT_DOC_NAME);
|
final String docName = props.optString("name", DEFAULT_DOC_NAME);
|
||||||
final boolean landscape = props.optBoolean("landscape", false);
|
final boolean landscape = props.optBoolean("landscape", false);
|
||||||
final boolean graystyle = props.optBoolean("graystyle", false);
|
final boolean graystyle = props.optBoolean("graystyle", false);
|
||||||
|
final String duplex = props.optString("duplex", "none");
|
||||||
|
|
||||||
view.setWebViewClient(new WebViewClient() {
|
view.setWebViewClient(new WebViewClient() {
|
||||||
@Override
|
@Override
|
||||||
@ -173,27 +184,31 @@ public class Printer extends CordovaPlugin {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPageFinished (WebView webView, String url) {
|
public void onPageFinished (WebView webView, String url) {
|
||||||
// Get a PrintManager instance
|
PrintManager printManager = getPrintMgr();
|
||||||
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();
|
PrintAttributes.Builder builder = new PrintAttributes.Builder();
|
||||||
|
PrintDocumentAdapter adapter = getAdapter(webView, docName);
|
||||||
|
|
||||||
// The page does itself set its own margins
|
|
||||||
builder.setMinMargins(PrintAttributes.Margins.NO_MARGINS);
|
builder.setMinMargins(PrintAttributes.Margins.NO_MARGINS);
|
||||||
|
|
||||||
builder.setColorMode(graystyle ? PrintAttributes.COLOR_MODE_MONOCHROME
|
builder.setColorMode(graystyle
|
||||||
|
? PrintAttributes.COLOR_MODE_MONOCHROME
|
||||||
: PrintAttributes.COLOR_MODE_COLOR);
|
: PrintAttributes.COLOR_MODE_COLOR);
|
||||||
|
|
||||||
builder.setMediaSize(landscape ? PrintAttributes.MediaSize.UNKNOWN_LANDSCAPE
|
builder.setMediaSize(landscape
|
||||||
|
? PrintAttributes.MediaSize.UNKNOWN_LANDSCAPE
|
||||||
: PrintAttributes.MediaSize.UNKNOWN_PORTRAIT);
|
: PrintAttributes.MediaSize.UNKNOWN_PORTRAIT);
|
||||||
|
|
||||||
// Create a print job with name and adapter instance
|
if (!duplex.equals("none") && Build.VERSION.SDK_INT >= 23) {
|
||||||
PrintJob job = printManager.print(docName, printAdapter, builder.build());
|
boolean longEdge = duplex.equals("long");
|
||||||
|
Method setDuplexModeMethod = getMethod(builder.getClass(),
|
||||||
|
"setDuplexMode", int.class);
|
||||||
|
|
||||||
|
invokeMethod(builder, setDuplexModeMethod,
|
||||||
|
longEdge ? 2 : 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
PrintJob job = printManager.print(
|
||||||
|
docName, adapter, builder.build());
|
||||||
|
|
||||||
invokeCallbackOnceCompletedOrCanceled(job);
|
invokeCallbackOnceCompletedOrCanceled(job);
|
||||||
|
|
||||||
@ -221,4 +236,125 @@ public class Printer extends CordovaPlugin {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a PrintManager instance.
|
||||||
|
*
|
||||||
|
* @return A PrintManager instance.
|
||||||
|
*/
|
||||||
|
private PrintManager getPrintMgr () {
|
||||||
|
return (PrintManager) cordova.getActivity()
|
||||||
|
.getSystemService(Context.PRINT_SERVICE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the print document adapter for the web view component. On
|
||||||
|
* devices older then SDK 21 it will use the deprecated method
|
||||||
|
* `createPrintDocumentAdapter` without arguments and on newer devices
|
||||||
|
* the recommended way.
|
||||||
|
*
|
||||||
|
* @param webView
|
||||||
|
* The web view which content to print out.
|
||||||
|
* @param docName
|
||||||
|
* The name of the printed document.
|
||||||
|
* @return
|
||||||
|
* The created adapter.
|
||||||
|
*/
|
||||||
|
private PrintDocumentAdapter getAdapter (WebView webView, String docName) {
|
||||||
|
if (Build.VERSION.SDK_INT >= 21) {
|
||||||
|
Method createPrintDocumentAdapterMethod = getMethod(
|
||||||
|
WebView.class, "createPrintDocumentAdapter", String.class);
|
||||||
|
|
||||||
|
return (PrintDocumentAdapter) invokeMethod(
|
||||||
|
webView, createPrintDocumentAdapterMethod, docName);
|
||||||
|
} else {
|
||||||
|
Method createPrintDocumentAdapterMethod = getMethod(
|
||||||
|
WebView.class, "createPrintDocumentAdapter");
|
||||||
|
|
||||||
|
return (PrintDocumentAdapter) invokeMethod(
|
||||||
|
webView, createPrintDocumentAdapterMethod);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of ids of all installed and enabled print services. For
|
||||||
|
* that it uses reflections to call public but hidden methods from the
|
||||||
|
* PrintManager.
|
||||||
|
*
|
||||||
|
* @return A list of found print service ids.
|
||||||
|
*/
|
||||||
|
private List<String> getEnabledPrintServiceIds () {
|
||||||
|
try {
|
||||||
|
PrintManager printMgr = getPrintMgr();
|
||||||
|
Class<?> printerCls = Class.forName(
|
||||||
|
"android.printservice.PrintServiceInfo");
|
||||||
|
Method getPrinterMethod = getMethod(printMgr.getClass(),
|
||||||
|
"getEnabledPrintServices");
|
||||||
|
Method getIdMethod = getMethod(printerCls,
|
||||||
|
"getId");
|
||||||
|
|
||||||
|
List printers = (List) invokeMethod(printMgr, getPrinterMethod);
|
||||||
|
ArrayList<String> printerIds = new ArrayList<String>();
|
||||||
|
|
||||||
|
printerIds.add("android.print.pdf");
|
||||||
|
|
||||||
|
if (printers == null)
|
||||||
|
return printerIds;
|
||||||
|
|
||||||
|
for (Object printer : printers) {
|
||||||
|
String printerId = (String) invokeMethod(printer, getIdMethod);
|
||||||
|
printerIds.add(printerId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return printerIds;
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds the method with given name and set of arguments.
|
||||||
|
*
|
||||||
|
* @param cls
|
||||||
|
* The class in where to look for the method declaration.
|
||||||
|
* @param name
|
||||||
|
* The name of the method.
|
||||||
|
* @param params
|
||||||
|
* The arguments of the method.
|
||||||
|
* @return
|
||||||
|
* The found method or null.
|
||||||
|
*/
|
||||||
|
private Method getMethod (Class<?> cls, String name, Class<?>... params) {
|
||||||
|
try {
|
||||||
|
return cls.getDeclaredMethod(name, params);
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invokes the method on the given object with the specified arguments.
|
||||||
|
*
|
||||||
|
* @param obj
|
||||||
|
* An object which class defines the method.
|
||||||
|
* @param method
|
||||||
|
* The method to invoke.
|
||||||
|
* @param args
|
||||||
|
* Set of arguments.
|
||||||
|
* @return
|
||||||
|
* The returned object or null.
|
||||||
|
*/
|
||||||
|
private Object invokeMethod (Object obj, Method method, Object... args) {
|
||||||
|
try {
|
||||||
|
return method.invoke(obj, args);
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (InvocationTargetException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user