您的位置:时时app平台注册网站 > web前端 > ionic2自定义cordova插件开发以及使用(Android),

ionic2自定义cordova插件开发以及使用(Android),

2019-11-14 20:19

  这个需求的难点在于需要访问手机的内存读取安装包文件,如果是普通的需求就可以一个html、一个JS(controller)外加上路由配置就 so easy~

ionic2自定义cordova插件开发以及使用(Android),ionic2cordova

如何写一个cordova 用于ionic2项目中呢,在搜索了一番之后,千篇一律,我都怀疑那些文章是不是全部都是复制来复制去的,而且都不是很详细。我自己也捣鼓了一下午,踩了很多坑。所以特此写这下这篇,记录一下。

假设需求是 写一个日志插件,可以将日志写在手机的sdcard中。

1.安装plugman

npm install -g plugman

2.creat一个插件框架

plugman creat --name 插件名字 --plugin_id 插件id --plugin_version 插件版本号

例如:

复制代码 代码如下:plugman create --name cordovaHeaLog --plugin_id cordova-plugin-hea-log --plugin_version 1.0

回车然后将生成这样一个结构的项目

彩世界网址 1

3.添加安卓平台支持

plugman platform add --platform_name android

我们可以看到src 下多了一个android文件夹 以及下面多了一个java文件。

彩世界网址 2

4.实现日志功能

在src/android 我添加了一个logUtil.java文件。

里面的内容如下:

package cordova.plugin.hea.log;

import android.os.Environment;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;


public class logUtil{
 private static int SDCARD_LOG_FILE_SAVE_DAYS = 180; // sd卡中日志文件的最多保存天数
 private static String LOG_PATH_SDCARD_DIR = Environment.getExternalStorageDirectory().toString() "/VP2/log/"; // 日志文件在sdcard中的路径

 // 日志的输出格式
 private static SimpleDateFormat LogSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 private static SimpleDateFormat logDay = new SimpleDateFormat("dd");
 private static SimpleDateFormat logTime = new SimpleDateFormat("yyyy-MM");

 /**
  * 打开日志文件并写入日志
  *
  * @return
  * **/
 public static void writeLogtoFile(String mylogtype, String tag, String text) {
  delFile();
  Date nowtime = new Date();
  String needWriteMessage = LogSdf.format(nowtime)   " "   tag   "n"   text "n";
  String logFileName;
  String logFolder=logTime.format(new Date());

  if(mylogtype=="error"){
   logFileName="error(" logDay.format(new Date()) ").log";
  }else if(mylogtype=="crash"){
   logFileName="crash(" logDay.format(new Date()) ").log";
  }else {
   logFileName="info(" logDay.format(new Date()) ").log";
  }

  File file = new File(LOG_PATH_SDCARD_DIR logFolder);
  if (!file.exists()) {
   file.mkdirs();
  }

  File f = new File(LOG_PATH_SDCARD_DIR logFolder,logFileName);
  try {
   FileWriter filerWriter = new FileWriter(f, true);
   BufferedWriter bufWriter = new BufferedWriter(filerWriter);
   bufWriter.write(needWriteMessage);
   bufWriter.newLine();
   bufWriter.close();
   filerWriter.close();
  } catch (IOException e) {
   e.printStackTrace();
  }
 }

 /**
  * 删除制定的日志文件
  * */
 private static void delFile(){
  String needDelFiel = logTime.format(getDateBefore());
  File file = new File(LOG_PATH_SDCARD_DIR, needDelFiel );
  if (file.exists()) {
   file.delete();
  }
 }

 private static Date getDateBefore() {
  Date nowtime = new Date();
  Calendar now = Calendar.getInstance();
  now.setTime(nowtime);
  now.set(Calendar.DATE, now.get(Calendar.DATE) - SDCARD_LOG_FILE_SAVE_DAYS);
  return now.getTime();
 }
}

修改src/android/cordovaHeaLog.java文件

package cordova.plugin.hea.log;

import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CallbackContext;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import cordova.plugin.hea.log.logUtil;
/**
 * This class echoes a string called from JavaScript.
 */
public class cordovaHeaLog extends CordovaPlugin {
 @Override
 public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
  if (action.equals("log")) {
   this.log(args.getString(0),args.getString(1),args.getString(2), callbackContext);
   return true;
  }
  return false;
 }

 private void log(String mylogtype, String tag,String text,CallbackContext callbackContext) {
  if (mylogtype != null && mylogtype.length() > 0&&text!=null&&text.length()>0&&tag!=null&&tag.length()>0) {
   logUtil.writeLogtoFile(mylogtype, tag, text);
   callbackContext.success(mylogtype " " tag " " text);
  } else {
   callbackContext.error("参数不可为空");
  }
 }
}

接下来修改 www/cordovaHeaLog.js.js

var exec = require('cordova/exec');
exports.log = function(arg0,arg1,arg2,success, error) {
exec(success, error, "Logjava", "log", [arg0,arg1,arg2]);
};

重点来了,项目下的 plugin.xml文件,我在这里踩了好久的坑,才跳出来。

我们将改成这样

<?xml version='1.0' encoding='utf-8'?>
<plugin id="cordova-plugin-hea-log" version="1" 
 xmlns="http://apache.org/cordova/ns/plugins/1.0" 
 xmlns:android="http://schemas.android.com/apk/res/android">
 <name>cordovaHeaLog</name>
 <js-module name="cordovaHeaLog" src="www/cordovaHeaLog.js">
  <clobbers target="cordovaHeaLog" />
 </js-module>
 <platform name="android">
  <config-file parent="/*" target="res/xml/config.xml">
   <feature name="Logjava">
    <param name="android-package" value="cordova.plugin.hea.log.cordovaHeaLog" />
   </feature>
  </config-file>
  <config-file parent="/*" target="AndroidManifest.xml"></config-file>
  <source-file src="src/android/cordovaHeaLog.java" target-dir="src/cordova/plugin/hea/log/cordovaHeaLog" />

  <source-file src="src/android/logUtil.java" target-dir="src/cordova/plugin/hea/log/logUtil" />
 </platform>
</plugin>

5.添加自定义插件

一般情况下是这样添加插件的

cordova plugin add cordova-plugin-hea-log

如果是添加本地的插件是这样添加的 比如我自定义插件是这样添加的

我的这个插件在这个路径下E:cordovaHeaLog那我就这样添加

cordova plugin add E:cordovaHeaLog

解释:为什么是addcordova-plugin-hea-log 呢 请往上翻 因为plugin.xml里的id 是cordova-plugin-hea-log

结果:

彩世界网址 3

6.添加安卓平台,设置权限,使用插件,运行查看结果

添加安卓平台

cordova platform add android

然后在项目的这个路径下 HeaIonic/android/AndroidManifest.xml 这个文件

添加权限 因为要写入日志在sdcard

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> 
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

如何使用插件呢

在HeaIonic/platforms/android/assets/www 这个路径下的这个文件cordova_plugins.js 打开

我们可以看到这个

彩世界网址 4

我们在页面上这样使用

圈起来的是添加的代码

彩世界网址 5

然后 ionic serve ,接着cordova build android

用android studio 打包项目 运行,关于如何 打包项目请看这里→ionic2 使用 cordova 打包成安卓apk

结果:调用插件日志写入成功

彩世界网址 6 彩世界网址 7

总结:

1.感觉自己在plugin.xml 配置出现最多问题,所以请先了解plugin.xml 如何进行配置。

2.还有比如logUtil.java 文件,可以写好测试功能没问题后再复制进插件里面。

3.关于调试,添加插件后出现问题,可以在android studio 中的Logcat 窗口查看是哪里出现了问题并进行调试,它会输出是什么问题啊,然后自行解决。一开始我也是一脸懵逼,不知道在哪里进行插件的调试写好后,也不是一次性就过完美的总要调试看看哪里会有出错的嘛,毕竟还是小菜鸟一只。

参考于:Android插件开发指南 →Android Plugin Development Guide

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持帮客之家。

如何写一个cordova 用于ionic2项目中呢,在搜索了一番之后,千篇一律,我都怀疑那...

  //error logic~~~
})

嗯~,貌似插件已近九成了~,下面该为命令准备一个package.json文件方便将插件添加到项目中:

 

 

View Code

定义一个包名称(虽然文件最终都是集中放置的,但请想想大热天一个人穿着裤衩在溜街多辣眼睛啊(● ̄(エ) ̄●)),命名如下,写java的童鞋大概都知道,这里就不解释啦~:

当前插件调用的方式是: 

  首先一个规范的cordova插件是这样子的(这里我写的一个插件的名字是 cordova-plugin-integrity-checking):

 彩世界网址 8

  //success logic~~~
},function (errorCallback) {

彩世界网址 9

我的博客即将搬运同步至腾讯云 社区,邀请大家一同入驻:

 

package.json:这里面用一个json声明了当前插件的文件结构,当然这个不是给开发者用的,是为了将此插件添加到项目中时打cordova命令用的,请不要忽略~

 一个完整的api包含api的id,以及一个回调,如第一行,这个api内部有一个核心(代码第10行),里面包含了一些调用的参数,需要说明的是第三个参数是一个别名(可随意写),这个名字需要对应到之后要说的plugin.xml里面的包的别名,第四个参数是action的名称,也就是刚刚在java文件里面写的action的名称(一定要对应啊~),最后一个是传入的参数,别忘了这也是与CordovaApkValidate.java里面对应的,最后17行共享出来的是一个变量,方便打点调用,仿佛快成了~o( ̄▽ ̄)d,别激动,这个会在最后的使用会详细讲解,现在安卓原生的逻辑已经写好了,api也已经写好,如何将两者结合起来,that is a trouble,but ,It's not trouble.不懂不懂(O_O)? ,下面就是嘿~

下是js所调用的api:

 

 

            /**
             * 思路:根据cordova对象获取包的路径
             *             然实例化MessageDigest对象的SHA-1算法
             *             再讲当前包加载到输入流
             *             再按字节数组读取输入流获取大integer的值
             *             后将大integer转换成16进制的hashcode的表示
             *             后再将16进制扔给callbackContext对象返回
             */
            String apkPath=cordova.getActivity().getApplicationContext().getPackageCodePath();
              MessageDigest msgDigest = null;
            if (action.equals("getSHA1")) {
                try {
                            msgDigest = MessageDigest.getInstance("SHA-1");
                            byte[] bytes = new byte[1024];
                            int byteCount;
                            FileInputStream fis = new FileInputStream(new File(apkPath));
                            while ((byteCount = fis.read(bytes)) > 0){
                                msgDigest.update(bytes, 0, byteCount);
                            }
                            BigInteger bi = new BigInteger(1, msgDigest.digest());
                            callbackContext.success(bi.toString(16));
                            fis.close();
                } catch (Exception e) {
                    callbackContext.error("ERROR MESSAGE:" e);
                    return false;
                }
            }
            return true;

以上两张图中,第一张图是在项目目录下打 "cordova plugin list"命令列出当前项目所用的所有的cordova插件,第二张图是在当前项目下将插件添加到项目中,只要不出现fail字样即插件添加成功,如果插件中需要添加变量,请在 命令后面 添加 “--veriable”(后面的英文单词是变量名)。。。。。。,添加成功,webstrom会自动刷新,这时候请看这里,看这里:

  插件的主目录下面有两个文件夹(src和www)以及四个文件(LICENSE、package.json、plugin.xml、README.md),插件内部的排列是根据cordova规范来的,这里不多解释,请看上图:

 彩世界网址 10

README.md:这里是一些使用说明、注意事项等~,一般你将开发的插件共享在github上的时候会需要这个,如涉及版权及项目安全此文件可忽略~

然后就是cordova规范固定的写法,继承CordovaPlugin重写execute方法,你可以改,结果当然是不能用<( ̄ˇ ̄)/,exceute方法的形参图上已经说明,这儿就不必缀诉啦~

  好了,咱们开始了~,首先按以上造型建文件和文件夹,我能说这是抄么-_-|||  

  在正式写下文之前,我先感谢公司大boss:王总,感谢他让我进入了一个有挑战性的技术公司 并在这个过程中一直鼓励我不断汲取新技术,同时也指正了我在开发中的一些不太好的习惯,十分感谢!

  之前由javaWeb转html5开发,由于面临新技术,遂在适应的过程中极为挣扎,不过还好~,这个过程也极为短暂;现如今面临一些较为复杂的需求还会有一丝丝头痛,却没有一开始那么强烈了。。。

package com.funnyZpC.integrityChecking.plugin;

 

雄关漫道真如铁,而今咱们只迈出了一步~,再接再厉哈(*^__^*)

请注意上图5~10行,其他地方随意哈~

 1 <?xml version='1.0' encoding='utf-8'?>
 2 <plugin id="cordova-plugin-integrity-checking" version="1.0.0" xmlns="http://apache.org/cordova/ns/plugins/1.0"
 3         xmlns:android="http://schemas.android.com/apk/res/android">
 4     <name>Integrity checking</name>
 5     <author>@funnyZpC</author>
 6     <description>Cordova Plugin for integrity checking</description>
 7     <keywords>Cordova,Integrity,Checking,Ecosystem:Cordova,Cordova-android</keywords>
 8     <license>MIT</license>
 9     <repo>https://github.com/funnyZpC/cordova-plugin-integrity-checking</repo>
10     <issue>https://github.com/funnyZpC/cordova-plugin-integrity-checking/issues</issue>
11     <engines>
12         <engine name="cordova" version=">=3.0.0"/>
13     </engines>
14     <js-module  src="www/apkValidatePlugin.js">
15         <clobbers target="Cordova"/>
16     </js-module>
17     <!-- android -->
18     <platform name="android">
19         <config-file parent="/*" target="res/xml/config.xml">
20             <feature name="ApkValidatePlugin">
21                 <param name="android-package" value="com.funnyZpC.integrityChecking.plugin.CordovaApkValidate"/>
22                 <param name="onload" value="true"/>
23             </feature>
24         </config-file>
25         <config-file parent="/*" target="AndroidManifest.xml"></config-file>
26         <source-file src="src/android/CordovaApkValidate.java" target-dir="src/com/funnyZpC/integrityChecking/plugin"/>
27     </platform>
28 </plugin>

 

 彩世界网址 11

在webstrom里面盲写没有引入包没有代码提示,bug率高,建议大家引入android SDK和cordova包在eclipse或idea里面写较nice~

你的项目有一个专门放置plugin的plugins的目录,目录下面有两个文件android.json和fetch.json,这两个文件里面都有插件的申明,以上三张图中第二和第三张,如没有请检查!,好了写了仨小时多该结束了(^o^)/,顺便放两张图(构建平台后的文件),读者自行思索,看有没有发现什么哈(∩_∩)

彩世界网址 12彩世界网址 13

LICENSE:是一些开源说明,一般声明的开源协议有GNU、BSD、Apache等~ 

 彩世界网址 14

                彩世界网址 15

 彩世界网址 16

  就拿最近一个需求来说吧,需求:未防止第三方破解app,客户找了一个安全公司做个评估,其中一个安全问题是安卓apk的包经过修改后依然可以安装运行(ios由于安全机制存在不存在这个问题),项目组内部讨论出一个比较好的解决方案是用户登陆前验证app包的hashcode值,并与后台交互验证当前发行版app的hashcode的有效性,以杜绝破解。

以下是代码的主体部分,这只是一个很简单的插件,逻辑说明已经写进去了,自行阅读哈~

 1 cordova.define("cordova-plugin-integrity-checking.apkValidatePlugin", function(require, exports, module) {
 2 /*
 3 var exec = require('cordova/exec');
 4 
 5 exports.isDeviceRooted = function(success, error) {
 6     exec(success, error, "RootDetection", "isDeviceRooted", []);
 7 };
 8 */
 9 var exec = function (command, success, fail) {
10   cordova.exec(success, fail, "ApkValidatePlugin", command, []);//参数(回调成功,回调错误,别名,action名称,参数)
11 };
12 var apkValidate={};
13 apkValidate.getSHA1 = function (success, fail) {
14          return exec('getSHA1', success, fail);
15 };
16 
17 module.exports = apkValidate;
18 
19 });

plugin.xml:这个文件里面是以xml的形式定义了包的路径以及api(js)对应原生的调用方法...,以及插件需要的权限声明(比如相机权限、位置权限、联系人权限等~),打apk及ipa包后此文件会被融合~

    给Ionic写一个cordova(PhoneGap)插件

Cordova.apkValidate.getSHA1(function (successCallback) {

    /**
     * Apk integrity checking
     * @author funnyZpC
     */
    public class CordovaApkValidate extends CordovaPlugin {
        /**
         * action:方法的动作,根据动作走相应的处理逻辑
         * args:js调用方法时传的参数,均以json的形式读入(这里未使用)
         * callbackContext:方法返回的对象,对象里面包好两个变量success和error,js的回调函数会用到
         * 
         */
        @Override
        public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {

  对于新手,建议准备好相应的IDE及环境:webstrom、google chrome、eclipse(或者 idea),android SDK ; webstrom 用于配合页面js以及插件开发,eclipse用于app插件调试。

www:这里放置的是js调用原生代码的api,里面有调用方法和返回对象(可无)。

1        <config-file target="AndroidManifest.xml" parent="/*">
2             <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
3         </config-file>

彩世界网址 17

  再~,感谢在开发中给予我太多帮助的杜勇以及孙金~,不论是需求讨论还是具体开发阶段都会给予一些十分有用的思路以及难点解答,尤其是面临技术瓶颈的时候~,再次感谢他们,十分感谢!

src:是放置安卓,ios,wp8等原生代目的地方,一般为了区分各个平台的代码都会先建一个文件夹(以上是android),文件夹下面是代码文件。

以上,第一行需要明确定义插件的id,这个建议与外部的插件名一致(第一张图中的文件夹的名称),14行中的路径需要参照api文件所在的相对路径填写,20行中定义的别名与api文件中的定义的调用别名一致,21行中的value值一定是上面java文件中最上面定义的package名 类名(这是个坑,我以前经常性写错,心伤~~(>_<)~~),最后需要注意的是26行中的src的值是java文件的相对路径,还有target-dir也是相对路径(窃不要以为后面是包名,包也是文件夹((* ̄^ ̄)),这些都不要写错,其他随意哈~<(* ̄▽ ̄*)/,另外,如果开发的是一个比较复杂的插件,比如中间需要调用内存卡读写权限,你需要再定义一个config-file(与其他的config-file同级),具体如下(name的值是官方定义的,自行google)

彩世界网址 18

 彩世界网址 19

  完毕,先写个原生的android代码吧(反正咱不会写oc d=====( ̄▽ ̄*)b), 一下样例是CordovaApkValidte.java =>

本文由时时app平台注册网站发布于web前端,转载请注明出处:ionic2自定义cordova插件开发以及使用(Android),

关键词:

  • 上一篇:checkbox
  • 下一篇:没有了