默认分类

默认分类

默认分类描述

Sublime text震撼插件,类似activate-power-mode

myxf 发表了文章 • 0 个评论 • 5438 次浏览 • 2017-02-22 14:57 • 来自相关话题

Atom编辑器的activate-power-mode看起来很屌的样子











就想着能不能把这个插件应用到sublime text编辑器中,但很遗憾这个插件只支持Atom,xcode等,并不zhi支持sublime text、editplus等常用编辑器,于是就自己写了一个。
不仅仅支持常用编辑器只要能输入文本的地方就有效果,还附带了机械键盘音效,原版当中的窗口震动效果看着太累眼我就没加。
效果如下:




















使用说明:
1.运行keyboard.exe即可看到效果
2.配置文件config.ini中的switch是特效控制开关,1是打开,0是关闭
3.快捷键Alt+F1是关闭音效
4.当音效处于关闭状态时,快捷键Alt+F2是打开音效
5.当音效处于开启状态时,快捷键Alt+F2是切换音效效果
6.快捷键Alt+F3关闭程序
7.SublimeText编辑器看不到效果,请将IMESupport-master文件夹复制到SublimeText根目录下/Data/Packages/,如果已存在就覆盖。
8.某些程序无法获取光标焦点,所有没有效果,例如QQ、迅雷等。
 
自带五种音效,7套样式。
由于是python写的所以打包exe比较大
下载地址:http://www.bilnn.com/uploads/avatar/keyboard.rar
  查看全部
Atom编辑器的activate-power-mode看起来很屌的样子

c4ca4238a0b923820dcc509a6f75849b.gif


cfcd208495d565ef66e7dff9f98764da.gif


就想着能不能把这个插件应用到sublime text编辑器中,但很遗憾这个插件只支持Atom,xcode等,并不zhi支持sublime text、editplus等常用编辑器,于是就自己写了一个。
不仅仅支持常用编辑器只要能输入文本的地方就有效果,还附带了机械键盘音效,原版当中的窗口震动效果看着太累眼我就没加。
效果如下:

GIF.gif


GIF1.gif


GIF2.gif


GIF3.gif

使用说明:
1.运行keyboard.exe即可看到效果
2.配置文件config.ini中的switch是特效控制开关,1是打开,0是关闭
3.快捷键Alt+F1是关闭音效
4.当音效处于关闭状态时,快捷键Alt+F2是打开音效
5.当音效处于开启状态时,快捷键Alt+F2是切换音效效果
6.快捷键Alt+F3关闭程序
7.SublimeText编辑器看不到效果,请将IMESupport-master文件夹复制到SublimeText根目录下/Data/Packages/,如果已存在就覆盖。
8.某些程序无法获取光标焦点,所有没有效果,例如QQ、迅雷等。
 
自带五种音效,7套样式。
由于是python写的所以打包exe比较大
下载地址:http://www.bilnn.com/uploads/avatar/keyboard.rar
 

android 多媒体数据库详解

jiangkaifang 发表了文章 • 0 个评论 • 1520 次浏览 • 2015-12-21 11:42 • 来自相关话题

1. Android的多媒体如何存储的?

Android的多媒体文件主要存储在/data/data/com.android.providers.media/databases目录下,该目录下有两个db文件,一个是内部存储数据库文件(internal.db),一个是存储卡数据库(external-XXXX.db)。媒体文件的操作主要是围绕着这两个数据库来进行。这两个数据库的结构是完全一模一样的。

我们先看一下这两个数据库包含了哪些表。

album_art audio search

album_info audio_genres searchhelpertitle

albums audio_genres_map thumbnails

android_metadata audio_meta video

artist_info audio_playlists videothumbnails

artists audio_playlists_map

artists_albums_map images

先从基本的分析:

Images表:主要存储images信息。可以看一下这个表的结构:

CREATE TABLE images (_id INTEGER PRIMARY KEY,_data TEXT,_size INTEGER,_display_name TEXT,mime_type TEXT,title

TEXT,date_added INTEGER,date_modified INTEGER,description TEXT,picasa_id TEXT,isprivate INTEGER,latitude DOUBL

E,longitude DOUBLE,datetaken INTEGER,orientation INTEGER,mini_thumb_magic INTEGER,bucket_id TEXT,bucket_displa

y_name TEXT);

包含了一些基本信息,其中大家一看就明白了。

Thumbnails表:这个表和images表是有直接关系的。主要存储图片的缩略图,Android为每一张保存进系统的图片文件都会自动生成一张缩略图文件。关于这一点还有一些特殊的技巧后面再讲。我们可以看一下这个表的结构:

CREATE TABLE thumbnails (_id INTEGER PRIMARY KEY,_data TEXT,image_id INTEGER,kind INTEGER,width INTEGER,height INTEGER);

每一张image对应一条thumbnail记录。

Video表:主要存储视频信息了。和images表类似。表结构如下:

CREATE TABLE video (_id INTEGER PRIMARY KEY,_data TEXT NOT NULL,_display_name TEXT,_size INTEGER,mime_type TEXT,date_added INTEGER,date_modified INTEGER,title TEXT,duration INTEGER,artist TEXT,album TEXT,resolution TEXT,description TEXT,isprivate INTEGER,tags TEXT,category TEXT,language TEXT,mini_thumb_data TEXT,latitude DOUBLE,longitude DOUBLE,datetaken INTEGER,mini_thumb_magic INTEGER, bucket_id TEXT, bucket_display_name TEXT, bookmark INTEGER);

Videothumbnails表:存储视频的缩略图信息。这个和thumbnails表类似。

Audio表:音频信息比视频信息和图片信息要稍微复杂一些,主要是存储了一些专辑(album)、歌手(artists)信息,而专辑和歌手信息是单独的表格存储的,audio其实是一个视图,真正的音频数据信息存储在audio_meta表格中。我们可以看一下audio视图的定义:

CREATE VIEW audio as SELECT * FROM audio_meta LEFT OUTER JOIN artists ON audio_meta.artist_id=artists.artist_id LEFT OUTER JOIN albums ON audio_meta.album_id=albums.album_id;

Albums表:主要存储专辑信息。

Artists表:主要存储歌手信息。不多赘述。

其他的一些表格我们平时可能用的比较少,就不做描述了,有兴趣可以自行研究一下。

2. Android的多媒体如何获取?

Android提供了媒体获取与存储的相关API,主要包含在android.provider.MediaStorepackage中。

MediaStore.Audio.AlbumColumns

Columns representing an album

MediaStore.Audio.ArtistColumns

Columns representing an artist

MediaStore.Audio.AudioColumns

Columns for audio file that show up in multiple tables.

MediaStore.Audio.GenresColumns

Columns representing an audio genre

MediaStore.Audio.PlaylistsColumns

Columns representing a playlist

MediaStore.Files.FileColumns

Fields for master table for all media files.

MediaStore.Images.ImageColumns

MediaStore.MediaColumns

Common fields for most MediaProvider tables

MediaStore.Video.VideoColumns

MediaStore

The Media provider contains meta data for all available media on both internal and external storage devices.

MediaStore.Audio

Container for all audio content.

MediaStore.Audio.Albums

Contains artists for audio files

MediaStore.Audio.Artists

Contains artists for audio files

MediaStore.Audio.Artists.Albums

Sub-directory of each artist containing all albums on which a song by the artist appears.

MediaStore.Audio.Genres

Contains all genres for audio files

MediaStore.Audio.Genres.Members

Sub-directory of each genre containing all members.

MediaStore.Audio.Media

MediaStore.Audio.Playlists

Contains playlists for audio files

MediaStore.Audio.Playlists.Members

Sub-directory of each playlist containing all members.

MediaStore.Files

Media provider table containing an index of all files in the media storage, including non-media files.

MediaStore.Images

Contains meta data for all available images.

MediaStore.Images.Media

MediaStore.Images.Thumbnails

This class allows developers to query and get two kinds of thumbnails: MINI_KIND: 512 x 384 thumbnail MICRO_KIND: 96 x 96 thumbnail

MediaStore.Video

MediaStore.Video.Media

MediaStore.Video.Thumbnails

This class allows developers to query and get two kinds of thumbnails: MINI_KIND: 512 x 384 thumbnail MICRO_KIND: 96 x 96 thumbnail

简单的观察一下,发现这些类也就是对数据库中的一些表的封装,弄懂了底层的存储结构,对于了解这些类的作用就很容易了。

Android系统中的每一种媒体文件有两种地址描述方式。

第一种模式,大家知道,在Android中,Content Provider是用来存储和获取公共数据的统一接口,Content Provider为每一类资源分配了URI地址,比如图片的地址就包括MediaStore.Images.Media.INTERNAL_CONTENT_URI和MediaStore.Images.Media.EXTERNAL_CONTENT_URI两个基础地址,其值分别是content://media/internal/images/media和content://media/external/images/media,对应内部库和外部库地址。每一张图片的地址基本上是上面的基础URL地址下加上图片的内部ID。打个比方一张存储卡上的图片ID为2,其对应的Uri地址就是content://media/external/images/media/2.知道了这个地址,基本上就可以操作这张图片的所有信息了。

另外一种描述文件地址标识就是传统的文件路径模式了,比如一张存储卡上的图片地址可能描述为:/mnt/sdcard/images/1.jpg。其实这个路径存储在images表格中的data字段中,有了这点关联,我们可以在这两种模式下进行任意切换。

前一种模式下,主要通过MediaStore.Images.Media、MediaStore.Audio.Media、MediaStore.Video.Media三个库中的query方法来查询或者获取特定条件的媒体了。

基本用法1:从一个Content Uri地址中生成Bitmap

可以采用android.provider.MediaStore.Images.Media.getBitmap(ContentResolvercr,Uriurl)方法,其中ContentResolver是应用与资源之间的衔接人,它的示例通常可以通过在Activity中调用的getContentResolver()方法中获取。Uri地址就是上面描述的content://media/external/images/media/2类似地址,也就是Content Provider定义的地址形式。

基本用法2:从一个传统地址中生成Bitmap

有时候我们只知道一张图片的路径,并不知道图片的内部地址,想去获取该图片,可以采用android.graphics.BitmapFactory中的decodeXXX方法来搞定,比如decodeFile方法就是从文件路径中读取图片,原图片可以支持jpg,png,gif,bmp等各种格式。decodeByteArray就是从字节流中解码了。最后都是转换成Bitmap格式。

基本用法3:获取一张图片的缩略图

有时候我们需要显示图片的缩略图,可以采用android.provider.MediaStore.Images.Thumbnails的getThumbnail方法。另外其实也可以采用bitmap的compress的方法对图片进行一些压缩处理。 查看全部
1. Android的多媒体如何存储的?

Android的多媒体文件主要存储在/data/data/com.android.providers.media/databases目录下,该目录下有两个db文件,一个是内部存储数据库文件(internal.db),一个是存储卡数据库(external-XXXX.db)。媒体文件的操作主要是围绕着这两个数据库来进行。这两个数据库的结构是完全一模一样的。

我们先看一下这两个数据库包含了哪些表。

album_art audio search

album_info audio_genres searchhelpertitle

albums audio_genres_map thumbnails

android_metadata audio_meta video

artist_info audio_playlists videothumbnails

artists audio_playlists_map

artists_albums_map images

先从基本的分析:

Images表:主要存储images信息。可以看一下这个表的结构:

CREATE TABLE images (_id INTEGER PRIMARY KEY,_data TEXT,_size INTEGER,_display_name TEXT,mime_type TEXT,title

TEXT,date_added INTEGER,date_modified INTEGER,description TEXT,picasa_id TEXT,isprivate INTEGER,latitude DOUBL

E,longitude DOUBLE,datetaken INTEGER,orientation INTEGER,mini_thumb_magic INTEGER,bucket_id TEXT,bucket_displa

y_name TEXT);

包含了一些基本信息,其中大家一看就明白了。

Thumbnails表:这个表和images表是有直接关系的。主要存储图片的缩略图,Android为每一张保存进系统的图片文件都会自动生成一张缩略图文件。关于这一点还有一些特殊的技巧后面再讲。我们可以看一下这个表的结构:

CREATE TABLE thumbnails (_id INTEGER PRIMARY KEY,_data TEXT,image_id INTEGER,kind INTEGER,width INTEGER,height INTEGER);

每一张image对应一条thumbnail记录。

Video表:主要存储视频信息了。和images表类似。表结构如下:

CREATE TABLE video (_id INTEGER PRIMARY KEY,_data TEXT NOT NULL,_display_name TEXT,_size INTEGER,mime_type TEXT,date_added INTEGER,date_modified INTEGER,title TEXT,duration INTEGER,artist TEXT,album TEXT,resolution TEXT,description TEXT,isprivate INTEGER,tags TEXT,category TEXT,language TEXT,mini_thumb_data TEXT,latitude DOUBLE,longitude DOUBLE,datetaken INTEGER,mini_thumb_magic INTEGER, bucket_id TEXT, bucket_display_name TEXT, bookmark INTEGER);

Videothumbnails表:存储视频的缩略图信息。这个和thumbnails表类似。

Audio表:音频信息比视频信息和图片信息要稍微复杂一些,主要是存储了一些专辑(album)、歌手(artists)信息,而专辑和歌手信息是单独的表格存储的,audio其实是一个视图,真正的音频数据信息存储在audio_meta表格中。我们可以看一下audio视图的定义:

CREATE VIEW audio as SELECT * FROM audio_meta LEFT OUTER JOIN artists ON audio_meta.artist_id=artists.artist_id LEFT OUTER JOIN albums ON audio_meta.album_id=albums.album_id;

Albums表:主要存储专辑信息。

Artists表:主要存储歌手信息。不多赘述。

其他的一些表格我们平时可能用的比较少,就不做描述了,有兴趣可以自行研究一下。

2. Android的多媒体如何获取?

Android提供了媒体获取与存储的相关API,主要包含在android.provider.MediaStorepackage中。

MediaStore.Audio.AlbumColumns

Columns representing an album

MediaStore.Audio.ArtistColumns

Columns representing an artist

MediaStore.Audio.AudioColumns

Columns for audio file that show up in multiple tables.

MediaStore.Audio.GenresColumns

Columns representing an audio genre

MediaStore.Audio.PlaylistsColumns

Columns representing a playlist

MediaStore.Files.FileColumns

Fields for master table for all media files.

MediaStore.Images.ImageColumns

MediaStore.MediaColumns

Common fields for most MediaProvider tables

MediaStore.Video.VideoColumns

MediaStore

The Media provider contains meta data for all available media on both internal and external storage devices.

MediaStore.Audio

Container for all audio content.

MediaStore.Audio.Albums

Contains artists for audio files

MediaStore.Audio.Artists

Contains artists for audio files

MediaStore.Audio.Artists.Albums

Sub-directory of each artist containing all albums on which a song by the artist appears.

MediaStore.Audio.Genres

Contains all genres for audio files

MediaStore.Audio.Genres.Members

Sub-directory of each genre containing all members.

MediaStore.Audio.Media

MediaStore.Audio.Playlists

Contains playlists for audio files

MediaStore.Audio.Playlists.Members

Sub-directory of each playlist containing all members.

MediaStore.Files

Media provider table containing an index of all files in the media storage, including non-media files.

MediaStore.Images

Contains meta data for all available images.

MediaStore.Images.Media

MediaStore.Images.Thumbnails

This class allows developers to query and get two kinds of thumbnails: MINI_KIND: 512 x 384 thumbnail MICRO_KIND: 96 x 96 thumbnail

MediaStore.Video

MediaStore.Video.Media

MediaStore.Video.Thumbnails

This class allows developers to query and get two kinds of thumbnails: MINI_KIND: 512 x 384 thumbnail MICRO_KIND: 96 x 96 thumbnail

简单的观察一下,发现这些类也就是对数据库中的一些表的封装,弄懂了底层的存储结构,对于了解这些类的作用就很容易了。

Android系统中的每一种媒体文件有两种地址描述方式。

第一种模式,大家知道,在Android中,Content Provider是用来存储和获取公共数据的统一接口,Content Provider为每一类资源分配了URI地址,比如图片的地址就包括MediaStore.Images.Media.INTERNAL_CONTENT_URI和MediaStore.Images.Media.EXTERNAL_CONTENT_URI两个基础地址,其值分别是content://media/internal/images/media和content://media/external/images/media,对应内部库和外部库地址。每一张图片的地址基本上是上面的基础URL地址下加上图片的内部ID。打个比方一张存储卡上的图片ID为2,其对应的Uri地址就是content://media/external/images/media/2.知道了这个地址,基本上就可以操作这张图片的所有信息了。

另外一种描述文件地址标识就是传统的文件路径模式了,比如一张存储卡上的图片地址可能描述为:/mnt/sdcard/images/1.jpg。其实这个路径存储在images表格中的data字段中,有了这点关联,我们可以在这两种模式下进行任意切换。

前一种模式下,主要通过MediaStore.Images.Media、MediaStore.Audio.Media、MediaStore.Video.Media三个库中的query方法来查询或者获取特定条件的媒体了。

基本用法1:从一个Content Uri地址中生成Bitmap

可以采用android.provider.MediaStore.Images.Media.getBitmap(ContentResolvercr,Uriurl)方法,其中ContentResolver是应用与资源之间的衔接人,它的示例通常可以通过在Activity中调用的getContentResolver()方法中获取。Uri地址就是上面描述的content://media/external/images/media/2类似地址,也就是Content Provider定义的地址形式。

基本用法2:从一个传统地址中生成Bitmap

有时候我们只知道一张图片的路径,并不知道图片的内部地址,想去获取该图片,可以采用android.graphics.BitmapFactory中的decodeXXX方法来搞定,比如decodeFile方法就是从文件路径中读取图片,原图片可以支持jpg,png,gif,bmp等各种格式。decodeByteArray就是从字节流中解码了。最后都是转换成Bitmap格式。

基本用法3:获取一张图片的缩略图

有时候我们需要显示图片的缩略图,可以采用android.provider.MediaStore.Images.Thumbnails的getThumbnail方法。另外其实也可以采用bitmap的compress的方法对图片进行一些压缩处理。

发现一个诡异的问题 求解

jiangkaifang 回复了问题 • 3 人关注 • 1 个回复 • 2530 次浏览 • 2015-12-21 11:28 • 来自相关话题

分享一个自己写的android手机监控软件

myxf 发表了文章 • 0 个评论 • 1551 次浏览 • 2015-12-16 16:16 • 来自相关话题

附件里有两个app,一个是监控程序一个是安装程序,为什么要有安装程序?因为android4.1之后如果该app从未运行过就无法接受广播也就不能自动启动所以,给个安装程序手动运行一次就可以了。
 
监控程序开机自动启动,如果被强制关闭也可以在接电话或短信时再启动,无桌面图标,完全无痕运行,可自动拦截通话记录、来往短信、实时定位、电话录音、获取通讯录、手机换卡自动通知,获取到数据后自动post上传自后台服务,自己写个服务端接受即可。
 
原来还想加个自动开启摄像头呢,没时间做就放弃了。
  查看全部
附件里有两个app,一个是监控程序一个是安装程序,为什么要有安装程序?因为android4.1之后如果该app从未运行过就无法接受广播也就不能自动启动所以,给个安装程序手动运行一次就可以了。
 
监控程序开机自动启动,如果被强制关闭也可以在接电话或短信时再启动,无桌面图标,完全无痕运行,可自动拦截通话记录、来往短信、实时定位、电话录音、获取通讯录、手机换卡自动通知,获取到数据后自动post上传自后台服务,自己写个服务端接受即可。
 
原来还想加个自动开启摄像头呢,没时间做就放弃了。
 

关于高德地图一个很扯淡的问题

jiangkaifang 发表了文章 • 0 个评论 • 1489 次浏览 • 2015-12-16 15:53 • 来自相关话题

  不想多说,就是想告诉朋友们如果在使用高德地图sdk的时候遇到部分城市不显示建筑物、道路等问题,千万别淡定!没错,高德地图就是这么扯淡,客户直接回应说正在积极解决问题,时间未知!反正本人的最终解决方案是更换sdk
  不想多说,就是想告诉朋友们如果在使用高德地图sdk的时候遇到部分城市不显示建筑物、道路等问题,千万别淡定!没错,高德地图就是这么扯淡,客户直接回应说正在积极解决问题,时间未知!反正本人的最终解决方案是更换sdk

一个识别刷卡器数据的android源码给你

myxf 发表了文章 • 0 个评论 • 1458 次浏览 • 2015-12-16 11:28 • 来自相关话题

以前做过的项目,需要读取银行卡里的磁条信息,就开发了一个demo用来读取刷卡器的信息,一次识别率90%以上,自己测试的pos刷卡器是乐刷的,一般只要刷卡器没有加密过都可以识别出来,源码已经放在附件了。
以前做过的项目,需要读取银行卡里的磁条信息,就开发了一个demo用来读取刷卡器的信息,一次识别率90%以上,自己测试的pos刷卡器是乐刷的,一般只要刷卡器没有加密过都可以识别出来,源码已经放在附件了。

关于ios开发html5应用时点击延迟的解决方案

myxf 发表了文章 • 0 个评论 • 3066 次浏览 • 2015-12-14 16:04 • 来自相关话题

不管在移动端还是PC端,我们都需要处理用户点击,这个最常用的事件。但在touch端click事件响应速度会比较慢,在较老的手机设备上会更为明显(300ms的延迟)。

[移动端click事件延迟300ms到底是怎么回事,该如何解决?]

问题由来 

这要追溯至 2007 年初。苹果公司在发布首款 iPhone 前夕,遇到一个问题:当时的网站都是为大屏幕设备所设计的。于是苹果的工程师们做了一些约定,应对 iPhone 这种小屏幕浏览桌面端站点的问题。 

这当中最出名的,当属双击缩放(double tap to zoom),这也是会有上述 300 毫秒延迟的主要原因。双击缩放,顾名思义,即用手指在屏幕上快速点击两次,iOS 自带的 Safari 浏览器会将网页缩放至原始比例。 

那么这和 300 毫秒延迟有什么联系呢? 

假定这么一个场景。用户在 iOS Safari 里边点击了一个链接。由于用户可以进行双击缩放或者双击滚动的操作,当用户一次点击屏幕之后,浏览器并不能立刻判断用户是确实要打开这个链接,还是想要进行双击操作。因此,iOS Safari 就等待 300 毫秒,以判断用户是否再次点击了屏幕。 

鉴于iPhone的成功,其他移动浏览器都复制了 iPhone Safari 浏览器的多数约定,包括双击缩放,几乎现在所有的移动端浏览器都有这个功能。之前人们刚刚接触移动端的页面,在欣喜的时候往往不会care这个300ms的延时问题,可是如今touch端界面如雨后春笋,用户对体验的要求也更高,这300ms带来的卡顿慢慢变得让人难以接受。

那么我们该如何解决这个问题,可能有的同学会想到touchstart事件,这个事件响应速度很快啊,如果说开发的界面上面可点击的地方很少,要么用户滑动下手指就触发touchstart事件,也会让人崩溃的。大家可以参考如下的几种方法。

粗暴型:禁用缩放 
<meta name="viewport" content="width=device-width, user-scalable=no"> 关键是 user-scalable = no。 这个属于简单粗暴型的,虽然看似完美,但有一个致命的缺陷,当你必须完全禁用缩放来达到目的时候,就傻眼了,只有特定场景下的交互界面,此方案才可行,其它大多数情况,此法都不可行。 另外:Chrome 开发团队不久前宣布,在 Chrome 32 这一版中,他们将在包含 width=device-width 或者置为比 viewport 值更小的页面上禁用双击缩放。当然,没有双击缩放就没有 300 毫秒点击延迟。

指针事件 (Pointer Events) 

指针事件最初由微软提出,现已进入 W3C 规范的候选推荐标准阶段 (Candidate Recommendation)。这个草案规范旨在使用一个单独的事件模型,对所有输入类型,包括鼠标 (mouse)、触摸 (touch)、触控 (stylus) 等,进行统一的处理。 

比如用css设置-ms-touch-action: none,那么对应的元素在被点击之后,浏览器不会启动缩放操作,也就避免了这个300ms延迟,但目前只有IE10+支持,目前touch开发的重点在safari和chrome,因此你懂的,此方案目前兼容性不好,不过chrome表示会在未来版本中支持的。

指针事件 (使非IE也支持) 

上面也说道touch-action: none是一个办法,那么其它浏览器不支持怎么办呢?下面的几个类库是关于这方面的,感兴趣的可以去研究下: 

1.Google的Polymer
2.微软的 HandJS
3.@Rich-Harris 的 Points

touch-action: none这种方案虽然可以解决这个问题,但影响的面比较广,不是单纯的来解决300ms延时问题的,有可能会带来性能和其它操作上的隐患,慎用。

FastClick:闪亮登场 

FastClick是FT Labs专门为解决移动端浏览器 300 毫秒点击延迟问题所开发的一个轻量级的库。简而言之,FastClick 在检测到 touchend 事件的时候,会通过 DOM 自定义事件立即触发一个模拟 click 事件,并把浏览器在 300 毫秒之后真正触发的click事件阻止掉。 

FastClick 的使用方法非常简单,在 window load 事件之后,在body上调用FastClick.attach()即可。
window.addEventListener('load', function() {
FastClick.attach(document.body);
}, false); 
attach方法虽可在更具体的元素上调用,直接绑定到body上可以确保整个应用都能受益。当 FastClick 检测到当前页面使用meta设置了user-scalable=no或者 touch-action 属性的解决方案时,会静默退出。可以说,这是真正的跨平台方案出来之前一种很好的变通方案。 

就目前而言,FastClick 非常实际地解决 300 毫秒点击延迟的问题,唯一的缺点可能也就是该脚本的文件尺寸 (尽管它只有10kb)。如果你连这10kb都接受不了的话,那么移动端类库 jQuery和zepto.js都支持tap事件来解决这个问题,尽管它们的响应速度比FastClick慢一些。

正是因为有这些解决方案,那么首先还是挑选眼前更合适的吧,毕竟以后会不会出新标准来解决这个问题,谁都不知道,理论上来说FastClick也是属于替代方案,希望有一天touch 端的开发可以不走pc的路,让本来都苦逼的前端雪上加霜。 查看全部
不管在移动端还是PC端,我们都需要处理用户点击,这个最常用的事件。但在touch端click事件响应速度会比较慢,在较老的手机设备上会更为明显(300ms的延迟)。

[移动端click事件延迟300ms到底是怎么回事,该如何解决?]

问题由来 

这要追溯至 2007 年初。苹果公司在发布首款 iPhone 前夕,遇到一个问题:当时的网站都是为大屏幕设备所设计的。于是苹果的工程师们做了一些约定,应对 iPhone 这种小屏幕浏览桌面端站点的问题。 

这当中最出名的,当属双击缩放(double tap to zoom),这也是会有上述 300 毫秒延迟的主要原因。双击缩放,顾名思义,即用手指在屏幕上快速点击两次,iOS 自带的 Safari 浏览器会将网页缩放至原始比例。 

那么这和 300 毫秒延迟有什么联系呢? 

假定这么一个场景。用户在 iOS Safari 里边点击了一个链接。由于用户可以进行双击缩放或者双击滚动的操作,当用户一次点击屏幕之后,浏览器并不能立刻判断用户是确实要打开这个链接,还是想要进行双击操作。因此,iOS Safari 就等待 300 毫秒,以判断用户是否再次点击了屏幕。 

鉴于iPhone的成功,其他移动浏览器都复制了 iPhone Safari 浏览器的多数约定,包括双击缩放,几乎现在所有的移动端浏览器都有这个功能。之前人们刚刚接触移动端的页面,在欣喜的时候往往不会care这个300ms的延时问题,可是如今touch端界面如雨后春笋,用户对体验的要求也更高,这300ms带来的卡顿慢慢变得让人难以接受。

那么我们该如何解决这个问题,可能有的同学会想到touchstart事件,这个事件响应速度很快啊,如果说开发的界面上面可点击的地方很少,要么用户滑动下手指就触发touchstart事件,也会让人崩溃的。大家可以参考如下的几种方法。

粗暴型:禁用缩放 
<meta name="viewport" content="width=device-width, user-scalable=no"> 关键是 user-scalable = no。 这个属于简单粗暴型的,虽然看似完美,但有一个致命的缺陷,当你必须完全禁用缩放来达到目的时候,就傻眼了,只有特定场景下的交互界面,此方案才可行,其它大多数情况,此法都不可行。 另外:Chrome 开发团队不久前宣布,在 Chrome 32 这一版中,他们将在包含 width=device-width 或者置为比 viewport 值更小的页面上禁用双击缩放。当然,没有双击缩放就没有 300 毫秒点击延迟。

指针事件 (Pointer Events) 

指针事件最初由微软提出,现已进入 W3C 规范的候选推荐标准阶段 (Candidate Recommendation)。这个草案规范旨在使用一个单独的事件模型,对所有输入类型,包括鼠标 (mouse)、触摸 (touch)、触控 (stylus) 等,进行统一的处理。 

比如用css设置-ms-touch-action: none,那么对应的元素在被点击之后,浏览器不会启动缩放操作,也就避免了这个300ms延迟,但目前只有IE10+支持,目前touch开发的重点在safari和chrome,因此你懂的,此方案目前兼容性不好,不过chrome表示会在未来版本中支持的。

指针事件 (使非IE也支持) 

上面也说道touch-action: none是一个办法,那么其它浏览器不支持怎么办呢?下面的几个类库是关于这方面的,感兴趣的可以去研究下: 

1.Google的Polymer
2.微软的 HandJS
3.@Rich-Harris 的 Points

touch-action: none这种方案虽然可以解决这个问题,但影响的面比较广,不是单纯的来解决300ms延时问题的,有可能会带来性能和其它操作上的隐患,慎用。

FastClick:闪亮登场 

FastClick是FT Labs专门为解决移动端浏览器 300 毫秒点击延迟问题所开发的一个轻量级的库。简而言之,FastClick 在检测到 touchend 事件的时候,会通过 DOM 自定义事件立即触发一个模拟 click 事件,并把浏览器在 300 毫秒之后真正触发的click事件阻止掉。 

FastClick 的使用方法非常简单,在 window load 事件之后,在body上调用FastClick.attach()即可。
window.addEventListener('load', function() {
FastClick.attach(document.body);
}, false);
 
attach方法虽可在更具体的元素上调用,直接绑定到body上可以确保整个应用都能受益。当 FastClick 检测到当前页面使用meta设置了user-scalable=no或者 touch-action 属性的解决方案时,会静默退出。可以说,这是真正的跨平台方案出来之前一种很好的变通方案。 

就目前而言,FastClick 非常实际地解决 300 毫秒点击延迟的问题,唯一的缺点可能也就是该脚本的文件尺寸 (尽管它只有10kb)。如果你连这10kb都接受不了的话,那么移动端类库 jQuery和zepto.js都支持tap事件来解决这个问题,尽管它们的响应速度比FastClick慢一些。

正是因为有这些解决方案,那么首先还是挑选眼前更合适的吧,毕竟以后会不会出新标准来解决这个问题,谁都不知道,理论上来说FastClick也是属于替代方案,希望有一天touch 端的开发可以不走pc的路,让本来都苦逼的前端雪上加霜。

关于使用手机做网络摄像头的研究

myxf 发表了文章 • 0 个评论 • 1227 次浏览 • 2015-12-14 15:57 • 来自相关话题

最近家里来了一个恶魔小金毛,简直是个拆迁大队队长有木有,于是乎就想知道再我上班的时间里这家伙究竟都在做些什么,就想着弄个监控摄像头,又不想花钱买啊,想到自己有一堆android平板没用,就想着能不能用手机当做网络摄像头试试传输观看呢?
 
于是乎先构想一下需求,首先家里是路由器属于内网,公司也是内网,任何传输方式都不能解决同时内网,所以就得有个服务端,就变成摄像客户端+服务器端+操作客户端。
 
第一步先解决摄像客户端,也就是app开发啦,调用摄像头将获取的数据实时保存成图片,一张图5M多太恐怖,就压缩然后修改像素,最终压缩到20KB以内,然后socket传送给服务器,服务器在转发给客户端,但在实际应用中发现这样操作丢包太大,最后实在没有办法,就将上传改成http协议,将截取的图片post到服务器保存,然后客户端不停的读取图片,最终成形,不过延迟还是很大啊,好歹还是能看了。
 
源码放附件了,服务端和客户端使用易语言编写,自己修改socket和post地址 查看全部
最近家里来了一个恶魔小金毛,简直是个拆迁大队队长有木有,于是乎就想知道再我上班的时间里这家伙究竟都在做些什么,就想着弄个监控摄像头,又不想花钱买啊,想到自己有一堆android平板没用,就想着能不能用手机当做网络摄像头试试传输观看呢?
 
于是乎先构想一下需求,首先家里是路由器属于内网,公司也是内网,任何传输方式都不能解决同时内网,所以就得有个服务端,就变成摄像客户端+服务器端+操作客户端。
 
第一步先解决摄像客户端,也就是app开发啦,调用摄像头将获取的数据实时保存成图片,一张图5M多太恐怖,就压缩然后修改像素,最终压缩到20KB以内,然后socket传送给服务器,服务器在转发给客户端,但在实际应用中发现这样操作丢包太大,最后实在没有办法,就将上传改成http协议,将截取的图片post到服务器保存,然后客户端不停的读取图片,最终成形,不过延迟还是很大啊,好歹还是能看了。
 
源码放附件了,服务端和客户端使用易语言编写,自己修改socket和post地址

关于微信运动数据获取的研究

myxf 发表了文章 • 6 个评论 • 7593 次浏览 • 2015-12-14 15:30 • 来自相关话题

最近因公司需求,要做一个微信里的html5应用,要求读取微信运动的步数数据,做数据分析与排行,个人中心、邀请好友pk和排行榜都好做,关键在于如何读取微信运行中的步数数据,研究了一下微信开放平台并没有相关的接口。

这样看来就只有自己想办法获取了,首先对微信客户端进行抓包,发现微信运动的界面是原生的,数据也是加密后的直接放弃解码,那究竟要怎么获取呢?

继续研究发现个人主页是可以分享给好友的,而分享出来的东西是一个url连接,打开是一个网页,这个就可以搞了,网页中的东东你不可能加密了吧,于是乎抓包获取地址:https://hw.weixin.qq.com/steprank/step/personal?openid=o95gOt4sls1KHY6KWvpTrFSqfCpU&fromShare=1&from=singlemessage&isappinstalled=0&pass_ticket=uIsL7ZQo5K8DBxRkgpuGmHXUk5%2BEf8b2C8%2B68Zi1eQY%3D

精简一下:https://hw.weixin.qq.com/steprank/step/personal?openid=o95gOt4sls1KHY6KWvpTrFSqfCpU 也可访问,源码中有想要的每日步数、最高纪录和总步数,在pc浏览器中直接打开是不行的需要微信登录,于是使用pc端的微信客户端打开链接:https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx7fa037cc7dfabad5&redirect_uri=http%3A%2F%2Fhw.weixin.qq.com%2Fsteprank%2Foauth%3Freturnurl%3Dhttp%253A%252F%252Fhw.weixin.qq.com%252Fsteprank%252Fstep%252Fpersonal%253Fopenid%253Do95gOt4sls1KHY6KWvpTrFSqfCpU%2526fromShare%253D1%2526from%253Dsinglemessage%2526isappinstalled%253D0%2526pass_ticket2%253DuIsL7ZQo5K8DBxRkgpuGmHXUk5%25252BEf8b2C8%25252B68Zi1eQY%25253D%26env%3D&response_type=code&scope=snsapi_base&state=8n8o-EO5FdgVe433j_4vPg&connect_redirect=1#wechat_redirect
可以正常访问,这里我们需要获取微信返回的code值,拿到这个数据就可以在pc版的浏览器中访问了,那究竟怎么获取的呢?

很简单修改一下返回url:redirect_uri url解密后:http://hw.weixin.qq.com/steprank/oauth?returnurl=http%3A%2F%2Fhw.weixin.qq.com%2Fsteprank%2Fstep%2Fpersonal%3Fopenid%3Do95gOt4sls1KHY6KWvpTrFSqfCpU%26fromShare%3D1%26from%3Dsinglemessage%26isappinstalled%3D0%26pass_ticket2%3DuIsL7ZQo5K8DBxRkgpuGmHXUk5%252BEf8b2C8%252B68Zi1eQY%253D&env=  returnurl就是微信登录验证后返回的地址,这里我们需要对url进行一点修改,首先微信登录的返回url必须在后台绑定也就是hw.weixin.qq.com这个域名是不能变的,但我们可以修改hosts文件重定向到我们本机上来,然后修改urlhttp://hw.weixin.qq.com/get.php?returnurl=http%3A%2F%2Fhw.weixin.qq.com%2Fsteprank%2Fstep%2Fpersonal%3Fopenid%3Do95gOt4sls1KHY6KWvpTrFSqfCpU%26fromShare%3D1%26from%3Dsinglemessage%26isappinstalled%3D0%26pass_ticket2%3DuIsL7ZQo5K8DBxRkgpuGmHXUk5%252BEf8b2C8%252B68Zi1eQY%253D&env=
 
写一个get.php获取返回个get参数,然后再通过微信客户端访问就可以输出微信返回的登录参数,再将修改的hosts文件注释,加上得到的返回参数访问http://hw.weixin.qq.com/steprank/oauth 就可以获得服务器输出的两个cookie hwstepranksk和pass_ticket 有了这两个cooke就可以通过浏览器正常访问:https://hw.weixin.qq.com/steprank/step/personal?openid=o95gOt4sls1KHY6KWvpTrFSqfCpU 获取步数了openid这个参数就是用户的id如果为空就读取自己本身的,可只能读取自己可不行,那其他用户的openid要怎么获取呢?

很简单了,当朋友通过微信运动主页分享给你的时候就会携带有当前用户openid的url,现在的问题是怎么自动读取到这个信息呢?

第一个想到的就是聊天记录,可惜分析了微信客户端数据库后发现数据库也是加密的,那要怎么样才能获取到这个url数据呢?于是乎想到了微信网页版,于是分析了微信网页版的源码,发现是socket通讯协议,当检查到有新消息后会触发js进行处理,如果能拦截到回调的js就好办了,当时就行通过brup拦截包修改指定的js文件:https://res.wx.qq.com/zh_CN/htmledition/v2/js/webwxApp28a2f7.js 在回调的function中加入自己的js代码,可这个方案还是太麻烦,有什么更好地方案吗?答案当然是有,还是修改hosts文件啦,将res.wx.qq.com调用的资源文件全部下载到自己的服务器上,然后修改webwxApp28a2f7.js 加上自己的代码,然后将res.wx.qq.com 定向到自己的服务器上,由于是https协议端口是443所以自己的服务器也必须是https,申请一个ssl即可,这样打开wx.qq.com 正常登录信息也可以正常回调也就会触发我们写的代码

webwxApp28a2f7.js 查找 calcMsgDisplayTime 增加一行代码输出url





这样有新消息的时候就会触发alert 输出url信息,只要在这里判断url中是否包含:https://hw.weixin.qq.com/steprank/step/personal 就截取出openid 然后构造一个iframe或者script 就可以将openid传回处理,有了openid就可以获取该用户的步数信息了。
 
总结的步奏是:
1.申请一个新的微信号;
2.使用新微信号通过微信pc客户端获取cookie值hwstepranksk和pass_ticket;
3.凡事参加活动的用户必须加这个微信号为好友,并将自己的微信运动主页分享到这个微信号中,只分享一次即可;
4.通过微信版微信获取分享的openid传到数据库中记录
5.写个php程序通过curl 附加cookie 轮询数据库中的openid主页获取微信步数
6.有了微信步数的数据就可以进行许多活动了。
 










  查看全部
最近因公司需求,要做一个微信里的html5应用,要求读取微信运动的步数数据,做数据分析与排行,个人中心、邀请好友pk和排行榜都好做,关键在于如何读取微信运行中的步数数据,研究了一下微信开放平台并没有相关的接口。

这样看来就只有自己想办法获取了,首先对微信客户端进行抓包,发现微信运动的界面是原生的,数据也是加密后的直接放弃解码,那究竟要怎么获取呢?

继续研究发现个人主页是可以分享给好友的,而分享出来的东西是一个url连接,打开是一个网页,这个就可以搞了,网页中的东东你不可能加密了吧,于是乎抓包获取地址:https://hw.weixin.qq.com/steprank/step/personal?openid=o95gOt4sls1KHY6KWvpTrFSqfCpU&fromShare=1&from=singlemessage&isappinstalled=0&pass_ticket=uIsL7ZQo5K8DBxRkgpuGmHXUk5%2BEf8b2C8%2B68Zi1eQY%3D

精简一下:https://hw.weixin.qq.com/steprank/step/personal?openid=o95gOt4sls1KHY6KWvpTrFSqfCpU 也可访问,源码中有想要的每日步数、最高纪录和总步数,在pc浏览器中直接打开是不行的需要微信登录,于是使用pc端的微信客户端打开链接:https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx7fa037cc7dfabad5&redirect_uri=http%3A%2F%2Fhw.weixin.qq.com%2Fsteprank%2Foauth%3Freturnurl%3Dhttp%253A%252F%252Fhw.weixin.qq.com%252Fsteprank%252Fstep%252Fpersonal%253Fopenid%253Do95gOt4sls1KHY6KWvpTrFSqfCpU%2526fromShare%253D1%2526from%253Dsinglemessage%2526isappinstalled%253D0%2526pass_ticket2%253DuIsL7ZQo5K8DBxRkgpuGmHXUk5%25252BEf8b2C8%25252B68Zi1eQY%25253D%26env%3D&response_type=code&scope=snsapi_base&state=8n8o-EO5FdgVe433j_4vPg&connect_redirect=1#wechat_redirect
可以正常访问,这里我们需要获取微信返回的code值,拿到这个数据就可以在pc版的浏览器中访问了,那究竟怎么获取的呢?

很简单修改一下返回url:redirect_uri url解密后:http://hw.weixin.qq.com/steprank/oauth?returnurl=http%3A%2F%2Fhw.weixin.qq.com%2Fsteprank%2Fstep%2Fpersonal%3Fopenid%3Do95gOt4sls1KHY6KWvpTrFSqfCpU%26fromShare%3D1%26from%3Dsinglemessage%26isappinstalled%3D0%26pass_ticket2%3DuIsL7ZQo5K8DBxRkgpuGmHXUk5%252BEf8b2C8%252B68Zi1eQY%253D&env=  returnurl就是微信登录验证后返回的地址,这里我们需要对url进行一点修改,首先微信登录的返回url必须在后台绑定也就是hw.weixin.qq.com这个域名是不能变的,但我们可以修改hosts文件重定向到我们本机上来,然后修改urlhttp://hw.weixin.qq.com/get.php?returnurl=http%3A%2F%2Fhw.weixin.qq.com%2Fsteprank%2Fstep%2Fpersonal%3Fopenid%3Do95gOt4sls1KHY6KWvpTrFSqfCpU%26fromShare%3D1%26from%3Dsinglemessage%26isappinstalled%3D0%26pass_ticket2%3DuIsL7ZQo5K8DBxRkgpuGmHXUk5%252BEf8b2C8%252B68Zi1eQY%253D&env=
 
写一个get.php获取返回个get参数,然后再通过微信客户端访问就可以输出微信返回的登录参数,再将修改的hosts文件注释,加上得到的返回参数访问http://hw.weixin.qq.com/steprank/oauth 就可以获得服务器输出的两个cookie hwstepranksk和pass_ticket 有了这两个cooke就可以通过浏览器正常访问:https://hw.weixin.qq.com/steprank/step/personal?openid=o95gOt4sls1KHY6KWvpTrFSqfCpU 获取步数了openid这个参数就是用户的id如果为空就读取自己本身的,可只能读取自己可不行,那其他用户的openid要怎么获取呢?

很简单了,当朋友通过微信运动主页分享给你的时候就会携带有当前用户openid的url,现在的问题是怎么自动读取到这个信息呢?

第一个想到的就是聊天记录,可惜分析了微信客户端数据库后发现数据库也是加密的,那要怎么样才能获取到这个url数据呢?于是乎想到了微信网页版,于是分析了微信网页版的源码,发现是socket通讯协议,当检查到有新消息后会触发js进行处理,如果能拦截到回调的js就好办了,当时就行通过brup拦截包修改指定的js文件:https://res.wx.qq.com/zh_CN/htmledition/v2/js/webwxApp28a2f7.js 在回调的function中加入自己的js代码,可这个方案还是太麻烦,有什么更好地方案吗?答案当然是有,还是修改hosts文件啦,将res.wx.qq.com调用的资源文件全部下载到自己的服务器上,然后修改webwxApp28a2f7.js 加上自己的代码,然后将res.wx.qq.com 定向到自己的服务器上,由于是https协议端口是443所以自己的服务器也必须是https,申请一个ssl即可,这样打开wx.qq.com 正常登录信息也可以正常回调也就会触发我们写的代码

webwxApp28a2f7.js 查找 calcMsgDisplayTime 增加一行代码输出url
QQ截图20151214152311.png


这样有新消息的时候就会触发alert 输出url信息,只要在这里判断url中是否包含:https://hw.weixin.qq.com/steprank/step/personal 就截取出openid 然后构造一个iframe或者script 就可以将openid传回处理,有了openid就可以获取该用户的步数信息了。
 
总结的步奏是:
1.申请一个新的微信号;
2.使用新微信号通过微信pc客户端获取cookie值hwstepranksk和pass_ticket;
3.凡事参加活动的用户必须加这个微信号为好友,并将自己的微信运动主页分享到这个微信号中,只分享一次即可;
4.通过微信版微信获取分享的openid传到数据库中记录
5.写个php程序通过curl 附加cookie 轮询数据库中的openid主页获取微信步数
6.有了微信步数的数据就可以进行许多活动了。
 

QQ截图20151214153011.png


QQ截图20151214153335.png

 

php Yaf框架持续更新

myxf 发表了文章 • 0 个评论 • 1820 次浏览 • 2015-12-10 17:18 • 来自相关话题

自己整理、完善的yaf框架,使用smarty模板引擎,修改了models层,增加许多扩展类比如邮件、上传等https://git.oschina.net/mayoushang/yaf
自己整理、完善的yaf框架,使用smarty模板引擎,修改了models层,增加许多扩展类比如邮件、上传等https://git.oschina.net/mayoushang/yaf