以上就是创建 Flutter 插件项目的整个过程,向读者介绍了系统为我们自动生成的两个重要类。之后我们的开发重心围绕这两个类来开展。
编写调节音量代码并测试
Android 端代码
首先在 VolumeControlPlugin.kt
编写需要实现的方法。如下,我写了四个对应的方法名供 Flutter 端来调用。分别是设置音量最大范围、获取当前电量、改变媒体音量、改变系统音量。VolumeManager
内部实现了这四个方法的具体逻辑,由于篇幅关系,且本文的目的是带读者熟悉整个 Flutter 插件开发流程,这里不贴出 VolumeManager
类的源代码,也不讲解其实现细节。代码放在 volume_flutter,感兴趣的读者可以去看看。
/** VolumeControlPlugin */
class VolumeControlPlugin: FlutterPlugin, MethodCallHandler {
private lateinit var channel : MethodChannel
private lateinit var volumeManager: VolumeManager
override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
channel = MethodChannel(flutterPluginBinding.binaryMessenger, “volume_control”)
channel.setMethodCallHandler(this)
volumeManager = VolumeManager(flutterPluginBinding.applicationContext)
}
override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
channel.setMethodCallHandler(null)
}
override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
when(call.method){
“setMaxVol” -> { // 设置最大音量范围
volumeManager.setMaxVol(call.arguments as Double);
}
“getCurrentVol” -> { // 获取当前音量
volumeManager.setAudioType(call.arguments as Int)
result.success(volumeManager.currentVolume);
}
“changeMediaVoice” -> { // 改变媒体音量
volumeManager.setAudioType(VolumeManager.TYPE_MUSIC)
val curVoice = volumeManager.setVoice(call.arguments as Double);
result.success(curVoice)
}
“changeSysVoice” -> { //改变系统音量
volumeManager.setAudioType(VolumeManager.TYPE_SYSTEM)
val curVoice = volumeManager.setVoice(call.arguments as Double);
result.success(curVoice)
}
else -> {
result.notImplemented()
}
}
}
}
Flutter 端代码
在 volume_control.dart
中编写 4 个异步方法,来调用上面 Android 端我们写好的处理方法,如下。
class VolumeControl {
static const MethodChannel _channel = const MethodChannel(‘volume_control’);
/// 设置音量最大范围
/// setMaxVol 方法考虑到了音量的最大值可以自由设置,如果不使用这个方法,默认音量最大值是 100
static Future setMaxVol(double num) async{
await _channel.invokeMethod(“setMaxVol”,num);
}
/// 获取当前音量
static Future getCurrentVol(AudioType audioType) async{
return await _channel.invokeMethod(“getCurrentVol”,_getStreamInt(audioType)) as double;
}
/// 改变媒体音量
static Future changeMediaVoice(double num) async{
return await _channel.invokeMethod(“changeMediaVoice”,num) as double;
}
/// 改变系统音量
static Future changeSysVoice(double num) async{
return await _channel.invokeMethod(“changeSysVoice”,num) as double;
}
}
enum AudioType {
/// Controls the Voice Call volume
STREAM_VOICE_CALL,
/// Controls the system volume
STREAM_SYSTEM,
/// Controls the ringer volume
STREAM_RING,
/// Controls the media volume
STREAM_MUSIC,
// Controls the alarm volume
STREAM_ALARM,
/// Controls the notification volume
STREAM_NOTIFICATION
}
int _getStreamInt(AudioType audioType) {
switch (audioType) {
case AudioType.STREAM_VOICE_CALL:
return 0;
case AudioType.STREAM_SYSTEM:
return 1;
case AudioType.STREAM_RING:
return 2;
case AudioType.STREAM_MUSIC:
return 3;
case AudioType.STREAM_ALARM:
return 4;
case AudioType.STREAM_NOTIFICATION:
return 5;
default:
return null;
}
}
在 Flutter 页面看看效果
Android 端和 Flutter 端的代码我们编写完毕,现在在项目生成的 example 目录下的 main.dart
来编写页面示例代码,来展示插件的功能。注意 example 是开发者写给使用者看的,告诉他们这个插件如何使用的一个 Flutter 项目,相当于帮助文档,我觉得这点很好,极大了加快了我们的上手速度。
在 main.dart
中用一个 Slider 滑块组件来展示下效果。按以下步骤编码。
- 进入页面的时候调用 getCurrentVol 方法来获取当前媒体音量,显示初始状态。
- 滑动滑块调用 changeMediaVoice 方法来改变媒体音量。
main.dart
页面代码如下,也很简单。
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State {
double _musicVoice;
@override
void initState() {
super.initState();
///1.获取当前媒体音量
initCurrentVol();
}
/// 获取当前媒体音量
Future initCurrentVol () async{
_musicVoice = await VolumeControl.getCurrentVol(AudioType.STREAM_MUSIC);
if(!mounted) return;
setState(() {});
}
/// 改变媒体音量
Future changeMediaVoice(double vol) async{
await VolumeControl.changeMediaVoice(vol);
_musicVoice = vol;
setState(() {});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text(‘Plugin example app’),
),
body: Center(
child: (_musicVoice != null) ? Slider(
value: _musicVoice,
min: 0,
max: 100,
inactiveColor: Colors.grey,
activeColor: Colors.blue,
onChanged: (vol){
/// 2. 滑动改变媒体音量
changeMediaVoice(vol);
},
): Container(),
),
),
);
}
}
实际效果如下,滑动滑块时,系统媒体音量也随之改变。我的测试机型是小米 MI 6X。其他机型可能会有差异,请读者注意。
将开发好的插件包上传到 Dart 仓库
我们的 Flutter 插件包整个开发流程就结束了。现在将它上传到 Dart 仓库,方便其他开发者可以使用这个插件包。在发布之前,检查 LICENSE
、pubspec.yaml
、README.md
以及 CHANGELOG.md
四个文件。
选择开源许可证(LICENSE)
软件开源许可证,大概有上百种。最流行的六种 — GPL、BSD、MIT、Mozilla、Apache 和 LGPL。读者可以从 Choose an open source license 选择适合自己的证书,我这里选择 MIT。
将复制的内容粘贴到 LICENSE
,用当前年份替换掉 [year]
,版权所有者替换掉 [fullname]
。如下图,证书就算是弄完了。
修改 pubspec.yaml
name: volume_control
description: A new Flutter plugin.
version: 0.0.1
author:
homepage:
这里按实际情况修改 description
插件的简要描述,version
插件的版本,homepage
项目主页,其中 author
已经不支持使用了,读者需要直接删除,不然后面检查会不通过,修改后如下。
name: volume_control
description: A Flutter plugin which can control android volume.
version: 0.0.1
homepage: https://github.com/liqvip/volume_control
修改 README.md 和 CHANGELOG.md
README.md 文件不用多说,读者可以根据自己插件是干什么的、有什么用、使用方法等自由发挥。 CHANGELOG.md 文件用来记录每个版本的更改。也是根据实际情况来填写。
0.0.1
initial commit
很简单,对于 0.0.1
版本我只填了一句话,嘻嘻~
开始上传
- 首先在 Android Studio Termial 中输入如下命令,来检查我们编写的好的上述文件是否符合发布的要求。
flutter pub publish --dry-run
- 如果检查没有问题,控制台会输出如下提示信息。
Package has 0 warnings.
- 然后输入如下命令,开始上传
flutter pub publish --server=https://pub.dartlang.org
会提示你一旦发布就是永久的,不能够取消发布。输入 y 继续下一步
Publishing is forever; packages cannot be unpublished.
Policy details are available at https://pub.dev/policy
Do you want to publish volume_control 0.0.1 (y/N)?
控制台接着会输出一个链接,这里我们要复制这个链接到浏览器打开,然后会提示你登录验证谷歌邮箱,没有的需要用 VPN 注册一个谷歌邮箱。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)
总结
首先是感觉自己的基础还是不够吧,大厂好像都喜欢问这些底层原理。
另外一部分原因在于资料也还没有看完,一面时凭借那份资料考前突击恶补个几天居然也能轻松应对(在这里还是要感谢那份资料,真的牛),于是自我感觉良好,资料就没有怎么深究下去了。
之前的准备只涉及了Java、Android、计网、数据结构与算法这些方面,面对面试官对其他基础课程的考察显得捉襟见肘。
下一步还是要查漏补缺,进行针对性复习。
最后的最后,那套资料这次一定要全部看完,是真的太全面了,各个知识点都涵盖了,几乎我面试遇到的所有问题的知识点这里面都有!希望大家不要犯和我一样的错误呀!!!一定要看完!
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
真的太全面了,各个知识点都涵盖了,几乎我面试遇到的所有问题的知识点这里面都有!希望大家不要犯和我一样的错误呀!!!一定要看完!**
[外链图片转存中…(img-PsNWzgjg-1712507558807)]
[外链图片转存中…(img-6NSdQzp3-1712507558807)]
[外链图片转存中…(img-ZrfbKSNX-1712507558807)]
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!