i***@qq.com
i***@qq.com
  • 发布:2023-06-29 13:04
  • 更新:2023-06-30 14:51
  • 阅读:693

uni-app 不使用插件的方式跳转Android原生界面(Activity)并传值和接收返回值

分类:uni-app

目前可以唤醒第三方app并且传递参数,但是唤醒的app返还的值怎么拿到?
我是通过下面的方式调用的。

const isApp = plus.runtime.isApplicationExist({  
                    pname: pname  
                });  
                if (isApp) {  
                    let cmPerPixel = (Math.floor(Math.random() * (150 - 50)) + 50).toString()  
                    plus.runtime.launchApplication({ //根据包名启动Android原生开发的App  
                            pname: pname,  
                            extra: {  
                                enableMask: "true",  
                                backActivityName: "uni.***",  
                                cmPerPixel: cmPerPixel  
                            }  
                        },  
                        function(e) {  
                            console.log('Open system default browser failed: ' + e.message);  
                        }  
                    );  
                } else {  
                    // 没有安装  
                    uni.showToast({  
                        title: "请安装拍照APP",  
                        icon: 'none',  
                        duration: 2000  
                    })  
                }

我更新成了下面的方式调用,同样可以唤醒app和传递参数,但是拿不到返回值,获取返回值的函数在开启新界面时就调用了,app返回结果却没有调用。
前端代码:

let cmPerPixel = (Math.floor(Math.random() * (150 - 50)) + 50).toString()  
                var main = plus.android.runtimeMainActivity();  
                var Intent = plus.android.importClass("android.content.Intent")  
                var intent = new Intent(main.getIntent())  
                let ComponentName = plus.android.importClass('android.content.ComponentName');  
                intent.setComponent(new ComponentName("com.***.***", "com.***.***.MainActivity"));  
                intent.putExtra("enableMask", "true");  
                intent.putExtra("cmPerPixel", cmPerPixel);  
                intent.putExtra("backActivityName", "annew");  
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  

                // 请求码保证了,开始的新界面和返回的是同一个操作  
                var CODE_REQUEST = 1;  
                // 采用startActivityForResult开启新的界面,当界面关闭时可以处理返回结果,CODE REQUEST请求码是唯一标识  
                main.startActivityForResult(intent, CODE_REQUEST);  
                // 设置原生界面返回后的回调操作  
                main.onActivityResult = function(requestCode, resultCode, data) {  
                    uni.showModal({  
                        title: '提示',  
                        content: 'requestCode:' + requestCode + ',resultCode:' + resultCode + ',data:' + data,  
                        success: function(res) {  
                            if (res.confirm) {  
                                console.log('用户点击确定');  
                            } else if (res.cancel) {  
                                console.log('用户点击取消');  
                            }  
                        }  
                    });  

                    console.log(requestCode, resultCode, data);  
                }

原生APP:

没有使用插件方式
需求是:uniapp(A)端调用其它app(B)端写的原生相机,B端拍完照片时返回照片的路径给A端,但是A端调起B端的同时onActivityResult 也调用了,当B端返回结果后A反而不执行onActivityResult 方法了。

2023-06-29 13:04 负责人:无 分享
已邀请:
i***@qq.com

i***@qq.com (作者)

已解决,由于上面的方式实在找不到解决方法,只能让原生app处理完时反调uniapp将结果传回。
uniapp:

<template>  
    <view class="content">  
        <image class="logo" :src="imgUrl"></image>  
        <view class="text-area">  
            <button @click="jsCallNativeActivity()"> 打开自定义相机 </button>  
        </view>  
    </view>  
</template>  

<script>  
    export default {  
        data() {  
            return {  
                imgUrl:'/static/logo.png'  
            }  
        },  
        onLoad() {  
            plus.runtime.arguments = ''  
        },  
        onShow() {  
            this.ActivityResult()  
        },  
        onHide() {  
            plus.runtime.arguments = ''  
        },  
        methods: {  
            jsCallNativeActivity() {  
                const isApp = plus.runtime.isApplicationExist({  
                    pname: 'com.***.***'  
                });  
                if (isApp) {// 已安装  
                    let cmPerPixel = (Math.floor(Math.random() * (150 - 50)) + 50).toString()  
                    var main = plus.android.runtimeMainActivity();  
                    var Intent = plus.android.importClass("android.content.Intent")  
                    var intent = new Intent(main.getIntent())  
                    let ComponentName = plus.android.importClass('android.content.ComponentName');  
                    intent.setComponent(new ComponentName("com.***.***", "com.***.***.MainActivity"));  
                    intent.putExtra("enableMask", "true"); //打开画框功能  
                    intent.putExtra("cmPerPixel", cmPerPixel); //参数大小  
                    intent.putExtra("backActivityName", "io.dcloud.HBuilder"); //此处的包名填本程序的包名,此参数必传,传错了拿不到返回值  
                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  

                    // 请求码保证了,开始的新界面和返回的是同一个操作  
                    var CODE_REQUEST = 1000;  
                    // 采用startActivityForResult开启新的界面,当界面关闭时可以处理返回结果,CODE REQUEST请求码是唯一标识  
                    main.startActivityForResult(intent, CODE_REQUEST);  
                }else{// 没有安装  
                    uni.showToast({  
                        title: "请安装拍照APP",  
                        icon: 'none',  
                        duration: 2000  
                    })  
                }  
            },  
            ActivityResult(){  
                setTimeout(() => {  //需要异步一下  
                    if (plus.runtime.arguments != "") {  
                        try {  
                            uni.showModal({  
                                title: '是否上传文件',  
                                confirmText: "确定",  
                                showCancel: true,  
                                content: plus.runtime.arguments.toString(),  
                                success: (res) => {  
                                    let data = JSON.parse(plus.runtime.arguments)  

                                    uni.showLoading({  
                                        title: '上传中'  
                                    })  
                                    uni.uploadFile({  
                                        url: 'http://192.168.100.80:8888/fileUploadAndDownload/upload',  
                                        header: {  
                                            'x-token': "*******************************************"  
                                        },  
                                        filePath: data.filepath,  
                                        name: 'file',  
                                        success: (uploadFileRes) => {  
                                            let dataInfo = JSON.parse(uploadFileRes.data);  
                                            console.log("dataInfo:", dataInfo);  
                                            uni.hideLoading()  
                                        },  
                                        fail: (e) => {  
                                            uni.showToast({  
                                                title: "上传失败",  
                                                icon: 'error',  
                                                duration: 2000  
                                            })  
                                            uni.hideLoading()  
                                            console.log(e);  
                                        }  
                                    });  
                                }  
                            })  
                        } catch (e) {  
                            console.log(e)  
                        }  
                    }  
                }, 200)  
            }  
        }  
    }  
</script>  

<style>  
    .content {  
        display: flex;  
        flex-direction: column;  
        align-items: center;  
        justify-content: center;  
    }  

    .logo {  
        height: 200rpx;  
        width: 200rpx;  
        margin-top: 200rpx;  
        margin-left: auto;  
        margin-right: auto;  
        margin-bottom: 50rpx;  
    }  

    .text-area {  
        display: flex;  
        justify-content: center;  
    }  

    .title {  
        font-size: 36rpx;  
        color: #8f8f94;  
    }  
</style>

原生APP:

package com.***.***;  

import androidx.annotation.NonNull;  
import androidx.appcompat.app.AppCompatActivity;  

import android.app.Activity;  
import android.content.ComponentName;  
import android.content.Context;  
import android.content.Intent;  
import android.content.pm.ActivityInfo;  
import android.content.pm.PackageInfo;  
import android.content.pm.PackageManager;  
import android.content.pm.ResolveInfo;  
import android.hardware.camera2.CameraAccessException;  
import android.hardware.camera2.CameraCharacteristics;  
import android.hardware.camera2.CameraManager;  
import android.os.Bundle;  
import android.util.Log;  
import android.view.View;  
import android.view.Window;  
import android.view.WindowManager;  
import android.widget.TextView;  
import android.widget.Toast;  

import com.otaliastudios.cameraview.CameraException;  
import com.otaliastudios.cameraview.CameraListener;  
import com.otaliastudios.cameraview.CameraLogger;  
import com.otaliastudios.cameraview.CameraOptions;  
import com.otaliastudios.cameraview.CameraView;  
import com.otaliastudios.cameraview.PictureResult;  
import com.otaliastudios.cameraview.VideoResult;  
import com.otaliastudios.cameraview.controls.Mode;  
import com.otaliastudios.cameraview.filter.Filters;  
import com.otaliastudios.cameraview.size.AspectRatio;  
import com.otaliastudios.cameraview.size.Size;  
import com.otaliastudios.cameraview.size.SizeSelector;  
import com.otaliastudios.cameraview.size.SizeSelectors;  

import org.greenrobot.eventbus.EventBus;  

import java.util.List;  

public class MainActivity extends AppCompatActivity {  

    public  static String backActivityName;  
    public static String latestPictureName;  
    public static boolean  hasNewPicture;  
    private CameraView camera;  
    private TextView infpreviewsize;  
    private TextView filterName;  

    private TextView callArgs;  
    private String TAG="zwscamra";  

    private Filters[] filters = Filters.values();  
    private int curFilter = 0;  

    //设置参数  
    private int cmPerPixel = 148;  
    private boolean enableMask = false;  

    private void updateIntentParams(){  

        CameraWaterMark watermarkCtrl = (CameraWaterMark)findViewById(R.id.watermark);  

        Intent intent =getIntent();  
        String propEnableMask = intent.getStringExtra("enableMask");  
        if ((propEnableMask != null)&&(propEnableMask.equals("true") )){  
            enableMask = true;  
        }else{  
            enableMask = false;  
        }  

        enableMask = true;  

        String propBackActivity = intent.getStringExtra("backActivityName");  
        try {  
            MainActivity.backActivityName = propBackActivity;  
        }  
        catch (NumberFormatException e) {  
            MainActivity.backActivityName = null;  
        }  

        String propCmPerPixel = intent.getStringExtra("cmPerPixel");  
        try {  
            cmPerPixel = Integer.parseInt(propCmPerPixel);  
        }  
        catch (NumberFormatException e) {  
            cmPerPixel = 148;  
        }  

        if (cmPerPixel >= 200)  
            cmPerPixel = 200;  
        if (cmPerPixel < 30){  
            cmPerPixel = 30;  
        }  

        if (enableMask == false){  
            watermarkCtrl.setVisibility(View.INVISIBLE);  
        } else{  
            watermarkCtrl.setVisibility(View.VISIBLE);  
            watermarkCtrl.bringToFront();  
        }  

        {  
            String msg;  
            if (enableMask)  
                msg = "enableMask=true;";  
            else  
                msg = "enableMask=false;";  

            msg += "cmPerPixel:" + cmPerPixel + ";";  

            if (MainActivity.backActivityName == null)  
                msg += "backActivityName: null;";  
            else  
                msg += "backActivityName:" + MainActivity.backActivityName + ";";  
            callArgs.setText(msg);  
        }  

        //backActivityName = "123";  
    }  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  

        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);  
        supportRequestWindowFeature(Window.FEATURE_NO_TITLE);  
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);  

        setContentView(R.layout.activity_main);  

        CameraLogger.setLogLevel(CameraLogger.LEVEL_VERBOSE);  

        hasNewPicture = false;  

        infpreviewsize = (TextView)findViewById(R.id.infopreviewsize);  
        filterName = (TextView)findViewById(R.id.filterName);  
        callArgs = (TextView)findViewById(R.id.callArgs);  

        camera = (CameraView)findViewById(R.id.camera);  
        SizeSelector width = SizeSelectors.minWidth(3000);  
        SizeSelector height = SizeSelectors.minHeight(4000);  
        SizeSelector dimensions = SizeSelectors.and(width, height);  
        SizeSelector ratio = SizeSelectors.aspectRatio(AspectRatio.of(3, 4), 0); // Matches 1:1 sizes.  

        SizeSelector result = SizeSelectors.or(  
                SizeSelectors.and(ratio, dimensions), // Try to match both constraints  
                ratio, // If none is found, at least try to match the aspect ratio  
                SizeSelectors.biggest() // If none is found, take the biggest  
        );  

        Log.i(TAG, "select size:" + result.toString());  

        updateIntentParams();  

        camera.setPictureSize(result);  
        camera.setVideoSize(result);  
        camera.setLifecycleOwner(this);  

        filterName.setText("Filter: None, id:" + curFilter + "/" + filters.length);  
        Log.i(TAG, "start");  

        camera.addCameraListener(new CameraListener() {  
            @Override  
            public void onPictureTaken(PictureResult result) {  
                // A Picture was taken!  
                Log.i(TAG, "onPictureTaken: ");  

                PictureViewActivity.imageTakeDone = result;  

                hasNewPicture = false;  
                Intent intent = new Intent(getBaseContext(),PictureViewActivity.class);  
                intent.putExtra("prop1", "我的写入");  
                startActivity(intent);  
            }  

            @Override  
            public void onVideoTaken(VideoResult result) {  
                // A Video was taken!  
            }  

            @Override  
            public void onCameraOpened(@NonNull CameraOptions options) {  
                super.onCameraOpened(options);  

                Size s = camera.getPictureSize();  
                if (s == null){  
                    infpreviewsize.setText("invalid preview size");  
                    Log.i(TAG, "onCameraOpened size null");  
                }  
                else {  
                    Log.i(TAG, "onCameraOpened size x:" + s.getWidth() + " y:"+s.getHeight());  
                    infpreviewsize.setText("preview size:" + s.getWidth() + "x"+s.getHeight());  

                    if (enableMask){  
                        //获取当前像素  
                        int screenWidth = camera.getWidth();  
                        int imageWidth = s.getWidth();  

                        //根据那个我们就算出尺寸,首先算20cm, 20*cmPerPixel 就是图片上的尺寸  
                        CameraWaterMark.boxMax = (20*cmPerPixel * screenWidth)/imageWidth;  
                        CameraWaterMark.boxMin = CameraWaterMark.boxMax/4;  
                    }  
                }  
            }  

            @Override  
            public void onCameraError(@NonNull CameraException exception) {  
                super.onCameraError(exception);  
            }  
        });  
    }  

    @Override  
    protected void onNewIntent(Intent intent) {  
        super.onNewIntent(intent);  
        setIntent(intent);  

        updateIntentParams();  
    }  

    @Override  
    protected void onResume() {  
        super.onResume();  
        Intent intent = getIntent();  

        if (hasNewPicture && (backActivityName != null)){  
            if (backActivityName.length() > 0){  

                doStartApplicationWithPackageName(backActivityName);  

                /*Intent mIntent = new Intent();  
                if (latestPictureName != null)  
                    mIntent.putExtra("filepath", latestPictureName);  
                setResult(Activity.RESULT_OK, mIntent);*/  
                //EventBus.getDefault().post();  

                //EventBus.getDefault().post(new DataSynEvent(1000, Activity.RESULT_OK,mIntent));  
                finish();  
            }  
        }  

        updateIntentParams();  
    }  

    public void btnTakePictureOnClicked(View v){  
        if (camera.getMode() == Mode.VIDEO) {  
            Log.w(TAG, "Can't take HQ pictures while in VIDEO mode");  
            return;  
        }  
        if (camera.isTakingPicture())  
            return;  

        camera.takePicture();  
    }  

    public void btnChangeFilterOnClicked(View v){  
        if (curFilter < filters.length - 1) {  
            curFilter++;  
        } else {  
            curFilter = 0;  
        }  

        Filters filter = filters[curFilter];  

        camera.setFilter(filter.newInstance());  

        filterName.setText("Filter: "+filter.toString()+", id:" + curFilter + "/" + filters.length);  
    }  

    private void doStartApplicationWithPackageName(String packagename) {  

        // 通过包名获取此APP详细信息,包括Activities、services、versioncode、name等等  
        PackageInfo packageinfo = null;  
        try {  
            packageinfo = getPackageManager().getPackageInfo(packagename, 0);  
        } catch (PackageManager.NameNotFoundException e) {  
            e.printStackTrace();  
        }  
        if (packageinfo == null) {  
            return;  
        }  

        // 创建一个类别为CATEGORY_LAUNCHER的该包名的Intent  
        Intent resolveIntent = new Intent(Intent.ACTION_MAIN, null);  
        resolveIntent.addCategory(Intent.CATEGORY_LAUNCHER);  
        resolveIntent.setPackage(packageinfo.packageName);  

        // 通过getPackageManager()的queryIntentActivities方法遍历  
        List<ResolveInfo> resolveinfoList = getPackageManager()  
                .queryIntentActivities(resolveIntent, 0);  

        ResolveInfo resolveinfo = resolveinfoList.iterator().next();  
        if (resolveinfo != null) {  
            // packagename = 参数packname  
            String packageName = resolveinfo.activityInfo.packageName;  
            // 这个就是我们要找的该APP的LAUNCHER的Activity[组织形式:packagename.mainActivityname]  
            String className = resolveinfo.activityInfo.name;  
            // LAUNCHER Intent  
            Intent intent = new Intent(Intent.ACTION_MAIN);  
            intent.addCategory(Intent.CATEGORY_LAUNCHER);  

            // 设置ComponentName参数1:packagename参数2:MainActivity路径  
            ComponentName cn = new ComponentName(packageName, className);  

            intent.setComponent(cn);  

            if (latestPictureName != null)  
                intent.putExtra("filepath", latestPictureName);  

            startActivity(intent);  
        }  
    }  
}

注意:原生APP从安卓11开始调用其它app需要开启权限

要回复问题请先登录注册