Vue組件調用Android原生接口並利用Android Studio 打包

做了一個小的App Demo,利用Webpack 搭建Vue應用框架,vue組件通過js調用android 接口調用相機實現掃一掃功能,最後利用android studio 打包成apk. 整個過程不復雜,但搭建開發環境及fix bug 花了不少時間,記錄下來做個備忘。 

Vue組件調用Android 接口:

export default {
    data: function(){
        return {
        }
    },
    mounted: function() {
    },
    created: function(){
        window.androidScanCallBack = this.scanCallBack;
    },
    methods: {
        scan: function() {
             window.android.scan();
        },
        scanCallBack:function (qrcodeUrl) {           
             this.$nextTick(()=>{
                this.$refs.qrcode.value=qrcodeUrl;
              });
            if(this.$utility.IsURL(qrcodeUrl)){                
                window.location.href=qrcodeUrl;
            }
        },
    },
    components:{
    }
}

 在組件生命週期創建時給window全局註冊js方法 : window.androidScanCallBack = this.scanCallBack;

 上面androidScanCallBack 供 Android webview 調用頁面js使用:

在Android 的Activity中使用如下:

String jscript = "javascript:androidScanCallBack('www.baidu.com')";
webView.loadUrl(method);        

 Vue 組件中調用js : window.android.scan();

上面window對象的android對象由android原生創建,代碼如下:

webView.addJavascriptInterface(new JavascriptCall(),"android");

JavasciptCall的定義如下:

private class JavascriptCall {        
        @JavascriptInterface //js接口聲明
        public void scan() {
            
        }
    }

Android 原生實現調用攝像頭掃碼的邏輯略,利用zxing的庫來實現的資源很多,稍加研究就可以實現掃碼的功能;

Android Studio打包Apk

1:首先 npm run build 生成待打包的html資源:

2: 打開Android Studio 新建Android 工程,選擇Empty Activity,

拷貝dist目錄到Android 工程中,添加到assets文件夾 

在MainActivity.java中創建WebView, 並加載本地資源:

webView.loadUrl("file:///android_asset/dist/index.html");

省略圖標,權限等的配置。準備完畢:就可以Build 成apk了

 完整的Android MaintActivity代碼如下:

代碼實現了zxing 的掃一掃功能:參考blog:https://www.jianshu.com/p/28c6aa7e1d24

public class MainActivity extends AppCompatActivity {
    WebView webView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        getWindow().setFormat(PixelFormat.TRANSLUCENT);
        webView= findViewById(R.id.myWebView);
        WebSettings ws= webView.getSettings();
        ws.setJavaScriptEnabled(true);
        ws.setLoadWithOverviewMode(true);
        ws.setUseWideViewPort(true);
        ws.setDefaultTextEncodingName("utf-8");
        ws.setLoadsImagesAutomatically(true);
        ws.setSupportZoom(false);
        ws.setBuiltInZoomControls(false);
        ws.setDomStorageEnabled(true);
        ws.setAppCacheEnabled(true);
        ws.setAllowFileAccess(true);
        ws.setCacheMode(WebSettings.LOAD_NO_CACHE);
        webView.setWebViewClient(new WebViewClient(){
             @Override
             public boolean shouldOverrideUrlLoading(WebView view, String url) {
                 view.loadUrl(url);
                 return true;
             }             
        });
        webView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
        webView.loadUrl("file:///android_asset/dist/index.html");
        webView.addJavascriptInterface(new JavascriptCall(),"android");
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if(keyCode== KeyEvent.KEYCODE_BACK && webView.canGoBack()){
            webView.goBack();
            return true;
        }
        AlertDialog dialog=new AlertDialog.Builder(this).create();
        dialog.setTitle("提示");
        dialog.setMessage("確定退出嗎?");
        dialog.setButton(DialogInterface.BUTTON_POSITIVE, "確定", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                    finish();
            }
        });
        dialog.setButton(DialogInterface.BUTTON_NEGATIVE, "取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
            }
        });

        dialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
            @Override
            public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
                if(keyCode==KeyEvent.KEYCODE_BACK){
                    return  true;
                }
                return  true;
            }
        });
        dialog.show();
        return  super.onKeyDown(keyCode,event);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        // 掃描二維碼/條碼回傳
        if (requestCode == REQUEST_CODE_SCAN && resultCode == RESULT_OK) {
            if (data != null) {
                String content = data.getStringExtra(Constant.CODED_CONTENT);
                Toast.makeText(MainActivity.this, content, Toast.LENGTH_SHORT).show();
                String method = "javascript:testResult('" + content + "')";
                webView.loadUrl(method);
            }
        }
    }

    int REQUEST_CODE_SCAN=100;
    private class JavascriptCall {        
        @JavascriptInterface //js接口
        public void takePhoto() {
            Intent intent = new Intent(MainActivity.this, CaptureActivity.class);
            startActivityForResult(intent, REQUEST_CODE_SCAN);
        }
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章