自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(31)
  • 资源 (1)
  • 收藏
  • 关注

原创 外研小学英语音频播放器-带字幕(Android app)

目录背景背景最近孩子学习小学英语的过程中需要背诵课文,但是孩子又不认识英文单词,所以背诵的过程困难重重。通过听英语音频的方式背诵,孩子也经常不知道音频播放的是哪一句。最初我买了一个扫描阅读笔,以为通过扫描阅读笔来朗读英语课文就可以了。但实际情况还是不太好,小孩经常不能扫描到完整的句子,听起来语句变得支离破碎。那么有什么好办法解决这个问题呢?我想开发一个播放英语音频的app,它既能播放音频文件,还能显示字幕。需求以列表的方式罗列出各个单元的音频文件。 点击音频文件后启动播放器播放音频

2021-11-30 22:08:03 3981

原创 Android app中这样用flow更方便-刷新token获取数据

背景移动app中展示的数据多数都是通过服务器接口获取的,当接口数据与用户相关时,服务端接口会要求客户端把用户信息通过接口发送到服务器。普遍的做法是把用户登录后的token数据发送给服务器的接口。考虑到安全问题,token都有过期时间,token过期后服务端就不能通过这个token查询用户的具体信息了。为了刷新过期token,服务端会提供一个刷新token的接口给客户端使用。问题分析由于要求上传token的服务端接口会有很多,所以这些接口的调用都需要考虑token过期失效问题...

2021-09-22 22:58:31 1240

原创 Android app中这样用flow更方便-加载列表数据

背景flow简单的可以理解为数据流,它可以生成连续的同类型数据。刚接触到flow的开发者都很疑惑,它的功能好像都有东西可以替代。比如通过foreach遍历Collection或Sequence都能有flow一样的生成数据效果,那为什么还要引入flow呢。大家可能会认为flow实现了观察者模式,这点与collection或sequence的遍历不同。其实LiveData就是按照观察者模式设计的,LiveData配合集合的遍历就可以达到数据被观察的目的。 刚接触flow...

2021-09-20 22:55:33 1660

原创 一款好用的运行在Android手机上的pdf阅读器

目录​一、背景二、解决了什么痛点问题三、PdfReader如何解决问题1、建立pdf文件索引数据库2、pdf文件移动功能3、pdf查看功能扫码下载app使用一、背景用户使用手机查看pdf文件的需求越来越多了,比如管理网购的pdf格式的电子发票、修改学生的学习软件生成的pdf格式习题、管理pdf格式的合同文件等。这些pdf文件被不同的应用程序创建,被不同的应用保存发送。同时他们也会被零散地保存在不同的目录。 ...

2021-09-13 23:18:40 475

原创 Kotlin Coroutine实现原理

lifecycleScope.launch { Log.d("testCoroutineScope","testCoroutineScope start $this") delay(2000) Log.d("testCoroutineScope","testCoroutineScope middle1") delay(2000) Log.d("testCoroutineScope","t.

2021-09-06 22:23:50 597

原创 Face++以flow的方式实现人脸检测

我们使用人脸检测sdk进行人脸识别的过程大致可以分为下面几个步骤:加载model文件并初始化接口 获取授权 调用人脸检测获取关键点 通知描画关键点 释放接口资源这里的步骤3和4在接收到camera数据后反复执行。我们可以把这几个步骤抽象成数据流来进行封装。face++检测人脸后不断地生成人脸坐标数据,所以整个检测过程就是人脸坐标数据生产的过程,这里与flow的概念对应上了。face++需要通过处理camera数据来获取人脸关键点,所以camera又是face++人脸检测api的数据提供者。

2022-02-15 20:39:38 1382

原创 Face++如何突破试用版本的授权限制

我们可以下载sdk进行免费测试,但是每天免费授权的次数是有限的10次。我们开发的时候肯定不只是10次就能完成的,所以我们要考虑如何更高效地利用免费授权测试。Face⁺⁺ - 旷视Face⁺⁺人工智能开放平台分析授权流程现在免费授权都是通过网络授权的,LicenseManager提供了网络授权的接口。下面的代码片段调用了face++的授权接口。 public static String API_KEY = "jAKhUoK6X1HFRZrxtRWFoObzhEby"; public

2022-01-10 22:07:26 1759

原创 Qt中实现拖拽控件到窗口外释放

在窗口内拖拽控件的实现在上一篇文章中已经讲解过了,这篇文章讲解如何将控件拖拽到窗口外。控件是不能脱离窗口区域渲染的,所以我们需要为拖拽过程中的控件创建一个窗口。实现的主要思路如下:为拖拽过程中的控件创建window。 修改拖拽控件的宿主为新创建的window。 根据MouseArea接收到移动坐标修改window显示位置。 如果拖拽控件停留在主window中,那么修改拖拽控件的宿主为主window。创建窗口为了能将控件拖拽到主窗口外,这里需要为他创建新的窗口。Window {

2021-12-05 19:21:03 1388

原创 Qt中如何实现拖拽释放控件

这篇文章将要介绍Qml中如何实现拖拽功能。实现拖拽并释放控件需要下面几个步骤:为控件添加鼠标响应事件,监听鼠标移动的横纵坐标。 根据鼠标的位置移动控件位置。 修改控件的宿主。处理鼠标事件为了处理鼠标事件,我们可以在qml文件中添加一个MouseArea对象。这个对象有位置和大小,但是不可见。这里为了演示MouseArea的使用,我们先添加一个click事件监听。Rectangle{ width: 100 height: 100 color:

2021-12-05 19:19:46 2442

原创 Android app 中这样用flow更方便-巧用flow实现polling

背景 在app开发过程中,实现polling逻辑也是很常见的。当然在移动端应用使用polling处理会影响应用的性能。比如polling处理增加了网络请求的次数,服务端压力增加。polling处理也消耗了更多的网络流量。但是应用polling的场景还是有的。有时是否选择polling要考虑很多综合的因素,比如我们可以使用长连接替代polling,但是长连接在服务端和客户端的开发成本相对要更高些,如果polling只是实现类似的跟帖等功能,我们完全可以使用polling实现,而不是选择代价更...

2021-10-01 22:49:53 1352

原创 QT qml中动态组件那些事

目录动态创建qml对象Qt.createComponentQt.createQmlObjectComponent qml type销毁动态创建的对象QQmlContext总结动态创建qml对象Qt.createComponentvar component = Qt.createComponent()⇒ component.createObject⇒QmlContext是createComponent方法被调用的qml对象的contextqml对象的文件定义:

2021-09-23 22:26:56 1052

原创 Android Floating header(悬浮的分组头)

背景Android应用中经常采用列表的方式展示信息,有些展示信息是需要分组的形式展示。比如在联系人列表中,列表按照姓名拼音的首字母进行分组显示。分组头显示首字母,分组头被推到顶部时会悬停在顶部直到被下一个分组头顶出。这样的显示方式可以让用户时刻了解当前展示的数据是哪一组的,提升了用户体验。技术分析现在主流的列表展示方案是使用RecyclerView,所以这里基于RecyclerView来分析如何实现可悬浮的分组头功能。网上有很多实现都是基于scroll listener来确定悬.

2021-07-20 22:52:55 557 3

原创 FileObserver失效,接收不到event

如何使用FileObserver1. 申请权限 别忘了在代码中申请动态权限 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />2.实现FileObserver 实现FileObserver时可以指定一个或多个文件及目

2021-07-19 22:20:48 931

原创 android player通过rtp协议接收h264视频数据播放

一、接收数据rtp包的组包与拆包已经由rtp 库完成,这里可以从rtp库的回调直接接收到原始发送的数据。videoRtpWrapper.open(40018, 96, 90000); videoRtpWrapper.setCallback { data, len -> Log.d("dragon_video", "received video data $len") nalu.appended(data, len) { ...

2021-06-24 22:40:31 1443

原创 android Recorder通过rtp发送h264视频数据给vlc播放

# 采集camera数据数据采集部分使用的是Camera2,CameraHolder是对camera2的简单封装。Camera2有个显著的优势,他可以同时添加多个surface用于接收camer数据。下面是通过CameraHolder启动camera的流程:``` override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) .........

2021-06-21 23:19:32 941

原创 Android player实现播放来自rtp连接的aac数据的player

截图开启RTP端口监听我们在发送端向端口40020发送数据,所以这里监听的是40020端口,payload type是97与发送端设置的一致。audioRtpWrapper.open(40020, 97, 1000);设置rtp callback用于接收aac原始数据。audioRtpWrapper.setCallback { data, len -> if (len < 4) return@setCallback v

2021-04-13 20:48:19 843

原创 Android recorder手机通过rtp发送aac数据给vlc播放

截图AudioRecord音频采集 private val sampleRate = mediaFormat.getInteger(MediaFormat.KEY_SAMPLE_RATE) private val channelCount = mediaFormat.getInteger(MediaFormat.KEY_CHANNEL_COUNT) private val minBufferSize = AudioRecord.getMinBufferSize(sampleRat

2021-04-10 21:08:33 470

原创 Android Opengl共享context的替代方案(创建多个eglsurface,通过makecurrent进行切换)

显示效果背景在应用的开发过程中,我们避免不了要使用Opengl共享context的技术。比如我们需要在预览的同时还要将预览的画面传递给MediaCodec进行编码。有的朋友会说Camera2可以设置多个surface,这样就可以把预览的surface和MediaCodec的surface同时传递给Camera2。这种只是实现比较简单的录制功能。现在多数有录制功能的应用都支持滤镜功能,可以把你拍得更漂亮。由于加入了滤镜的功能,所以我们要通过Opengl技术来实现。当我们加入opengl的滤镜功能后就有

2020-11-19 20:16:47 3943

原创 H.264数据通过rtp分片发送

一、H264的nalu的组成start code [00 00 00 01]nalu headernalu payloadnalu header +---------------+ |0|1|2|3|4|5|6|7| +-+-+-+-+-+-+-+-+ |F|NRI| Type | +---------------+F(forbidden_zero_bit)H.264规范中规定必须为0NRI(nal_ref_idc)00~11,数值越大表示数据越重要。关键帧、sp

2020-10-20 21:41:21 433

原创 为RecyclerView定义通用的Adapter和Holder

背景Android开发过程中经常使用到RecyclerView来展示列表形式的信息。我们需要定义一个Adapter来适配数据与UI展示,同时还有定义ui对应的ViewHolder。如果每个列表形式的界面都要定义这样的一套类的话,那么使用RecyclerView变得有些繁琐。为了解决这个问题,本文介绍了如何定义一个通用的Adapter和ViewHolder。定义BaseItemBaseItem 是抽象类,用于item数据绑定。BaseItem定义了一个bind抽象方法用于数据与ui的绑定。Adapter

2020-09-18 22:57:36 636

原创 Android 高效播放apng文件(支持在RecycleView、ListView中显示)

背景之前写了一篇关于如何自定义APngDrawable的文章,当时通过提交任务到线程池来解码apng 文件。其中帧播放的逻辑控制也过于复杂,需要不断的计算帧延时刷新。并且APngDrawable在播放apng文件的过程中,解码线程会经常的发生挂起。为了充分的利用线程,避免挂起线程,并且简化帧播放逻辑。所以我们考虑使用协程来解决这些问题。协程协程可以挂起执行,这里的挂起执行与线程的挂起不同。它没有阻塞线程,而是记录当前执行的位置。当异步执行结束后从记录的执行位置继续执行,挂起前后的执行线程有可能不同。利

2020-09-08 22:15:48 2793

原创 Camera2实现二维码扫描功能(qrcode scanner)

实现二维码识别的流程开启Camera创建ImageReader通过ImageReader获取surface对像设置surface对象给camera并启动preview当有preview数据产生时ImageReader的onImageAvailable回调会被调用调用ImageReader 的acquireLatestImage()方法获取image数据把image数据传递给QRCo...

2020-04-29 20:42:20 3490

原创 GLSurfaceView显示Camera2的preview内容(支持前后摄像头切换和分辨率切换)

效果实现的基本功能使用GLSurfaceView绘制camera的preview内容。支持前后摄像头切换。支持切换preview size。通过手势可以缩放preview画面,移动previw画面。初识OpenGlGLSurfaceView为我们构建了一个OpenGl环境,如果我们想通过GLSurfaceView来渲染camera的Preview内容,那么我们必须掌握一些基础的...

2020-04-22 22:52:33 1426

原创 Camera2的简单封装

背景Camera2已经发布很长时间了,但是一直没有用它替换老的Camera接口。没有替换的原因是新接口使用比较复杂并且与老接口的调用逻辑相差较大。正是因为Camera2接口使用比较复杂,学习成本比较高,所以google提供了Camera2的封装组件CameraX。使用CameraX来开发相机功能轻松了许多,但是要将原有的项目迁移到CameraX组件又要面对很多的代码适配问题。总之是一言难尽。...

2020-04-08 20:42:09 719 2

原创 Fragment使用要点

一、添加fragment和删除fragmentadd:添加一个fragment到fragment manager。 remove:从fragment manager中删除一个fragment。 replace:替换fragment manager中的fragment。等同于先remove旧的fragment,然后add新的fragment。当我们使用这几个操作的时候,还有一些细节需要了解...

2020-03-06 21:25:15 393

原创 通过自定义FragmentController的FragmentHostCallback实现浮窗界面的管理

效果FragmentController介绍FragmentController用于控制fragment,它把activity的许多事件分发给fragment处理。更准确的说法是分配给fragment manager,然后由fragment manager分发给fragment。FragmentController通常都是在activity中创建的,并且activity作为FragmentC...

2020-02-03 23:44:37 1099

原创 CenterImageSpan

一、背景在实际的app开发过程中,我们经常需要在文本中插入图标。Android系统已经封装了ImageSpan,我们可以使用这个类实现文本插入的功能。如果ui设计师对插入图标的对齐方式有明确要求,那么用系统的ImageSpan就不能灵活的应对了。所以在这种情况下,我们需要通过自定义ImageSpan来满足ui设计师的各种要求。...

2019-12-22 19:57:52 953

原创 自定义APngDrawable

自定义APngDrawableAPng是什么?Png fileAPng fileAPng是什么?简单理解就是Animation Png file,支持动画的 png file。Png fileHeader frameFrame dataAPng file1.Animate control frame2.Frame data...

2019-12-05 22:24:35 959

原创 图片拖拽排序自定义控件实现(gallery、custom ViewGroup)

一、实现效果二、应用到的主要技术点android:animateLayoutChanges="true"设置这个属性有效。主要的作用是当childView 显示位置发生变化时,系统自动播放动画。 自定义ViewGroup要求我们自己实现onMeasure和onLayout控制childView的大小和显示位置。 重写onInterruptTouchEvent方法判断自定义Vi...

2019-10-30 21:13:35 334

原创 支持侧滑删除的list item实现

一、实现效果图二、实现的基本思路(不需要重写RecyclerView的touch事件)自定义ViewGroup,每一个list的item项的根布局都使用自定义的ViewGoup。在其中管理item view和menu view显示的位置。 在自定义的ViewGroup中处理滑动事件,根据滑动事件处理view的移动(item view 和menu view的移动) 使用scrolle...

2019-09-24 20:50:23 157

原创 自定义Drawable实现彩虹条边框

一、首先展示下效果二、如何使用自定义Drawable private void initRainbowView(){ TextView rainbowView = findViewById(R.id.rainbowDrawableView); RainbowDrawable.Builder builder = new Rain...

2019-04-03 21:34:01 881

jrtp 库资源

jrtp lib 支持android jni编译

2015-01-19

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除