Android&H5-js通过jsbridge调用安卓相机/相册/通讯录

引文

是有这样一个需求 在vue里通过js可以直接调用安卓原生的照相机、相册和通讯录,并返回相应数据。当然前提是用webview来进行加载。

Android端处理

  • 在build.gradle引入(moudule:app)
dependencies {
    compile 'com.github.lzyzsd:jsbridge:1.0.4'
}
  • 在build.gradle引入(moudule:本项目)
allprojects {
    repositories {
        google()
        jcenter()
        maven { url "https://jitpack.io" }
    }
}
  • xml代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    android:orientation="vertical"
    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.github.lzyzsd.jsbridge.BridgeWebView
        android:id="@+id/web"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </com.github.lzyzsd.jsbridge.BridgeWebView>

</LinearLayout>
  • java代码
/**
 * Webview
 * @author ace
 * @date 2020/4/16
 */

public class WebView extends AppCompatActivity {
    private final static int PHOTO_REQUEST = 100;
    private final static int PHOTO_STORY_REQUEST = 101;
    private final static int CONTACT_REQUEST = 102;
    private BridgeWebView mBridgeWebView;
    private Uri imageUri;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_web_view);
        findViewById();
        init();
    }

    private void findViewById() {
        mBridgeWebView = findViewById(R.id.web);
    }

    private void init() {
        WebSettings mSettings = mBridgeWebView.getSettings();
        mSettings.setUseWideViewPort(true);
        mSettings.setLoadWithOverviewMode(true);
        mSettings.setDomStorageEnabled(true);
        mSettings.setDefaultTextEncodingName("UTF-8");
        // 是否可访问Content Provider的资源,默认值 true
        mSettings.setAllowContentAccess(true);
        // 是否可访问本地文件,默认值 true
        mSettings.setAllowFileAccess(true);
        mSettings.setJavaScriptEnabled(true);

        mBridgeWebView.setWebChromeClient(new MyWebChromeClient());
        mBridgeWebView.loadUrl("http://10.3.102.129:8080/#/?time=1000015576");

        mBridgeWebView.setDefaultHandler(new BridgeHandler() {
            @Override
            public void handler(String data, CallBackFunction function) {
                function.onCallBack("DefaultHandler收到Web发来的数据,回传数据给你");
            }
        });

        mBridgeWebView.registerHandler("scan", new BridgeHandler() {
            @Override
            public void handler(String data, CallBackFunction function) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    if (!checkPermission()) {
                        requestPermissions();
                    } else {
                        takePhoto();//拍照逻辑
                    }
                } else {
                    takePhoto();//拍照逻辑
                }
                function.onCallBack("正在调用相机");
            }
        });

        mBridgeWebView.registerHandler("contact", new BridgeHandler() {
            @Override
            public void handler(String data, CallBackFunction function) {
                PhotoUtils.takeContact(WebView.this, CONTACT_REQUEST);
                function.onCallBack("正在调用通讯录");
            }
        });


    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == PHOTO_REQUEST) {
            //照相回调
            try {
                Bitmap bitmap = PhotoUtils.getBitmapFormUri(this, imageUri);
                mBridgeWebView.callHandler("scanResult", PhotoUtils.bitmapToBase64(bitmap), new CallBackFunction() {
                    @Override
                    public void onCallBack(String data) {
                        Toast.makeText(WebView.this, data, Toast.LENGTH_SHORT).show();
                    }
                });
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else if (requestCode == PHOTO_STORY_REQUEST) {
            //相册回调
            Uri[] results = null;
            if (data == null) {
                results = null;
            } else {
                String dataString = data.getDataString();
                ClipData clipData = data.getClipData();
                if (clipData != null) {
                    results = new Uri[clipData.getItemCount()];
                    for (int i = 0; i < clipData.getItemCount(); i++) {
                        ClipData.Item item = clipData.getItemAt(i);
                        results[i] = item.getUri();
                    }
                }
                if (dataString != null) {
                    results = new Uri[]{Uri.parse(dataString)};
                }
            }
            try {
                Bitmap bitmap = PhotoUtils.getBitmapFormUri(this, results[0]);
                mBridgeWebView.callHandler("scanResult", PhotoUtils.bitmapToBase64(bitmap), new CallBackFunction() {
                    @Override
                    public void onCallBack(String data) {
                        Toast.makeText(WebView.this, data, Toast.LENGTH_SHORT).show();
                    }
                });
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else if (requestCode == CONTACT_REQUEST) {
            //通讯录回调
            if (data != null) {
                Uri uri = data.getData();
                String phoneNum = null;
                String contactName = null;
                ContentResolver contentResolver = getContentResolver();
                Cursor cursor = null;
                if (uri != null) {
                    cursor = contentResolver.query(uri,
                            new String[]{"display_name", "data1"}, null, null, null);
                }
                while (cursor.moveToNext()) {
                    contactName = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
                    phoneNum = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                }
                cursor.close();
                //  把电话号码中的  -  符号 替换成空格
                if (phoneNum != null) {
                    phoneNum = phoneNum.replaceAll("-", " ");
                    // 空格去掉  为什么不直接-替换成"" 因为测试的时候发现还是会有空格 只能这么处理
                    phoneNum = phoneNum.replaceAll(" ", "");
                }
                ContactBean contactBean = new ContactBean(phoneNum, contactName);
                String str = GsonUtil.BeanToJson(contactBean);
                mBridgeWebView.callHandler("contactResult", str, new CallBackFunction() {
                    @Override
                    public void onCallBack(String data) {
                    }
                });
            }
        }
    }

    /**
     * 拍照
     */
    private void takePhoto() {
        File fileUri = new File(Environment.getExternalStorageDirectory().getPath() + "/" + SystemClock.currentThreadTimeMillis() + ".jpg");
        if (!fileUri.getParentFile().exists()) {
            fileUri.getParentFile().mkdirs();
        }
        imageUri = Uri.fromFile(fileUri);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            //通过FileProvider创建一个content类型的Uri
            imageUri = FileProvider.getUriForFile(WebView.this, getPackageName() + ".fileProvider", fileUri);
        }
        PhotoUtils.takePicture(WebView.this, imageUri);
    }

    /**
     * 用户权限 申请 的回调方法
     *
     * @param requestCode
     * @param permissions
     * @param grantResults
     */
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode == 101) {
            if (checkPermission()) {
                takePhoto();
            } else {
                Toast toast = Toast.makeText(this, "没有相应权限!", Toast.LENGTH_SHORT);
                toast.show();

            }
        }
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

    /**
     * 是否有权限
     *
     * @return
     */
    private boolean checkPermission() {
        boolean haveCameraPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED;
        boolean haveWritePermission = ContextCompat.checkSelfPermission(this,
                Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;

        return haveCameraPermission && haveWritePermission;

    }

    /**
     * 请求所需权限
     */
    @RequiresApi(api = Build.VERSION_CODES.M)
    private void requestPermissions() {
        ActivityCompat.requestPermissions(WebView.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 101);
    }

    public class MyWebChromeClient extends WebChromeClient {
        @Override
        public boolean onJsAlert(android.webkit.WebView view, String url, String message, final JsResult result) {
            //创建一个Builder来显示网页中的对话框
            new AlertDialog.Builder(WebView.this)
                    .setTitle("Alert对话框")
                    .setMessage(message)
                    .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            result.confirm();
                        }
                    }).setCancelable(false).show();
            return true;
        }
    }
}

前端处理

工具js

<template>
  <div>
    <button @click="clickUploadImg">获取图片</button>
    <button @click="click">测试</button>
    <button @click="contact">通讯录获取</button>
    <img style="width: 50px;height: 50px" :src="src">
    <p>{{text}}</p>
    <br>&nbsp;<br>


  </div>
</template>

<script>

  export default {
    name: '',
    components: {},
    data(){
      return{
        text:"通讯录text4",
        src:''
      }
    },
    mounted() {
      // 注册
      this.$bridge.registerhandler('scanResult', (data, responseCallback)=>{
        this.src = "data:image/jpg;base64,"+data;
        responseCallback(data);
      });
      this.$bridge.registerhandler('contactResult',(data,responseCallback)=>{
        this.text = data;
        responseCallback(data);
      });

    },
    methods: {
      contact(){
        const params = {
          data:'i'
        };
        this.$bridge.callhandler('contact',params,(data)=>{
          alert(data);
        })
      },
      clickUploadImg() {
        // eslint-disable-next-line no-unused-vars
        const params = {
          data: '1'
        };
        this.$bridge.callhandler('scan', params, (data)=>{
          this.text = JSON.stringify(data);
          alert(JSON.stringify(data));
          // 处理返回数据
        });

      },
      click(){

      }
    }
  }
</script>

发布了11 篇原创文章 · 获赞 0 · 访问量 259

猜你喜欢

转载自blog.csdn.net/jinbiao8246/article/details/105563335