吾逍遥
吾逍遥
  • 发布:2021-01-11 11:04
  • 更新:2022-09-28 18:33
  • 阅读:2498

获取本机所有安装程序的包名和应用名(含解决JSBObject方案)

分类:Native.js

因为项目需要启动本机第三方应用,但由于管控软件已经启用,无法再随意安装程序获取本机所有安装程序的包名和应用名,于是就想到使用Nativejs或Java原生获取,下面是网上我查找到的获取包名和应用名的方法,我进行了整合

//Java实现代码  
//获取PackageManager  
PackageManager packageManager = context.getPackageManager();  
//获取所有已安装程序的包信息  
List <PackageInfo> packageInfos = packageManager.getInstalledPackages(0);  
// 遍历所有安装程序的包信息和应用程序名  
ApplicationInfo applicationInfo = null;  
if (packageInfos != null) {  
    for (int i = 0; i < packageInfos.size(); i++) {  
        String packName = packageInfos.get(i).packageName;  
        applicationInfo = packageManager.getApplicationInfo(packName, 0);  
        String appName=(String)((applicationInfo != null) ? packageManager.getApplicationLabel(applicationInfo) : "???");  
        Log.e(TAG, "PackageName:" + packName+",ApplicationName:"+appName);  
    }  
 }

那么如何转换为NJS代码呢了,我认真拜读了DCloud_App_Array老大写的入门教程https://ask.dcloud.net.cn/article/88,Nativejs示例https://ask.dcloud.net.cn/article/114和在插件市场的Nativejs的代码(重点是DCloud_App_Array写的),还有最推荐实践项目就是HbuilderX自带的Hello 5+的HTML5Plus规范演示,它基本演示绝大部分应用。但是对于简单的不需要类相互调用的还好实现,但遇到上面相互调用首先想到的是plus.android.importClass,然后通过类的.来调用,这点和https://ask.dcloud.net.cn/question/65208非常类似,但Java对象毕竟是非JS对象,所以经常出现JSBObject的问题,无法获取真实内容,该文章作者在回复中提到了invoke解决的,但没有实际代码,我和后面回复中一样急切需要解决方案,不过还好通过自己测试还是实现,同时对Nativejsy调用原生能力的认识也真正算是入门了,现在只要有java代码,而且Nativejs能实现的,就可以完成Java转NJS了。为了给自己留下记录,同时也帮助还在NativeJS迷茫路上的人们一点方向。

先看我实现上面功能的NJS代码,看你是否理解:

const main = plus.android.runtimeMainActivity();  
let pManager = plus.android.invoke(main, 'getPackageManager');  
let pInfo = plus.android.invoke(pManager, 'getInstalledPackages', 0);  
let total = plus.android.invoke(pInfo, 'size');  
let packName = '';  
let appName = '';  
let obj = null;  
// 遍历获取包名和应用名称  
for (let i = 0; i < total; i++) {  
    // 获取包名  
    packName = plus.android.getAttribute(plus.android.invoke(pInfo, 'get', i), 'packageName');  
    // 获取包名对应的应用名  
    obj = plus.android.invoke(pManager, 'getApplicationInfo', packName, 0);  
    appName = plus.android.invoke(pManager, 'getApplicationLabel', obj);  
    console.log(packName, appName);  
}

我现在归纳总结Java转NJS代码几个要点:
1、plus.android.runtimeMainActivity(),起初我认识它就是普通Activity,其实它是Context,它是Html5+运行期环境主组件,用于处理与用户交互的各种事件,也是应用程序全局环境android.app.Activity的实现对象,是唯一的,生命周期是应用程序生命周期,可以完成所有有关程序的操作,至于Context重要可以百度.
2、plus.android.getAttribute和plus.android.setAttribute,获取或设置类或对象的属性,不再建议使用.来操作了,对于属性就建议使用它两个都可以完成了,毕竟android中java类还是比较复杂的,一个不好就访问了非静态常量,它两者则不存在这样问吧
3、plus.android.invoke调用类或对象的方法,支持静态或非静态,同样不建议使用.来操作了,原因同上。无论是importClass获取类对象(ClassObject)还是newObject获取的实例对象(InstanceObject)使用这种方法调用方法则没问题
4、遇到上面这种不断调用类的方法获取下一步操作的对象,甚至是能完.连续调用的,一定要使用我上面介绍的一个对象和三个函数来转换,其它都会非常容易出现失败的。同时要牢记为了思路清晰, 连续调用可分解为一个一个invoke调用,返回的对象就用let申明即可 ,这里有个 最大误区就是以为要和Java一样,先导入类再定义返回的对象,我开始也是在这里迷茫的,JS中不存在让它种写法啊,就是使用构造函数传递返回值相当于this来获取,结果经常返回null或JSBObject 后来想明白了,在JS中只有对象概念,才不管你是A类的对象还是B类的对象,只要是对象就是由属性和方法组成,上面转换代码你引入类就是多此一举了。
5、plus.android.importClass和plus.android.newObject什么时候使用呢?Java代码中调用类的静态方法或new获得的对象的代码就需要使用它们了,前者使用importClass,后者使用newObject。
总结:如果你理解我的代码,也掌握我提的五个要点,尤其是前面四个要点,任何Java代码转NJS都不再算复杂了

最后,还要是提供NativeJS还在入门的同学们,看完入门教程后,重点可参考Hello 5+的HTML5Plus规范来学习,它的示例代码非常多,毕竟是官方的模板,写法和技巧都值得学习。

1 关注 分享
小虾米哈

要回复文章请先登录注册

落嘤神斧

落嘤神斧

请问怎么获取 invoke 的第二个参数字段呢?
2022-09-28 18:33
3***@qq.com

3***@qq.com

那要只显示桌面有icon图标的应用呢?
2021-04-24 00:26
2***@qq.com

2***@qq.com

回复 m***@foxmail.com :
应该是同步,因为我感觉到页面停止加载了。
2021-01-22 18:22
m***@foxmail.com

m***@foxmail.com

js通过native.js调用原生是同步还是异步的
2021-01-22 18:16