随便建一个 . gradle 后缀名 文件。
比如说起名叫
config . gradle
内容如下::
ext { /** * 导入狗日的阿里云短视频SDK * 导入狗日的阿里云短视频SDK * 导入狗日的阿里云短视频SDK * 导入狗日的阿里云短视频SDK * 导入狗日的阿里云短视频SDK * 导入狗日的阿里云短视频SDK * 导入狗日的阿里云短视频SDK * 导入狗日的阿里云短视频SDK * 导入狗日的阿里云短视频SDK * 导入狗日的阿里云短视频SDK */ projectVersion = '3.0.0-2017.1.22' externalAndroidBuildGradlePlugin = 'com.android.tools.build:gradle:2.2.0' externalAndroidAppCompatV7 = 'com.android.support:appcompat-v7:24.2.1' externalAndroidCardView = 'com.android.support:cardview-v7:21.0.+' externalAndroidMultiDex = 'com.android.support:multidex:1.0.1' externalAndroidRecyclerView = 'com.android.support:recyclerview-v7:24.2.1' externalAndroidSupportV13 = 'com.android.support:support-v13:23.4.0' externalAndroidSupportV4 = 'com.android.support:support-v4:23.4.0' externalAndroidDesign = 'com.android.support:design:24.2.1' externalAndroidTestEspressoCore = 'com.android.support.test.espresso:espresso-core:2.2.2' externalAndroidTestRunner = 'com.android.support.test:runner:0.4.1' // externalAndroidAsyncHttp = 'com.loopj.android:android-async-http:1.4.9' // externalAutoFactory = 'com.google.auto.factory:auto-factory:1.0-beta2' // externalDagger = 'com.google.dagger:dagger:2.0.1' // externalDaggerCompiler = 'com.google.dagger:dagger-compiler:2.0.1' externalDexmakerDx = 'com.crittercism.dexmaker:dexmaker-dx:1.4' externalDexmakerMockito = 'com.crittercism.dexmaker:dexmaker-mockito:1.4' // externalFastJson = 'com.alibaba:fastjson:1.2.5' externalHamcrestLibrary = 'org.hamcrest:hamcrest-library:1.3' // externalInject = 'javax.inject:javax.inject:1' externalJSR305 = 'com.google.code.findbugs:jsr305:3.0.0' externalMockito = 'org.mockito:mockito-core:1.10.19' externalOrmLiteAndroid = 'com.j256.ormlite:ormlite-android:4.48' externalGlide = 'com.github.bumptech.glide:glide:3.7.0' externalGlideOkHttp = 'com.github.bumptech.glide:okhttp3-integration:1.4.0@aar' externalOKHTTP = 'com.squareup.okhttp3:okhttp:3.2.0' externalGSON = 'com.google.code.gson:gson:2.8.0' externalOKIO = 'com.squareup.okio:okio:1.12.0' externalPagerSlidingTabStrip = 'com.astuetz:pagerslidingtabstrip:1.0.1' externalEasyPermissions = 'pub.devrel:easypermissions:0.2.1' externalJunit = 'junit:junit:4.12' externalCompileSdkVersion = 25 externalBuildToolsVersion = "25.0.1" externalMinSdkVersion=15 externalTargetSdkVersion=25 }
然后在 Module 的 build 里面的 根目录 , 或者 Project项目 的 build 里面的 buildScript { } 目录
apply from: 'config.gradle'
这岂不是
这岂不是
这岂不是
这岂不是 和 PHP 很像很像很像吗????
require() 函数
或者
include() 函数
然后变量值都可以用了啊啊啊啊
ext 列表名, 或许就意味着
global 关键字 在PHP中
只有声明了, 才能全局使用
2.非常诡异,非常 邪性的一点
诡异 + 邪性
这样子能写,
哪怕是 compile == 25
而官方限定死的 24.2.1
以下代码也可以光明正大的跑通
dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile(project(':AliyunSnap:snap_core')) { transitive = false } compile externalAndroidAppCompatV7 compile externalAndroidDesign compile externalJSR305 compile externalGlide compile externalEasyPermissions compile externalOKHTTP compile externalGlideOkHttp compile externalOKIO compile externalGSON }
而以下这样写就不行
compile 'com.android.support:appcompat-v7:24.2.1'//此处报错 compile 'com.android.support:design:24.2.1'//此处报错 compile 'com.google.code.findbugs:jsr305:3.0.0' compile 'com.github.bumptech.glide:glide:3.7.0' compile 'pub.devrel:easypermissions:0.2.1' compile 'com.squareup.okhttp3:okhttp:3.2.0' compile 'com.github.bumptech.glide:okhttp3-integration:1.4.0@aar' compile 'com.squareup.okio:okio:1.12.0' compile 'com.google.code.gson:gson:2.8.0' }
可见非常 邪性 , 血腥 , 邪性
但无疑非常好用。
3.
一些关键词
compile
Conflict with dependency
App ( 3.0.0 )
test App ( 2.0.1 )
Resolved versions
testCompile
androidTestCompile
configurations.all { }
resolutionStrategy { }
force ' 仓库:模块:版本 '
androidTestCompile (' 仓库:模块:版本 ') {
exclude module: '模块名称'
}
以及,参照以下文章
https://github.com/square/assertj-android/issues/193
https://stackoverflow.com/questions/33317555/conflict-with-dependency-com-android-supportsupport-annotations-resolved-ver 【正解】
https://stackoverflow.com/questions/28999124/resolved-versions-for-app-22-0-0-and-test-app-21-0-3-differ
https://www.google.com.hk/search?safe=strict&source=hp&q=Error%3AConflict+with+dependency++Resolved+versions&oq=Error%3AConflict+with+dependency++Resolved+versions&gs_l=psy-ab.3...226.39418.0.40394.6.6.0.0.0.0.99.99.1.1.0....0...1.1.64.psy-ab..5.0.0.1RofdFC0v9c【搜索】
【已解决】
4.
(1)
Error:
Dependency XXXXX: unspecified on project app resolves to an APK archive which is not supported as a compilation dependency
可能是:创建了两个Module,其中一个Module依赖另一个Module而导致了出现该问题
解法:
- apply plugin: 'com.android.application'
修改为
- apply plugin: 'com.android.library'
(2)
Error:
Library projects cannot set applicationId. applicationId is set to 'package_name' in default config
Module —— build . gradle —— android { defaultConfig {
applicationId "xxx包名“ //注释掉。
} }
以上两种解法,
均来自于同一篇文章
http://blog.csdn.net/u012336923/article/details/48049479 【csdn博客:yao伟斌】
4.发现一点——————惊天大谜团。
阿里云短视频的 Demo 是 SDK 25 的版本,
却可以使用
24.2.1 的V7包。
android { compileSdkVersion 25 buildToolsVersion "25.0.2" defaultConfig { minSdkVersion 15 targetSdkVersion 25 versionCode 1 versionName "1.0"
compile externalAndroidAppCompatV7 compile externalAndroidDesign
externalAndroidAppCompatV7 = 'com.android.support:appcompat-v7:24.2.1'
externalAndroidDesign = 'com.android.support:design:24.2.1'
至少编译器错误层面上的区别,
在于从 外界ext compile导的不会报错。
直接写固定的版本号,必定报错。
后来再三查看,好像只解决了编译器在 dependencies中的 运行:
即————
使得 compileSDK 为 25,26 的Module , 能够使用 24.0.0 的 v7 support (以及其它各 版本同步包)
但仍然解决不了,
其它所有第三方库中, 因为已封装, 无法直接调换已写死的 v7 support (以及其它各 版本同步包) 的问题
即,只能解决【当前】 【所处项目】 的【问题】。
仍然无法穿透,
,,,,,,,,,,,,,,,,,,,,,,,,,,
5.改用【标准版】
基础版的内容,连客服也说了,除了逐个改第三方库的路径,别无别法。
标准版:
1.问题一
unable to delete directory
解决办法,将 报错的build路径,整个删掉。重新来。
2.问题二
明明已经导入了DownloaderManager包,偏偏说找不到。
更改build:gradle 插件版本,即可 2.20 ————> 2.3.3
'com.android.tools.build:gradle:2.3.3'
6.
if(key == R.mipmap.demo_camera_icon){ Intent camera = new Intent("com.duanqu.qupai.action.camera"); }
然后Manifest文件,
<activity android:name="com.aliyun.demo.recorder.CameraDemo"> <intent-filter> <action android:name="com.duanqu.qupai.action.camera"/> <category android:name="android.intent.category.DEFAULT"/> </intent-filter> </activity>
可见,是从这里开始调取的。
7.大神文章, 解决所有傻逼阿里依赖。
【踩坑速记】二次依赖?android studio编译运行各种踩坑解决方案,杜绝弯路,总有你想要的~
http://www.cnblogs.com/liushilin/p/6068098.html
针对《基础版》,有可能达到必杀效果!!!
【等待尝试 ing 】
【等忙完了一定要去尝试!!!!!!!!!!!!!!!!!!!!】
【等忙完了一定要去尝试!!!!!!!!!!!!!!!!!!!!】
【等忙完了一定要去尝试!!!!!!!!!!!!!!!!!!!!】
【等忙完了一定要去尝试!!!!!!!!!!!!!!!!!!!!】
【等忙完了一定要去尝试!!!!!!!!!!!!!!!!!!!!】
【等忙完了一定要去尝试!!!!!!!!!!!!!!!!!!!!】
【等忙完了一定要去尝试!!!!!!!!!!!!!!!!!!!!】
【等忙完了一定要去尝试!!!!!!!!!!!!!!!!!!!!】
【等忙完了一定要去尝试!!!!!!!!!!!!!!!!!!!!】
【等忙完了一定要去尝试!!!!!!!!!!!!!!!!!!!!】
【等忙完了一定要去尝试!!!!!!!!!!!!!!!!!!!!】
【等忙完了一定要去尝试!!!!!!!!!!!!!!!!!!!!】
【等忙完了一定要去尝试!!!!!!!!!!!!!!!!!!!!】
【等忙完了一定要去尝试!!!!!!!!!!!!!!!!!!!!】
【等忙完了一定要去尝试!!!!!!!!!!!!!!!!!!!!】
【等忙完了一定要去尝试!!!!!!!!!!!!!!!!!!!!】
【等忙完了一定要去尝试!!!!!!!!!!!!!!!!!!!!】
8.
结构分析【标准版】
Demo:引导页面,进入各分支SDK的菜单页面。
AliyunCrop:crop_demo:视频拼接与裁剪页面。
AliyunRecorder:record_demo:视频录制页面。
AliyunVideoSdk:仅包含arr和gradle的模块。
AliyunHelp:展示版权文本的页面。
AliyunFileDownLoader:downloadermanager:提供下载各种彩图动画特效的下载模块。(如果不加入彩图动画,可以去掉。)
STMobileJNI:(据说是要,让用户自己选择)怎样显示彩图动画、怎样捕捉人脸位置加特效。(但因为没有交费,没有授权,所以Demo中不可用。)【而且,捕捉人脸和彩图动图,都是专业版才有的功能(那你他娘的放在这里干嘛?)】
AliyunView:用到的诸多自定义特效控件。
9.
有空要研究一下下面的写法:
configurations.maybeCreate("default") artifacts.add("default", file('AliyunSdk-RC.aar'))
在一个Module中,只有
一个 build.gradle 和一个 AliyunSdk-RC.arr 文件
build.gradle 只有两行代码。
而其它模块对这个写法的模块的导入为
dependencies { compile(project(':AliyunVideoSdk')) { transitive = false } }
10.【最新消息】
经过与阿里的安卓程序员的联系,
他们一时半会也找不到根本原因,只说和arr的分包有关。
他们给了我一个
v7 support 包 为 25.3.1 的版本。
经过我的导入,目前问题暂时得到了解决。
问题暂时得到了解决!!!
问题暂时得到了解决!!!
问题暂时得到了解决!!!
问题暂时得到了解决!!!
问题暂时得到了解决!!!
以下是调试的大体经过,
基本按照【基础版3.3.1】的流程来的,
不同之处我列在下面:
1.注释了 v7包 为 25.4.0 的第三方库Compile 。
保证都是小于等于 25.3.1 的情况。
2.根据
编译器的报错结果,分别逐条对比,添加force如下。 (根据每个人个人情况)
configurations.all {//【测试】【测试】【测试】【测试】【测试】【测试】
resolutionStrategy {
failOnVersionConflict()
force 'org.jetbrains.kotlin:kotlin-stdlib:1.1.3-2'
force 'com.android.support:appcompat-v7:25.3.1'
force 'com.android.support:recyclerview-v7:25.3.1'
force 'com.android.support:support-compat:25.3.1'
force 'com.squareup.okio:okio:1.12.0'
force 'com.squareup.okhttp3:okhttp:3.2.0'
force 'com.squareup.retrofit2:retrofit:2.3.0'
force 'com.google.code.gson:gson:2.8.0'
force 'com.android.support:support-annotations:25.3.1'
force 'com.android.support:support-v4:25.3.1'
force 'com.squareup:javapoet:1.8.0'
force 'com.google.code.findbugs:jsr305:3.0.0'
}
}
然后操作的原理,和技术备忘录,
如下:
然后我的一些自己的尝试总结如下:
1.将短视频SDK的 v7 包 指定为唯一的最高版本标准。然后所有在此版本之下的第三方库,都是有着自己的向下兼容机制的,所以都可以得到合理解决。
2.然后解决兼容问题。用 configurations.all 里面的 resolutionStrategy 策略,
用 failOnVersionConflict 和 forece 这两个方法,
来根据编译器的实时报错,进行版本的强制修改。
3.以上的情况,都是建立在 短视频SDK 的 v7 包,高于所有第三方库的 v7包的情况之下。
4.若存在某一 第三方库的v7版本,
高于短视频SDK 的标准v7版本。(当前为 25.3.1 )
则以上的向下兼容机制,则失效。
而且,很有可能,产生预料之外的错误(版本冲突)。
11.并且,
我还预备给他们两条建议,————更好的使用第三方库:
建议一:
(1)
除了利用
resolutionStrategy
的
force之外,
还有一种
待选解法
具体解决方案为:由于很多第三方包都会用到v4支持包,这样在你导入多个支持的时候难免会出现这样的错误,只需在build.gradle里面添加上
configurations {
all*.exclude group: 'com.android.support', module: 'support-v4'
}
参见大神文章:
【踩坑速记】二次依赖?android studio编译运行各种踩坑解决方案,杜绝弯路,总有你想要的~
里面的第二点,就是讲这个的。
(2)
所有的activity xml 命名,
一、不应让用户避让自己的 xml文件命名。
二、应该自己想办法,比如在 xml文件名、各种value属性,的后面,加上自己独一无二仅有的不可能冲突的后缀名。应该是自己主动避让客户。
整体上!学习到了非常多的东西!自学,是最厉害最无法阻拦的解法!
荣神益人!
进入常规项目阶段:
12.
base-64 加密的 UploadAddress 字段:
eyJFbmRwb2ludCI6Imh0dHBzOi8vb3NzLWNuLXNoYW5naGFpLmFsaXl1bmNzLmNvbSIsIkJ1Y2tldCI6ImluLTIwMTcwODAzMTg1MDE1OTE4LWlyMjVsajE2dGwiLCJGaWxlTmFtZSI6InZpZGVvLzEwQkREMzBFLTE1RTE4MEJFMTNELTExOTEtNzAwNS00MDUtMDE2MTgubXA0In0=
变为了:
eyJFbmRwb2ludCI6Imh0dHBzOi8vb3NzLWNuLXNoYW5naGFpLmFsaXl1bmNzLmNvbSIsIkJ1Y2tldCI6ImluLTIwMTcwODAzMTg1MDE1OTE4LWlyMjVsajE2dGwiLCJGaWxlTmFtZSI6InZpZGVvLzEwQkREMzBFLTE1RTE4MEJFMTNELTExOTEtNzAwNS00MDUtMDE2MTgubXA0In0\u003d
末位的等号,变了
解析出来的Json也由
{"Endpoint":"https://oss-cn-shanghai.aliyuncs.com","Bucket":"in-20170803185015918-ir25lj16tl","FileName":"video/10BDD30E-15E180BE13D-1191-7005-405-01618.mp4"}
变为了
{"Endpoint":"https://oss-cn-shanghai.aliyuncs.com","Bucket":"in-20170803185015918-ir25lj16tl","FileName":"video/10BDD30E-15E180BE13D-1191-7005-405-01618.mp4"}.Ӎ݀
相关解决文章为:
使用Gson将对象类转成Json对象时出现\u003d的问题
http://blog.csdn.net/taven/article/details/42706451
这种情况,如果Student属性中的某个值包含有=,会变为\u003d的情况
只需将Gson的初始化修改为
对于
retrofit = Retrofit.Builder().baseUrl(BASE_URL) .addConverterFactory(GsonConverterFactory.create(gson))
没用。
那么,手动转化吧:
uploadAddress = uploadAddress?.replace("\\u003d","=")//【解决Gson的Bug。】
13.
全屏,SDK不提供现成方法。 手动调整。
竖向:
//自己的一些控件,进行显示 rl_titlebar_012.visibility = View.VISIBLE rl_namebar_012.visibility = View.VISIBLE ll_menubar_public.visibility = View.VISIBLE ll_describebar_012.visibility = View.VISIBLE btn_join_005.visibility = View.VISIBLE
横向:
//自己的一些控件,进行隐藏 rl_titlebar_012.visibility = View.GONE rl_namebar_012.visibility = View.GONE ll_menubar_public.visibility = View.GONE ll_describebar_012.visibility = View.GONE btn_join_005.visibility = View.GONE
然后
ViewGroup.LayoutParams.MATCH_PARENT.let { params.height = it; params.width = it }不起作用
windowManager.defaultDisplay .let { params.width = it.width*3; params.height = it.height*3 }不起作用
var trueParams = rl_wrap_match_home_player.layoutParams windowManager.defaultDisplay .let { trueParams.width = 500;trueParams.height = 500 }
不起作用
甚至天才般的思考:
windowManager.defaultDisplay .let { params.width = it.height;params.height = it.width }
都不起作用。
A
match_home_player.changeScreenMode(AliyunScreenMode.Full)//全屏模式
和
B
ViewGroup.LayoutParams.MATCH_PARENT.let { params.height = it; params.width = it }
的前后顺序交换,都不起作用。
match_home_player.layoutParams = params也不起作用。
params.width = windowManager.defaultDisplay.width params.height = windowManager.defaultDisplay.height match_home_player.layoutParams = params手动一个个字,打进去,也不起作用。
14、
外层wrap嵌套可以改layoutParams,
内层的播放器不可以改layoutParams
始终扩不到全屏。
14问题已解决。。。。。【核心方案是:1.width必须写 wrap_content 或者 match_parent 。 2. height必须写 dp 或 px 。 3. 其他的任意占用面积的UI,都gone掉。4.在onConfigurationChanged里面, 设置对应的尺寸变化方法。 5. 说不定有其他 6.说不定有其他】
15.
自己设计了一套, 用Surface 显示, player 管理流程的, 基本的播放。
以及自己设计的高级版UI。
16.
自己设计了一套, List中 播放器Item 的全套生命管理系统。
17.
基础版的短视频录制,这个 选择相册 的按钮,应该用什么方法去隐藏呢?
答曰:
snap_demo 里style文件里面<item name="qusnap_gallery_icon_visibility">visible</item> 该属性设置为gone就可以了
18.
多Item列表的播放器模式
和单列表item的播放器模式
的抽取与组合。
19.
全画面点击。
而且简单重排了一下生命周期中的方法。
20.
自动播放处理。
21.
播放器
音量设置
//TODO 测试 TLog.l("现在监测到的音量是——————${playerHashMap[index]?.player?.volume}")
每次变动7个。
音量从 0 -- 100 。 有14阶变量。
可以手动 setVolume ( Int )
和 手动 getVolume ( Int )
22.
设置屏幕亮度
* 设置屏幕亮度
* 0 最暗
* 1 最亮
*/
public void setBrightness(float brightness) {
WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.screenBrightness = lp.screenBrightness + brightness / 255.0f;
if (lp.screenBrightness > 1) {
lp.screenBrightness = 1;
} else if (lp.screenBrightness < 0.1) {
lp.screenBrightness = (float) 0.1;
}
getWindow().setAttributes(lp);
float sb = lp.screenBrightness;
brightnessTextView.setText((int) Math.ceil(sb * 100) + "%");
}
直接设置整机的屏幕亮度代码。
23.
设置了好久。
发现 马云视频播放器的 setVolume 这个api ,是没用的
无论输入什么进去, 都是播放器的 音量为 0
playerHashMap[index]?.volumeBtn?.setOnClickListener { /** * 如果播放器音量大于0。则记录下播放器音量,并重新将音量设为0 * 如果播放器音量已为0。则将播放器音量设置为上次存储的音量。 */ TLog.l("根据系统音量,此时当前系统媒体音量是 ${getSystemMediaVolume(true)}", "Volume") TLog.l("此时播放器的音量是 ${playerHashMap[index]?.player?.volume}", "Volume") TLog.l("现在存储的上次音量值为 ${playerHashMap[index]?.original_volume},然后开始判断", "Volume") playerHashMap[index]?.original_volume?.let { when (it > 0) { /** * 若大于0 */ true -> let { TLog.l("走大于0的分支 :设置之前前前,播放器的音量为${playerHashMap[index]?.player?.volume}", "Volume") val savedVolume = playerHashMap[index]?.player?.volume playerHashMap[index]?.original_volume = savedVolume playerHashMap[index]?.player?.volume = 0//设置为0 TLog.l("设置之后后后,播放器的音量为${playerHashMap[index]?.player?.volume}", "Volume") } /** * 若小于等于0 */ false -> let { TLog.l("走小于等于0的分支 :设置之前前前播放器的音量为${playerHashMap[index]?.player?.volume}", "Volume") playerHashMap[index]?.player?.volume = playerHashMap[index]?.original_volume ?: 50//设为上一次的值。如为null则50 TLog.l("设置之后后后播放器的音量为${playerHashMap[index]?.player?.volume}", "Volume") } } } }
哪怕有乘了一百倍后,也照样无效。
后来发现。。。。
上面那个判断分支写错了:
TLog.l("现在存储的上次音量值为 ${playerHashMap[index]?.original_volume},然后开始判断", "Volume")
playerHashMap[index]?.player?.volume?.let {
写着写着写多了,就糊涂了。
24.
系统的 Call 通话音量
从 0 最小 到 7 最大 , 有 7 级
系统 的 Media(Music一样的) 媒体音量
从 0 最小 到 15最大 , 有 15 级
马云视频播放器,
是从 0 - ----- -- 100 ,总共有 100 级。
25.
经过很多微细的调整和Log调整之后。
马云视频播放器的音量功能,调通了。
音量是可以调节的。
没问题,只是SDK比较绕。
还要注意有一点。
public class PlayerProxy implements IAliyunVodPlayer
里面是这样写的
public void setVolume(int volume) { if(this.mAvmPlayer != null) { this.mAvmPlayer.setVolume((float)volume * 1.0F / 100.0F); } } public int getVolume() { if(this.mAvmPlayer == null) { return 0; } else { float volume = this.mAvmPlayer.getVolume(); return (int)(volume * 100.0F); } }
26.
firstVisibleItem = layoutManager.findFirstCompletelyVisibleItemPosition()//完全可见。————? firstVisibleItem = layoutManager.findFirstVisibleItemPosition()//只要有一点点部分可见。——————?
RecyclerView.LayoutManager
找到的方法——————
一、第一个为部分可见的条目
二、第一个全部可见的条目
最后一个以此类推
感觉。。。
这API很神奇
可以大作文章