自定义ImageView 宽度自适应屏幕,高度等比缩放

实现方法很简单,根据图片文件的宽度与ImageView的宽度比例关系算出ImageView的高度。 package com.etongwl.commonlibs.view; import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.NinePatchDrawable; import android.util.AttributeSet; import android.view.ViewGroup; import android.widget.ImageView; /* * @Override public void setImageDrawable(final Drawable drawable) { super.setImageDrawable(drawable); if (drawable != null) { post(new Runnable() { @Override public void run() { float mWidth = getWidth(); float pWidth = drawable.getBounds().width(); float pHeight = drawable.getBounds().height(); int mHeight = (int) ((mWidth / pWidth) * pHeight); LayoutParams params = getLayoutParams(); params.height = mHeight; params.width = (int) mWidth; setLayoutParams(params); } }); } } 首先, 如果drawable不为空, 则通过drawable.getBounds()去获取drawable边界的宽和高. 在根据ImageView的宽与drawable的宽的比例去计算高度, 最后通过LayoutParams设置ImageView的高度 * */ /* <com.etongwl.commonlibs.view.AdaptiveImageView android:id="@+id/detail_image" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginTop="15dp" android:scaleType="centerCrop" android:background="@drawable/diandianxinwen" android:visibility="visible" /> */ /** * 按比例缩放 */ @SuppressLint("AppCompatCustomView") public class AdaptiveImageView extends ImageView { // 控件默认长、宽 private int defaultWidth = 0; private int defaultHeight = 0; // 比例 private float scale = 0; public AdaptiveImageView(Context context) { super(context); } public AdaptiveImageView(Context context, AttributeSet attrs) { super(context, attrs); } public AdaptiveImageView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override protected void onDraw(Canvas canvas) { Drawable drawable = getDrawable(); if (drawable == null) { return; } if (getWidth() == 0 || getHeight() == 0) { return; } this.measure(0, 0); if (drawable.getClass() == NinePatchDrawable.class) return; Bitmap b = ((BitmapDrawable) drawable).getBitmap(); Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888, true); if (bitmap.getWidth() == 0 || bitmap.getHeight() == 0) { return; } if (defaultWidth == 0) { defaultWidth = getWidth(); } if (defaultHeight == 0) { defaultHeight = getHeight(); } scale = (float) defaultWidth / (float) bitmap.getWidth(); defaultHeight = Math.round(bitmap.getHeight() * scale); ViewGroup.LayoutParams params = this.getLayoutParams(); params.width = defaultWidth; params.height = defaultHeight; this.setLayoutParams(params); super.onDraw(canvas); } } 简单实现ImageView宽度填满屏幕,高度自适应的两种方式 两种方式 1.重写View的onMeasure方法参考这里easion_zms的专栏 核心代码 ...

2017年5月2日 · 4 分钟 · 天边的星星

Android 中的CreatePackageContext()

/** * Return a new Context object for the given application name. This * Context is the same as what the named application gets when it is * launched, containing the same resources and class loader. Each call to * this method returns a new instance of a Context object; Context objects * are not shared, however they share common state (Resources, ClassLoader, * etc) so the Context instance itself is fairly lightweight. ...

2017年4月25日 · 3 分钟 · 天边的星星

Android动态加载基础 ClassLoader工作机制

类加载器ClassLoader 早期使用过Eclipse等Java编写的软件的同学可能比较熟悉,Eclipse可以加载许多第三方的插件(或者叫扩展),这就是动态加载。这些插件大多是一些Jar包,而使用插件其实就是动态加载Jar包里的Class进行工作。这其实非常好理解,Java代码都是写在Class里面的,程序运行在虚拟机上时,虚拟机需要把需要的Class加载进来才能创建实例对象并工作,而完成这一个加载工作的角色就是ClassLoader。 对于Java程序来说,编写程序就是编写类,运行程序也就是运行类(编译得到的class文件),其中起到关键作用的就是类加载器ClassLoader。 Android的Dalvik/ART虚拟机如同标准JAVA的JVM虚拟机一样,在运行程序时首先需要将对应的类加载到内存中。因此,我们可以利用这一点,在程序运行时手动加载Class,从而达到代码动态加载可执行文件的目的。Android的Dalvik/ART虚拟机虽然与标准Java的JVM虚拟机不一样,ClassLoader具体的加载细节不一样,但是工作机制是类似的,也就是说在Android中同样可以采用类似的动态加载插件的功能,只是在Android应用中动态加载一个插件的工作要比Eclipse加载一个插件复杂许多(这点后面在解释说明)。 有几个ClassLoader实例? 动态加载的基础是ClassLoader,从名字也可以看出,ClassLoader就是专门用来处理类加载工作的,所以这货也叫类加载器,而且一个运行中的APP 不仅只有一个类加载器。 其实,在Android系统启动的时候会创建一个Boot类型的ClassLoader实例,用于加载一些系统Framework层级需要的类,我们的Android应用里也需要用到一些系统的类,所以APP启动的时候也会把这个Boot类型的ClassLoader传进来。 此外,APP也有自己的类,这些类保存在APK的dex文件里面,所以APP启动的时候,也会创建一个自己的ClassLoader实例,用于加载自己dex文件中的类。下面我们在项目里验证看看 ` <span class="hljs-annotation">@Override</span> <span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onCreate</span><span class="hljs-params">(Bundle savedInstanceState)</span> </span>{ <span class="hljs-keyword">super</span>.onCreate(savedInstanceState); ClassLoader classLoader = getClassLoader(); <span class="hljs-keyword">if</span> (classLoader != <span class="hljs-keyword">null</span>){ Log.i(TAG, <span class="hljs-string">"[onCreate] classLoader "</span> + i + <span class="hljs-string">" : "</span> + classLoader.toString()); <span class="hljs-keyword">while</span> (classLoader.getParent()!=<span class="hljs-keyword">null</span>){ classLoader = classLoader.getParent(); Log.i(TAG,<span class="hljs-string">"[onCreate] classLoader "</span> + i + <span class="hljs-string">" : "</span> + classLoader.toString()); } } }` 输出结果为 ...

2017年4月25日 · 7 分钟 · 天边的星星

深入浅出ClassLoader ,超详细java中的ClassLoader详解

你真的了解ClassLoader吗? 这篇文章翻译自zeroturnaround.com的 Do You Really Get Classloaders? ,融入和补充了笔者的一些实践、经验和样例。本文的例子比原文更加具有实际意义,文字内容也更充沛一些,非常感谢作者 Jevgeni Kabanov 能够共享如此优秀的文档。 1. 为什么你需要了解和敬畏ClassLoader ClassLoader在Java语言中占据了核心地位,Java应用服务器,OSGi,以及大量的网络框架,它们大多数都用到了ClassLoader。如果在使用过程中出现了类加载错误,你能解决它吗? 我们将从JVM和开发者两个角度讲述ClassLoader,将会选择一些典型的案例,然后演示如何解决它们。NoClassDefFoundError,LinkageError等很多错误都会有特定的表征,我们分析每个例子,然后进行解决。 2. 进入ClassLoader 每个ClassLoader对象都是一个java.lang.ClassLoader的实例。每个Class对象都被这些ClassLoader对象所加载,通过继承java.lang.ClassLoader可以扩展出自定义ClassLoader,并使用这些自定义的ClassLoader对类进行加载。 先大体了解一下ClassLoader的API: `01` <td class="content"> `package` `java.lang;` </td> </tr> </table> </div> <div class="line alt2"> <table> <tr> <td class="number"> `02` </td> <td class="content"> </td> </tr> </table> </div> <div class="line alt1"> <table> <tr> <td class="number"> `03` </td> <td class="content"> `public` `abstract` `class` `ClassLoader {` </td> </tr> </table> </div> <div class="line alt2"> <table> <tr> <td class="number"> `04` </td> <td class="content"> ` ``public` `Class loadClass(String name);` </td> </tr> </table> </div> <div class="line alt1"> <table> <tr> <td class="number"> `05` </td> <td class="content"> </td> </tr> </table> </div> <div class="line alt2"> <table> <tr> <td class="number"> `06` </td> <td class="content"> ` ``protected` `Class defineClass(``byte``[] b);` </td> </tr> </table> </div> <div class="line alt1"> <table> <tr> <td class="number"> `07` </td> <td class="content"> </td> </tr> </table> </div> <div class="line alt2"> <table> <tr> <td class="number"> `08` </td> <td class="content"> ` ``public` `URL getResource(String name);` </td> </tr> </table> </div> <div class="line alt1"> <table> <tr> <td class="number"> `09` </td> <td class="content"> </td> </tr> </table> </div> <div class="line alt2"> <table> <tr> <td class="number"> `10` </td> <td class="content"> ` ``public` `Enumeration getResources(String name);` </td> </tr> </table> </div> <div class="line alt1"> <table> <tr> <td class="number"> `11` </td> <td class="content"> </td> </tr> </table> </div> <div class="line alt2"> <table> <tr> <td class="number"> `12` </td> <td class="content"> ` ``public` `ClassLoader getParent();` </td> </tr> </table> </div> <div class="line alt1"> <table> <tr> <td class="number"> `13` </td> <td class="content"> `}` </td> </tr> </table> </div> 最重要的是ClassLoader的<span lang="EN-US">loadClass</span>方法,它接受一个全类名,然后返回一个Class类型的实例。 ...

2017年4月25日 · 39 分钟 · 天边的星星

资源收藏

Android实现图片相似度 http://zzimoo.com/similar/ OpenCV笔记大集锦 http://blog.csdn.net/langb2014/article/details/51379326 ThinkPHP5.0完全开发手册 http://www.kancloud.cn/manual/thinkphp5 GitHub秘籍(中文版) http://www.kancloud.cn/thinkphp/github-tips REST API 安全设计指南 http://www.kancloud.cn/kancloud/rest-api-design-safety Atom IDE极速入门 http://www.kancloud.cn/kinghs/atom OHSCE官方教程免费版 http://www.kancloud.cn/ohsce/ohscebook 深入浅出ES6 http://www.kancloud.cn/kancloud/es6-in-depth ECMAScript 6入门 http://www.kancloud.cn/kancloud/ecmascript6-guide Sublime Text 全程指南 http://www.kancloud.cn/digest/sublime-text-complete-guide 深入浅出React http://www.kancloud.cn/kancloud/react-in-depth 图像处理算法 http://www.kancloud.cn/digest/imageproebow iOS 高级 http://www.kancloud.cn/digest/data Flex 布局教程:语法篇 http://www.kancloud.cn/digest/flex-grammar Android性能优化 http://www.kancloud.cn/digest/android-performance 设计模式C++实现 http://www.kancloud.cn/digest/walker1 系统架构师技能学习 http://www.kancloud.cn/digest/archi Java工具类专栏 http://www.kancloud.cn/digest/java-utility-classes C++开发人脸性别识别教程 http://www.kancloud.cn/digest/genderrecogtion UiAutomator从入门到原理 http://www.kancloud.cn/digest/uiautomatorpriciple Android NDK开发学习 http://www.kancloud.cn/digest/zlndk React Native学习指南 http://www.kancloud.cn/digest/rnative RabbitMQ Java入门教程 http://www.kancloud.cn/digest/rabbitmq-for-java FFmpeg入门实践与分析 http://www.kancloud.cn/digest/ffmpegtutorial 开源物联网系统设计 http://www.kancloud.cn/digest/bare-minimum-iot-system IOS 网络编程 http://www.kancloud.cn/digest/ios-data Android流媒体播放 http://www.kancloud.cn/digest/rtmp-android Cocos2d游戏开发 http://www.kancloud.cn/digest/cocos2d Android核心分析 http://www.kancloud.cn/digest/androidcore OpenCV 应用笔记 http://www.kancloud.cn/digest/usingopencv 游戏引擎开发 http://www.kancloud.cn/digest/game-engine-dev 电商系统 http://www.kancloud.cn/digest/b2c-it 无线局域网开发 http://www.kancloud.cn/digest/wlan android SDK开发 http://www.kancloud.cn/digest/phoebe 大数据开源框架 http://www.kancloud.cn/digest/bigdata-open android源码解析 http://www.kancloud.cn/digest/androidframeworks Android Studio详细教程 http://www.kancloud.cn/stormzhang/android_studio iOS开发进阶 http://www.kancloud.cn/digest/iosdevelopment001 Android特效专辑 http://www.kancloud.cn/digest/liuguilin Android开发高手进阶 http://www.kancloud.cn/digest/androidadvanced vue http://www.kancloud.cn/dingyiming/vue JNI/NDK开发指南 http://www.kancloud.cn/xyang0917/blogjnindk 《架构师成长之路》漫画连载 http://www.kancloud.cn/qiniu/architect-growth Android(OpenCV)开发 http://www.kancloud.cn/yanzi1225627/android-opencv Android JNI入门 http://www.kancloud.cn/digest/android-jni 设计模式与系统架构 http://www.kancloud.cn/longxuan/my-designpattern 轻松搞定RabbitMQ http://www.kancloud.cn/longxuan/rabbitmq-arron android应用安全 http://www.kancloud.cn/digest/android-safe Java线程 http://www.kancloud.cn/digest/java-thread 微信硬件平台解决方案 http://www.kancloud.cn/yueqian_scut/iot-wechat Appium之android平台的源码分析 http://www.kancloud.cn/digest/itfootball-appium Gradle学习系列 http://www.kancloud.cn/digest/itfootball-gradle react-native试玩 http://www.kancloud.cn/digest/doctorqrn 《机器学习实战》笔记 http://www.kancloud.cn/digest/machinglearninginact ...

2017年3月22日 · 2 分钟 · 天边的星星

使用Artifactory搭建本地maven仓库

引言 前段日子,公司为了提高产品出产效率,想把公司每个产品各个小功能抽取出来,这样再做一个新产品的时候,重复的功能就可以直接使用之前写好的模块就行了。想法是不错的,但一开始实践起来很麻烦,同事A就将自己的模块做成module,为了图方便,将整个module项目直接发送给同事B和同事C,代码第一次写成以后一般都会有一些小bug的,这样,同事A在自己电脑上修改代码,然后再次修改代码分别传给B和C。B和C需要替换之前的module,重新运行。这相当的麻烦,如果还有同事D,E,F..做起来真是噩梦,可能有有人想问,为什么不用svn或者git,用版本控制工具当然会好非常多,但每次pull其实也比较麻烦。还有另一种方法,使用本地maven仓库,使用过android studio的开发者都应该体会过其中的好处,当需要依赖一个新的模块(或者叫library)时,只需要这样 填写需要的模块及对应的版本号,同步一下就行了,很方便。本篇文章就教各位如何使用Artifactory来搭建本地仓库,来完成上图的效果 什么是Artifactory? 一句话,开源的Maven仓库管理者 搭建Artifactory 1.检测你的jdk版本是否为1.8及以上 打开cmd,输入java -version,如果输出结果如下所示即可,如果是1.6或者1.7,去官网下载最新版本替换 `java -version java version "1.8.0_31" Java(TM) SE Runtime Environment (build 1.8.0_31-b13) Java HotSpot(TM) 64-Bit Server VM (build 25.31-b07, mixed mode)" data-snippet-id="ext.437a4825669d574acb250e72155a8b81" data-snippet-saved="false" data-codota-status="done">C:\Users\Administrator>java -version<br /> java version "1.8.0_31"<br /> Java(TM) SE Runtime Environment (build 1.8.0_31-b13)<br /> Java HotSpot(TM) 64-Bit Server VM (build 25.31-b07, mixed mode)` 2.下载Artifactory,解压下载好的安装包,打开解压后文件夹下的bin文件夹,运行artifactory.bat,大概等待1分钟左右就安装完成了 3.打开http://localhost:8081/artifactory将会看到管理界面,如果看到此界面,就表示artifactory已经安装成功了.如果不是该界面,则需要等待安装完成 上传library到maven 创建自己的library project(注意你的 module是apply plugin: ‘com.android.library’),写好自己模块的代码后,准备上传 1.添加相关插件引用 在你library 项目中顶级的build.gradle文件中,添加一条新的classpath引用 **[plain]** [view plain](http://blog.csdn.net/level_26/article/details/53483444#)<span class="tracking-ad" data-mod="popu_168"> [copy](http://blog.csdn.net/level_26/article/details/53483444#)</span> <div> <embed id="ZeroClipboardMovie_1" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="16" height="16" align="middle" name="ZeroClipboardMovie_1" data-mce-fragment="1"> </embed> </div> </div> - <span style=&#8221;font-family:Microsoft YaHei;font-size:14px;&#8221;>buildscript { - dependencies { - classpath &#8220;org.jfrog.buildinfo:build-info-extractor-gradle:4.4.0&#8221; - } - }</span> 然后在你的library module的build.gradle中,添加两条语句 ...

2017年3月21日 · 3 分钟 · 天边的星星

MAC JDK默认安装路径 JAVA路径

打开终端,执行 /usr/libexec/java_home -V MacBook-Air:~ eng$ /usr/libexec/java_home -V Matching Java Virtual Machines (4): 1.8.0_101, x86_64: “Java SE 8” /Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home 1.7.0_79, x86_64: “Java SE 7” /Library/Java/JavaVirtualMachines/jdk1.7.0_79.jdk/Contents/Home 1.6.0_65-b14-466.1, x86_64: “Java SE 6” /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home 1.6.0_65-b14-466.1, i386: “Java SE 6” /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home /Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home 默认JDK1.6(Apple自带JDK)路径: /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home 默认JDK1.7、1.8(Oracle) Home : /Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home

2017年3月18日 · 1 分钟 · 天边的星星

AndroidStudio 多层级 Module 对 aar 引用

问题:有个arr文件被放到Module A中引用,现在Module B又依赖了Module A,则在编译过程中会发生错误,Module B找不到aar文件。(同时如果又有Module C 依赖了Module B,C也会出同样的问题) ![](data:image/png;base64,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) 解法: 1、正常给一个module加入aar文件的步骤是: - 把aar文件放入module文件夹下libs包下 - 然后在项目的build.gradle文件的android节点下加入 - <table> <tr> <td> <div class="top-box hide"> </div> <div class="top-box hide"> </div> ``` repositories { flatDir { dirs ’libs' } } </td> </tr> </table> - 然后继续在dependencies节点中加入:compile(name: &#8216;xxxxxxx&#8217;, ext: &#8216;aar&#8217;) </div> <div> </div> <div> 2、就是这样会引发上面的问题,所以你要做的是,给所有依赖或间接依赖Module A 的Module的build.gradle的android节点下加入 </div> <div> repositories { </div> <div> <div class="top-box hide"> flatDir { dirs &#8216;../模块名称/libs&#8217;,&#8217;libs&#8217; } } </div> 其中dirs前面一段路径是Module A的文件夹 </div> <div> </div> <div> 问题原因: </div> <div> 对于Module B和Module C来说,他们依赖了Module A,不管用不用,他们都会去把Module A的依赖走一遍,当走到你添加的aar本地依赖时,他们去找aar的路径也需要你给出,而且给的方式如果是libs这样的路径,它会去找自己包下的libs,里边自然没有,所以你要给出另一个相对路径:../模块名称/libs这样才能找到,而为了不影响自己这个Module对自己Module下的libs的引用,就使用逗号再添加一个路径 </div>

2017年3月3日 · 1 分钟 · 天边的星星

android Home键监听

监听工具类 import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.util.Log; public class HomeWatcher { static final String TAG = “HomeWatcher”; private Context mContext; private IntentFilter mFilter; private OnHomePressedListener mListener; private InnerRecevier mRecevier; // 回调接口 public interface OnHomePressedListener { public void onHomePressed(); public void onHomeLongPressed(); } public HomeWatcher(Context context) { mContext = context; mRecevier = new InnerRecevier(); mFilter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); } /** 设置监听 @param listener */ public void setOnHomePressedListener(OnHomePressedListener listener) { mListener = listener; } /** ...

2017年2月26日 · 2 分钟 · 天边的星星

Android 蓝牙4.0 BLE 理解

转载自:http://blog.csdn.net/chaoyue0071/article/details/43450183/ 本文简单结合两篇文章 http://blog.csdn.net/hellogv/article/details/24267685 http://blog.csdn.net/jimoduwu/article/details/21604215 在BLE协议中,有两个角色,周边(Periphery)和中央(Central),一个中央可以同时连接多个周边,但是一个周边某一时刻只能连接一个中央。但是不管是Periphery还是Central都是可以实现 GATT server 和 GATT client去传输数据,但是无法同时都是。 大概了解了概念后,看看Android BLE SDK的四个关键类(class): a) BluetoothGattServer作为周边来提供数据; BluetoothGattServerCallback返回周边的状态。 b) BluetoothGatt作为中央来使用和处理数据;BluetoothGattCallback返回中央的状态和周边提供的数据。 因为我们讨论的是Android的BLE SDK,下面所有的BluetoothGattServer代表周边,BluetoothGatt代表中央。 一.创建一个周边(虽然目前周边API在Android手机上不工作,但还是看看) a)先看看周边用到的class,蓝色椭圆 b)说明: 每一个周边BluetoothGattServer,包含多个服务Service,每一个Service包含多个特征Characteristic。 1.new一个特征:character = new BluetoothGattCharacteristic( UUID.fromString(characteristicUUID), BluetoothGattCharacteristic.PROPERTY_NOTIFY, BluetoothGattCharacteristic.PERMISSION_READ); 2.new一个服务:service = new BluetoothGattService(UUID.fromString(serviceUUID), BluetoothGattService.SERVICE_TYPE_PRIMARY); 3.把特征添加到服务:service.addCharacteristic(character); 4.获取BluetoothManager:manager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); 5.获取/打开周边:BluetoothGattServer server = manager.openGattServer(this, new BluetoothGattServerCallback(){…}); 6.把service添加到周边:server.addService(service); 7.开始广播service:Google还没有广播Service的API,等吧!!!!!所以目前我们还不能让一个Android手机作为周边来提供数据。 二.创建一个中央(这次不会让你失望,可以成功创建并且连接到周边的) a)先看看中央用到的class,蓝色椭圆 b)说明: 为了拿到中央BluetoothGatt,可要爬山涉水十八弯: 1.先拿到BluetoothManager:bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); 2.再拿到BluetoothAdapt:btAdapter = bluetoothManager.getAdapter(); 3.开始扫描:btAdapter.startLeScan( BluetoothAdapter.LeScanCallback); 4.从LeScanCallback中得到BluetoothDevice:public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {…..} 5.用BluetoothDevice得到BluetoothGatt:gatt = device.connectGatt(this, true, gattCallback); 终于拿到中央BluetoothGatt了,它有一堆方法(查API吧),调用这些方法,你就可以通过BluetoothGattCallback和周边BluetoothGattServer交互了。 官方有给出BLE 通信的sample ,下面是牛人简化了代码,简化得简单明了 本文来自http://blog.csdn.net/hellogv/ ,引用必须注明出处! 最近穿戴设备发展得很火,把相关技术也带旺了,其中一项是BLE(Bluetooth Low Energy)。BLE是蓝牙4.0的核心Profile,主打功能是快速搜索,快速连接,超低功耗保持连接和传输数据,弱点是数据传输速率低,由于BLE的低功耗特点,因此普遍用于穿戴设备。Android 4.3才开始支持BLE API,所以请各位客官把本文代码运行在蓝牙4.0和Android 4.3及其以上的系统,另外本文所用的BLE终端是一个蓝牙4.0的串口蓝牙模块。 PS:我的i9100刷了4.4系统后,竟然也能跟BLE蓝牙模块通信。 ...

2017年2月25日 · 6 分钟 · 天边的星星