做了一个小的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);
        }
    }
}

 

Logo

前往低代码交流专区

更多推荐