Android科尔多瓦插件开发 - JS界面中的错误

问题描述:

我试图开发Android平台的科尔多瓦插件,并承认这是我的第一个,所以我的错误可能是基本的,但对于我的生活,我不能弄清楚为什么我的科尔多瓦插件不起作用。我不断收到引用错误类似如下:Android科尔多瓦插件开发 - JS界面中的错误

"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)

除了这种类型错误 "Uncaught TypeError: Cannot read property 'display' of undefined", source: file:///android_asset/www/js/index.js (37)

这里是我的插件Java代码:

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 
    ); 
} 
} 

我的JavaScript插件界面(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> 

任何人可以帮助我弄清楚为什么我得到这些错误?

首先,你不能直接要求Cordova模块。 会发生什么事是,当你的插件安装到Android平台,科尔多瓦CLI将包裹你的JS插件组件的功能:

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

因此,在你的插件代码,你可以假设cordova已经被定义为一个全局变量,以及require,exports,module

因此,从pdfRenderer.js中删除var cordova = require('cordova');行。

此外,您应该从正文标记中删除onload处理程序:<body onload="initialize()">。 这不是必要的,因为deviceready事件的是什么(也应该)被用来开始应用初始化,并且你已经有了这个在你app.js

这些是我能看到两个明显的错误,所以尝试做出这些改变并看看会发生什么。

+0

谢谢!这是一个好的开始。 这里是我的错误现在: ' “未捕获的ReferenceError:模块没有定义”,来源:文件:///android_asset/www/js/pdfRenderer.js(81)' 和 '“类未找到“,来源:file:///android_asset/www/js/pdfRenderer.js(16)' –

+1

'”Class not found“,来源:file:///android_asset/www/js/pdfRenderer.js(16) '这是因为你已经命名了你的插件''但是你把它叫做'PLUGIN_NAME =“PdfRendererService”;'。最简单的方法是用相同的名称命名插件的所有组件,以避免此类问题。 – DaveAlden

+0

由于您的建议,我似乎正在取得更多进展,并且在JS界面的错误回调中删除了任何'console.log'调用。我不再收到这些错误,但现在当我尝试调用插件函数时,出现以下错误: 'D/PluginManager:exec()调用未知插件:PdfRendererPlugin' 这是来自android侧,所以它看起来像JS接口正在工作。也许我应该关闭这个线程,并打开一个新的,如果还没有一个答案我的问题在那里? –