简体   繁体   中英

Android Cordova Plugin Development - Errors in JS Interface

I'm attempting to develop a Cordova plugin for the Android platform, and admittedly this is my first one so my mistakes are probably elementary, but for the life of me I can't figure out why my cordova plugin just won't work. I keep getting reference errors like the following:

"Uncaught ReferenceError: require is not defined", source: file:///android_asset/www/js/pdfRenderer.js (3)

"Uncaught ReferenceError: initialize is not defined", source: file:///android_asset/www/index.html (10)

As well as this TypeError "Uncaught TypeError: Cannot read property 'display' of undefined", source: file:///android_asset/www/js/index.js (37)

Here's my Plugin Java code:

package com.dev.plugin.PdfRendererService;

import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CallbackContext;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.graphics.pdf.PdfRenderer;
import android.graphics.pdf.PdfRenderer.Page;

/**
 * This class handles a pdf file called from JavaScript and converts a 
selected page (default is first) to a byte array representing a bitmap.
 */
public class PdfRendererService extends CordovaPlugin {

private ParcelFileDescriptor fileDescriptor = null;
private PdfRenderer renderer = null;
private Page currentPage = null;

private int mWidth = 400, mHeight = 600;
private String mRenderMode = "display";

@Override
public void initialize(CordovaInterface cordova, CordovaWebView webView){        
    super.initialize(cordova, webView);
}

@Override
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
    this.validatePermissions();

    boolean isPageOpen = false;
    switch(action){
        case "open":
            return executeOpen(args, callbackContext);
        case "renderPage":
            return executeRenderPage(args, callbackContext);
        case "pageCount":
            callbackContext.success(this.getPageCount());
            return true;
        case "close":
            this.closeRenderer();
            callbackContext.success();
            return true;
    }
    return false;
}

private boolean executeOpen(JSONArray args, CallbackContext callbackContext){
    //TODO - Implement this method
    return true;
}

private boolean executeRenderPage(JSONArray args, CallbackContext callbackContext){
    //TODO - Implement this method
    return true;
}

private int getPageCount() {
    if(renderer == null)
        return 0;

    return renderer.getPageCount();
}

private void initializeWriteFileDescriptor(String filePath, CallbackContext callbackContext){
    //TODO - Implement this method
}

private void initializeRenderer(String filePath, CallbackContext callbackContext){
    renderer = null;

    initializeWriteFileDescriptor(filePath, callbackContext);

    if(fileDescriptor == null) {
        callbackContext.error("An error has occurred while loading the requested file.");
        return;
    }

    renderer = new PdfRenderer(fileDescriptor);
}

private void closeRenderer() {
    if(renderer == null) {
        return;
    }

    renderer.close();
}

private boolean openPage(int index, CallbackContext callbackContext){
    //TODO - Implement this method
    return true;
}

private void sendBitmapAsBytes(int index, Bitmap bitmap, CallbackContext callbackContext){
    //TODO - Implement this method
}

private static byte[] toByteArray(Bitmap bitmap){
    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.JPG, 100, stream);

    return stream.toByteArray();
}

private static Bitmap getBitmap(int width, int height){
    return Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
}

private static ParcelFileDescriptor getWriteFileDescriptor(String filePath){
    return ParcelFileDescriptor(
            new File(filePath),
            ParcelFileDescriptor.MODE_TRUNCATE |
            ParcelFileDescriptor.MODE_CREATE   |
            ParcelFileDescriptor.MODE_WRITE_ONLY
    );
}
}

My Javascript Plugin interface (pdfRenderer.js)

'use strict';

var cordova = require('cordova');

var PLUGIN_NAME = "PdfRendererService";

var SERVICE_OPEN = "open";
var SERVICE_CLOSE = "close";
var SERVICE_PAGE_COUNT = "pageCount";
var SERVICE_RENDER_PAGE = "renderPage";

var RENDER_MODE_DISPLAY = "display";
var RENDER_MODE_PRINT = "print";

var PdfRendererPlugin = {
display: function(filePath, callback){
    cordova.exec(callback, function(err){
        console.log(err);
    }, PLUGIN_NAME, SERVICE_OPEN, [filePath, RENDER_MODE_DISPLAY]);
},

renderPage: function(pageNo, callback){
    cordova.exec(callback, function(err){
        console.log(err);
    }, PLUGIN_NAME, SERVICE_RENDER_PAGE, [pageNo]);
},

close: function(callback){
    cordova.exec(callback, function(err){
        console.log(err);
    }, PLUGIN_NAME, SERVICE_CLOSE, []);
},

getPageCount: function(callback){
    cordova.exec(callback, function(err){
        console.log(err);
    }, PLUGIN_NAME, SERVICE_PAGE_COUNT, []);
}
};

module.exports = PdfRendererPlugin;

index.js

var testFilePath = 'assets/software-development.pdf';

var app = {
// Application Constructor
initialize: function() {
    document.addEventListener('deviceready', this.onDeviceReady.bind(this), false);
},

// deviceready Event Handler
//
// Bind any cordova events here. Common events are:
// 'pause', 'resume', etc.
onDeviceReady: function() {
    this.display();
},

display: function(){
    PdfRendererPlugin.display(testFilePath, function(data){
    console.log('Bitmap Bytes');
        console.log(data);
    });
}
};

app.initialize();

index.html

<!DOCTYPE html>
<html>
<head>
    <title>Cordova PDF Generator Plugin Test</title>

    <meta name="viewport" content="user-scalable=no, initial-scale=1,
          maximum-scale=1, minimum-scale=1, width=device-width,
          height=device-height" />
</head>
<body onload="initialize()">
    <div class="app">
        <h1>Cordova PDF Generation Plugin Test</h1>
    </div>

    <script type="text/javascript" src="cordova.js"></script>
    <script type="text/javascript" src="js/pdfRenderer.js"></script>
    <script type="text/javascript" src="js/index.js"></script>
</body>
</html>

plugin.xml

<?xml version="1.0" encoding="UTF-8"?>
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
    id="cordova-plugin-pdf-renderer" version="0.2.3">
<name>PdfRenderer</name>
<description>Cordova PDF Renderer Plugin</description>
<license>MIT</license>
<keywords>cordova,pdf,renderer</keywords>

<platform name="android">
    <js-module src="www/js/pdfRenderer.js" name="PdfRendererPlugin">
        <runs/>

        <clobbers target="PdfRendererPlugin" />
    </js-module>

    <config-file target="config.xml" parent="/*">
        <feature name="PdfRendererPlugin">
            <param name="android-package" value="com.dev.plugin.PdfRendererService"/>
            <param name="onload" value="true" />
        </feature>
    </config-file>

    <source-file src="src/android/PdfRendererService.java" target-dir="src/com/dev/plugin/" />
</platform>
</plugin>

Can anybody help me figure out why I'm getting these errors?

Firstly, you can't require the Cordova module directly. What happens is, when you plugin is installed to the Android platform, the Cordova CLI will wrap your JS plugin component in a function:

cordova.define("your.plugin.namespace", function(require, exports, module) {
// Your plugin code
});

Therefore, in your plugin code, you can assume cordova is already defined as a global variable, and require , exports , module .

So remove the line var cordova = require('cordova'); from your pdfRenderer.js .

Also you should remove the onload handler from the body tag: <body onload="initialize()"> . This is not necessary as the deviceready event is what is being (and should be) used to kick off app initialization, and you already have this in your app.js

These are the two obvious errors that I can see, so try making these changes and see what happens.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM