Cordova自定义插件与第三方原生android库无法正常工作

时间:2015-09-25 07:22:27

标签: javascript cordova android-library

在我的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();
        }
    };
}

0 个答案:

没有答案