我正在try 编写插件,以便在react native中获得带有包名和图标的应用程序列表.我正在以JSONArray的形式获取所有需要的数据,图像存储在SD卡中.

我使用回调将结果(JSON数组)返回给javascript(成功或失败).我得到了上面提到的错误.

请查找获取以下详细信息的java代码.

包裹通讯.sampleapp;

import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.uimanager.ViewManager;
import com.facebook.react.views.drawer.ReactDrawerLayoutManager;
import com.facebook.react.views.image.ReactImageManager;
import com.facebook.react.views.progressbar.ReactProgressBarViewManager;
import com.facebook.react.views.scroll.ReactHorizontalScrollViewManager;
import com.facebook.react.views.scroll.ReactScrollViewManager;
import com.facebook.react.views.switchview.ReactSwitchManager;
import com.facebook.react.views.text.ReactRawTextManager;
import com.facebook.react.views.text.ReactTextViewManager;
import com.facebook.react.views.text.ReactVirtualTextViewManager;
import com.facebook.react.views.textinput.ReactTextInputManager;
import com.facebook.react.views.toolbar.ReactToolbarManager;
import com.facebook.react.views.view.ReactViewManager;
import com.facebook.react.views.viewpager.ReactViewPagerManager;

public class ToastModule extends ReactContextBaseJavaModule {
    private static final String DURATION_SHORT_KEY = "SHORT";
    private static final String DURATION_LONG_KEY = "LONG";
    public static JSONArray applist;

    public ToastModule(ReactApplicationContext reactContext) {
        super(reactContext);
    }

    @Override
    public String getName() {
        return "ToastAnd";
    }

    @ReactMethod
    public void show(Callback errorCallback, Callback successCallback) {
        try {
            //get a list of installed apps.
            PackageManager pm = getReactApplicationContext().getPackageManager();
            List<ApplicationInfo> packages = pm.getInstalledApplications(0);

            JSONArray app_list = new JSONArray();
            int cnt = 0;
            String path = getSDPath();
            makeRootDirectory(path + "/com.framework.xxx/");
            makeRootDirectory(path + "/com.framework.xxx/Cache/");
            for (ApplicationInfo packageInfo : packages) {
                try {

                    if (getReactApplicationContext().getPackageManager().getLaunchIntentForPackage(packageInfo.packageName) != null) {
                        JSONObject info = new JSONObject();
                        info.put("name", packageInfo.loadLabel(pm));
                        info.put("packagename", packageInfo.packageName);
                        String img_name = "/com.ionicframework.xxx/Cache/" + packageInfo.packageName + ".png";
                        info.put("img", path + img_name);
                        //cheak exist  or not
                        File cheakfile = new File(path + img_name);
                        if (!cheakfile.exists()) {

                            Drawable icon = pm.getApplicationIcon(packageInfo);
                            if (icon != null) {
                                drawableTofile(icon, path + img_name);
                            }
                        }
                        app_list.put(cnt++, info);
                    }
                } catch (Exception ex) {
                    System.err.println("Exception: " + ex.getMessage());
                }
            }
            applist = app_list;
            successCallback.invoke(applist);

        } catch (Exception e) {
            errorCallback.invoke(e.getMessage());
        }
    }

    public static void drawableTofile(Drawable drawable,String path)
    {
        File file = new File(path);
        Bitmap bitmap=((BitmapDrawable)drawable).getBitmap();
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 100 /*ignored for PNG*/, bos);
        byte[] bitmapdata = bos.toByteArray();


        //write the bytes in file
        FileOutputStream fos;
        try {
            fos = new FileOutputStream(file);
            fos.write(bitmapdata);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    public String getSDPath()
    {
        File SDdir = null;
        boolean sdCardExist= Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);
        if(sdCardExist){
            SDdir=Environment.getExternalStorageDirectory();
        }
        if(SDdir!=null){

            return SDdir.toString();
        }
        else{
            return null;
        }
    }

    public static void makeRootDirectory(String filePath) {
        File file = null;
        try {
            file = new File(filePath);
            if (!file.exists()) {
                file.mkdirs();  //make Directory
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

在安卓系统中.指数js我正在调用本机方法,如下所示:

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 */
'use strict';

var React = require('react-native');

var {
  AppRegistry,
  StyleSheet,
  Text,
  View,
} = React;

var toastMessage = require('./sampleToast');
toastMessage.show(
  (msg) => { console.log(msg); },
   (result) => { alert(JSON.stringify(result)); }

  );

var SampleApp = React.createClass({
  render: function() {
    return (
      <View style={styles.container}>
        <Text style={styles.welcome}>
          Welcome to React Native!
        </Text>
        <Text style={styles.instructions}>
          To get started, edit index.android.js
        </Text>
        <Text style={styles.instructions}>
          Shake or press menu button for dev menu
        </Text>
      </View>
    );
  }
});

var styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  instructions: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },
});

AppRegistry.registerComponent('SampleApp', () => SampleApp);

但是返回applist(successCallback.invoke(applist);)时,java代码中的我得到了上面提到的错误.

你能帮我找出哪里做错了吗.谢谢

详细错误:

Exception in native call from JS
11-14 09:01:24.780 20592-20624/com.sampleapp E/unknown:React: java.lang.RuntimeException: Cannot convert argument of type class org.json.JSONArray
11-14 09:01:24.780 20592-20624/com.sampleapp E/unknown:React:     at com.facebook.react.bridge.Arguments.fromJavaArgs(Arguments.java:55)
11-14 09:01:24.780 20592-20624/com.sampleapp E/unknown:React:     at com.facebook.react.bridge.CallbackImpl.invoke(CallbackImpl.java:27)
11-14 09:01:24.780 20592-20624/com.sampleapp E/unknown:React:     at com.sampleapp.ToastModule.show(ToastModule.java:100)
11-14 09:01:24.780 20592-20624/com.sampleapp E/unknown:React:     at java.lang.reflect.Method.invokeNative(Native Method)
11-14 09:01:24.780 20592-20624/com.sampleapp E/unknown:React:     at java.lang.reflect.Method.invoke(Method.java:515)
11-14 09:01:24.780 20592-20624/com.sampleapp E/unknown:React:     at com.facebook.react.bridge.BaseJavaModule$JavaMethod.invoke(BaseJavaModule.java:106)
11-14 09:01:24.780 20592-20624/com.sampleapp E/unknown:React:     at com.facebook.react.bridge.NativeModuleRegistry$ModuleDefinition.call(NativeModuleRegistry.java:143)
11-14 09:01:24.780 20592-20624/com.sampleapp E/unknown:React:     at com.facebook.react.bridge.NativeModuleRegistry.call(NativeModuleRegistry.java:64)
11-14 09:01:24.780 20592-20624/com.sampleapp E/unknown:React:     at com.facebook.react.bridge.CatalystInstance$NativeModulesReactCallback.call(CatalystInstance.java:366)
11-14 09:01:24.780 20592-20624/com.sampleapp E/unknown:React:     at com.facebook.react.bridge.queue.NativeRunnable.run(Native Method)
11-14 09:01:24.780 20592-20624/com.sampleapp E/unknown:React:     at android.os.Handler.handleCallback(Handler.java:733)
11-14 09:01:24.780 20592-20624/com.sampleapp E/unknown:React:     at android.os.Handler.dispatchMessage(Handler.java:95)
11-14 09:01:24.780 20592-20624/com.sampleapp E/unknown:React:     at com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage(MessageQueueThreadHandler.java:31)
11-14 09:01:24.780 20592-20624/com.sampleapp E/unknown:React:     at android.os.Looper.loop(Looper.java:136)
11-14 09:01:24.780 20592-20624/com.sampleapp E/unknown:React:     at com.facebook.react.bridge.queue.MessageQueueThread$1.run(MessageQueueThread.java:137)
11-14 09:01:24.780 20592-20624/com.sampleapp E/unknown:React:     at java.lang.Thread.run(Thread.java:841)

推荐答案

在使用本机网桥时,应该使用com.facebook.react.bridge包中的WritableNative个组件调用回调.

WritableNativeMap代替JSONObject

例如,使用WritableNativeMap:

@ReactMethod
public void reactMethod(Callback onSuccess) {
  WritableMap resultData = new WritableNativeMap();
  resultData.putString("key1", "data");
  resultData.putString("key2", "data2");

  onSuccessCallback(resultData);
}

在你的情况下,你应该有这样的东西:

public static WritableArray applist;

// ...

@ReactMethod
public void show(Callback errorCallback, Callback successCallback) {
    try {
        //get a list of installed apps.
        PackageManager pm = getReactApplicationContext().getPackageManager();
        List<ApplicationInfo> packages = pm.getInstalledApplications(0);

        WritableArray app_list = new WritableNativeArray();

        // ...

        for (ApplicationInfo packageInfo : packages) {
            try {

                if (getReactApplicationContext().getPackageManager().getLaunchIntentForPackage(packageInfo.packageName) != null) {
                    WritableMap info = new WritableNativeMap();
                    info.putString("name", packageInfo.loadLabel(pm).toString());
                    info.putString("packagename", packageInfo.packageName);

                    // ...

                    app_list.pushMap(info);
                }
            } catch (Exception ex) {
                System.err.println("Exception: " + ex.getMessage());
            }
        }
        applist = app_list;
        successCallback.invoke(applist);

    } catch (Exception e) {
        errorCallback.invoke(e.getMessage());
    }
}

React-native相关问答推荐

react 本机函数不通过usContext触发

如何在Reaction Native DrawerNavigation中添加注销功能

@react-native-community/cli-platform-ios/native_modules' 来自哪里?

应用管理

将值从一个 js 文件传递​​到 react native 中的另一个 js 文件:react native

错误:图片:找不到 ID 为1的assets资源 .请判断图像源或打包器

获取 TypeError:this.InnerNativeModule.configureProps 不是 mac 上 expo 中的函数

找不到变量 atob

带有 SafeAreaView-wrapper 的 react-native Modal 不起作用

如何在获取请求中传递 POST 参数?

使用react native获取设备令牌

无法访问函数内部的状态

React-native 解码 base64 编码字符串

Jest 的配置在更新到 26.x 后抛出type ErrorHandler = (error: mixed, isFatal: boolean) => void

react-native 自动完成文本输入

设置 react-native 元素时使用特定的包名称

在 React-native 上加载图像时出错:Unexpected character

react-native:多色文本视图

React-native iOS 不显示图像(pod 问题)

无法在react-native中分配给# 的只读属性props