Fix missing callback with result on Android

This commit is contained in:
Sebastián Katzer 2019-02-04 11:43:51 +01:00
parent 49ad2187df
commit d74bd6c4b6
9 changed files with 267 additions and 93 deletions

View File

@ -1,26 +1,24 @@
<?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@
Copyright 2013 Sebastián Katzer
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.
-->
<plugin id="cordova-plugin-printer"
@ -115,6 +113,9 @@
<source-file src="src/android/PrintOptions.java"
target-dir="src/de/appplant/cordova/plugin/printer" />
<source-file src="src/android/PrintProxy.java"
target-dir="src/de/appplant/cordova/plugin/printer" />
</platform>
<!-- windows -->

View File

@ -1,4 +1,6 @@
/*
Copyright 2013 Sebastián Katzer
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
@ -27,7 +29,6 @@ import android.print.PrintAttributes;
import android.print.PrintDocumentAdapter;
import android.print.PrintDocumentInfo;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.print.PrintHelper;
import java.io.FileOutputStream;
@ -49,7 +50,7 @@ class PrintAdapter extends PrintDocumentAdapter {
private final @NonNull InputStream input;
// The callback to inform once the job is done
private final @Nullable PrintHelper.OnPrintFinishCallback callback;
private final @NonNull PrintHelper.OnPrintFinishCallback callback;
/**
* Constructor
@ -59,7 +60,7 @@ class PrintAdapter extends PrintDocumentAdapter {
* @param callback The callback to inform once the job is done.
*/
PrintAdapter (@NonNull String jobName, @NonNull InputStream input,
@Nullable PrintHelper.OnPrintFinishCallback callback)
@NonNull PrintHelper.OnPrintFinishCallback callback)
{
this.jobName = jobName;
this.input = input;
@ -109,7 +110,7 @@ class PrintAdapter extends PrintDocumentAdapter {
}
/**
* Close input stream once the printing is done.
* Closes the input stream and invokes the callback.
*/
@Override
public void onFinish ()
@ -118,8 +119,6 @@ class PrintAdapter extends PrintDocumentAdapter {
PrintContent.close(input);
if (callback != null) {
callback.onFinish();
}
}
}

View File

@ -1,4 +1,6 @@
/*
Copyright 2013 Sebastián Katzer
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

View File

@ -1,5 +1,5 @@
/*
Copyright 2013-2016 appPlant GmbH
Copyright 2013 Sebastián Katzer
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
@ -26,6 +26,7 @@ import android.content.Context;
import android.graphics.Bitmap;
import android.print.PrintAttributes;
import android.print.PrintDocumentAdapter;
import android.print.PrintJob;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.print.PrintHelper;
@ -41,10 +42,15 @@ import java.io.InputStream;
import static android.content.Context.PRINT_SERVICE;
import static android.os.Build.VERSION.SDK_INT;
import static android.print.PrintJobInfo.STATE_COMPLETED;
import static de.appplant.cordova.plugin.printer.PrintContent.ContentType.UNSUPPORTED;
class PrintManager {
interface OnPrintFinishCallback {
void onFinish (boolean completed);
}
// The application context
private final @NonNull Context context;
@ -110,8 +116,7 @@ class PrintManager {
*/
@SuppressWarnings("ConstantConditions")
void print (@Nullable String content, @NonNull JSONObject settings,
@NonNull WebView view,
@Nullable PrintHelper.OnPrintFinishCallback callback)
@NonNull WebView view, @NonNull OnPrintFinishCallback callback)
{
switch (PrintContent.getContentType(content, context))
{
@ -123,26 +128,57 @@ class PrintManager {
break;
case HTML:
if (content == null || content.isEmpty()) {
printWebView(view, settings);
printWebView(view, settings, callback);
} else {
printText(content, "text/html", settings);
printHtml(content, settings, callback);
}
break;
case UNSUPPORTED:
// TODO unsupported content
case PLAIN:
printText(content, "text/plain", settings);
printText(content, settings, callback);
}
}
/**
* Prints the HTML content.
*
* @param content The HTML text to print.
* @param settings Additional settings how to render the content.
* @param callback The function to invoke once the job is done.
*/
private void printHtml (@Nullable String content,
@NonNull JSONObject settings,
@NonNull OnPrintFinishCallback callback)
{
printContent(content, "text/html", settings, callback);
}
/**
* Prints the plain text content.
*
* @param content The plain text to print.
* @param settings Additional settings how to render the content.
* @param callback The function to invoke once the job is done.
*/
private void printText (@Nullable String content,
@NonNull JSONObject settings,
@NonNull OnPrintFinishCallback callback)
{
printContent(content, "text/plain", settings, callback);
}
/**
* Prints the markup content.
*
* @param content The HTML markup to print.
* @param mimeType The mime type to render.
* @param settings Additional settings how to render the content.
* @param callback The function to invoke once the job is done.
*/
private void printText (@Nullable String content, @NonNull String mimeType,
@NonNull JSONObject settings)
private void printContent (@Nullable String content, @NonNull String mimeType,
@NonNull JSONObject settings,
@NonNull OnPrintFinishCallback callback)
{
((Activity) context).runOnUiThread(() -> {
view = this.createWebView(settings);
@ -155,7 +191,7 @@ class PrintManager {
@Override
public void onPageFinished (WebView view, String url) {
printWebView(PrintManager.this.view, settings);
printWebView(PrintManager.this.view, settings, callback);
PrintManager.this.view = null;
}
});
@ -169,9 +205,11 @@ class PrintManager {
*
* @param view The web view instance to print.
* @param settings Additional settings how to render the content.
* @param callback The function to invoke once the job is done.
*/
private void printWebView (@NonNull WebView view,
@NonNull JSONObject settings)
@NonNull JSONObject settings,
@NonNull OnPrintFinishCallback callback)
{
PrintOptions options = new PrintOptions(settings);
String jobName = options.getJobName();
@ -185,7 +223,9 @@ class PrintManager {
adapter = view.createPrintDocumentAdapter();
}
printAdapter(adapter, options);
PrintProxy proxy = new PrintProxy(adapter, () -> callback.onFinish(isPrintJobCompleted(jobName)));
printAdapter(proxy, options);
});
}
@ -197,7 +237,7 @@ class PrintManager {
* @param callback The function to invoke once the job is done.
*/
private void printPdf (@NonNull String path, @NonNull JSONObject settings,
@Nullable PrintHelper.OnPrintFinishCallback callback)
@NonNull OnPrintFinishCallback callback)
{
InputStream stream = PrintContent.open(path, context);
@ -205,7 +245,7 @@ class PrintManager {
PrintOptions options = new PrintOptions(settings);
String jobName = options.getJobName();
PrintAdapter adapter = new PrintAdapter(jobName, stream, callback);
PrintAdapter adapter = new PrintAdapter(jobName, stream, () -> callback.onFinish(isPrintJobCompleted(jobName)));
printAdapter(adapter, options);
}
@ -233,7 +273,7 @@ class PrintManager {
* @param callback The function to invoke once the job is done.
*/
private void printImage (@NonNull String path, @NonNull JSONObject settings,
@Nullable PrintHelper.OnPrintFinishCallback callback)
@NonNull OnPrintFinishCallback callback)
{
Bitmap bitmap = PrintContent.decode(path, context);
@ -245,7 +285,7 @@ class PrintManager {
options.decoratePrintHelper(printer);
printer.printBitmap(jobName, bitmap, callback);
printer.printBitmap(jobName, bitmap, () -> callback.onFinish(isPrintJobCompleted(jobName)));
}
/**
@ -283,6 +323,37 @@ class PrintManager {
return view;
}
/**
* Finds the print job by its name.
*
* @param jobName The name of the print job.
*
* @return null if it could not find any job with this label.
*/
@Nullable
private PrintJob findPrintJobByName (@NonNull String jobName)
{
for (PrintJob job : getPrintService().getPrintJobs()) {
if (job.getInfo().getLabel().equals(jobName)) {
return job;
}
}
return null;
}
/**
* Returns if the print job is done.
*
* @param jobName The name of the print job.
*/
private boolean isPrintJobCompleted (@NonNull String jobName)
{
PrintJob job = findPrintJobByName(jobName);
return (job == null || job.getInfo().getState() <= STATE_COMPLETED);
}
/**
* Returns the print service of the app.
*/

View File

@ -1,4 +1,6 @@
/*
Copyright 2013 Sebastián Katzer
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

View File

@ -0,0 +1,84 @@
/*
Copyright 2013 Sebastián Katzer
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 android.os.Bundle;
import android.os.CancellationSignal;
import android.os.ParcelFileDescriptor;
import android.print.PageRange;
import android.print.PrintAttributes;
import android.print.PrintDocumentAdapter;
import android.support.annotation.NonNull;
import android.support.v4.print.PrintHelper;
/**
* Simple delegate class to have access to the onFinish method.
*/
class PrintProxy extends PrintDocumentAdapter {
// Holds the delegate object
private final @NonNull PrintDocumentAdapter delegate;
// The callback to inform once the job is done
private final @NonNull PrintHelper.OnPrintFinishCallback callback;
/**
* Constructor
*
* @param adapter The real adapter.
* @param callback The callback to invoke once the printing is done.
*/
PrintProxy (@NonNull PrintDocumentAdapter adapter,
@NonNull PrintHelper.OnPrintFinishCallback callback)
{
this.delegate = adapter;
this.callback = callback;
}
@Override
public void onLayout (PrintAttributes oldAttributes,
PrintAttributes newAttributes,
CancellationSignal cancellationSignal,
LayoutResultCallback callback,
Bundle bundle)
{
delegate.onLayout(oldAttributes, newAttributes, cancellationSignal, callback, bundle);
}
@Override
public void onWrite (PageRange[] range,
ParcelFileDescriptor dest,
CancellationSignal cancellationSignal,
WriteResultCallback callback)
{
delegate.onWrite(range, dest, cancellationSignal, callback);
}
/**
* Invokes the callback.
*/
@Override
public void onFinish () {
super.onFinish();
callback.onFinish();
}
}

View File

@ -1,5 +1,5 @@
/*
Copyright 2013-2016 appPlant GmbH
Copyright 2013 Sebastián Katzer
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
@ -21,12 +21,14 @@
package de.appplant.cordova.plugin.printer;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.webkit.WebView;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.PluginResult;
import org.apache.cordova.PluginResult.Status;
import org.json.JSONArray;
import org.json.JSONObject;
@ -90,10 +92,7 @@ public class Printer extends CordovaPlugin {
PrintManager pm = new PrintManager(cordova.getContext());
boolean printable = pm.canPrintItem(item);
PluginResult res = new PluginResult(
PluginResult.Status.OK, printable);
callback.sendPluginResult(res);
sendPluginResult(callback, printable);
});
}
@ -108,7 +107,7 @@ public class Printer extends CordovaPlugin {
JSONArray utis = PrintManager.getPrintableUTIs();
PluginResult res = new PluginResult(
PluginResult.Status.OK, utis);
Status.OK, utis);
callback.sendPluginResult(res);
});
@ -129,7 +128,21 @@ public class Printer extends CordovaPlugin {
PrintManager pm = new PrintManager(cordova.getContext());
WebView view = (WebView) webView.getView();
pm.print(content, settings, view, callback::success);
pm.print(content, settings, view, (boolean completed) -> sendPluginResult(callback, completed));
});
}
/**
* Sends the result back to the client.
*
* @param callback The callback to invoke.
* @param value The argument to pass with.
*/
private void sendPluginResult (@NonNull CallbackContext callback,
boolean value)
{
PluginResult result = new PluginResult(Status.OK, value);
callback.sendPluginResult(result);
}
}

View File

@ -1,7 +1,7 @@
/* globals Windows: true */
/*
Copyright 2013-2016 appPlant GmbH
Copyright 2013 Sebastián Katzer
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file

View File

@ -1,4 +1,6 @@
/*
Copyright 2013 Sebastián Katzer
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