Support for picking a printer for iOS and Android
This commit is contained in:
parent
049f72dea6
commit
4251c0639d
@ -2,8 +2,9 @@
|
|||||||
#### Version 0.7.2 (not yet released)
|
#### Version 0.7.2 (not yet released)
|
||||||
- [__change__:] Changed plugin ID to `cordova-plugin-printer`
|
- [__change__:] Changed plugin ID to `cordova-plugin-printer`
|
||||||
- [__change__:] Plugin requires Android KitKat or newer
|
- [__change__:] Plugin requires Android KitKat or newer
|
||||||
- [__change__:] `isAvailable` returns false if no enabled print services can be found (Android)
|
- [__change__:] `isAvailable` returns false if no enabled service can be found (Android)
|
||||||
- [enhancement:] `isAvailable` returns additional list of available print services (Android)
|
- [feature:] New `pick` interface to pick a printer for future usage
|
||||||
|
- [enhancement:] `isAvailable` returns count of available services (Android)
|
||||||
- [enhancement:] `print` returns bool value to indicate the result
|
- [enhancement:] `print` returns bool value to indicate the result
|
||||||
- [enhancement:] Added missing `duplex` support (Android)
|
- [enhancement:] Added missing `duplex` support (Android)
|
||||||
- [__change__:] `duplex` requires a string (`none`, `long` or `short`)
|
- [__change__:] `duplex` requires a string (`none`, `long` or `short`)
|
||||||
|
30
plugin.xml
30
plugin.xml
@ -73,7 +73,37 @@
|
|||||||
</feature>
|
</feature>
|
||||||
</config-file>
|
</config-file>
|
||||||
|
|
||||||
|
<config-file target="AndroidManifest.xml" parent="/manifest/application">
|
||||||
|
<activity
|
||||||
|
android:name="de.appplant.cordova.plugin.printer.ui.SelectPrinterActivity"
|
||||||
|
android:label="Printer"
|
||||||
|
android:theme="@android:style/Theme.Material.Settings"
|
||||||
|
android:exported="false">
|
||||||
|
</activity>
|
||||||
|
</config-file>
|
||||||
|
|
||||||
<source-file src="src/android/Printer.java"
|
<source-file src="src/android/Printer.java"
|
||||||
target-dir="src/de/appplant/cordova/plugin/printer" />
|
target-dir="src/de/appplant/cordova/plugin/printer" />
|
||||||
|
|
||||||
|
<source-file src="src/android/ui/SelectPrinterActivity.java"
|
||||||
|
target-dir="src/de/appplant/cordova/plugin/printer/ui" />
|
||||||
|
|
||||||
|
<source-file src="src/android/reflect/Meta.java"
|
||||||
|
target-dir="src/de/appplant/cordova/plugin/printer/reflect" />
|
||||||
|
|
||||||
|
<source-file src="src/android/ext/PrinterDiscoverySession.java"
|
||||||
|
target-dir="src/de/appplant/cordova/plugin/printer/ext" />
|
||||||
|
|
||||||
|
<source-file src="src/android/ext/PrintManager.java"
|
||||||
|
target-dir="src/de/appplant/cordova/plugin/printer/ext" />
|
||||||
|
|
||||||
|
<source-file src="src/android/ext/PrintServiceInfo.java"
|
||||||
|
target-dir="src/de/appplant/cordova/plugin/printer/ext" />
|
||||||
|
|
||||||
|
<resource-file src="res/android/layout/printer_list_item.xml"
|
||||||
|
target="res/layout/printer_list_item.xml" />
|
||||||
|
|
||||||
|
<resource-file src="res/android/layout/select_printer_activity.xml"
|
||||||
|
target="res/layout/select_printer_activity.xml" />
|
||||||
</platform>
|
</platform>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
80
res/android/layout/printer_list_item.xml
Normal file
80
res/android/layout/printer_list_item.xml
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
* Copyright (c) 2013-2016 by appPlant GmbH. All rights reserved.
|
||||||
|
*
|
||||||
|
* @APPPLANT_LICENSE_HEADER_START@
|
||||||
|
*
|
||||||
|
* This file contains Original Code and/or Modifications of Original Code
|
||||||
|
* as defined in and that are subject to the Apache License
|
||||||
|
* Version 2.0 (the 'License'). You may not use this file except in
|
||||||
|
* compliance with the License. Please obtain a copy of the License at
|
||||||
|
* http://opensource.org/licenses/Apache-2.0/ and read it before using this
|
||||||
|
* file.
|
||||||
|
*
|
||||||
|
* The Original Code and all software distributed under the License are
|
||||||
|
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||||
|
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||||
|
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||||
|
* Please see the License for the specific language governing rights and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* @APPPLANT_LICENSE_HEADER_END@
|
||||||
|
-->
|
||||||
|
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
|
||||||
|
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
|
||||||
|
android:minHeight="?android:attr/listPreferredItemHeight"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:gravity="start|center_vertical">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@android:id/icon"
|
||||||
|
android:layout_width="32dip"
|
||||||
|
android:layout_height="32dip"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_marginEnd="8dip"
|
||||||
|
android:duplicateParentState="true"
|
||||||
|
android:contentDescription="@null"
|
||||||
|
android:visibility="invisible">
|
||||||
|
</ImageView>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:duplicateParentState="true">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@android:id/title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:textIsSelectable="false"
|
||||||
|
android:gravity="top|start"
|
||||||
|
android:textColor="?android:attr/textColorPrimary"
|
||||||
|
android:duplicateParentState="true">
|
||||||
|
</TextView>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@android:id/hint"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:textIsSelectable="false"
|
||||||
|
android:visibility="gone"
|
||||||
|
android:textColor="?android:attr/textColorPrimary"
|
||||||
|
android:duplicateParentState="true">
|
||||||
|
</TextView>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
74
res/android/layout/select_printer_activity.xml
Normal file
74
res/android/layout/select_printer_activity.xml
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
* Copyright (c) 2013-2016 by appPlant GmbH. All rights reserved.
|
||||||
|
*
|
||||||
|
* @APPPLANT_LICENSE_HEADER_START@
|
||||||
|
*
|
||||||
|
* This file contains Original Code and/or Modifications of Original Code
|
||||||
|
* as defined in and that are subject to the Apache License
|
||||||
|
* Version 2.0 (the 'License'). You may not use this file except in
|
||||||
|
* compliance with the License. Please obtain a copy of the License at
|
||||||
|
* http://opensource.org/licenses/Apache-2.0/ and read it before using this
|
||||||
|
* file.
|
||||||
|
*
|
||||||
|
* The Original Code and all software distributed under the License are
|
||||||
|
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||||
|
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||||
|
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||||
|
* Please see the License for the specific language governing rights and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* @APPPLANT_LICENSE_HEADER_END@
|
||||||
|
-->
|
||||||
|
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent">
|
||||||
|
|
||||||
|
<ListView
|
||||||
|
android:id="@android:id/list"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:scrollbarStyle="outsideOverlay"
|
||||||
|
android:cacheColorHint="@android:color/transparent"
|
||||||
|
android:scrollbarAlwaysDrawVerticalTrack="true" >
|
||||||
|
</ListView>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@android:id/empty"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@android:id/title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||||
|
android:textColor="?android:attr/textColorSecondary"
|
||||||
|
android:text="Searching for printers">
|
||||||
|
</TextView>
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@android:id/progress"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:indeterminate="true"
|
||||||
|
style="@android:style/Widget.DeviceDefault.Light.ProgressBar.Horizontal">
|
||||||
|
</ProgressBar>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
@ -22,13 +22,12 @@
|
|||||||
package de.appplant.cordova.plugin.printer;
|
package de.appplant.cordova.plugin.printer;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.print.PrintAttributes;
|
import android.print.PrintAttributes;
|
||||||
import android.print.PrintDocumentAdapter;
|
import android.print.PrintDocumentAdapter;
|
||||||
import android.print.PrintJob;
|
import android.print.PrintJob;
|
||||||
import android.print.PrintManager;
|
import android.print.PrinterId;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.webkit.WebSettings;
|
import android.webkit.WebSettings;
|
||||||
import android.webkit.WebView;
|
import android.webkit.WebView;
|
||||||
@ -41,13 +40,17 @@ import org.json.JSONArray;
|
|||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import de.appplant.cordova.plugin.printer.ext.PrintManager;
|
||||||
|
import de.appplant.cordova.plugin.printer.ext.PrintServiceInfo;
|
||||||
|
import de.appplant.cordova.plugin.printer.reflect.Meta;
|
||||||
|
import de.appplant.cordova.plugin.printer.ui.SelectPrinterActivity;
|
||||||
|
|
||||||
|
import static de.appplant.cordova.plugin.printer.ui.SelectPrinterActivity.EXTRA_PRINTER_ID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Plugin to print HTML documents. Therefore it creates an invisible web view
|
* Plugin to print HTML documents. Therefore it creates an invisible web view
|
||||||
* that loads the markup data. Once the page has been fully rendered it takes
|
* that loads the markup data. Once the page has been fully rendered it takes
|
||||||
@ -102,6 +105,11 @@ public class Printer extends CordovaPlugin {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (action.equalsIgnoreCase("pick")) {
|
||||||
|
pick();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (action.equalsIgnoreCase("print")) {
|
if (action.equalsIgnoreCase("print")) {
|
||||||
print(args);
|
print(args);
|
||||||
return true;
|
return true;
|
||||||
@ -118,13 +126,14 @@ public class Printer extends CordovaPlugin {
|
|||||||
cordova.getThreadPool().execute(new Runnable() {
|
cordova.getThreadPool().execute(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
List<String> ids = getEnabledPrintServiceIds();
|
PrintManager pm = new PrintManager(cordova.getActivity());
|
||||||
Boolean available = ids.size() > 1;
|
List<PrintServiceInfo> services = pm.getEnabledPrintServices();
|
||||||
|
Boolean available = services.size() > 0;
|
||||||
|
|
||||||
PluginResult res1 = new PluginResult(
|
PluginResult res1 = new PluginResult(
|
||||||
PluginResult.Status.OK, available);
|
PluginResult.Status.OK, available);
|
||||||
PluginResult res2 = new PluginResult(
|
PluginResult res2 = new PluginResult(
|
||||||
PluginResult.Status.OK, new JSONArray(ids));
|
PluginResult.Status.OK, services.size());
|
||||||
PluginResult res = new PluginResult(
|
PluginResult res = new PluginResult(
|
||||||
PluginResult.Status.OK, Arrays.asList(res1, res2));
|
PluginResult.Status.OK, Arrays.asList(res1, res2));
|
||||||
|
|
||||||
@ -152,6 +161,17 @@ public class Printer extends CordovaPlugin {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Presents a list with all enabled print services and invokes the
|
||||||
|
* callback with the selected one.
|
||||||
|
*/
|
||||||
|
private void pick () {
|
||||||
|
Intent intent = new Intent(
|
||||||
|
cordova.getActivity(), SelectPrinterActivity.class);
|
||||||
|
|
||||||
|
cordova.startActivityForResult(this, intent, 0);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads the content into the web view.
|
* Loads the content into the web view.
|
||||||
*
|
*
|
||||||
@ -190,10 +210,10 @@ public class Printer extends CordovaPlugin {
|
|||||||
view.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
|
view.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= 21) {
|
if (Build.VERSION.SDK_INT >= 21) {
|
||||||
Method setMixedContentModeMethod = getMethod(settings.getClass(),
|
Method setMixedContentModeMethod = Meta.getMethod(
|
||||||
"setMixedContentMode", int.class);
|
settings.getClass(), "setMixedContentMode", int.class);
|
||||||
|
|
||||||
invokeMethod(settings, setMixedContentModeMethod, 2);
|
Meta.invokeMethod(settings, setMixedContentModeMethod, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
setWebViewClient(props);
|
setWebViewClient(props);
|
||||||
@ -219,7 +239,7 @@ public class Printer extends CordovaPlugin {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPageFinished (WebView webView, String url) {
|
public void onPageFinished (WebView webView, String url) {
|
||||||
PrintManager printManager = getPrintMgr();
|
PrintManager pm = new PrintManager(cordova.getActivity());
|
||||||
PrintAttributes.Builder builder = new PrintAttributes.Builder();
|
PrintAttributes.Builder builder = new PrintAttributes.Builder();
|
||||||
PrintDocumentAdapter adapter = getAdapter(webView, docName);
|
PrintDocumentAdapter adapter = getAdapter(webView, docName);
|
||||||
|
|
||||||
@ -235,14 +255,14 @@ public class Printer extends CordovaPlugin {
|
|||||||
|
|
||||||
if (!duplex.equals("none") && Build.VERSION.SDK_INT >= 23) {
|
if (!duplex.equals("none") && Build.VERSION.SDK_INT >= 23) {
|
||||||
boolean longEdge = duplex.equals("long");
|
boolean longEdge = duplex.equals("long");
|
||||||
Method setDuplexModeMethod = getMethod(builder.getClass(),
|
Method setDuplexModeMethod = Meta.getMethod(
|
||||||
"setDuplexMode", int.class);
|
builder.getClass(), "setDuplexMode", int.class);
|
||||||
|
|
||||||
invokeMethod(builder, setDuplexModeMethod,
|
Meta.invokeMethod(builder, setDuplexModeMethod,
|
||||||
longEdge ? 2 : 4);
|
longEdge ? 2 : 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
job = printManager.print(docName, adapter, builder.build());
|
job = pm.getInstance().print(docName, adapter, builder.build());
|
||||||
view = null;
|
view = null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -265,14 +285,24 @@ public class Printer extends CordovaPlugin {
|
|||||||
command.sendPluginResult(res);
|
command.sendPluginResult(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* Get a PrintManager instance.
|
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
|
||||||
*
|
super.onActivityResult(requestCode, resultCode, intent);
|
||||||
* @return A PrintManager instance.
|
|
||||||
*/
|
if (command == null)
|
||||||
private PrintManager getPrintMgr () {
|
return;
|
||||||
return (PrintManager) cordova.getActivity()
|
|
||||||
.getSystemService(Context.PRINT_SERVICE);
|
String url = null;
|
||||||
|
|
||||||
|
if (intent != null) {
|
||||||
|
PrinterId printerId = intent.getParcelableExtra(EXTRA_PRINTER_ID);
|
||||||
|
url = printerId.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
PluginResult res = new PluginResult(
|
||||||
|
PluginResult.Status.OK, url);
|
||||||
|
|
||||||
|
command.sendPluginResult(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -290,99 +320,14 @@ public class Printer extends CordovaPlugin {
|
|||||||
*/
|
*/
|
||||||
private PrintDocumentAdapter getAdapter (WebView webView, String docName) {
|
private PrintDocumentAdapter getAdapter (WebView webView, String docName) {
|
||||||
if (Build.VERSION.SDK_INT >= 21) {
|
if (Build.VERSION.SDK_INT >= 21) {
|
||||||
Method createPrintDocumentAdapterMethod = getMethod(
|
Method createPrintDocumentAdapterMethod = Meta.getMethod(
|
||||||
WebView.class, "createPrintDocumentAdapter", String.class);
|
WebView.class, "createPrintDocumentAdapter", String.class);
|
||||||
|
|
||||||
return (PrintDocumentAdapter) invokeMethod(
|
return (PrintDocumentAdapter) Meta.invokeMethod(
|
||||||
webView, createPrintDocumentAdapterMethod, docName);
|
webView, createPrintDocumentAdapterMethod, docName);
|
||||||
} else {
|
} else {
|
||||||
Method createPrintDocumentAdapterMethod = getMethod(
|
return (PrintDocumentAdapter) Meta.invokeMethod(webView,
|
||||||
WebView.class, "createPrintDocumentAdapter");
|
"createPrintDocumentAdapterMethod");
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
115
src/android/ext/PrintManager.java
Normal file
115
src/android/ext/PrintManager.java
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2013-2016 appPlant GmbH
|
||||||
|
|
||||||
|
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.ext;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import de.appplant.cordova.plugin.printer.reflect.Meta;
|
||||||
|
|
||||||
|
public final class PrintManager {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The application context.
|
||||||
|
*/
|
||||||
|
private Context ctx;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param context The context where to look for.
|
||||||
|
*/
|
||||||
|
public PrintManager (Context context) {
|
||||||
|
this.ctx = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an instance from PrintManager service.
|
||||||
|
*
|
||||||
|
* @return A PrintManager instance.
|
||||||
|
*/
|
||||||
|
public final android.print.PrintManager getInstance () {
|
||||||
|
return (android.print.PrintManager)
|
||||||
|
ctx.getSystemService(Context.PRINT_SERVICE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the list of installed print services.
|
||||||
|
*
|
||||||
|
* @return The found service list or an empty list.
|
||||||
|
*/
|
||||||
|
public final List<PrintServiceInfo> getInstalledPrintServices () {
|
||||||
|
List printers = (List) Meta.invokeMethod(getInstance(),
|
||||||
|
"getInstalledPrintServices");
|
||||||
|
|
||||||
|
ArrayList<PrintServiceInfo> services =
|
||||||
|
new ArrayList<PrintServiceInfo>();
|
||||||
|
|
||||||
|
if (printers == null)
|
||||||
|
return Collections.emptyList();
|
||||||
|
|
||||||
|
for (Object printer : printers) {
|
||||||
|
services.add(new PrintServiceInfo(printer));
|
||||||
|
}
|
||||||
|
|
||||||
|
return services;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the list of enabled print services.
|
||||||
|
*
|
||||||
|
* @return The found service list or an empty list.
|
||||||
|
*/
|
||||||
|
public final List<PrintServiceInfo> getEnabledPrintServices () {
|
||||||
|
List printers = (List) Meta.invokeMethod(getInstance(),
|
||||||
|
"getEnabledPrintServices");
|
||||||
|
|
||||||
|
ArrayList<PrintServiceInfo> services =
|
||||||
|
new ArrayList<PrintServiceInfo>();
|
||||||
|
|
||||||
|
if (printers == null)
|
||||||
|
return Collections.emptyList();
|
||||||
|
|
||||||
|
for (Object printer : printers) {
|
||||||
|
services.add(new PrintServiceInfo(printer));
|
||||||
|
}
|
||||||
|
|
||||||
|
return services;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an session object to discover all printer services. To do so
|
||||||
|
* you need to register a listener object and start the discovery process.
|
||||||
|
*
|
||||||
|
* @return An instance of class PrinterDiscoverySession.
|
||||||
|
*/
|
||||||
|
public final PrinterDiscoverySession createPrinterDiscoverySession () {
|
||||||
|
Object session = Meta.invokeMethod(getInstance(),
|
||||||
|
"createPrinterDiscoverySession");
|
||||||
|
|
||||||
|
return new PrinterDiscoverySession(session);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
62
src/android/ext/PrintServiceInfo.java
Normal file
62
src/android/ext/PrintServiceInfo.java
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2013-2016 appPlant GmbH
|
||||||
|
|
||||||
|
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.ext;
|
||||||
|
|
||||||
|
import android.content.pm.ResolveInfo;
|
||||||
|
|
||||||
|
import de.appplant.cordova.plugin.printer.reflect.Meta;
|
||||||
|
|
||||||
|
public final class PrintServiceInfo {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The wrapped object of type android.printservice.PrintServiceInfo
|
||||||
|
*/
|
||||||
|
private Object obj;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wraps the object of the hidden class
|
||||||
|
* android.printservice.PrintServiceInfo.
|
||||||
|
*
|
||||||
|
* @param wrappedObj The object to wrap.
|
||||||
|
*/
|
||||||
|
PrintServiceInfo (Object wrappedObj) {
|
||||||
|
obj = wrappedObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The add printers activity name.
|
||||||
|
*
|
||||||
|
* @return The add printers activity name.
|
||||||
|
*/
|
||||||
|
public final String getAddPrintersActivityName() {
|
||||||
|
return (String) Meta.invokeMethod(obj, "getAddPrintersActivityName");
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* The service {@link ResolveInfo}.
|
||||||
|
*
|
||||||
|
* @return The info.
|
||||||
|
*/
|
||||||
|
public final ResolveInfo getResolveInfo() {
|
||||||
|
return (ResolveInfo) Meta.invokeMethod(obj, "getResolveInfo");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
178
src/android/ext/PrinterDiscoverySession.java
Normal file
178
src/android/ext/PrinterDiscoverySession.java
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2013-2016 appPlant GmbH
|
||||||
|
|
||||||
|
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.ext;
|
||||||
|
|
||||||
|
import android.print.PrinterInfo;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationHandler;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.lang.reflect.Proxy;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import de.appplant.cordova.plugin.printer.reflect.Meta;
|
||||||
|
|
||||||
|
public final class PrinterDiscoverySession {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Required interface of the listener.
|
||||||
|
*/
|
||||||
|
public interface OnPrintersChangeListener {
|
||||||
|
void onPrintersChanged(List<PrinterInfo> printerInfos);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Required to be able to register a listener of the expected type.
|
||||||
|
*/
|
||||||
|
private class OnPrintersChangeProxy implements InvocationHandler {
|
||||||
|
@Override
|
||||||
|
public Object invoke (Object o, Method method, Object[] objects)
|
||||||
|
throws Throwable {
|
||||||
|
|
||||||
|
if (method.getName().equals("onPrintersChanged")) {
|
||||||
|
onPrintersChanged();
|
||||||
|
return null;
|
||||||
|
} else throw new Exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delegate the event to the listener.
|
||||||
|
*/
|
||||||
|
public void onPrintersChanged() {
|
||||||
|
notifyOnPrintersChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The wrapped session of type
|
||||||
|
* android.print.PrinterDiscoverySession
|
||||||
|
*/
|
||||||
|
private Object session;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registered listener object.
|
||||||
|
*/
|
||||||
|
private OnPrintersChangeListener listener = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param session An instance of type
|
||||||
|
* android.print.PrinterDiscoverySession
|
||||||
|
*/
|
||||||
|
public PrinterDiscoverySession (Object session) {
|
||||||
|
this.session = session;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start discovering available printers.
|
||||||
|
*/
|
||||||
|
public final void startPrinterDiscovery () {
|
||||||
|
Method method = Meta.getMethod(session.getClass(),
|
||||||
|
"startPrinterDiscovery", List.class);
|
||||||
|
|
||||||
|
Meta.invokeMethod(session, method, Collections.emptyList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop discovering printers.
|
||||||
|
*/
|
||||||
|
public final void stopPrinterDiscovery() {
|
||||||
|
Meta.invokeMethod(session, "stopPrinterDiscovery");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If session is discovering printers.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("ConstantConditions")
|
||||||
|
public final boolean isPrinterDiscoveryStarted() {
|
||||||
|
return (Boolean) Meta.invokeMethod(session,
|
||||||
|
"isPrinterDiscoveryStarted");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the listener.
|
||||||
|
*
|
||||||
|
* @param listener Use null to unregister the listener.
|
||||||
|
*/
|
||||||
|
public final void setOnPrintersChangeListener(
|
||||||
|
OnPrintersChangeListener listener) {
|
||||||
|
|
||||||
|
Class<?> interfaceCls = null;
|
||||||
|
Object proxy = null;
|
||||||
|
|
||||||
|
this.listener = listener;
|
||||||
|
|
||||||
|
try {
|
||||||
|
interfaceCls = Class.forName(
|
||||||
|
"android.print.PrinterDiscoverySession$OnPrintersChangeListener");
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (interfaceCls == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Method method = Meta.getMethod(session.getClass(),
|
||||||
|
"setOnPrintersChangeListener", interfaceCls);
|
||||||
|
|
||||||
|
if (listener != null) {
|
||||||
|
Class<?>[] interfaces = {interfaceCls};
|
||||||
|
|
||||||
|
proxy = Proxy.newProxyInstance(
|
||||||
|
interfaceCls.getClassLoader(),
|
||||||
|
interfaces,
|
||||||
|
new OnPrintersChangeProxy()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Meta.invokeMethod(session, method, proxy);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy the session if not already done.
|
||||||
|
*/
|
||||||
|
public final void destroy() {
|
||||||
|
Meta.invokeMethod(session, "destroy");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of all yet discovered printers.
|
||||||
|
*
|
||||||
|
* @return List of their basic infos
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public final List<PrinterInfo> getPrinters() {
|
||||||
|
Method method = Meta.getMethod(session.getClass(), "getPrinters");
|
||||||
|
|
||||||
|
return (List<PrinterInfo>) Meta.invokeMethod(session, method);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notifies the listener about the occurred event.
|
||||||
|
*/
|
||||||
|
private void notifyOnPrintersChanged() {
|
||||||
|
if (listener != null) {
|
||||||
|
listener.onPrintersChanged(getPrinters());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
123
src/android/reflect/Meta.java
Normal file
123
src/android/reflect/Meta.java
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2013-2016 appPlant GmbH
|
||||||
|
|
||||||
|
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.reflect;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.res.Resources;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is an activity for selecting a printer.
|
||||||
|
*/
|
||||||
|
public abstract class Meta {
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
public static 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.
|
||||||
|
*/
|
||||||
|
public static 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invokes the method on the given object.
|
||||||
|
*
|
||||||
|
* @param obj
|
||||||
|
* An object which class defines the method.
|
||||||
|
* @param methodName
|
||||||
|
* The name of method to invoke.
|
||||||
|
* @return
|
||||||
|
* The returned object or null.
|
||||||
|
*/
|
||||||
|
public static Object invokeMethod (Object obj, String methodName) {
|
||||||
|
Method method = getMethod(obj.getClass(), methodName);
|
||||||
|
|
||||||
|
if (method == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
return method.invoke(obj);
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (InvocationTargetException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a resource identifier for the given resource name.
|
||||||
|
*
|
||||||
|
* @param context The applications context.
|
||||||
|
* @param type Resource type to find (id or layout or string ...)
|
||||||
|
* @param name The name of the desired resource.
|
||||||
|
*
|
||||||
|
* @return The associated resource identifier or 0 if not found.
|
||||||
|
*/
|
||||||
|
public static int getResId (Context context, String type, String name) {
|
||||||
|
Resources res = context.getResources();
|
||||||
|
String pkgName = context.getPackageName();
|
||||||
|
|
||||||
|
int resId;
|
||||||
|
resId = res.getIdentifier(name, type, pkgName);
|
||||||
|
|
||||||
|
return resId;
|
||||||
|
}
|
||||||
|
}
|
339
src/android/ui/SelectPrinterActivity.java
Normal file
339
src/android/ui/SelectPrinterActivity.java
Normal file
@ -0,0 +1,339 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2013-2016 appPlant GmbH
|
||||||
|
|
||||||
|
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.ui;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.pm.PackageInfo;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.content.pm.PackageManager.NameNotFoundException;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.print.PrinterId;
|
||||||
|
import android.print.PrinterInfo;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.AdapterView;
|
||||||
|
import android.widget.BaseAdapter;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.ListView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import de.appplant.cordova.plugin.printer.ext.PrintManager;
|
||||||
|
import de.appplant.cordova.plugin.printer.ext.PrinterDiscoverySession;
|
||||||
|
import de.appplant.cordova.plugin.printer.ext.PrinterDiscoverySession.OnPrintersChangeListener;
|
||||||
|
import de.appplant.cordova.plugin.printer.reflect.Meta;
|
||||||
|
|
||||||
|
@SuppressLint("SetTextI18n")
|
||||||
|
public final class SelectPrinterActivity extends Activity {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The extra string to identify the data from the intents bundle.
|
||||||
|
*/
|
||||||
|
public static final String EXTRA_PRINTER_ID =
|
||||||
|
"INTENT_EXTRA_PRINTER_ID";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reference to the main view which lists all discovered printers.
|
||||||
|
*/
|
||||||
|
private ListView listView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Session for printer discovering within the network.
|
||||||
|
*/
|
||||||
|
private PrinterDiscoverySession discoverySession;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the activity is starting.
|
||||||
|
*
|
||||||
|
* @param savedInstanceState If the activity is being re-initialized
|
||||||
|
* after previously being shut down then this
|
||||||
|
* Bundle contains the data it most recently
|
||||||
|
* supplied in.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
setContentView(Meta.getResId(
|
||||||
|
this, "layout", "select_printer_activity"));
|
||||||
|
|
||||||
|
discoverySession = new PrintManager(this).createPrinterDiscoverySession();
|
||||||
|
listView = (ListView) findViewById(android.R.id.list);
|
||||||
|
|
||||||
|
initListView();
|
||||||
|
startPrinterDiscovery();
|
||||||
|
updateEmptyView();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform any final cleanup before an activity is destroyed.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
discoverySession.destroy();
|
||||||
|
super.onDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends an intent with the specified printer back to the owning activity
|
||||||
|
* and finishes that activity.
|
||||||
|
*
|
||||||
|
* @param printerId The printerId object of the printer containing
|
||||||
|
* everything necessary to identify and contact him.
|
||||||
|
*/
|
||||||
|
private void onPrinterSelected (PrinterId printerId) {
|
||||||
|
Intent intent = new Intent();
|
||||||
|
|
||||||
|
intent.putExtra(EXTRA_PRINTER_ID, printerId);
|
||||||
|
setResult(RESULT_OK, intent);
|
||||||
|
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assigns the adapter and the click listener to the list.
|
||||||
|
*/
|
||||||
|
private void initListView() {
|
||||||
|
listView.setAdapter(new ListViewAdapter());
|
||||||
|
|
||||||
|
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||||
|
if (!listView.getAdapter().isEnabled(position)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PrinterInfo printer = (PrinterInfo)
|
||||||
|
listView.getAdapter().getItem(position);
|
||||||
|
|
||||||
|
onPrinterSelected(printer.getId());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start printer discovery if there are installed services found on the
|
||||||
|
* device.
|
||||||
|
*/
|
||||||
|
private void startPrinterDiscovery() {
|
||||||
|
PrintManager pm = new PrintManager(this);
|
||||||
|
|
||||||
|
if (pm.getInstalledPrintServices().isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
discoverySession.startPrinterDiscovery();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows or hides the empty-view of the list view depend on if the
|
||||||
|
* adapter contains any printers or not.
|
||||||
|
*/
|
||||||
|
private void updateEmptyView() {
|
||||||
|
TextView titleView = (TextView) findViewById(android.R.id.title);
|
||||||
|
View progressBar = findViewById(android.R.id.progress);
|
||||||
|
|
||||||
|
if (listView.getEmptyView() == null) {
|
||||||
|
View emptyView = findViewById(android.R.id.empty);
|
||||||
|
listView.setEmptyView(emptyView);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (discoverySession.isPrinterDiscoveryStarted()) {
|
||||||
|
titleView.setText("Searching for printers");
|
||||||
|
progressBar.setVisibility(View.VISIBLE);
|
||||||
|
} else {
|
||||||
|
titleView.setText("No printers found");
|
||||||
|
progressBar.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final class ListViewAdapter extends BaseAdapter {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wait lock for synchronization.
|
||||||
|
*/
|
||||||
|
private final Object lock = new Object();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of all received printer to display in the list.
|
||||||
|
*/
|
||||||
|
private final List<PrinterInfo> printers = new ArrayList<PrinterInfo>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor registers a listener to monitor about newly discovered
|
||||||
|
* printers.
|
||||||
|
*/
|
||||||
|
ListViewAdapter() {
|
||||||
|
discoverySession.setOnPrintersChangeListener(new OnPrintersChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void onPrintersChanged (List<PrinterInfo> printerInfos) {
|
||||||
|
printers.addAll(printerInfos);
|
||||||
|
notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* How many items are in the data set represented by this Adapter.
|
||||||
|
*
|
||||||
|
* @return Count of items.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int getCount() {
|
||||||
|
synchronized (lock) {
|
||||||
|
return printers.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the data item associated with the specified position in the
|
||||||
|
* data set.
|
||||||
|
*
|
||||||
|
* @param position Position of the item whose data we want within the
|
||||||
|
* adapter's data set.
|
||||||
|
*
|
||||||
|
* @return The data at the specified position.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Object getItem (int position) {
|
||||||
|
synchronized (lock) {
|
||||||
|
return printers.get(position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the row id associated with the specified position in the list.
|
||||||
|
*
|
||||||
|
* @param position The position of the item within the adapter's data
|
||||||
|
* set whose row id we want.
|
||||||
|
*
|
||||||
|
* @return The id of the item at the specified position.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public long getItemId (int position) {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a View that displays in the drop down popup the data at the
|
||||||
|
* specified position in the data set.
|
||||||
|
*
|
||||||
|
* @param pos The index of the item whose view we want.
|
||||||
|
* @param view The old view to reuse, if possible. Note: You should
|
||||||
|
* check that this view is non-null and of an appropriate
|
||||||
|
* type before using. If it is not possible to convert
|
||||||
|
* this view to display the correct data.
|
||||||
|
* @param parent The parent that this view will eventually be
|
||||||
|
* attached to.
|
||||||
|
*
|
||||||
|
* @return A View corresponding to the data at the specified position.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public View getDropDownView (int pos, View view, ViewGroup parent) {
|
||||||
|
return getView(pos, view, parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a View that displays the data at the specified position in the
|
||||||
|
* data set.
|
||||||
|
*
|
||||||
|
* @param pos The position of the item within the adapter's data set
|
||||||
|
* of the item whose view we want.
|
||||||
|
* @param view The old view to reuse, if possible. Note: You should
|
||||||
|
* check that this view is non-null and of an appropriate
|
||||||
|
* type before using. If it is not possible to convert
|
||||||
|
* this view to display the correct data.
|
||||||
|
* @param parent The parent that this view will eventually be
|
||||||
|
* attached to.
|
||||||
|
*
|
||||||
|
* @return A View corresponding to the data at the specified position.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public View getView (int pos, View view, ViewGroup parent) {
|
||||||
|
PrinterInfo printer = (PrinterInfo) getItem(pos);
|
||||||
|
CharSequence title = printer.getName();
|
||||||
|
CharSequence subtitle = null;
|
||||||
|
Drawable icon = null;
|
||||||
|
|
||||||
|
if (view == null) {
|
||||||
|
view = getLayoutInflater().inflate(
|
||||||
|
Meta.getResId(getApplicationContext(), "layout", "printer_list_item"),
|
||||||
|
parent, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
PackageManager pm = getPackageManager();
|
||||||
|
PrinterId pId = printer.getId();
|
||||||
|
Object cmpName = Meta.invokeMethod(pId, "getServiceName");
|
||||||
|
Object pkgName = Meta.invokeMethod(cmpName, "getPackageName");
|
||||||
|
|
||||||
|
PackageInfo packageInfo = pm.getPackageInfo(
|
||||||
|
(String) pkgName, 0);
|
||||||
|
|
||||||
|
subtitle = packageInfo.applicationInfo.loadLabel(pm);
|
||||||
|
icon = packageInfo.applicationInfo.loadIcon(pm);
|
||||||
|
} catch (NameNotFoundException e) {
|
||||||
|
/* ignore */
|
||||||
|
}
|
||||||
|
|
||||||
|
TextView titleView = (TextView) view.findViewById(android.R.id.title);
|
||||||
|
titleView.setText(title);
|
||||||
|
|
||||||
|
TextView subtitleView = (TextView) view.findViewById(android.R.id.hint);
|
||||||
|
if (!TextUtils.isEmpty(subtitle)) {
|
||||||
|
subtitleView.setText(subtitle);
|
||||||
|
subtitleView.setVisibility(View.VISIBLE);
|
||||||
|
} else {
|
||||||
|
subtitleView.setText(null);
|
||||||
|
subtitleView.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageView iconView = (ImageView) view.findViewById(android.R.id.icon);
|
||||||
|
if (icon != null) {
|
||||||
|
iconView.setImageDrawable(icon);
|
||||||
|
iconView.setVisibility(View.VISIBLE);
|
||||||
|
} else {
|
||||||
|
iconView.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicate whether the specified printer by position is available.
|
||||||
|
*
|
||||||
|
* @param position The position of the printer in the list.
|
||||||
|
*
|
||||||
|
* @return A truthy value means that the printer is available.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled (int position) {
|
||||||
|
PrinterInfo printer = (PrinterInfo) getItem(position);
|
||||||
|
return printer.getStatus() != PrinterInfo.STATUS_UNAVAILABLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -46,7 +46,8 @@
|
|||||||
[self.commandDelegate runInBackground:^{
|
[self.commandDelegate runInBackground:^{
|
||||||
CDVPluginResult* pluginResult;
|
CDVPluginResult* pluginResult;
|
||||||
BOOL isAvailable = [self isPrintingAvailable];
|
BOOL isAvailable = [self isPrintingAvailable];
|
||||||
NSArray *multipart = @[[NSNumber numberWithBool:isAvailable], @[]];
|
NSArray *multipart = @[[NSNumber numberWithBool:isAvailable],
|
||||||
|
[NSNumber numberWithInt:-1]];
|
||||||
|
|
||||||
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
|
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
|
||||||
messageAsMultipart:multipart];
|
messageAsMultipart:multipart];
|
||||||
|
Loading…
Reference in New Issue
Block a user