Android 小黄车扫描ios 二维码扫描框架用的啥框架

&>&Android最好用的二维码扫描Demo
Android最好用的二维码扫描Demo
上传大小:1.59MB
最好用的二维码扫描demo,可以自己更改扫描框大小,和扫描线上下扫描的速度,扫描速度快,注释清晰代码简单易懂
综合评分:3
下载个数:
{%username%}回复{%com_username%}{%time%}\
/*点击出现回复框*/
$(".respond_btn").on("click", function (e) {
$(this).parents(".rightLi").children(".respond_box").show();
e.stopPropagation();
$(".cancel_res").on("click", function (e) {
$(this).parents(".res_b").siblings(".res_area").val("");
$(this).parents(".respond_box").hide();
e.stopPropagation();
/*删除评论*/
$(".del_comment_c").on("click", function (e) {
var id = $(e.target).attr("id");
$.getJSON('/index.php/comment/do_invalid/' + id,
function (data) {
if (data.succ == 1) {
$(e.target).parents(".conLi").remove();
alert(data.msg);
$(".res_btn").click(function (e) {
var parentWrap = $(this).parents(".respond_box"),
q = parentWrap.find(".form1").serializeArray(),
resStr = $.trim(parentWrap.find(".res_area_r").val());
console.log(q);
//var res_area_r = $.trim($(".res_area_r").val());
if (resStr == '') {
$(".res_text").css({color: "red"});
$.post("/index.php/comment/do_comment_reply/", q,
function (data) {
if (data.succ == 1) {
var $target,
evt = e || window.
$target = $(evt.target || evt.srcElement);
var $dd = $target.parents('dd');
var $wrapReply = $dd.find('.respond_box');
console.log($wrapReply);
//var mess = $(".res_area_r").val();
var mess = resS
var str = str.replace(/{%header%}/g, data.header)
.replace(/{%href%}/g, 'http://' + window.location.host + '/user/' + data.username)
.replace(/{%username%}/g, data.username)
.replace(/{%com_username%}/g, data.com_username)
.replace(/{%time%}/g, data.time)
.replace(/{%id%}/g, data.id)
.replace(/{%mess%}/g, mess);
$dd.after(str);
$(".respond_box").hide();
$(".res_area_r").val("");
$(".res_area").val("");
$wrapReply.hide();
alert(data.msg);
}, "json");
/*删除回复*/
$(".rightLi").on("click", '.del_comment_r', function (e) {
var id = $(e.target).attr("id");
$.getJSON('/index.php/comment/do_comment_del/' + id,
function (data) {
if (data.succ == 1) {
$(e.target).parent().parent().parent().parent().parent().remove();
$(e.target).parents('.res_list').remove()
alert(data.msg);
//填充回复
function KeyP(v) {
var parentWrap = $(v).parents(".respond_box");
parentWrap.find(".res_area_r").val($.trim(parentWrap.find(".res_area").val()));
评论共有11条
哇,坑爹,扫描电脑上的二维码扫描不出来
Nice!兄dei~
东西不错 可以下载
下雪吃西瓜
综合评分:
积分/C币:11
综合评分:
积分/C币:13
下雪吃西瓜
综合评分:
积分/C币:11
综合评分:
积分/C币:3
VIP会员动态
CSDN下载频道资源及相关规则调整公告V11.10
下载频道用户反馈专区
下载频道积分规则调整V1710.18
spring mvc+mybatis+mysql+maven+bootstrap 整合实现增删查改简单实例.zip
资源所需积分/C币
当前拥有积分
当前拥有C币
输入下载码
为了良好体验,不建议使用迅雷下载
Android最好用的二维码扫描Demo
会员到期时间:
剩余下载个数:
剩余积分:0
为了良好体验,不建议使用迅雷下载
积分不足!
资源所需积分/C币
当前拥有积分
您可以选择
程序员的必选
绿色安全资源
资源所需积分/C币
当前拥有积分
当前拥有C币
为了良好体验,不建议使用迅雷下载
资源所需积分/C币
当前拥有积分
当前拥有C币
为了良好体验,不建议使用迅雷下载
资源所需积分/C币
当前拥有积分
当前拥有C币
您的积分不足,将扣除 10 C币
为了良好体验,不建议使用迅雷下载
无法举报自己的资源
你当前的下载分为234。
你还不是VIP会员
开通VIP会员权限,免积分下载
你下载资源过于频繁,请输入验证码
您因违反CSDN下载频道规则而被锁定帐户,如有疑问,请联络:!
若举报审核通过,可返还被扣除的积分
被举报人:
举报的资源分:
请选择类型
资源无法下载 ( 404页面、下载失败、资源本身问题)
资源无法使用 (文件损坏、内容缺失、题文不符)
侵犯版权资源 (侵犯公司或个人版权)
虚假资源 (恶意欺诈、刷分资源)
含色情、危害国家安全内容
含广告、木马病毒资源
*详细原因:
Android最好用的二维码扫描Demo在 SegmentFault,学习技能、解决问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。
标签:至少1个,最多5个
哎呀呀,在杭州2015 Hackthon的现场,因为没有二维码签到功能,被吐槽low!这是我近期最丢脸的事啦~于是回来就开始着手开发二维码相关的东西了。
一搜索Google和我们SegmentFault,发现在Android上,Google的zxing这个二维码的库比较受欢迎,好,那就是它了(我就是这么任性= =)
OK,看下zxing这个项目好像非常大啊,如何快速用起来呢?
简化的话,带来的副作用就是适用性降低,比如在这个场景里面,我们不考虑横屏的情况,不考虑对摄像头进行过多的配置,不存在截图。
我们看下这个项目有一个android目录,它里面其实就是条码扫描器这个app的开源代码,因为我们暂时不需要深究它是如何进行图像识别,如何帮我们从图像里解析出二维码的,所以我们就不研究core相关的内容(但是里面都是干货啊!图像识别的干货啊!)
我们最主要就是参考这个里面的源码啦。
先把整个项目clone下来,然后把android这个源码导入到Android Studio里面去,经过小小的配置,就能搞定啦,直接运行我们就能看见这个App了。
先看下我们要做的工作是啥:
对摄像头进行管理(为了兼容老设备,我们要用即将被Google舍弃的android.hardware.camera类)。
对获取的一帧图片进行解析。
对解析的结果进行处理。
如果不带着问题或者目的去看源码的话,会非常没头绪,所以我们一定要记得我们想要做什么。
OK,先看第一个问题,我们需要对摄像头进行管理。我们可以看到目录中有三个文件和摄像机有关
就是这三个文件啦。
CameraConfigurationManager
这个类主要用于对摄像头进行一些配置,包括旋转角度、预览图尺寸等等
CameraConfigurationUtils
工具类,在CameraConfigurationManager调用,
CameraManager
控制摄像头的生命周期,获取预览尺寸,生成原始数据发送给解析器
在这里,我把CameraConfigurationUtils拷贝过来,另外两个类合成到CameraManager里面,在初始化的时候,做好配置。
摄像头的管理(横屏改竖屏)
因为原先zxing给的demo是横屏的,这里要改成竖屏,就需要做几个配置。
getFramingRectInPreview
在getFramingRectInPreview这个函数中,cameraResolution和screenResolution方向不对,所以
rect.left = rect.left * cameraResolution.y / screenResolution.x;
rect.right = rect.right * cameraResolution.y / screenResolution.x;
rect.top = rect.top * cameraResolution.x / screenResolution.y;
rect.bottom = rect.bottom * cameraResolution.x / screenResolution.y;
这里需要把方向换一下。
binary data
还需要更改的地方,就是在获取帧预览中的原始数据,需要进行一个旋转,因为zxing原先是对横向的图片一行一行读取的,如果我们给予纵向的数据,就必须旋转数据,或者更改读取算法。 这里更改数据可能会更加方便,在buildLuminanceSource中,更改:
byte[] rotatedData = new byte[data.length];
for (int y = 0; y & y++) {
for (int x = 0; x & x++)
rotatedData[x * height + height - y - 1] = data[x + y * width];
最后记得把摄像头的预览旋转改成90°即可。
camera.setDisplayOrientation(90);
附上这部分代码(比较长)
public class CameraManager {
private static final int MIN_FRAME_WIDTH = 240;
private static final int MIN_FRAME_HEIGHT = 240;
// 这里修正扫描大小
private static final int MAX_FRAME_WIDTH = 675; // = 5/8 * 1920
private static final int MAX_FRAME_HEIGHT = 1200; // = 5/8 * 1080
private Context mC
private Point mScreenR
private Point mCameraR
private Point mBestPreviewS
private Point mPreviewSizeOnS
private Rect mFramingRectInP
private Rect mFramingR
private Camera mC
private PreviewCallback mPreviewC
private AutoFocusManager mAutoFocusM
public CameraManager(Context context) {
mContext =
mPreviewCallback = new PreviewCallback(this);
public void openDriver(Camera camera, SurfaceHolder holder) {
Camera.Parameters parameters = camera.getParameters();
CameraConfigurationUtils.setBarcodeSceneMode(parameters);
CameraConfigurationUtils.setFocus(parameters,
Point theScreenResolution = new Point();
Rect rect = holder.getSurfaceFrame();
theScreenResolution.set(rect.height(), rect.width());
mScreenResolution = theScreenR
mCameraResolution = CameraConfigurationUtils.findBestPreviewSizeValue(parameters, mScreenResolution);
mBestPreviewSize = CameraConfigurationUtils.findBestPreviewSizeValue(parameters, mScreenResolution);
boolean isScreenPortrait = mScreenResolution.x & mScreenResolution.y;
boolean isPreviewSizePortrait = mBestPreviewSize.x & mBestPreviewSize.y;
if (isScreenPortrait == isPreviewSizePortrait) {
mPreviewSizeOnScreen = mBestPreviewS
mPreviewSizeOnScreen = new Point(mBestPreviewSize.y, mBestPreviewSize.x);
parameters.setPreviewSize(mBestPreviewSize.x, mBestPreviewSize.y);
camera.setParameters(parameters);
camera.setDisplayOrientation(90);
Camera.Parameters afterParameters = camera.getParameters();
Camera.Size afterSize = afterParameters.getPreviewSize();
if (afterSize != null && (mBestPreviewSize.x != afterSize.width || mBestPreviewSize.y != afterSize.height)) {
mBestPreviewSize.x = afterSize.
mBestPreviewSize.y = afterSize.
public synchronized Rect getFramingRect() {
if (mFramingRect == null) {
Point screenResolution = mScreenR
if (screenResolution == null) {
// Called early, before init even finished
int width = findDesiredDimensionInRange(screenResolution.x, MIN_FRAME_WIDTH, MAX_FRAME_WIDTH);
int height = findDesiredDimensionInRange(screenResolution.y, MIN_FRAME_HEIGHT, MAX_FRAME_HEIGHT);
int leftOffset = (screenResolution.x - width) / 2;
int topOffset = (screenResolution.y - height) / 2;
mFramingRect = new Rect(leftOffset, topOffset, leftOffset + width, topOffset + height);
return mFramingR
public Point getCameraResolution() {
return mCameraR
public synchronized Rect getFramingRectInPreview() {
if (mFramingRectInPreview == null) {
Rect framingRect = getFramingRect();
if (framingRect == null) {
Rect rect = new Rect(framingRect);
Point cameraResolution = mCameraR
Point screenResolution = mScreenR
if (cameraResolution == null || screenResolution == null) {
// Called early, before init even finished
rect.left = rect.left * cameraResolution.y / screenResolution.x;
rect.right = rect.right * cameraResolution.y / screenResolution.x;
rect.top = rect.top * cameraResolution.x / screenResolution.y;
rect.bottom = rect.bottom * cameraResolution.x / screenResolution.y;
mFramingRectInPreview =
return mFramingRectInP
private static int findDesiredDimensionInRange(int resolution, int hardMin, int hardMax) {
int dim = 5 * resolution / 8; // Target 5/8 of each dimension
if (dim & hardMin) {
return hardM
if (dim & hardMax) {
return hardM
* A factory method to build the appropriate LuminanceSource object based on the format
* of the preview buffers, as described by Camera.Parameters.
* @param data A preview frame.
* @param width The width of the image.
* @param height The height of the image.
* @return A PlanarYUVLuminanceSource instance.
public PlanarYUVLuminanceSource buildLuminanceSource(byte[] data, int width, int height) {
Rect rect = getFramingRectInPreview();
if (rect == null) {
byte[] rotatedData = new byte[data.length];
for (int y = 0; y & y++) {
for (int x = 0; x & x++)
rotatedData[x * height + height - y - 1] = data[x + y * width];
// Go ahead and assume it's YUV rather than die.
return new PlanarYUVLuminanceSource(rotatedData, width, height, rect.left, rect.top,
rect.width(), rect.height(), false);
* A single preview frame will be returned to the handler supplied. The data will arrive as byte[]
* in the message.obj field, with width and height encoded as message.arg1 and message.arg2,
* respectively.
* @param handler The handler to send the message to.
* @param message The what field of the message to be sent.
public synchronized void requestPreviewFrame(Handler handler, int message) {
if (mCamera != null) {
mPreviewCallback.setHandler(handler, message);
mCamera.setOneShotPreviewCallback(mPreviewCallback);
public synchronized void startPreview() {
mCamera.startPreview();
mAutoFocusManager = new AutoFocusManager(mContext, mCamera);
public synchronized void stopPreview() {
if (mAutoFocusManager != null) {
mAutoFocusManager.stop();
mAutoFocusManager =
if (mCamera != null) {
mCamera.stopPreview();
mPreviewCallback.setHandler(null, 0);
public synchronized void closeDriver() {
mCamera.release();
获取图像数据
Camera提供这么一个函数:setOneShotPreviewCallback,看名字就知道,它是会在某个时间点,回调你给的接口,然后传入一个二进制的图像数组,让你去解析,这正是我们想要的东西,所以我们看下这个PreviewCallback,它只有一个函数,
public void onPreviewFrame(byte[] data, Camera camera) {
很显然,第一个参数就是图像数组了,我们看看zxing里面是怎么处理这个数据的。
public void onPreviewFrame(byte[] data, Camera camera) {
Point cameraResolution = mCameraManager.getCameraResolution();
Handler thePreviewHandler = mPreviewH
if (cameraResolution != null && thePreviewHandler != null) {
Message message = thePreviewHandler.obtainMessage(mPreviewMessage, cameraResolution.x,
cameraResolution.y, data);
message.sendToTarget();
mPreviewHandler =
zxing是发送到另外一个handler,也就是说,这个解析数据的过程比较浪费时间,所以要开线程来解决这个事。我们跟踪这个previewHanlder可以发现,它是一个DecodeHandler,其中有个重要的decode函数
private void decode(byte[] data, int width, int height) {
long start = System.currentTimeMillis();
Result rawResult =
PlanarYUVLuminanceSource source = activity.getCameraManager().buildLuminanceSource(data, width, height);
if (source != null) {
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
rawResult = multiFormatReader.decodeWithState(bitmap);
} catch (ReaderException re) {
// continue
} finally {
multiFormatReader.reset();
Handler handler = activity.getHandler();
if (rawResult != null) {
// Don't log the barcode contents for security.
long end = System.currentTimeMillis();
Log.d(TAG, "Found barcode in " + (end - start) + " ms");
if (handler != null) {
Message message = Message.obtain(handler, R.id.decode_succeeded, rawResult);
Bundle bundle = new Bundle();
bundleThumbnail(source, bundle);
message.setData(bundle);
message.sendToTarget();
if (handler != null) {
Message message = Message.obtain(handler, R.id.decode_failed);
message.sendToTarget();
这里用到我们刚刚重写的buildLuminanceSource这个函数了,可以理解这个函数是对我们的原始数据做一个包装,来给解析器读取。
解析器的配置我们可以看看DecodeThread这个类(专门用于解析图像的线程)
decodeFormats = EnumSet.noneOf(BarcodeFormat.class);
decodeFormats.addAll(DecodeFormatManager.PRODUCT_FORMATS);
decodeFormats.addAll(DecodeFormatManager.INDUSTRIAL_FORMATS);
decodeFormats.addAll(DecodeFormatManager.QR_CODE_FORMATS);
decodeFormats.addAll(DecodeFormatManager.DATA_MATRIX_FORMATS);
mHints.put(DecodeHintType.POSSIBLE_FORMATS, decodeFormats);
这里我们可以为我们的扫描器加更多格式的支持(比如条形码、二维码、XX码)
zxing是使用List来管理这些解析器,然后每次读取数据,都经过这些解析器过滤一遍,如果解析成功就有结果,否则就没有结果。
最后我们跟踪R.id.decode_success找到CaptureActivityHandler这里的handleMessage中有
case R.id.decode_succeeded:
state = State.SUCCESS;
Bundle bundle = message.getData();
Bitmap barcode =
float scaleFactor = 1.0f;
if (bundle != null) {
byte[] compressedBitmap = bundle.getByteArray(DecodeThread.BARCODE_BITMAP);
if (compressedBitmap != null) {
barcode = BitmapFactory.decodeByteArray(compressedBitmap, 0, compressedBitmap.length, null);
// Mutable copy:
barcode = barcode.copy(Bitmap.Config.ARGB_8888, true);
scaleFactor = bundle.getFloat(DecodeThread.BARCODE_SCALED_FACTOR);
activity.handleDecode((Result) message.obj, barcode, scaleFactor);
我们读取Result对象的text成员变量就是我们想要的二维码信息了!最后的工作当然是解析我们的二维码中的URI,然后进行后续的工作啦~
PS: 附带二维码扫描的SegmentFault for Android版本 即将上线!!
欢迎关注我 以及 、
4 收藏&&|&&53
你可能感兴趣的文章
5 收藏,5.1k
10 收藏,9.1k
前辈,能不能写一下是如何把android这个文件夹导入AS的,我导进去后提示一些依赖库不存在。把整个项目导进去后,识别为了一个JavaSe的工程。
前辈,能不能写一下是如何把android这个文件夹导入AS的,我导进去后提示一些依赖库不存在。把整个项目导进去后,识别为了一个JavaSe的工程。
来自3.0客户端
来自3.0客户端
core 和 androidcore 这两个目录有操作吗
core 和 androidcore 这两个目录有操作吗
分享到微博?
我要该,理由是:
在 SegmentFault,学习技能、解决问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。  小黄车罪孽啊,把这些不要脸的人硬是逼到了大街上丢人现眼,小黄不厚道
楼主发言:16次 发图: | 更多
  这些人等于在背上写着小偷两个字,我真的很佩服这些人,,,刚才中午想找辆共享单车,连着3辆都是涂掉二维码的,还有一个上了私锁
  楼主终于发了个正常贴  
  我真的很难理解,这些偷车的还明目张胆的到处骑的,这些人怎么对身边的亲朋好友怎么解释这个事情???  可能小孩有叛逆期,觉得这样叛逆,但那些成年人到底是怎么想的?是不是对世界绝望了?还是身边人都已经放弃自己了于是破罐子破摔?
  偷东西的见过,但偷完东西明目张胆死皮赖脸就在大街上展示赃物的,还真的没见过,小黄车让人见识了某些国人是没有底线的。
  前几天碰到个上私锁涂二维码的小黄,准备上去看看,后面一个当妈的带着十几岁的儿子出现了,说这是我的车,没有任何的不安和愧疚,我说这不是共享单车吗,她面不改色的说这是我骑过来的,  我说你怎么把码涂了还上私锁?她不吭声了,我说你真缺德啊,她支支吾吾,  很同情她儿子,在这种低劣的家庭生存。
  因为JC叔叔懒得管,真要抓的话,一抓一个准。现在的法律其实是利于恶人的。
  这个世界并不是只有马云王思聪,还有大把挣扎着生存的草民,可能这些人注定是社会运行中的炮灰和渣滓吧,,  这些人及其群体是不能碰的,最好远离,里面没有规则,只有互相碾压和厮杀。  让自己,和自己的亲人,远离这些人和群体。  看见得意洋洋骑着偷来的车满大街乱窜的成年人,这样的人,不管是谁,见一个拉黑一个,让他从此以后从你的眼界和生活里消失,就是对你自己最大的负责!
  这种人 我说句难听的 真希望他们骑出去的时候死掉  
  前天在沿河路散步,还看到河里有辆摩拜,不知道哪个缺德鬼的。
  我们小区门口的房产中介门口停的小黄不是涂掉了二维码的,就是上锁的,真是缺德。
  前几天出门,小区里3辆+路上看到2辆,压根没有一辆能骑的,硬生生走到目的地  
  能干出这事儿的,能有啥脸。
  这些偷车的人先不谈法律和道德,从智商上说,就是一些非常蠢的人  这明显是笔不划算的买卖嘛,为了几百元的便宜,满大街向人展示我是小偷????  所以说这些人注定穷困一辈子,,,必须的,这么明显的帐都算不过来,,,这说明他根本没打算利用自己的信用来谋生,  只有注定一辈子挣扎的人才会用几百元的财物把自己的信用卖的一干二净,这是个令人绝望的人和群体  他是你的父母,你不要指望他能帮你,他的所作所为已经表明他已经自绝于这个世界了,这就是个令人绝望的家庭,尽早独立吧  如果这些人是你的同事,远离他吧,他以后的路注定是狭窄和令人窒息的路,他的意见比放屁都不如,你只当他是透明的就可以了  在这样的人身上多停留一秒都是对你生命的不负责任!!
  这个支持楼主,有些人素质低到尘埃
  这些人以为占到了便宜,这种智商真的低到很可怕,能活到现在真的是奇迹,,,  等于满大街骑着车打广告,说我是小偷我是傻比,我是缺德的,我是警查下一个该抓的漏网之鱼  你想想,智商低到这种程度,且已经成年,还有时间和机会改吗???恐怕很难了  小黄车真是照妖镜啊,直接一条黄线,把社会上最low的群体现了原形,这些人还天天的满大街展示自己,哈哈哈哈哈
  等于小黄挖了个坑,看似占便宜,傻比纷纷掉坑里了哈哈哈哈,暴漏了令人恐怖和绝望的智商  这就是传说中的垃圾人啊,这回很清晰的标示出来了,,,各位逃命吧
  去南京看演唱会   跟朋友找小黄车   6辆有四辆是刮掉二维码的  然后当我在买荧光棒的时候 把车停在身后的时候  一个中年男子 居然偷我的车!!!!!  幸好我朋友面对我 跟我讲话抬头 看到了抓住了他  太尼玛恶心了 光天化日
小黄车都偷
  楼主这么正经我好不习惯啊
  我刚还见到把小黄车扛上电梯搬进家的,我真的想说,本来挺好的一件事情,给这些人糟蹋得都不好了!  
  许老师,这个话题不够争议性啊。不像上次许老师发的那个大学生脚踹熊孩子的帖子,那么热啊。还是要继续努力啊。
  @夜色摘星
14:56:23  我刚还见到把小黄车扛上电梯搬进家的,我真的想说,本来挺好的一件事情,给这些人糟蹋得都不好了!  -----------------------------  从另一个角度也是好事,就是清楚的让大家知道潜伏在大家中间的垃圾人是哪些人,违法+缺德+
,为大家指明了方向,这样的人以后就自生自灭吧
  还有乱停乱扔车辆的,有时候看到一些巷子口堆满了共享单车,开始可能是使用者贪方便,随意停车。可乱停放又挡了一些人的道,于是有人泄愤一样把单车乱七八糟地摔倒堆放在一起,好好的车被好像垃圾一样扔在那里被破坏,虽然不是自己的,看的也很难受。  但也是因为不是自己的,大多路人看到也就是看到,骂一句继续走,也不会有人扶一下,理一理。
  前天看到一个人骑着,二维码被挂掉了。想说,你就这么缺辆自行车?你缺的是德吧!
  菲菲呀,这次你真的好正,给你点赞哦
  特别鄙视将共享单车据为己有的渣渣
  —打酱油啦啦
  都是被人涂掉二维码,上私锁,或者损坏的,几十辆找得到一辆好的都算好了,太没素质和公德心了。              
  不要动辄说素质了。你能想到周围的人就想不到?背后有那么多的原因,资本的疯狂,垄断地位的争夺,新生事物配套的不完善,最主要,骑车是要付押金的好吗?知道这个资金池有多巨大吗?而且从这个点上说,除了不够共享不够环保外,私车化的行为跟小偷能画上等号?还有大数据模式下的个人信息收集呢?另外,大批量恶意涂黑 丢弃的,你身边有这样的正常人吗?违反道德违反法律。顶风作案的自然是有利可图啊,灭了对方的你才能抢占市场啊。怪消费者不够体贴,不如怪商人唯利是图
  只骑摩拜,貌似摩拜没有被涂二维码的,可能是押金高,小黄只要99元  
  我家小区后面有一个小黄维修点,排在那里等着修的四五十辆,多数都是被涂掉二维码的。  
<span class="count" title="
<span class="count" title="
<span class="count" title="
<span class="count" title="
请遵守言论规则,不得违反国家法律法规回复(Ctrl+Enter)

我要回帖

更多关于 微信小黄群二维码 的文章

 

随机推荐