H5+ 移动app学习之二 Native.js
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.方法:
- importClass: 导入Java类对象
- newObject: 创建实例对象
- getAttribute: 获取对象(类对象/实例对象)的属性值
- setAttribute: 设置对象(类对象/实例对象)的属性值
- invoke: 调用对象(类对象/实例对象)的方法
- implements: 实现Interface的方法
- runtimeMainActivity: 获取应用主Activity实例对象
- currentWebview: 获取当前Webview窗口对象的native层实例对象
2.对象:
- ClassObject: Java类对象
- InstanceObject: Java实例对象
创建对象:
<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("结束"); }