在我的cordova项目中,我需要使用本机代码,通过PDA上的扫描设备扫描,而不是通过相机扫描。我有原生的android项目,我把它改成了android库项目。然后我将res,src,project.properties和AndroidManifest.xml文件复制到myCordovaPlugin-> SRC-> android-> LibraryProject。当我在Ripple中构建我的cordova应用程序时,没有错误。但是当我构建设备时,我收到此错误消息。 “错误102 cmd:命令失败,退出代码为8”。我尝试了一些我在网上找到的解决方案。但仍然存在错误。 请帮我。我对cordova很新,这是我的第一个应用程序。我非常感谢任何帮助。谢谢。
这是Scanner.java。
package com.customplugin.barcodescanner;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.content.Intent;
import android.util.Log;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.PluginResult;
import android.util.Log;
public class Scanner extends CordovaPlugin {
public static final int REQUEST_CODE = 1;
private static final String SCAN_INTENT = com.adlink.sample.SDK.SCAN;
private CallbackContext callbackContext;
public Scanner() {
}
@Override
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) {
this.callbackContext = callbackContext;
if (action.equals(SCAN)) {
scan(args);
} else {
return false;
}
return true;
}
}
public void scan(JSONArray args) {
Intent intentScan = new Intent(SCAN_INTENT);
intentScan.addCategory(Intent.CATEGORY_DEFAULT);
// add config as intent extras
if(args.length() > 0) {
JSONObject obj;
JSONArray names;
String key;
Object value;
for(int i=0; i<args.length(); i++) {
try {
obj = args.getJSONObject(i);
} catch(JSONException e) {
Log.i("CordovaLog", e.getLocalizedMessage());
continue;
}
names = obj.names();
for(int j=0; j<names.length(); j++) {
try {
key = names.getString(j);
value = obj.get(key);
if(value instanceof Integer) {
intentScan.putExtra(key, (Integer)value);
} else if(value instanceof String) {
intentScan.putExtra(key, (String)value);
}
} catch(JSONException e) {
Log.i("CordovaLog", e.getLocalizedMessage());
continue;
}
}
}
}
// avoid calling other phonegap apps
intentScan.setPackage(this.cordova.getActivity().getApplicationContext().getPackageName());
this.cordova.startActivityForResult((CordovaPlugin) this, intentScan, REQUEST_CODE);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
if (requestCode == REQUEST_CODE) {
if (resultCode == Activity.RESULT_OK) {
JSONObject obj = new JSONObject();
try {
obj.put(TEXT, intent.getStringExtra("SCAN_RESULT"));
obj.put(FORMAT, intent.getStringExtra("SCAN_RESULT_FORMAT"));
obj.put(CANCELLED, false);
} catch (JSONException e) {
Log.d(LOG_TAG, "This should never happen");
}
//this.success(new PluginResult(PluginResult.Status.OK, obj), this.callback);
this.callbackContext.success(obj);
} else if (resultCode == Activity.RESULT_CANCELED) {
JSONObject obj = new JSONObject();
try {
obj.put(TEXT, "");
obj.put(FORMAT, "");
obj.put(CANCELLED, true);
} catch (JSONException e) {
Log.d(LOG_TAG, "This should never happen");
}
//this.success(new PluginResult(PluginResult.Status.OK, obj), this.callback);
this.callbackContext.success(obj);
} else {
//this.error(new PluginResult(PluginResult.Status.ERROR), this.callback);
this.callbackContext.error("Unexpected error");
}
}
}
/**
* Initiates a barcode encode.
*
* @param type Endoiding type.
* @param data The data to encode in the bar code.
*/
public void encode(String type, String data) {
Intent intentEncode = new Intent(ENCODE_INTENT);
intentEncode.putExtra(ENCODE_TYPE, type);
intentEncode.putExtra(ENCODE_DATA, data);
// avoid calling other phonegap apps
intentEncode.setPackage(this.cordova.getActivity().getApplicationContext().getPackageName());
this.cordova.getActivity().startActivity(intentEncode);
}
}
这是Scanner.js。
cordova.define('cordova/plugin/Scanner', function(require, exports, module) {
var exec = require("cordova/exec");
/**
* Empty constructor
*/
var customScanner = function() {
};
customScanner.prototype.scan=
function (successCallback, errorCallback) {
exec(successCallback,
errorCallback,
"Scanner",
"scan",
[]);
}
module.exports = new customScanner();
});
这是来自index.js的onDeviceReady函数的插件调用。
var Scanner = cordova.require("cordova/plugin/Scanner");
Scanner.scan();
这是我的Native ScannerActivity.java。
package com.mypackage.sample.SDK;
import com.mypackage.sample.SDK.ENGINE;
import android.os.Bundle;
import android.os.SystemClock;
import android.preference.PreferenceManager;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.DialogInterface.OnDismissListener;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.util.SparseArray;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnKeyListener;
import android.widget.RadioButton;
import android.widget.TextView;
public class ScanActivity extends Activity implements OnClickListener
{
private static FakeR fakeR;
private static final String TAG = "ScanActivity";
private static final int DIALOG_WAITTING = 2;
private BroadcastReceiver m_msgReceiver = null;
private DBaseUtil m_db = null;
private SparseArray<Boolean> m_engineSupported = null;
private TextView m_btnScan = null;
private RadioButton m_rbBarcode1D = null;
private RadioButton m_rbBarcodeCCD = null;
private TextView m_scanSymbology = null;
private TextView m_scanSize = null;
private TextView m_scanValue = null;
private TextView m_scanElapse = null;
private boolean m_inProgress = false;
private boolean m_scanStarted = false;
private int m_nextEngine = ADMSG.ENGINE.None;
private ProgressDialog m_dlgProgress = null;
private boolean m_showMoreInfo = false;
private long m_scanStartTime = 0;
private int m_scanMode = ADMSG.SCANMODE.ONETIME;
private int m_scanKeycode = -1;
@Override
public void onCreate(Bundle savedInstanceState)
{
fakeR = new FakeR(this);
super.onCreate(savedInstanceState);
setContentView(fakeR.getId("layout", "scan_main"));
m_db = new DBaseUtil(this);
m_engineSupported = new SparseArray<Boolean>();
decideScanEngine();
boolean Barcode1D_enabled = engineEnabled(ADMSG.ENGINE.Barcode_1D);
boolean BarcodeCCD_enabled = engineEnabled(ADMSG.ENGINE.Barcode_CCD);
Log.d(TAG, "onCreate - Barcode_1D="+Barcode1D_enabled+", Barcode_CCD="+BarcodeCCD_enabled);
if(!Barcode1D_enabled && !BarcodeCCD_enabled)
{
showDialog_noSupportedEngine();
}
m_btnScan = (TextView)findViewById(fakeR.getId("id", "btnScan"));
m_btnScan.setOnClickListener(this);
//m_btnScan.setOnKeyListener(this);
m_rbBarcode1D = setEngineSwitch(fakeR.getId("id", "Reader_Barcode_1D"), Barcode1D_enabled);
m_rbBarcodeCCD = setEngineSwitch(fakeR.getId("id", "Reader_Barcode_CCD"), BarcodeCCD_enabled);
m_scanKeycode = getBgScanKeycode();
//Log.d(TAG, "onCreate - scanKeycode="+m_scanKeycode);
int currentEngine = checkAndCorrectEngine(m_db.getCurrentEngine());
Log.d(TAG, "onCreate - currentEngine="+currentEngine);
switch(currentEngine)
{
case ADMSG.ENGINE.Barcode_1D: m_rbBarcode1D.setChecked(true); break;
case ADMSG.ENGINE.Barcode_CCD: m_rbBarcodeCCD.setChecked(true); break;
}
m_scanSymbology = (TextView)findViewById(fakeR.getId("id", "scan_symbology"));
//m_scanSymbology.setVisibility((m_rbBarcodeCCD.isChecked())?(View.GONE):(View.VISIBLE));
if(m_showMoreInfo)
{
m_scanSize = (TextView)findViewById(fakeR.getId("id", "scan_size"));
m_scanSize.setVisibility(View.VISIBLE);
m_scanElapse = (TextView)findViewById(fakeR.getId("id", "scan_elapse"));
m_scanElapse.setVisibility(View.VISIBLE);
}
m_scanValue = (TextView)findViewById(fakeR.getId("id", "scan_value"));
m_scanValue.setMovementMethod(new ScrollingMovementMethod());
}
@Override
public void onRestart()
{
Log.d(TAG, "onRestart");
super.onRestart();
m_scanSymbology.setText(null);
m_scanValue.setText(null);
if(m_scanSize != null)
{
m_scanSize.setText(null);
}
if(m_scanElapse != null)
{
m_scanElapse.setText(null);
}
}
@Override
public void onResume()
{
Log.d(TAG, "onResume");
super.onResume();
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);
if(pref != null)
{
m_scanMode = (pref.getBoolean("_System_ScanMode_Continuous_", false))?(ADMSG.SCANMODE.CONTINUOUS):(ADMSG.SCANMODE.ONETIME);
}
switch(m_db.getCurrentEngine())
{
case ADMSG.ENGINE.Barcode_1D: m_rbBarcode1D.setChecked(true); break;
case ADMSG.ENGINE.Barcode_CCD: m_rbBarcodeCCD.setChecked(true); break;
}
disableBgScanMode();
enableFgScanMode();
registerMessageReceivers();
}
@Override
public void onPause()
{
Log.d(TAG, "onPause");
unregisterMessageReceivers();
disableFgScanMode();
enableBgScanMode();
setScanButtonState(false);
super.onPause();
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event)
{
if(keyCode == m_scanKeycode)
{
onClick(m_btnScan);
return(true);
}
return(super.onKeyUp(keyCode, event));
}
@Override
public void onClick(View view)
{
if(view == m_btnScan)
{
if(m_inProgress)
{
if(m_scanMode == ADMSG.SCANMODE.CONTINUOUS)
{
stopScan();
}
}
else
{
startScan();
}
}
else if(view == m_rbBarcode1D)
{
changeEngine(ADMSG.ENGINE.Barcode_1D);
}
else if(view == m_rbBarcodeCCD)
{
changeEngine(ADMSG.ENGINE.Barcode_CCD);
}
}
private void decideScanEngine()
{
boolean enable_1D = m_db.getEngineSupported(ADMSG.ENGINE.Barcode_1D);
boolean enable_CCD = m_db.getEngineSupported(ADMSG.ENGINE.Barcode_CCD);
m_engineSupported.put(ADMSG.ENGINE.Barcode_1D, enable_1D);
m_engineSupported.put(ADMSG.ENGINE.Barcode_CCD, enable_CCD);
int currentEngine = m_db.getCurrentEngine();
Log.d(TAG, "decideScanEngine - currentEngine="+currentEngine);
if(!isValidEngine(currentEngine))
{
m_db.setCurrentEngine(checkAndCorrectEngine(currentEngine));
}
}
private boolean engineEnabled(int id)
{
return(m_engineSupported.get(id));
}
private boolean isValidEngine(int engine)
{
return((engine == ENGINE.Barcode_1D) || (engine == ENGINE.Barcode_CCD));
}
private int checkAndCorrectEngine(int engine)
{
int validEngine = engine;
/*
if(!isValidEngine(validEngine))
{
validEngine = m_db.getCurrentEngine();
}
*/
if(!isValidEngine(validEngine))
{
if(engineEnabled(ADMSG.ENGINE.Barcode_CCD))
{
validEngine = ADMSG.ENGINE.Barcode_CCD;
}
else if(engineEnabled(ADMSG.ENGINE.Barcode_1D))
{
validEngine = ADMSG.ENGINE.Barcode_1D;
}
else
{
validEngine = ADMSG.ENGINE.None;
}
}
Log.d(TAG, "checkAndCorrectEngine - validEngine="+validEngine);
return(validEngine);
}
private RadioButton setEngineSwitch(int resId, boolean enabled)
{
RadioButton rb = (RadioButton)findViewById(resId);
if(rb != null)
{
rb.setOnClickListener(this);
if(!enabled)
{
rb.setVisibility(View.GONE);
}
}
return(rb);
}
private void registerMessageReceivers()
{
if(m_msgReceiver == null)
{
m_msgReceiver = new MessageReceiver();
}
IntentFilter filter = new IntentFilter();
filter.addAction(ADMSG.ACTION.OBTAIN_SCAN_DATA);
filter.addAction(ADMSG.ACTION.ENGINE_STATE_CHANGED);
registerReceiver(m_msgReceiver, filter);
}
private void unregisterMessageReceivers()
{
if(m_msgReceiver != null)
{
unregisterReceiver(m_msgReceiver);
}
}
private class MessageReceiver extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent)
{
String action = intent.getAction();
Log.d(TAG, "onReceive - action="+action);
if(ADMSG.ACTION.OBTAIN_SCAN_DATA.equals(action))
{
String value = intent.getStringExtra(ADMSG.KEY.SCAN.VALUE);
String symbology = intent.getStringExtra(ADMSG.KEY.SCAN.SYMBOLOGY);
boolean finished = intent.getBooleanExtra(ADMSG.KEY.SCAN.FINISHED, true);
Log.d(TAG, "\tvalue="+value);
m_scanSymbology.setText(symbology);
m_scanValue.setText(value);
m_scanValue.scrollTo(0, 0);
if(m_scanSize != null)
{
int dataCnt = (value != null)?(value.length()):(0);
m_scanSize.setText(String.format("%d", dataCnt));
}
if(m_scanElapse != null)
{
long elapse = SystemClock.elapsedRealtime() - m_scanStartTime;
m_scanElapse.setText(String.format("%dms", elapse));
}
setScanButtonState(!finished);
}
else if(ADMSG.ACTION.ENGINE_STATE_CHANGED.equals(action))
{
Bundle extras = intent.getExtras();
if(extras == null)
{
return;
}
int currentEngine = m_db.getCurrentEngine();
int state = extras.getInt(ADMSG.KEY.ENGINE.STATE);
boolean engineChanged = extras.getBoolean(ADMSG.KEY.ENGINE.CHANGED);
Log.d(TAG, "onReceive - ENGINE_STATE_CHANGED - state="+state+", engineChanged="+engineChanged);
if(state == ADMSG.ENGINE.STATE.STARTED)
{
showInitEngineProgress(false);
}
else if((state == ADMSG.ENGINE.STATE.STARTING) ||
(state == ADMSG.ENGINE.STATE.STOPPING))
{
}
else if(state == ADMSG.ENGINE.STATE.STOPPED)
{
Log.d(TAG, "\tSTOPPED - engine: "+currentEngine+" -> "+m_nextEngine);
if((m_nextEngine == currentEngine) ||
!isValidEngine(m_nextEngine))
{
return;
}
m_db.setCurrentEngine(checkAndCorrectEngine(currentEngine));
m_nextEngine = ADMSG.ENGINE.None;
}
}
}
}
private void setScanMode(boolean bgScan, boolean enable)
{
Log.d(TAG, "setScanMode - bgScan="+bgScan+", enable="+enable);
Intent in = new Intent();
in.setAction((bgScan)?(ADMSG.ACTION.BGSCAN_MODE):(ADMSG.ACTION.FGSCAN_MODE));
in.putExtra(ADMSG.KEY.SCAN.COMMAND, (enable)?(ADMSG.CMD.ENABLE):(ADMSG.CMD.DISABLE));
in.putExtra(ADMSG.KEY.REQUESTER.PACKAGE, getPackageName());
in.putExtra(ADMSG.KEY.REQUESTER.CLASS, getClass().getName());
in.putExtra(ADMSG.KEY.SCAN.MODE, m_scanMode);
if(m_scanMode == ADMSG.SCANMODE.CONTINUOUS)
{
in.putExtra(ADMSG.KEY.SCAN.OPT.CS.FIXED_PERIOD, false);
in.putExtra(ADMSG.KEY.SCAN.OPT.CS.IGNORE_SAME_ONE, true);
in.putExtra(ADMSG.KEY.SCAN.OPT.CS.STOP_IF_SUCCESS, true);
in.putExtra(ADMSG.KEY.SCAN.OPT.CS.TIME_INTERVAL, 1500);
}
//in.putExtra(ADMSG.KEY.BGSCAN_KEYCODE, KeyEvent.KEYCODE_ENTER);
sendBroadcast(in);
}
private void enableBgScanMode()
{
setScanMode(true, true);
}
private void disableBgScanMode()
{
setScanMode(true, false);
}
private void enableFgScanMode()
{
setScanMode(false, true);
}
private void disableFgScanMode()
{
setScanMode(false, false);
}
private void startScan()
{
m_scanSymbology.setText(null);
m_scanValue.setText(null);
if(m_scanSize != null)
{
m_scanSize.setText(null);
}
if(m_scanElapse != null)
{
m_scanElapse.setText(null);
}
setScanButtonState(true);
sendScanCommand(this, -1, ADMSG.CMD.START);
m_scanStartTime = SystemClock.elapsedRealtime();
}
private void stopScan()
{
sendScanCommand(this, -1, ADMSG.CMD.STOP);
}
private void changeScanEngine(Context context, int engine)
{
//Log.d(TAG, "chageEngine - engine="+engine);
Intent in = new Intent();
in.setAction(ADMSG.ACTION.ENGINE_CHANGE);
in.putExtra(ADMSG.KEY.ENGINE.ID, engine);
context.sendBroadcast(in);
}
private void sendScanCommand(Context context, int engine, String cmd)
{
//Log.d(TAG, "startScanService - engine="+engine+", cmd="+cmd);
Bundle extras = new Bundle();
extras.putString(ADMSG.KEY.SCAN.COMMAND, cmd);
extras.putInt(ADMSG.KEY.SCAN.ENGINE, engine);
sendScanCommand(context, extras);
}
private void sendScanCommand(Context context, Bundle extras)
{
Intent in = new Intent();
in.setAction(ADMSG.ACTION.SCAN);
in.putExtras(extras);
context.sendBroadcast(in);
}
private void enableScanButton(boolean enabled)
{
//Log.d(TAG, "> enableScanButton - m_scanStarted="+m_scanStarted);
m_inProgress = !enabled;
Resources rcs = getResources();
if(m_scanMode == ADMSG.SCANMODE.CONTINUOUS)
{
int txtRes = (enabled)?(fakeR.getId("string", "txt_Scan")):(fakeR.getId("string", "txt_Stop"));
m_btnScan.setText(txtRes);
}
else
{
int txtColorRes = (enabled)?(fakeR.getId("color", "text_color_tab_checked")):(fakeR.getId("color", "text_color_tab_unchecked"));
m_btnScan.setTextColor(rcs.getColor(txtColorRes));
m_btnScan.setEnabled(enabled);
}
}
private void setScanButtonState(boolean pressed)
{
Log.d(TAG, ">> setScanButtonState - pressed="+pressed);
m_scanStarted = pressed;
enableScanButton(!pressed);
}
private void changeEngine(int engine)
{
int currentEngine = m_db.getCurrentEngine();
Log.d(TAG, "changeEngine - engine: "+currentEngine+" -> "+engine);
if(engine == currentEngine)
{
return;
}
showInitEngineProgress(true);
m_scanSymbology.setText(null);
m_scanValue.setText(null);
if(m_scanSize != null)
{
m_scanSize.setText(null);
}
if(m_scanElapse != null)
{
m_scanElapse.setText(null);
}
changeScanEngine(this, engine);
m_nextEngine = engine;
}
private void showInitEngineProgress(boolean show)
{
if(show)
{
enableScanButton(false);
showDialog(DIALOG_WAITTING);
return;
}
Log.d(TAG, "showInitEngineProgress - m_dlgProgress="+m_dlgProgress);
if(m_dlgProgress != null)
{
m_dlgProgress.dismiss();
//m_dlgProgress = null;
}
if(!m_scanStarted)
{
enableScanButton(true);
}
}
private int getBgScanKeycode()
{
try
{
return(Integer.valueOf(m_db.getBgScanKeycode()));
}
catch(NumberFormatException e)
{
Log.e(TAG, "getBgScanKeycode - "+e.toString());
}
catch(NullPointerException e)
{
Log.e(TAG, "getBgScanKeycode - "+e.toString());
}
return(KeyEvent.KEYCODE_DPAD_CENTER);
}
@Override
protected Dialog onCreateDialog(int id)
{
switch(id)
{
case DIALOG_WAITTING:
{
String msg = getResources().getString(fakeR.getId("string", "txt_Engine_initializing"));
if(m_dlgProgress == null)
{
m_dlgProgress = new ProgressDialog(this);
m_dlgProgress.setIndeterminate(true);
m_dlgProgress.setCancelable(false);
}
m_dlgProgress.setMessage(msg);
return(m_dlgProgress);
}
}
return null;
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
super.onCreateOptionsMenu(menu);
MenuInflater inflater = getMenuInflater();
inflater.inflate(fakeR.getId("menu", "settings_menu"), menu);
MenuItem item = null;
item = menu.getItem(0);
item.setIcon(fakeR.getId("drawable", "ic_menu_preferences"));
item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener()
{
public boolean onMenuItemClick(MenuItem item)
{
Intent preferences = new Intent();
preferences.setClass(ScanActivity.this, SettingsActivity.class);
startActivity(preferences);
return(true);
}
});
return(true);
}
private void showDialog_noSupportedEngine()
{
AlertDialog.Builder builder = new AlertDialog.Builder(this);
//builder.setTitle(R.string.txt_ResetToDefault);
builder.setMessage(fakeR.getId("string", "txt_NoAnyValidScanEngine"));
builder.setPositiveButton(fakeR.getId("string", "txt_OK"), null);
builder.show().setOnDismissListener(m_dlgResetDismissListener);
}
OnDismissListener m_dlgResetDismissListener = new OnDismissListener()
{
public void onDismiss(DialogInterface dialog)
{
finish();
}
};
}