Android开发之PhoneGap打包及错误解决办法

 更新时间:2016年9月20日 19:58  点击:2977
下面来给各位简单的介绍一下关于Android开发之PhoneGap打包及错误解决办法,希望碰到此类问题的同学可进入参考一下哦。


在我安装、配置好PhoneGap项目的所有依赖后,试图执行

$ cordova run android

命令时,出现过如下错误。


Error: /home/sam/front/redwine/platforms/android/cordova/run: Command failed with exit code 8
    at ChildProcess.whenDone (/usr/lib/node_modules/cordova/node_modules/cordova-lib/src/cordova/superspawn.js:135:23)
    at ChildProcess.EventEmitter.emit (events.js:98:17)
    at maybeClose (child_process.js:743:16)
    at Process.ChildProcess._handle.onexit (child_process.js:810:5)
view rawphonegapError hosted with ❤ by GitHub
cordova build android或cordova emulate android的结果也是一样。


但其实真正的问题在上面几行:

[aapt]     (skipping file '.jshintrc' due to ANDROID_AAPT_IGNORE pattern '.*')
     [aapt]     (skipping file '.bower.json' due to ANDROID_AAPT_IGNORE pattern '.*')
     [aapt]     (skipping file '.directory' due to ANDROID_AAPT_IGNORE pattern '.*')
     [aapt]       Unable to add '/home/sam/front/redwine/platforms/android/assets/www/bower_components/jquery-mobile/node_modules/grunt-bowercopy/node_modules/bower/node_modules/semver/semver.browser.js.gz': file already in archive (try '-u'?)
     [aapt] ERROR: unable to process assets while packaging '/home/sam/front/redwine/platforms/android/ant-build/wine.ap_'
     [aapt] ERROR: packaging of '/home/sam/front/redwine/platforms/android/ant-build/wine.ap_' failed
 
BUILD FAILED
/home/sam/bin/android-sdk-linux/tools/ant/build.xml:932: The following error occurred while executing this line:
/home/sam/bin/android-sdk-linux/tools/ant/build.xml:950: null returned: 1
view rawphonegapError2 hosted with ❤ by GitHub

这是因为项目下有多个node_modules目录,被重复打包而引发的Command failed with exit code 8问题。


解决办法是修改platforms/android/build.xml:

<property name="aapt.ignore.assets" value="&lt;dir&gt;node_*" />

将node_modules目录排除掉,就可以正常执行cordova命令。

iPhone6 plus来电闪光灯怎么设置呢,这个来电闪光灯功能默认是没有开启了,只有我们打开它之后才有这个功能,此功能也是非常的个性化的哦,下面一聚教程小编就为各位果粉介绍一下iPhone6 plus来电闪光灯设置方法吧。
1)这个我们在iPhone6 plus桌面点击设置然后再找到里边的【通用】之后再点击【辅助功能】。(如下图)
iPhone6 plus来电闪光灯设置方法图解 iPhone6 plus来电闪光灯设置方法图解
2)然后我们再点击【LED闪烁以示提醒】点击它开启了

iPhone6 plus来电闪光灯设置方法图解 iPhone6 plus来电闪光灯设置方法图解

好了到这里iPhone6 plus开关来电闪光灯教程就介绍到这里了,希望能帮助到各位。

下面一起来看一个关于wpf使用WPFMediaKit调用平板(surface2)摄像头拍照,希望例子能给各位同学带来帮助哦。

wpf中怎么调用surface(或者其他平板)的摄像头进行拍照那?今天分享一下使用WPFMediaKit调用平板(surface2)摄像头拍照。

wpf使用WPFMediaKit调用平板(surface2)摄像头拍照

下载最新的代码,加入到项目中。

 

wpf使用WPFMediaKit调用平板(surface2)摄像头拍照


2、test项目引用WPFMediaKit

xaml代码:

 代码如下 复制代码
<Window x:Class="test.WPFMediaKitWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 xmlns:wpfmedia="clr-namespace:WPFMediaKit.DirectShow.Controls;assembly=WPFMediaKit"
Title="WPFMediaKitWindow" Loaded="Window_Loaded"WindowState="Maximized">
<Grid>
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<ComboBox Name="cb" SelectionChanged="cb_SelectionChanged" Width="100" />
<Button Content="打开摄像头" x:Name="btnOpen" Click="btnOpen_Click"Width="100"/>
<Button Content="拍照" x:Name="btnCapture" Click="btnCapture_Click"Width="100" />
<Button Content="保存" x:Name="btnSave" Click="btnSave_Click" Width="100" />
</StackPanel>
<wpfmedia:VideoCaptureElement Name="vce" />
 
</StackPanel>
</Grid>
</Window>

后台代码:

获取摄像头:

 代码如下 复制代码
private void cameraOpen()
{
cb.ItemsSource = MultimediaUtil.VideoInputNames;
if (MultimediaUtil.VideoInputNames.Length > 1)
{
cb.SelectedIndex = 1;
}
else
{
cb.SelectedIndex = 0;
}
}

拍照保存到硬盘:win8注意有文件夹的权限问题

 代码如下 复制代码


private void TakePhoto()
{
RenderTargetBitmap bmp = new RenderTargetBitmap(
(int)vce.ActualWidth, (int)vce.ActualHeight,
96, 96, PixelFormats.Default);
//vce.Stretch = Stretch.Fill;
vce.Measure(vce.RenderSize);
vce.Arrange(new Rect(vce.RenderSize));
bmp.Render(vce);
BitmapEncoder encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bmp));
using (MemoryStream ms = new MemoryStream())
{
encoder.Save(ms);
CaptureData = ms.ToArray();
File.WriteAllBytes(@"C:aaaa" + DateTime.Now.ToString("yyyy-mm-dd-hh-mm-sss")+".png", CaptureData);
}
vce.Play();
//capCreateCaptureWindowA()
return;
}

移动手机中实现端文件上传是现在WEB开发中也需要考虑到的一个问题,在这里我们来介绍使用XMLHttpRequest 结合Nodejs实现移动端文件上传了,下面我们一起来看看相关例子吧,希望文章能给各位带来帮助哦。

input[type="file"] 可以选择手机里的文件,还可以调用拍照功能(某些浏览器不行),Form 表单如下:

 代码如下 复制代码
<form id="upload-form" action="/upload" enctype="multipart/form-data" method="post">
  <input id="selece-files" type="file" name="fileToUpload" />
  <input id="do-upload" type="submit" value="上传" />
</form>

这里做单文件上传,多文件上传可以给 input[type="file"] 加个 multiple 属性便可。当触发 submit 事件提交:

 代码如下 复制代码


var Upload = (function(win, upload) {

  upload.submit = function() {
    var self = this,
      form = document.getElementById('form'),
      formdata = new FormData(form),
      xhr = new XMLHttpRequest();

    // xhr.upload 在 iOS Safari、 大部分 Android 4.0+ 的自带浏览器、Chrome 都支持
    xhr.upload.addEventListener("progress", self.onProgress, false);
    xhr.addEventListener("load", self.onSuccess, false);
    xhr.addEventListener("error", self.onError, false);
    xhr.addEventListener("abort", self.onCancel, false);

    xhr.open('post', form.action, false);
    xhr.send(formdata);
  }

  // 可以在 onProgress 的时候处理进度条
  upload.onProgress = function(e) {
    if (e.lengthComputable) {
      var progress = Math.round(e.loaded * 100 / e.total) + '%';
      console.log('on progress: ', progress);
    }
  }

  upload.onError = function() {}
  upload.onCancel = function() {}

  // 上传完成
  upload.onSuccess = function() {}

  return upload;

})(window, window.Upload || {});
FormData,这是另一种针对 XHR2 设计的新数据类型。使用 FormData 能够很方便地实时以 JavaScript 创建 HTML <form>。

Server 端用了 formidable 这个中间件:npm install formidable。
当然不用 formidable 也能处理文件上传。

 代码如下 复制代码

var fs = require('fs'),
  formidable = require('formidable');

app.post('/upload', function(req, res) {
  var form = new formidable.IncomingForm(),
    data;

  // formidable 属性设置可以参考 github 上说明
  form.uploadDir = './uploads';
  form.encoding = 'utf-8';
  form.keepExtensions = true;
  form.maxFieldsSize = 1024 * 1024 * 50; // 50MB

  form.parse(req, function(err, fields, files) {
    console.log('on parse');
    res.writeHead(200, {'content-type': 'text/plain'});
    data = files.fileToUpload;
    res.end(JSON.stringify(data));
  });

  // 我们可以在文件上传完成后移到放置文件的目标目录
  form.on('end', function() {
    fs.renameSync(data.path, './uploads/'+ data.name);
  });
});

经过这么久在android客户端和服务器端的开发,感觉还是积累了不少东西想要和大家分享一下,但是好想单独拎一个点出来又不太值得,所以就汇集到一起写成系列吧。

一. 关于用户数据存储

首先在注册的协议里,定义如下公共传输字段:

version: 这个其实是xml中配置的versionCode。versionName个人认为没有什么必要,所以就不传了。

channel:  用户渠道,这个和xml中的UMENG_CHANNEL 是共用的,因为一直在使用umeng,所以这样定义反而清楚一些。

device_id: 设备ID

os: 操作系统类型,这里默认传入android

os_version: 操作系统版本

对于小数据量,用户数据存储在mysql中是相对较好的选择,这里直接以django的model为例:

 代码如下 复制代码
from django.db import models
class User(models.Model):
    device_id = models.CharField(max_length=255, null=True, blank=True)
    version = models.IntegerField()
    channel = models.CharField(max_length=64, null=True, blank=True)
    os = models.CharField(max_length=64, null=True, blank=True)
    os_version = models.CharField(max_length, null=True, blank=True)
    create_time = models.DateTimeField(default=get_cur_time)
    login_time = models.DateTimeField(default=get_cur_time)


如果需要用到如facebook之类的联合登录,对于小规模的服务,我个人倾向于不破坏User的定义,因为毕竟这种联合登录什么时候会加入很难预知:

 代码如下 复制代码
class FBUser(models.Model):
    # facebook 用户ID
    userid = models.CharField(max_length=32, unique=True)
    # User.id,这里不用外键,是为了以后拆分表或者换数据存储留下后路
    native_id = models.IntegerField(default=0)
 
    def __unicode__(self):
        return '%s-&gt;%s' % (self.userid, self.native_id)


其他的业务相关的字段定义就由业务自己决定了。

我不是很建议在未来可能数据量很大的表里使用 外键,因为很可能以后要设计到分库分表、或者迁移数据到redis、mongodb之类的,这在我之前的博文里面就有提到过,大家有兴趣可以看一下。

 

二. 关于通信协议的选择

其实这块还真的有不少东西可以说的。

HTTP

最简单的肯定是用http协议,但是http协议在手机应用上其实只能满足传统一收一发的需求,即使是使用long poll之类技术,经过我测试,当在3G网络下时,运营商经常会强制返回http请求为502错误。

WebSocket

当然,如果对http还是心有所属,可以使用 websocket,经过测试 websocket还是比较好用的,cocos2d-x 有专门提供websocket的封装,android下也有专门的websocket的库: AndroidAsync

python也提供了很多websocket的server和client。比如server端有 gevent-websocket、以及在其基础上开发的flask plugin: flask-sockets。当然django也是可以直接使用gevent-websocket的,django还有一个不基于gevent的版本:django-websocket。client端有 websocket-client。

基于gevent的server之前测试过,可以正常的收到断掉链接的消息,逻辑处理也都比较正常。最终要的一点是,他可以和现有http服务器无缝结合,不需要做跨进程在两个server间通讯。

SocketIO

这个我也测试过,但是实在不建议大家在项目中使用,他做了太多的兼容的事情了,而我们客户端又不是浏览器,根本不需要考虑那么多事情,只要用一种协议就可以了。

还有一点就是,我试了下python的socketio server似乎有点问题,在客户端主动close链接时,服务器端并没有收到事件,而只有客户端发送disconnect命令才会触发服务器端的相关事件。这个事情在网上查了一下,貌似是官方故意做的处理,防止浏览器在刷新时触发一些奇怪的事情,但是这样处理对于我是无法忍受的。

不过还是把相关的链接发给大家,大家可以试一下。android客户端:还是  AndroidAsync。 python server端:Flask-SocketIO,django-socketio,python client端:socketIO-client。

原生socket+自定义协议

这种方式灵活度肯定是最高的,但是相应的开发难度肯定也会增大。协议可以使用json或者google 的 protobuf。这个可能一两句话还说不清楚,下一篇我们专门花篇幅聊一下。

[!--infotagslink--]

相关文章

  • Ecshop提示Only variables should be passed by reference in错误

    在安装好ecshop软件之后我们打开首页时提示Only variables should be passed by reference in错误了,碰到这个问题是什么原因呢?下面我们就一起来看看解决办法吧。...2016-11-25
  • 409错误是什么 http 409错误怎么解决

    409错误是什么?http 409错误怎么解决呢?不少站长在遇到这个错误代码之后都一筹莫展,本次一聚教程网为大家带来了详细的说明,快来看看吧。 409错误是什么: HTTP 40...2017-01-22
  • PHP session_start()很慢问题分析与解决办法

    本文章来给各位同学介绍一下关于PHP session_start()很慢问题分析与解决办法,希望碰到此问题的同学可进入参考。 最近在做东西的时候发现一个问题 有一个接口挂...2016-11-25
  • 414错误是什么 414错误怎么解决

    414错误是HTTP协议状态码中的一种,很多都还不知道414错误是什么,以及不知道怎么解决414错误,那么就来看看小编带来的介绍吧。 414错误是什么: HTTP 414错误,(Requ...2017-01-22
  • http 405错误是什么 http 405错误怎么解决

    http 405错误是什么?http 405错误怎么解决?相信很多站长都在找这两个问题的答案,本次小编为大家带来了详细的教程,快来看看吧。 405错误是什么: HTTP 405错误是H...2017-01-22
  • php中json_decode()和json_encode()用法与中文不显示解决办法

    本文章介绍了关于php中json_decode()和json_encode()用法与中文不显示解决办法,有需要的朋友可以参考一下下。 php中json_decode()和json_encode() 1.json_decode(...2016-11-25
  • phpexcel导出数据身份证后四位0000解决办法

    在php中我们如果要导入excel数据我们通常会使用phpexcel插件了,但是有朋友会发与使用phpexcel导出数据出现身份证后四位是0000情况了,下面我们就来看解决办法。 最...2016-11-25
  • 401错误码代表什么 401错误解决办法

    401是HTTP状态码的一种,属于“请示错误”,表示请求可能出错,已妨碍了服务器对请求的处理。具体的401错误是指:未授权,请求要求进行身份验证。登录后,服务器可能会返回对页面...2017-01-22
  • http 402错误是什么 http 402简介

    http 402错误是什么?402错误较为少见,一般不轻易出现,下面小编就来告诉大家402错误是什么吧。 HTTP 402错误是HTTP状态码的一种,表示“要求付费”; 所求的...2017-01-22
  • 411错误是什么 411错误怎么解决

    411错误是HTTP协议状态码的一种,很多人都还不知道411错误是什么,本次一聚教程网将为大家进行解答,并且告诉大家411错误怎么解决。 411错误是什么: HTTP 411错误,(Lengt...2017-01-22
  • apache网站提示503错误解决办法

    Apache status 503 的原因大致有如下几种情况 : 1、 CPU 负载过高,服务器响应不过来,返回503 2、 系统连接数超限,超过MaxVhostClients的上限,返回503 3、 单IP连接数超限,超过M...2016-01-28
  • 404错误是什么 404错误怎么解决

    403错误是网站访问过程中,常见的错误提示。资源不可用,服务器理解客户的请求,但拒绝处理它。通常由于服务器上文件或目录的权限设置导致,比如IIS或者apache设置了访问权限...2017-01-22
  • 403错误是什么 403错误怎么解决

    403错误是HTTP状态码的一种,属于“请示错误”,表示服务器拒绝请求。如果在搜索引擎尝试抓取您网站上的有效网页时显示此状态代码,那么,这可能是您的服务器或主机拒绝搜索...2017-01-22
  • 412错误是什么 412错误怎么解决

    412错误是什么?412错误怎么解决?本次一聚教程网将为大家带来详细的介绍,帮助大家全面了解412错误的意思以及解决412错误的方法。 412错误是什么: HTTP 412错误,(Precond...2017-01-22
  • Perl CPAN::Modulelist的解决办法

    今天用CPAN安装Term::ReadLine,报了个这样的错误 Going to read /root/.cpan/sources/modules/03modlist.data.gz Can't locate object method "data" via package "C...2016-11-25
  • HTTP 408错误是什么 HTTP 408错误解决方法

    相信很多站长都遇到过这样一个问题,访问页面时出现408错误,下面一聚教程网将为大家介绍408错误出现的原因以及408错误的解决办法。 HTTP 408错误出现原因: HTT...2017-01-22
  • Android子控件超出父控件的范围显示出来方法

    下面我们来看一篇关于Android子控件超出父控件的范围显示出来方法,希望这篇文章能够帮助到各位朋友,有碰到此问题的朋友可以进来看看哦。 <RelativeLayout xmlns:an...2016-10-02
  • 407错误是什么 407错误怎么解决

    407错误是什么?407错误怎么解决?不少站长都遇到过407错误,下面小编将告诉大家如何处理407错误。 407错误是什么: HTTP 407错误是HTTP协议状态码的一种,表示需要代...2017-01-22
  • 406错误是什么 406错误怎么解决

    HTTP 406错误是HTTP协议状态码的一种,表示无法使用请求的内容特性来响应请求的网页。一般是指客户端浏览器不接受所请求页面的 MIME 类型。 而MIME类型是在把输出...2017-01-22
  • 410错误是什么 http 410错误怎么解决

    410错误是HTTP协议状态码的一种,本次一聚教程网将为大家详细介绍HTTP 410错误是什么,以及410错误的解决办法。 410错误是什么: HTTP 410错误是HTTP协议状态码的...2017-01-22