Native.js技术,简称NJS,是一种将手机操作系统的原生对象转义,映射为JS对象,在JS里编写原生代码的技术。如果说Node.js把js扩展到服务器世界,那么Native.js则把js扩展到手机App的原生世界。Native.js不是一个js库,不需要下载引入到页面的script中,也不像node.js那样有单独的运行环境,Native.js的运行环境是集成在5+runtime里的。

Native.js for Android封装一条通过JS语法直接调用Native Java接口通道,通过plus.android可调用几乎所有的系统API。

判断平台

Native API具有平台依赖性,所以需要通过以下方式判断当前的运行平台:

function judgePlatform(){
switch ( plus.os.name ) {
case "Android":
// Android平台: plus.android.*
break;
case "iOS":
// iOS平台: plus.ios.*
break;
default:
// 其它平台
break;
}
}

开始写NJS

使用NJS调用Native API非常简单,基本步骤如下:
1. 导入要使用到的类;
2. 创建类的实例对象(或者调用类的静态方法创建);
3. 调用实例对象的方法;

1.方法:

2.对象:

创建对象:

<script>
/**
* 1.导入类,通过new操作实例化对象
* 通过.操作符直接调用对象的方法
*/
var Intent = plus.android.importClass("android.content.Intent");
var intent = new Intent(); /**
* 2.不导入类,用plus.android.newObject实例化对象
* 使用plus.android.invoke方法来调用对象的方法
*/
var intent = plus.android.newObject("android.content.Intent");
</script>

3.实例:

1.拨打电话:

<body>
拨打电话<br/>
<button onclick="call()">Dial</button> <script src="js/mui.min.js"></script>
<script type="text/javascript">
mui.init(); function call() {
// 导入Activity、Intent类
var Intent = plus.android.importClass("android.content.Intent");
var Uri = plus.android.importClass("android.net.Uri");
// 获取主Activity对象的实例
var main = plus.android.runtimeMainActivity();
// 创建Intent
var uri = Uri.parse("tel:10010"); // 这里可修改电话号码
var call = new Intent("android.intent.action.CALL", uri);
// 调用startActivity方法拨打电话
main.startActivity(call);
// ...
} </script>
</body>

2.弹框

<body>
<button onclick="njsAlertForAndroid()">弹框</button>
<button onclick="h5Alert()">h5弹框</button>
<script src="js/mui.min.js"></script>
<script type="text/javascript">
mui.init();
function njsAlertForAndroid(){
//导入类
var alertDialog = plus.android.importClass("android.app.AlertDialog");
//创建对象
var dlg = new alertDialog.Builder(plus.android.runtimeMainActivity());
//调用方法
dlg.setTitle("标题");
dlg.setMessage("原生弹出框");
dlg.setPositiveButton("确定",null);
dlg.show();
}
//也可以使用它集成好的
function h5Alert(){
var message = "消息";
var alertCB ;
var title = "标题";
var buttonCapture = "按钮";
plus.ui.alert(message, alertCB, title, buttonCapture);
}
</script>
</body>

弹框优化

<script type="text/javascript">
mui.init();
var AlertDialog = null,mainActivity=null;
document.addEventListener("plusready",function(){
switch(plus.os.name){
case "Android":
mainActivity = plus.android.runtimeMainActivity();
AlertDialog = plus.android.importClass("android.app.AlertDialog");
break;
default: break;
}
},false); function njsAlertForAndroid(){
//创建对象
var dlg = new AlertDialog.Builder(mainActivity);
//调用方法
dlg.setTitle("标题");
dlg.setMessage("原生弹出框");
dlg.setPositiveButton("确定",null);
dlg.show();
}
</script>

使用高级API优化

<script type="text/javascript">
mui.init();
var AlertDialog = null,mainActivity=null;
document.addEventListener("plusready",function(){
switch(plus.os.name){
case "Android":
mainActivity = plus.android.runtimeMainActivity();
break;
default: break;
}
},false); function njsAlertForAndroid(){
//创建对象
var dlg = plus.android.newObject("android.app.AlertDialog$Builder",mainActivity);
//调用方法
dlg.setTitle("标题");
dlg.setMessage("原生弹出框");
dlg.setPositiveButton("确定",null);
dlg.show();
}
</script>

3.GPS

<script>
if(plus.os.name == "Android") {
var context = plus.android.importClass("android.content.Context");
var locationManager = plus.android.importClass("android.location.LocationManager");
var main = plus.android.runtimeMainActivity();
var mainSvr = main.getSystemService(context.LOCATION_SERVICE);
var gpsProvider = mainSvr.isProviderEnabled(locationManager.GPS_PROVIDER); //检查是否开启了GPS
if(!gpsProvider) {
var message = "为了获取您的精准位置,请开启GPS设备。";
var title = "GPS未启用";
var alertCB = function() {
var Intent = plus.android.importClass("android.content.Intent");
var mIntent = new Intent('android.settings.LOCATION_SOURCE_SETTINGS');
main.startActivity(mIntent); //打开GPS设置
}
plus.nativeUI.alert(message, alertCB, title);
}
}
</script>

4.分享

<script type="text/javascript">
mui.init(); //调用
// share('分享到...','要分享的文本'); function share(shareTip, shareText) {
//导入Java类对象
var Context = plus.android.importClass("android.content.Intent");
//获取应用主Activity
var Main = plus.android.runtimeMainActivity();
//将类Context的这个行为(Action)ACTION_SEND,赋给shareIntent
var shareIntent = new Context(Context.ACTION_SEND);
//***以下两种写法是一样的
//***1.
//plus.android.invoke(shareIntent,"setType","text/plain");
//plus.android.invoke(shareIntent,"putExtra",Context.EXTRA_TEXT,shareText);
//***2.
//设置分享类型
shareIntent.setType("text/plain");
//设置分享文本
shareIntent.putExtra(Context.EXTRA_TEXT, shareText);
//***以上两种写法是一样的
//指定分享的包名
//shareIntent.setPackage('com.tencent.mm',);
Main.startActivity(Context.createChooser(shareIntent, shareTip));
} //原生代码:
/*
Intent sendIntent = new Intent(android.content.Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, "This is my text to send.");
sendIntent.setType("text/plain");
startActivity(Intent.createChooser(sendIntent,'send to...'));
*/
</script>

5.选择要使用的应用

<script type="text/javascript">
mui.init();
document.querySelector('#btn').addEventListener('click', function() {
var REQUESTCODE = 1;
var main = plus.android.runtimeMainActivity();
var Intent = plus.android.importClass('android.content.Intent');
var intent = new Intent(Intent.ACTION_GET_CONTENT); intent.setType("*/*"); //设置类型,任意类型
// intent.setType("image/*");
// intent.setType("audio/*"); //选择音频
// intent.setType("video/*"); //选择视频 (mp4 3gp 是android支持的视频格式) intent.addCategory(Intent.CATEGORY_OPENABLE);
main.startActivityForResult(intent, REQUESTCODE); // http://stackoverflow.com/questions/3401579/get-filename-and-path-from-uri-from-mediastore main.onActivityResult = function(requestCode, resultCode, data) {
if(REQUESTCODE == requestCode) {
var context = main;
plus.android.importClass(data); // 获得文件URI路径 (content://开头的uri)
var uri = data.getData();
// 获取管理所有程序的实例
var resolver = context.getContentResolver();
plus.android.importClass(resolver);
// 判断文件类型
var fileType = plus.android.invoke(resolver, "getType", uri);
console.log("fileType:" + fileType);
// 图片
if(fileType.indexOf('image') > -1) {
var MediaStore = plus.android.importClass("android.provider.MediaStore");
// 获取实例
var cursor = resolver.query(uri, null, null, null, null);
plus.android.importClass(cursor);
if(cursor != null && cursor.moveToFirst()) {
var columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
// 取出文件路径
var filePath = cursor.getString(columnIndex);
console.log("filePath:" + filePath);
}
// 关闭游标
cursor.close();
}
}
}
})
</script>

6.扫描手机音频文件

<script type="text/javascript">
mui.init(); document.addEventListener("plusready", function() { if(plus.os.name == "Android") {
var Context = plus.android.importClass("android.content.Context");
var ContentResolver = plus.android.importClass("android.content.ContentResolver");
var Cursor = plus.android.importClass("android.database.Cursor");
var Uri = plus.android.importClass("android.net.Uri");
var MediaStore = plus.android.importClass("android.provider.MediaStore");
var main = plus.android.runtimeMainActivity(); var list = document.getElementById("list");
var li; //创建一个游标对象
var context = main;
var Uri = new Uri();
Uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
var resolver = new ContentResolver();
resolver = context.getContentResolver();
var c = new Cursor();
c =resolver.query(Uri, null, null, null, null);
c.moveToFirst(); if(c != null) {
while(c.moveToNext()) {
//扫描本地文件,得到歌曲的相关信息
var music_name = c.getString(c.getColumnIndex(MediaStore.Audio.Media.TITLE));
var music_singer = c.getString(c.getColumnIndex(MediaStore.Audio.Media.ARTIST));
var music_time = c.getString(c.getColumnIndex(MediaStore.Audio.Media.DURATION));
var music_path = c.getString(c.getColumnIndex(MediaStore.Audio.Media.DATA)); li = document.createElement('li');
li.className = "mui-table-view-cell mui-media";
li.setAttribute('name', music_name);
li.setAttribute('data-type', 'File');
li.innerHTML = '<a class="mui-navigate-right">' +
'<img class="mui-media-object mui-pull-left" src="img/folder.png">' +
'<div class="mui-media-body">' + music_name +
'<p class="mui-ellipsis">' + music_singer +
'</p></div></a>';
list.appendChild(li);
}
}
c.close();
}
}, false); </script>

通过遍历文件系统扫描音频文件

var count = 0;
// document.addEventListener("plusready",plusReady, false);
function plusReady(){ if(plus.storage.getLength() == 0) {
alert("文件夹");
plus.io.resolveLocalFileSystemURL("/storage/sdcard0/", function(fs) {//手机内存
findMP3(fs);
}, function() {
alert("打开失败");
});
plus.io.resolveLocalFileSystemURL("/storage/sdcard1/", function(fs) {//内存卡
findMP3(fs);
}, function() {
alert("打开失败");
}); } else {
alert("应用数据");
for(var i = 1; i <= plus.storage.getLength(); i++) {
count++;
var songitem = plus.storage.getItem(i + ".mp3");
li = document.createElement("li");
li.innerText =count+" "+songitem;
li.className = "mui-table-view-cell";
document.getElementById("songUl").appendChild(li);
}
} } function isHidden(fs) {
var reg = /^\./;
return reg.test(fs.name);
} function findMP3(fs) { if(fs.isDirectory) { var directoryReader = fs.createReader();
directoryReader.readEntries(function(entries) {
var i;
var li = null;
if(entries.length == 0) {
return;
}
for(i = 0; i < entries.length; i++) {
if(isHidden(entries[i])) {
continue
}
if(entries[i].isDirectory) {
findMP3(entries[i]);
}
if(entries[i].isFile) {
var reg = /\.mp3$/;
if(reg.test(entries[i].name)) {
count++;
li = document.createElement("li");
li.innerText =count+" "+entries[i].fullPath;
li.className = "mui-table-view-cell";
li.setAttribute("id",entries[i].fullPath);
document.getElementById("songUl").appendChild(li);
plus.storage.setItem(count + ".mp3", entries[i].fullPath);
}
}
}
}, function(e) {
alert("Read entries failed: " + e.message);
});
} else { //过滤掉不是mp3的文件格式
var reg = /\.mp3$/;
if(!reg.test(fs.name)) {
count++;
li = document.createElement("li");
li.innerText =count+" "+fs.fullPath;
li.className = "mui-table-view-cell";
li.setAttribute("id",fs.fullPath);
document.getElementById("songUl").appendChild(li);
plus.storage.setItem(count + ".mp3", fs.fullPath);
} }
} function loadMusic() {
alert("开始");
document.addEventListener("plusready",plusReady, false);
plusReady();
alert("结束");
}

H5+ 移动app学习之二 Native.js的更多相关文章

  1. Hybrid APP基础篇(二)->Native、Hybrid、React Native、Web App方案的分析比较

    说明 Native.Hybrid.React.Web App方案的分析比较 目录 前言 参考来源 前置技术要求 楔子 几种APP开发模式 概述 Native App Web App Hybrid Ap ...

  2. JavaScript 基础学习(二)js 和 html 的结合方式

    第一种 使用一个标签 <script type="text/javascript"> js代码; </script> 第二种 使用 script 标签,引入 ...

  3. 前端学习(十二)js数据类型(笔记)

    选项卡:        for循环 for(初始值,条件,自增){}    for(var i=0; i<9;i++){} 几个按钮对应相同个内容!!! -------------------- ...

  4. Java Script 学习笔记 (二) Casper JS

    1. click() VS mouse.click() 在写自动化脚本要勾选一个复选框时,用casper.mouse.click() 无法选上这个checkbox, 需要用到casper.click( ...

  5. WebView全面学习(二)-- Native与js双方通信

    WebView全面学习(二)-- Native与js双方通信 Native与js通信的本质 Native与js通信的核心在于WebView. 两端的通信主要还是单向的.假如要完成js->Nati ...

  6. 客户端相关知识学习(二)之h5与原生app交互的原理

    前言 现在移动端 web 应用,很多时候都需要与原生 app 进行交互.沟通(运行在 webview中),比如微信的 jssdk,通过 window.wx 对象调用一些原生 app 的功能.所以,这次 ...

  7. App开发Native.js入门指南

    概述 Native.js技术,简称NJS,是一种将手机操作系统的原生对象转义,映射为JS对象,在JS里编写原生代码的技术.如果说Node.js把js扩展到服务器世界,那么Native.js则把js扩展 ...

  8. 【REACT NATIVE 系列教程之十二】REACT NATIVE(JS/ES)与IOS(OBJECT-C)交互通信

    http://blog.csdn.net/xiaominghimi/article/details/51586492 一用到跨平台的引擎必然要有引擎与各平台原生进行交互通信的需要.那么Himi先讲解R ...

  9. mui开发app之html5+,5+Runtime,5+sdk,native.js

    说说几个名词 html5:目前最新的html规范,w3c联盟制定,手机端主要由webkit实现规范,对用户来说就是浏览器实现了它 html5+:所谓"+",扩充了html5原本没有 ...

随机推荐

  1. Java使用Fork/Join框架来并行执行任务

    现代的计算机已经向多CPU方向发展,即使是普通的PC,甚至现在的智能手机.多核处理器已被广泛应用.在未来,处理器的核心数将会发展的越来越多. 虽然硬件上的多核CPU已经十分成熟,但是很多应用程序并未这 ...

  2. 小程序和APP谁将主导未来?

    APP和小程序的未来会怎么样?小程序的出现真的会加速APP的灭亡吗?今天这篇文章,是对小程序和App未来发展格局的一些思考,更多的是想提醒各位拥抱小程序的的参与者,我们在决定参与这场狂欢的同时,切勿盲 ...

  3. React项目(二):生命游戏

    引子 这是16年最后的一个练手项目,一贯的感觉就是,做项目容易,写说明文档难.更何况是一个唤起抑郁感觉的项目,码下的每个字,心就如加了一个千斤的砝码. 2016年,有些事我都已忘记,但我现在还记得.2 ...

  4. stackoverfow访问 ajax.googleapis.com

    本文实验环境:Fedora 23 先用nslookup 查看stackoverflow.com的ip -vc参数,表示用强制用TCP 查到的stackoverflow的地址似乎没错, 用本地的DNS解 ...

  5. 前端Js框架汇总

    概述: 有些日子没有正襟危坐写博客了,互联网飞速发展的时代,技术更新迭代的速度也在加快.看着Java.Js.Swift在各领域心花路放,也是煞是羡慕.寻了寻.net的消息,也是振奋人心,.net co ...

  6. MyBatis源码分析(3)—— Cache接口以及实现

    @(MyBatis)[Cache] MyBatis源码分析--Cache接口以及实现 Cache接口 MyBatis中的Cache以SPI实现,给需要集成其它Cache或者自定义Cache提供了接口. ...

  7. 百度编辑器ueditor插入表格没有边框颜色的解决方法

    附:从word excel 中 复制的表格提交后无边框,参考这个同学的,写的很详细:   http://blog.csdn.net/lovelyelfpop/article/details/51678 ...

  8. shell条件判断与流程控制

    一 条件判断式语句 1.按文件类型进行判断 测试类型 作用 -b 文件 判断文件是否存在,并且是否为块设备文件(是块设备文件为真) -c 文件 判断文件是否存在,并且是否为字符设备文件(是字符设备设备 ...

  9. 学习CodeIgniter框架之旅(二)继承自定义类

    在很多情况下,框架类并不能满足项目的需求,这时候需要程序要自定义一些类,比如说基类等等,对比了TP框架,CI框架目前好像还没加入命名空间,这点TP做得比较好,不用特殊的处理就可以随便继承自定义的类,只 ...

  10. tips~function pointer

    An simple example: #include<stdio.h> int plus(int a,int b) { return a+b; } int main() { int (* ...