├── .gitignore
├── AppGrpc
├── .gitignore
├── build.gradle
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── yc
│ │ └── appgrpc
│ │ ├── GRPCClient.java
│ │ ├── GRPCServer.java
│ │ ├── GreeterActivity.java
│ │ ├── HelloWorldActivity.java
│ │ ├── MainActivity.java
│ │ └── ProtoJsonTest.java
│ ├── proto
│ ├── efficient_test.proto
│ ├── greeter.proto
│ ├── hello_world.proto
│ └── msg_test.proto
│ └── res
│ ├── drawable
│ └── ic_launcher_background.xml
│ ├── layout
│ ├── activity_greeter.xml
│ ├── activity_helloworld.xml
│ └── activity_rpc_main.xml
│ ├── mipmap-xhdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-xxhdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ └── values
│ ├── colors.xml
│ └── strings.xml
├── CompressServer
├── .gitignore
├── README.md
├── build.gradle
├── src
│ └── main
│ │ ├── AndroidManifest.xml
│ │ ├── java
│ │ └── com
│ │ │ └── yc
│ │ │ └── compress
│ │ │ ├── image
│ │ │ ├── AppBitmapUtils.java
│ │ │ ├── ImageDataSource.java
│ │ │ ├── ImageSaveUtils.java
│ │ │ ├── NetImageUtils.java
│ │ │ ├── PicCalculateUtils.java
│ │ │ ├── PicMimeTypeUtils.java
│ │ │ └── ViewBitmapUtils.java
│ │ │ ├── luban
│ │ │ ├── Checker.java
│ │ │ ├── CompressionPredicate.java
│ │ │ ├── Engine.java
│ │ │ ├── InputStreamAdapter.java
│ │ │ ├── InputStreamProvider.java
│ │ │ ├── Luban.java
│ │ │ ├── OnCompressListener.java
│ │ │ └── OnRenameListener.java
│ │ │ └── utils
│ │ │ ├── AppCompress.java
│ │ │ ├── CompressConfig.java
│ │ │ └── CompressUtils.java
│ │ └── res
│ │ └── values
│ │ └── strings.xml
└── 图片README.md
├── EasyBleServer
├── .gitignore
├── README.md
├── build.gradle
└── src
│ └── main
│ ├── AndroidManifest.xml
│ └── java
│ └── com
│ └── yc
│ └── easyble
│ ├── BleManager.java
│ ├── bluetooth
│ ├── BleBluetooth.java
│ ├── BleConnector.java
│ ├── MultipleBluetoothController.java
│ └── SplitWriter.java
│ ├── callback
│ ├── BleBaseCallback.java
│ ├── BleGattCallback.java
│ ├── BleIndicateCallback.java
│ ├── BleMtuChangedCallback.java
│ ├── BleNotifyCallback.java
│ ├── BleReadCallback.java
│ ├── BleRssiCallback.java
│ ├── BleScanAndConnectCallback.java
│ ├── BleScanCallback.java
│ ├── BleWriteCallback.java
│ └── IBleScanCallback.java
│ ├── config
│ ├── BleScanConfig.java
│ └── BleScanRuleConfig.java
│ ├── data
│ ├── BleConnectStateParameter.java
│ ├── BleDevice.java
│ ├── BleMsg.java
│ ├── BleScanState.java
│ └── BleWriteState.java
│ ├── exception
│ ├── BleException.java
│ ├── ConnectException.java
│ ├── GattException.java
│ ├── OtherException.java
│ └── TimeoutException.java
│ ├── scan
│ ├── BleScanPresenter.java
│ └── BleScanner.java
│ └── utils
│ ├── BleHelperUtils.java
│ ├── BleLog.java
│ ├── BleLruHashMap.java
│ └── HexUtil.java
├── GalleryPagerLib
├── .gitignore
├── .idea
│ ├── .gitignore
│ ├── misc.xml
│ ├── modules.xml
│ └── runConfigurations.xml
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── yc
│ │ └── gallerypager
│ │ ├── Constants.java
│ │ ├── ImageFragment.java
│ │ ├── MediaInfo.java
│ │ ├── SafeViewPager.java
│ │ ├── ScrollGalleryView.java
│ │ ├── SlidePagerAdapter.java
│ │ ├── VideoPlayActivity.java
│ │ ├── builder
│ │ ├── BasicMediaHelper.java
│ │ └── GallerySettings.java
│ │ ├── impl
│ │ ├── GalleryBuilderImpl.java
│ │ └── SettingsBuilderImpl.java
│ │ ├── inter
│ │ ├── IGalleryBuilder.java
│ │ ├── IMediaHelper.java
│ │ ├── IMediaLoader.java
│ │ └── ISettingsBuilder.java
│ │ └── loader
│ │ ├── DefaultImageLoader.java
│ │ └── DefaultVideoLoader.java
│ └── res
│ ├── drawable-hdpi
│ ├── placeholder_image.png
│ └── placeholder_video.png
│ ├── drawable-xhdpi
│ ├── placeholder_image.png
│ └── placeholder_video.png
│ ├── drawable-xxhdpi
│ ├── placeholder_image.png
│ └── placeholder_video.png
│ ├── drawable-xxxhdpi
│ ├── placeholder_image.png
│ └── placeholder_video.png
│ ├── layout
│ ├── image_fragment.xml
│ ├── scroll_gallery_view.xml
│ └── video_fragment.xml
│ ├── values-ru
│ └── strings.xml
│ └── values
│ └── strings.xml
├── GalleryViewLib
├── .gitignore
├── README_CH.md
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── yc
│ │ └── gallerylib
│ │ ├── gallery
│ │ ├── GalleryFragment.java
│ │ ├── GalleryImageView.java
│ │ ├── GalleryViewPager.java
│ │ └── ViewPagerAdapter.java
│ │ └── recyclerView
│ │ ├── GalleryLayoutManager.java
│ │ ├── GalleryRecyclerView.java
│ │ └── OnGalleryListener.java
│ └── res
│ ├── layout
│ ├── fragment_image_gallery.xml
│ ├── view_scroll_gallery.xml
│ └── view_zoom_load.xml
│ └── values
│ └── strings.xml
├── GrpcServer
├── .gitignore
├── build.gradle
└── src
│ └── main
│ ├── AndroidManifest.xml
│ └── java
│ └── com
│ └── yc
│ └── grpcserver
│ ├── BaseRequest.java
│ ├── BaseResponse.java
│ ├── ChannelHelper.java
│ ├── GrpcCallback.java
│ ├── GrpcChannelBuilder.java
│ ├── GrpcHelper.java
│ ├── GrpcStubManager.java
│ ├── GrpcToolUtils.java
│ ├── LoggingInterceptor.java
│ ├── RequestInterceptor.java
│ └── Tls12SocketFactory.java
├── LICENSE
├── README.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── assets
│ └── yc.png
│ ├── java
│ └── com
│ │ └── yc
│ │ └── cn
│ │ └── ycgallery
│ │ ├── FirstActivity.java
│ │ ├── FiveActivity.java
│ │ ├── FourActivity.java
│ │ ├── MainActivity.java
│ │ ├── PicassoImageLoader.java
│ │ ├── PicassoMediaHelper.java
│ │ ├── SecondActivity.java
│ │ ├── SnapAdapter.java
│ │ ├── ThirdActivity.java
│ │ └── animations
│ │ ├── EnterScreenAnimations.java
│ │ ├── ExitScreenAnimations.java
│ │ ├── MatrixEvaluator.java
│ │ ├── MatrixUtils.java
│ │ ├── ScreenAnimation.java
│ │ └── SimpleAnimationListener.java
│ └── res
│ ├── anim
│ ├── screen_zoom_in.xml
│ ├── screen_zoom_out.xml
│ ├── slide_in_left.xml
│ ├── slide_in_right.xml
│ ├── slide_in_top.xml
│ ├── slide_out_left.xml
│ └── slide_out_right.xml
│ ├── drawable-xhdpi
│ ├── image1.jpg
│ ├── image2.jpg
│ ├── image3.png
│ ├── image4.png
│ ├── image5.png
│ ├── image6.png
│ ├── image7.png
│ └── image8.png
│ ├── drawable-xxhdpi
│ ├── beauty1.jpg
│ ├── beauty10.jpg
│ ├── beauty11.jpg
│ ├── beauty12.jpg
│ ├── beauty13.jpg
│ ├── beauty2.jpg
│ ├── beauty3.jpg
│ ├── beauty4.jpg
│ ├── beauty5.jpg
│ ├── beauty6.jpg
│ ├── beauty7.jpg
│ ├── beauty8.jpg
│ └── beauty9.jpg
│ ├── drawable
│ └── shape_b3666666_bg_3.xml
│ ├── layout
│ ├── activity_first.xml
│ ├── activity_five.xml
│ ├── activity_four.xml
│ ├── activity_main.xml
│ ├── activity_second.xml
│ ├── activity_third.xml
│ └── item_snap.xml
│ ├── menu
│ └── menu_main.xml
│ ├── mipmap-hdpi
│ └── ic_launcher.png
│ ├── mipmap-mdpi
│ └── ic_launcher.png
│ ├── mipmap-xhdpi
│ └── ic_launcher.png
│ ├── mipmap-xxhdpi
│ └── ic_launcher.png
│ ├── mipmap-xxxhdpi
│ ├── default_video.png
│ └── ic_launcher.png
│ ├── transition
│ └── activity_explode.xml
│ ├── values-w820dp
│ └── dimens.xml
│ └── values
│ ├── array.xml
│ ├── colors.xml
│ ├── dimens.xml
│ ├── strings.xml
│ └── styles.xml
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
└── yc.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | # Built application files
2 | *.apk
3 | *.ap_
4 |
5 | # Files for the ART/Dalvik VM
6 | *.dex
7 |
8 | # Java class files
9 | *.class
10 |
11 | # Generated files
12 | bin/
13 | gen/
14 | out/
15 |
16 | # Gradle files
17 | .gradle/
18 | build/
19 |
20 | # Local configuration file (sdk path, etc)
21 | local.properties
22 |
23 | # Proguard folder generated by Eclipse
24 | proguard/
25 |
26 | # Log Files
27 | *.log
28 |
29 | # Android Studio Navigation editor temp files
30 | .navigation/
31 |
32 | # Android Studio captures folder
33 | captures/
34 |
35 | # Intellij
36 | *.iml
37 | .idea/workspace.xml
38 | .idea/tasks.xml
39 | .idea/gradle.xml
40 | .idea/dictionaries
41 | .idea/libraries
42 |
43 | # Keystore files
44 | *.jks
45 |
46 | # External native build folder generated in Android Studio 2.2 and later
47 | .externalNativeBuild
48 |
49 | # Google Services (e.g. APIs or Firebase)
50 | google-services.json
51 |
52 | # Freeline
53 | freeline.py
54 | freeline/
55 | freeline_project_description.json
56 | .idea/
57 | .gradle/
58 |
--------------------------------------------------------------------------------
/AppGrpc/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/AppGrpc/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | apply plugin: 'com.google.protobuf'
3 | //apply from: rootProject.projectDir.absolutePath + "/yc.gradle"
4 |
5 | android {
6 | compileSdkVersion rootProject.ext.android["compileSdkVersion"]
7 | //buildToolsVersion rootProject.ext.android["buildToolsVersion"]
8 | defaultConfig {
9 | minSdkVersion rootProject.ext.android["minSdkVersion"]
10 | targetSdkVersion rootProject.ext.android["targetSdkVersion"]
11 | versionCode rootProject.ext.android["versionCode"]
12 | versionName rootProject.ext.android["versionName"]
13 | applicationId "com.yc.appgrpc"
14 | // dex突破65535的限制
15 | multiDexEnabled true
16 | }
17 |
18 | buildTypes {
19 | debug { minifyEnabled false }
20 | release {
21 | minifyEnabled true
22 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
23 | }
24 | }
25 | lintOptions {
26 | disable 'GoogleAppIndexingWarning', 'HardcodedText', 'InvalidPackage'
27 | textReport true
28 | textOutput "stdout"
29 | }
30 |
31 | compileOptions {
32 | sourceCompatibility JavaVersion.VERSION_1_8
33 | targetCompatibility JavaVersion.VERSION_1_8
34 | }
35 |
36 | packagingOptions {
37 | exclude 'META-INF/*******'
38 | exclude 'META-INF/INDEX.LIST'
39 | }
40 | }
41 |
42 | protobuf {
43 | protoc {
44 | // 相当于proto编译器
45 | artifact = 'com.google.protobuf:protoc:3.22.3'
46 | }
47 | plugins {
48 | // grpc单独的编译器
49 | grpc {
50 | artifact = 'io.grpc:protoc-gen-grpc-java:1.19.0'
51 | }
52 | // 官方推荐的方法,Android 适用javalite,相较于java插件,生成的代码更轻量化
53 | //javalite {artifact = 'com.google.protobuf:protoc-gen-javalite:3.0.0'}
54 | }
55 | generateProtoTasks {
56 | all().each { task ->
57 | task.builtins {
58 | java { option 'lite' }
59 | }
60 | task.plugins {
61 | grpc { // Options added to --grpc_out
62 | option 'lite'
63 | }
64 | }
65 | }
66 | }
67 | }
68 |
69 |
70 | dependencies {
71 | implementation fileTree(dir: 'libs', include: ['*.jar'])
72 | implementation rootProject.ext.dependencies["appcompat"]
73 | implementation rootProject.ext.dependencies["annotation"]
74 | implementation(rootProject.ext.dependencies["constraintlayout"])
75 | implementation rootProject.ext.dependencies["gson"]
76 | implementation 'com.github.yangchong211.YCWidgetLib:RoundCorners:1.0.6'
77 | implementation project(path: ':GrpcServer')
78 | implementation 'com.github.yangchong211.YCDialog:ToastUtils:3.6.9'
79 | //工具类utils
80 | implementation 'com.github.yangchong211.YCCommonLib:ToolUtilsLib:1.4.9'
81 |
82 | //protobuf
83 | implementation 'io.grpc:grpc-netty:1.33.0'
84 | implementation 'io.grpc:grpc-okhttp:1.33.0'
85 | implementation 'io.grpc:grpc-protobuf-lite:1.33.0'
86 | implementation 'io.grpc:grpc-stub:1.33.0'
87 | implementation 'org.apache.tomcat:annotations-api:6.0.53'
88 | }
89 |
--------------------------------------------------------------------------------
/AppGrpc/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/AppGrpc/src/main/java/com/yc/appgrpc/GreeterActivity.java:
--------------------------------------------------------------------------------
1 | package com.yc.appgrpc;
2 |
3 | import android.content.BroadcastReceiver;
4 | import android.content.Context;
5 | import android.content.Intent;
6 | import android.content.IntentFilter;
7 | import android.os.Bundle;
8 | import android.text.method.ScrollingMovementMethod;
9 | import android.util.Log;
10 | import android.view.View;
11 | import android.widget.Button;
12 | import android.widget.TextView;
13 |
14 | import androidx.appcompat.app.AppCompatActivity;
15 |
16 | public class GreeterActivity extends AppCompatActivity {
17 |
18 | private final String TAG = MainActivity.class.toString();
19 | private TextView text_info;
20 | // 服务端和客户端
21 | private GRPCClient grpcClient;
22 |
23 | public static void startActivity(Context context) {
24 | try {
25 | Intent target = new Intent();
26 | target.setClass(context, GreeterActivity.class);
27 | target.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
28 | context.startActivity(target);
29 | } catch (Exception e) {
30 | e.printStackTrace();
31 | }
32 | }
33 |
34 | @Override
35 | protected void onCreate(Bundle savedInstanceState) {
36 | super.onCreate(savedInstanceState);
37 | setContentView(R.layout.activity_greeter);
38 | // 初始化控件
39 | initView();
40 | // 注册广播接收器
41 | register();
42 | // 初始化服务端和客户端
43 | grpcClient = new GRPCClient(GreeterActivity.this);
44 | GRPCServer grpcServer = new GRPCServer(GreeterActivity.this);
45 | }
46 |
47 | // 初始化控件
48 | private void initView() {
49 | Button button1 = findViewById(R.id.button1);
50 | button1.setOnClickListener(v -> grpcClient.simpleHello());
51 | Button button2 = findViewById(R.id.button2);
52 | button2.setOnClickListener(v -> grpcClient.clientStream());
53 | Button button3 = findViewById(R.id.button3);
54 | button3.setOnClickListener(v -> grpcClient.serverStream());
55 | Button button4 = findViewById(R.id.button4);
56 | button4.setOnClickListener(v -> grpcClient.bothFlowStream());
57 | text_info = findViewById(R.id.text_info);
58 | text_info.setMovementMethod(new ScrollingMovementMethod());
59 | }
60 |
61 | // 注册广播更新ui
62 | private void register() {
63 | // 注册一个广播用于更新ui
64 | BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
65 | @Override
66 | public void onReceive(Context context, Intent intent) {
67 | Log.d(TAG, "广播收到消息" + intent.getStringExtra("info"));
68 | text_info.append(intent.getStringExtra("info") + "\n");
69 | }
70 | };
71 | IntentFilter filter = new IntentFilter("main.info");
72 | registerReceiver(broadcastReceiver, filter);
73 | }
74 |
75 | }
76 |
--------------------------------------------------------------------------------
/AppGrpc/src/main/java/com/yc/appgrpc/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.yc.appgrpc;
2 |
3 | import androidx.appcompat.app.AppCompatActivity;
4 |
5 | import android.os.Bundle;
6 | import android.view.View;
7 |
8 | import com.yc.roundcorner.view.RoundTextView;
9 | import com.yc.toastutils.ToastUtils;
10 |
11 | public class MainActivity extends AppCompatActivity {
12 |
13 | private RoundTextView tvRpc1;
14 | private RoundTextView tvRpc2;
15 |
16 | @Override
17 | protected void onCreate(Bundle savedInstanceState) {
18 | super.onCreate(savedInstanceState);
19 | setContentView(R.layout.activity_rpc_main);
20 | tvRpc1 = findViewById(R.id.tv_rpc_1);
21 | tvRpc2 = findViewById(R.id.tv_rpc_2);
22 | tvRpc1.setOnClickListener(new View.OnClickListener() {
23 | @Override
24 | public void onClick(View v) {
25 | GreeterActivity.startActivity(MainActivity.this);
26 | }
27 | });
28 | tvRpc2.setOnClickListener(new View.OnClickListener() {
29 | @Override
30 | public void onClick(View v) {
31 | ToastUtils.showRoundRectToast("效率测试");
32 | new ProtoJsonTest.JsonProtoTest().gson();
33 | new ProtoJsonTest.JsonProtoTest().protoTest();
34 | new ProtoJsonTest.JsonProtoTest().testSearchRequest();
35 | }
36 | });
37 | }
38 | }
--------------------------------------------------------------------------------
/AppGrpc/src/main/proto/efficient_test.proto:
--------------------------------------------------------------------------------
1 | //版本:默认为proto2,也可以为proto3
2 | syntax = "proto3";
3 |
4 | //相当于命名空间
5 | package tutorial;
6 |
7 | option java_package = "com.yc.appgrpc";
8 | //java_package 就是生成我们.java文件的包名
9 | option java_outer_classname = "AddressBookProto";
10 | //java_outer_classname也就是我们把.proto编译成.java后的名字(即AddressBookProto.java)
11 |
12 | //Person 类,消息结构
13 | message Person {
14 | string name = 1;
15 | //这里的required 的修饰符表示候name必须赋值(没有默认值)
16 | int32 id = 2;
17 | string email = 3;
18 | //optional 也就是可不赋值, proto3中已移除该关键字
19 | //当然optional string email = 3;[default = 0]默认值是0
20 | //required和optional可以有默认值
21 |
22 | //枚举定义
23 | enum PhoneType {
24 | MOBILE = 0;
25 | HOME = 1;
26 | WORK = 2;
27 | }
28 |
29 | //结构体、类,统一定义为 message实际上是嵌套类
30 | message PhoneNumber {
31 | string number = 1;
32 | PhoneType type = 2;
33 | }
34 |
35 | //repeated 表示词字段可以出现多次
36 | repeated PhoneNumber phones = 4;
37 | }
38 |
39 | //AddressBook 类
40 | message AddressBook {
41 | repeated Person people = 1;
42 | }
43 |
44 | message SearchRequest {
45 | string query = 1;
46 | int32 page_number = 2;
47 | int32 result_per_page = 3;
48 | }
--------------------------------------------------------------------------------
/AppGrpc/src/main/proto/greeter.proto:
--------------------------------------------------------------------------------
1 | // Copyright 2015 The gRPC Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 |
16 |
17 | //protobuf 有2个版本,语法不同,默认版本是 proto2
18 | //如果需要 proto3,则需要在非空非注释第一行使用 syntax = "proto3" 标明版本。现在推荐使用proto3版本。
19 | syntax = "proto3";
20 | option java_multiple_files = true;
21 | //这指定了我们要用于生成的 Java 类的包。如果java_package.proto 文件中没有给出明确的选项,那么默认情况下将使用 proto 包(使用“package”关键字指定)。
22 | //但是,proto 包通常不会成为好的 Java 包,因为 proto 包不应该以反向域名开头。如果我们从这个 .proto 生成另一种语言的代码,则该java_package选项无效。
23 | option java_package = "com.yc.appgrpc";
24 | option java_outer_classname = "GreeterProto";
25 | option objc_class_prefix = "HLW";
26 |
27 | //proto文件上方定义了package,调用方不可以更改此路径!!!
28 | package greeter;
29 |
30 | //这个是定义的服务接口
31 | //当您构建示例时,构建过程会重新生成GreeterGrpc.java,其中包含生成的 gRPC 客户端和服务器类。
32 | //这也会重新生成用于填充、序列化和检索我们的请求和响应类型的类。
33 | service Greeter {
34 | // 简单一元模式
35 | // 一个简单的 RPC,其中客户端使用存根向服务器发送请求并等待响应返回,就像普通的函数调用一样。
36 | rpc simpleHello (Request) returns (Reply) {}
37 | // 客户端流模式
38 | // 客户端流式 RPC,客户端写入一系列消息并将它们发送到服务器,再次使用提供的流。
39 | // 客户端写完消息后,它会等待服务器读取所有消息并返回响应。您可以通过将关键字放在请求stream类型之前来指定客户端流式传输方法。
40 | rpc clientStream (stream Request) returns (Reply) {}
41 | // 服务端流模式
42 | // 服务器端流式 RPC,客户端向服务器发送请求并获取流以读取一系列消息。
43 | // 客户端从返回的流中读取,直到没有更多消息为止。正如您在我们的示例中看到的,您通过将关键字放在响应stream类型 之前来指定服务器端流式传输方法。
44 | rpc serverStream (Request) returns (stream Reply) {}
45 | // 双向流模式
46 | // 双向流式 RPC,双方使用读写流发送一系列消息。
47 | // 这两个流独立运行,因此客户端和服务器可以按照他们喜欢的任何顺序读取和写入:
48 | // 例如,服务器可以在写入响应之前等待接收所有客户端消息,或者它可以交替读取一条消息然后写入一条消息,或其他一些读写组合。
49 | // 保留每个流中消息的顺序。stream 您可以通过将关键字放在请求和响应之前来指定这种类型的方法。
50 | rpc bothFlowStream (stream Request) returns (stream Reply) {}
51 | }
52 |
53 | message Request {
54 | string reqInfo = 1;
55 | }
56 |
57 | message Reply {
58 | string repInfo = 1;
59 | }
60 |
--------------------------------------------------------------------------------
/AppGrpc/src/main/proto/hello_world.proto:
--------------------------------------------------------------------------------
1 | // Copyright 2015 The gRPC Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 |
16 |
17 | //protobuf 有2个版本,语法不同,默认版本是 proto2
18 | //如果需要 proto3,则需要在非空非注释第一行使用 syntax = "proto3" 标明版本。现在推荐使用proto3版本。
19 | syntax = "proto3";
20 | option java_multiple_files = true;
21 | //这指定了我们要用于生成的 Java 类的包。如果java_package.proto 文件中没有给出明确的选项,那么默认情况下将使用 proto 包(使用“package”关键字指定)。
22 | //但是,proto 包通常不会成为好的 Java 包,因为 proto 包不应该以反向域名开头。如果我们从这个 .proto 生成另一种语言的代码,则该java_package选项无效。
23 | option java_package = "com.yc.appgrpc";
24 | option java_outer_classname = "HelloWorldProto";
25 | option objc_class_prefix = "HLW";
26 |
27 | //proto文件上方定义了package,调用方不可以更改此路径!!!
28 | package helloworld;
29 |
30 | //这个是定义的服务接口
31 | //当您构建示例时,构建过程会重新生成GreeterGrpc.java,其中包含生成的 gRPC 客户端和服务器类。
32 | //这也会重新生成用于填充、序列化和检索我们的请求和响应类型的类。
33 | service HelloWorld {
34 | rpc SayHello (HelloRequest) returns (HelloReply) {}
35 | }
36 |
37 |
38 | //关键字message: 代表了实体结构,由多个消息字段(field)组成。
39 | //这个是发送的request
40 | message HelloRequest {
41 | //消息字段(field): 包括数据类型、字段名、字段规则、字段唯一标识、默认值
42 | //数据类型:常见的原子类型都支持(在FieldDescriptor::kTypeToName中有定义)
43 | //字段规则:(在FieldDescriptor::kLabelToName中定义)
44 | //required:必须初始化字段,如果没有赋值,在数据序列化时会抛出异常
45 | //optional:可选字段,可以不必初始化。
46 | //repeated:数据可以重复(相当于java 中的Array或List)
47 | //字段唯一标识:序列化和反序列化将会使用到。
48 | //默认值:在定义消息字段时可以给出默认值。
49 | string name = 1;
50 | }
51 |
52 | //这个是收到的respond
53 | message HelloReply {
54 | string message = 1;
55 | }
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/AppGrpc/src/main/proto/msg_test.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 | package msg;
3 | option java_package = "com.yc.appgrpc";
4 | option java_outer_classname = "MsgProto";
5 |
6 | message Msg {
7 | string text = 1;
8 | }
--------------------------------------------------------------------------------
/AppGrpc/src/main/res/layout/activity_greeter.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
11 |
17 |
23 |
24 |
28 |
34 |
40 |
41 |
45 |
49 |
50 |
--------------------------------------------------------------------------------
/AppGrpc/src/main/res/layout/activity_helloworld.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
11 |
17 |
24 |
25 |
26 |
27 |
32 |
33 |
38 |
39 |
46 |
47 |
53 |
54 |
--------------------------------------------------------------------------------
/AppGrpc/src/main/res/layout/activity_rpc_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
14 |
15 |
27 |
28 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/AppGrpc/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCServerLib/90383f44339525cc8761fcf3d82d12e64a9b00bc/AppGrpc/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/AppGrpc/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCServerLib/90383f44339525cc8761fcf3d82d12e64a9b00bc/AppGrpc/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/AppGrpc/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCServerLib/90383f44339525cc8761fcf3d82d12e64a9b00bc/AppGrpc/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/AppGrpc/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCServerLib/90383f44339525cc8761fcf3d82d12e64a9b00bc/AppGrpc/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/AppGrpc/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FFBB86FC
4 | #FF6200EE
5 | #FF3700B3
6 | #FF03DAC5
7 | #FF018786
8 | #FF000000
9 | #FFFFFFFF
10 |
--------------------------------------------------------------------------------
/AppGrpc/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | AppGrpc
3 |
--------------------------------------------------------------------------------
/CompressServer/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 | gradle.properties
--------------------------------------------------------------------------------
/CompressServer/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply from: rootProject.projectDir.absolutePath + "/yc.gradle"
3 |
4 | android {
5 | compileSdkVersion rootProject.ext.android["compileSdkVersion"]
6 | //buildToolsVersion rootProject.ext.android["buildToolsVersion"]
7 |
8 | defaultConfig {
9 | minSdkVersion rootProject.ext.android["minSdkVersion"]
10 | targetSdkVersion rootProject.ext.android["targetSdkVersion"]
11 | versionCode rootProject.ext.android["versionCode"]
12 | versionName rootProject.ext.android["versionName"]
13 | multiDexEnabled true
14 | }
15 |
16 |
17 | buildTypes {
18 | release {
19 | minifyEnabled false
20 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
21 | }
22 | }
23 | }
24 |
25 | dependencies {
26 | implementation fileTree(dir: "libs", include: ["*.jar"])
27 | implementation(rootProject.ext.dependencies["appcompat"])
28 | implementation(rootProject.ext.dependencies["annotation"])
29 | //图片工具库
30 | implementation 'com.github.yangchong211.YCCommonLib:ImageToolLib:1.4.9'
31 | //File文件库
32 | implementation 'com.github.yangchong211.YCCommonLib:ToolFileLib:1.4.9'
33 | //io流读写库
34 | implementation 'com.github.yangchong211.YCCommonLib:FileIoHelper:1.4.9'
35 | //implementation project(path: ':ImageToolLib')
36 | //implementation project(path: ':ToolFileLib')
37 | //implementation project(path: ':FileIoHelper')
38 | implementation 'com.github.yangchong211.YCThreadPool:EasyExecutor:1.3.8'
39 | }
--------------------------------------------------------------------------------
/CompressServer/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/CompressServer/src/main/java/com/yc/compress/image/NetImageUtils.java:
--------------------------------------------------------------------------------
1 | package com.yc.compress.image;
2 |
3 | import android.graphics.Bitmap;
4 | import android.graphics.BitmapFactory;
5 | import android.util.Log;
6 |
7 | import java.io.IOException;
8 | import java.io.InputStream;
9 | import java.net.HttpURLConnection;
10 | import java.net.MalformedURLException;
11 | import java.net.URL;
12 |
13 | /**
14 | *
15 | * @author yangchong
16 | * email : yangchong211@163.com
17 | * time : 2020/07/22
18 | * desc : 网络图片请求工具
19 | * revise :
20 | *
21 | */
22 | public final class NetImageUtils {
23 |
24 |
25 | /**
26 | * 请求网络图片转化成bitmap
27 | * @param url url
28 | * @return 将url图片转化成bitmap对象
29 | */
30 | public static Bitmap returnBitMap(String url) {
31 | long l1 = System.currentTimeMillis();
32 | URL myFileUrl = null;
33 | Bitmap bitmap = null;
34 | HttpURLConnection conn = null;
35 | InputStream is = null;
36 | try {
37 | myFileUrl = new URL(url);
38 | } catch (MalformedURLException e) {
39 | e.printStackTrace();
40 | }
41 | if (myFileUrl==null){
42 | return null;
43 | }
44 | try {
45 | conn = (HttpURLConnection) myFileUrl.openConnection();
46 | conn.setConnectTimeout(10000);
47 | conn.setReadTimeout(5000);
48 | conn.setDoInput(true);
49 | conn.connect();
50 | is = conn.getInputStream();
51 | bitmap = BitmapFactory.decodeStream(is);
52 | } catch (IOException e) {
53 | e.printStackTrace();
54 | } finally {
55 | try {
56 | if (is != null) {
57 | is.close();
58 | conn.disconnect();
59 | }
60 | } catch (IOException e) {
61 | e.printStackTrace();
62 | }
63 | long l2 = System.currentTimeMillis();
64 | long time = (l2-l1) ;
65 | Log.e("毫秒值",time+"");
66 | }
67 | return bitmap;
68 | }
69 |
70 |
71 |
72 | }
73 |
--------------------------------------------------------------------------------
/CompressServer/src/main/java/com/yc/compress/image/ViewBitmapUtils.java:
--------------------------------------------------------------------------------
1 | package com.yc.compress.image;
2 |
3 | import android.graphics.Bitmap;
4 | import android.graphics.Canvas;
5 | import android.graphics.Color;
6 | import android.util.DisplayMetrics;
7 | import android.view.SurfaceView;
8 | import android.view.View;
9 |
10 | /**
11 | *
12 | * @author yangchong
13 | * email : yangchong211@163.com
14 | * time : 2020/07/22
15 | * desc : 将view转化为bitmap图片工具类
16 | * revise :
17 | *
18 | */
19 | public final class ViewBitmapUtils {
20 |
21 | public static Bitmap loadBitmapFromView1(View v){
22 | // 打开图像缓存
23 | v.setDrawingCacheEnabled(true);
24 | // 必须调用measure和layout方法才能成功保存可视组件的截图到png图像文件
25 | // 测量View大小
26 | int i = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
27 | int n = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
28 | v.measure(i, n);
29 | // 发送位置和尺寸到View及其所有的子View
30 | v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
31 | // 获得可视组件的截图
32 | Bitmap bitmap = v.getDrawingCache();
33 | return bitmap;
34 | }
35 |
36 | public static Bitmap loadBitmapFromView2(View v) {
37 | v.measure(0, 0);
38 | int w = v.getMeasuredWidth();
39 | int h = v.getMeasuredHeight();
40 | //如果view的宽高是小于或等于0,则是获取整个屏幕宽和高
41 | if (w <= 0 || h <= 0) {
42 | DisplayMetrics metric = new DisplayMetrics();
43 | // 屏幕宽度(像素)
44 | w = metric.widthPixels;
45 | // 屏幕高度(像素)
46 | h = metric.heightPixels;
47 | }
48 | //创建bitmap
49 | Bitmap bmp = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
50 | Canvas c = new Canvas(bmp);
51 | c.drawColor(Color.WHITE);
52 | //如果不设置canvas画布为白色,则生成透明
53 | v.layout(0, 0, w, h);
54 | v.draw(c);
55 | return bmp;
56 | }
57 |
58 | public static Bitmap loadBitmapFromView3(View view){
59 | if (view == null) {
60 | return null;
61 | }
62 | view.setDrawingCacheEnabled(true);
63 | //普通View生成图片
64 | Bitmap drawingCache = view.getDrawingCache();
65 | Bitmap bitmap = Bitmap.createBitmap(drawingCache);
66 | view.setDrawingCacheEnabled(false);
67 | view.destroyDrawingCache();
68 | return bitmap;
69 | }
70 |
71 | public static Bitmap loadBitmapFromView4(SurfaceView view){
72 | if (view == null) {
73 | return null;
74 | }
75 | view.setDrawingCacheEnabled(true);
76 | //普通View生成图片
77 | Bitmap drawingCache = view.getDrawingCache();
78 | Bitmap bitmap = Bitmap.createBitmap(drawingCache);
79 | view.setDrawingCacheEnabled(false);
80 | view.destroyDrawingCache();
81 | return bitmap;
82 | }
83 |
84 | }
85 |
--------------------------------------------------------------------------------
/CompressServer/src/main/java/com/yc/compress/luban/Checker.java:
--------------------------------------------------------------------------------
1 | package com.yc.compress.luban;
2 |
3 | import android.graphics.BitmapFactory;
4 |
5 | import com.yc.fileiohelper.BaseIoUtils;
6 | import com.yc.compress.image.PicCalculateUtils;
7 |
8 | import java.io.File;
9 | import java.io.InputStream;
10 | import java.util.Arrays;
11 |
12 | enum Checker {
13 | /**
14 | * 单例对象
15 | */
16 | SINGLE;
17 |
18 | private static final String JPG = ".jpg";
19 |
20 | private final byte[] JPEG_SIGNATURE = new byte[]{(byte) 0xFF, (byte) 0xD8, (byte) 0xFF};
21 |
22 | /**
23 | * Determine if it is JPG.
24 | *
25 | * @param is image file input stream
26 | */
27 | boolean isJPG(InputStream is) {
28 | return isJPG(BaseIoUtils.toByteArray(is));
29 | }
30 |
31 | /**
32 | * Returns the degrees in clockwise. Values are 0, 90, 180, or 270.
33 | */
34 | int getOrientation(InputStream is) {
35 | return PicCalculateUtils.getOrientation(BaseIoUtils.toByteArray(is));
36 | }
37 |
38 | private boolean isJPG(byte[] data) {
39 | if (data == null || data.length < 3) {
40 | return false;
41 | }
42 | byte[] signatureB = new byte[]{data[0], data[1], data[2]};
43 | return Arrays.equals(JPEG_SIGNATURE, signatureB);
44 | }
45 |
46 |
47 | String extSuffix(InputStreamProvider input) {
48 | try {
49 | BitmapFactory.Options options = new BitmapFactory.Options();
50 | options.inJustDecodeBounds = true;
51 | BitmapFactory.decodeStream(input.open(), null, options);
52 | return options.outMimeType.replace("image/", ".");
53 | } catch (Exception e) {
54 | return JPG;
55 | }
56 | }
57 |
58 | boolean needCompress(int leastCompressSize, String path) {
59 | if (leastCompressSize > 0) {
60 | File source = new File(path);
61 | return source.exists() && source.length() > (leastCompressSize << 10);
62 | }
63 | return true;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/CompressServer/src/main/java/com/yc/compress/luban/CompressionPredicate.java:
--------------------------------------------------------------------------------
1 | package com.yc.compress.luban;
2 |
3 | public interface CompressionPredicate {
4 |
5 | /**
6 | * Determine the given input path should be compressed and return a boolean.
7 | *
8 | * @param path input path
9 | * @return the boolean result
10 | */
11 | boolean apply(String path);
12 | }
13 |
--------------------------------------------------------------------------------
/CompressServer/src/main/java/com/yc/compress/luban/Engine.java:
--------------------------------------------------------------------------------
1 | package com.yc.compress.luban;
2 |
3 | import android.graphics.Bitmap;
4 | import android.graphics.BitmapFactory;
5 |
6 | import com.yc.compress.image.AppBitmapUtils;
7 | import com.yc.compress.image.PicCalculateUtils;
8 |
9 | import java.io.ByteArrayOutputStream;
10 | import java.io.File;
11 | import java.io.FileOutputStream;
12 | import java.io.IOException;
13 |
14 | /**
15 | * Responsible for starting compress and managing active and cached resources.
16 | */
17 | class Engine {
18 | private final InputStreamProvider srcImg;
19 | private final File tagImg;
20 | private int srcWidth;
21 | private int srcHeight;
22 | private final boolean focusAlpha;
23 |
24 | Engine(InputStreamProvider srcImg, File tagImg, boolean focusAlpha) throws IOException {
25 | this.tagImg = tagImg;
26 | this.srcImg = srcImg;
27 | this.focusAlpha = focusAlpha;
28 |
29 | BitmapFactory.Options options = new BitmapFactory.Options();
30 | options.inJustDecodeBounds = true;
31 | options.inSampleSize = 1;
32 |
33 | BitmapFactory.decodeStream(srcImg.open(), null, options);
34 | this.srcWidth = options.outWidth;
35 | this.srcHeight = options.outHeight;
36 | }
37 |
38 | File compress() throws IOException {
39 | BitmapFactory.Options options = new BitmapFactory.Options();
40 | //计算采样率
41 | options.inSampleSize = PicCalculateUtils.computeSize(srcWidth,srcHeight);
42 |
43 | Bitmap tagBitmap = BitmapFactory.decodeStream(srcImg.open(), null, options);
44 | ByteArrayOutputStream stream = new ByteArrayOutputStream();
45 |
46 | if (Checker.SINGLE.isJPG(srcImg.open())) {
47 | //旋转Bitmap的角度,获取一张新的图片
48 | tagBitmap = AppBitmapUtils.rotatingImage(tagBitmap, Checker.SINGLE.getOrientation(srcImg.open()));
49 | }
50 | tagBitmap.compress(focusAlpha ? Bitmap.CompressFormat.PNG : Bitmap.CompressFormat.JPEG, 60, stream);
51 | tagBitmap.recycle();
52 |
53 | FileOutputStream fos = new FileOutputStream(tagImg);
54 | fos.write(stream.toByteArray());
55 | fos.flush();
56 | fos.close();
57 | stream.close();
58 |
59 | return tagImg;
60 | }
61 | }
--------------------------------------------------------------------------------
/CompressServer/src/main/java/com/yc/compress/luban/InputStreamAdapter.java:
--------------------------------------------------------------------------------
1 | package com.yc.compress.luban;
2 |
3 | import java.io.IOException;
4 | import java.io.InputStream;
5 |
6 | /**
7 | * Automatically close the previous InputStream when opening a new InputStream,
8 | * and finally need to manually call {@link #close()} to release the resource.
9 | */
10 | public abstract class InputStreamAdapter implements InputStreamProvider {
11 |
12 | private InputStream inputStream;
13 |
14 | @Override
15 | public InputStream open() throws IOException {
16 | close();
17 | inputStream = openInternal();
18 | return inputStream;
19 | }
20 |
21 | public abstract InputStream openInternal() throws IOException;
22 |
23 | @Override
24 | public void close() {
25 | if (inputStream != null) {
26 | try {
27 | inputStream.close();
28 | } catch (IOException ignore) {
29 | } finally {
30 | inputStream = null;
31 | }
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/CompressServer/src/main/java/com/yc/compress/luban/InputStreamProvider.java:
--------------------------------------------------------------------------------
1 | package com.yc.compress.luban;
2 |
3 | import java.io.IOException;
4 | import java.io.InputStream;
5 |
6 | /**
7 | * 通过此接口获取输入流,以兼容文件、FileProvider方式获取到的图片
8 | *
9 | * Get the input stream through this interface, and obtain the picture using compatible files and FileProvider
10 | */
11 | public interface InputStreamProvider {
12 |
13 | InputStream open() throws IOException;
14 |
15 | void close();
16 |
17 | String getPath();
18 | }
19 |
--------------------------------------------------------------------------------
/CompressServer/src/main/java/com/yc/compress/luban/OnCompressListener.java:
--------------------------------------------------------------------------------
1 | package com.yc.compress.luban;
2 |
3 | import java.io.File;
4 |
5 | public interface OnCompressListener {
6 |
7 | /**
8 | * Fired when the compression is started, override to handle in your own code
9 | */
10 | void onStart();
11 |
12 | /**
13 | * Fired when a compression returns successfully, override to handle in your own code
14 | */
15 | void onSuccess(File file);
16 |
17 | /**
18 | * Fired when a compression fails to complete, override to handle in your own code
19 | */
20 | void onError(Throwable e);
21 | }
22 |
--------------------------------------------------------------------------------
/CompressServer/src/main/java/com/yc/compress/luban/OnRenameListener.java:
--------------------------------------------------------------------------------
1 | package com.yc.compress.luban;
2 |
3 | public interface OnRenameListener {
4 |
5 | /**
6 | * 压缩前调用该方法用于修改压缩后文件名
7 | *
8 | * Call before compression begins.
9 | *
10 | * @param filePath 传入文件路径/ file path
11 | * @return 返回重命名后的字符串/ file name
12 | */
13 | String rename(String filePath);
14 | }
15 |
--------------------------------------------------------------------------------
/CompressServer/src/main/java/com/yc/compress/utils/AppCompress.java:
--------------------------------------------------------------------------------
1 | package com.yc.compress.utils;
2 |
3 | import android.graphics.Bitmap;
4 | import android.graphics.BitmapFactory;
5 | /**
6 | *
7 | * @author yangchong
8 | * email : yangchong211@163.com
9 | * time : 2017/5/11
10 | * desc : 图片压缩
11 | * revise :
12 | * GitHub :
13 | *
14 | */
15 | public final class AppCompress {
16 |
17 | private static volatile AppCompress INSTANCE;
18 | private CompressConfig compressConfig;
19 |
20 | private AppCompress() {
21 |
22 | }
23 |
24 | public static AppCompress getInstance() {
25 | if (INSTANCE == null) {
26 | synchronized (AppCompress.class) {
27 | if (INSTANCE == null) {
28 | INSTANCE = new AppCompress();
29 | }
30 | }
31 | }
32 | return INSTANCE;
33 | }
34 |
35 | public void setCompressConfig(CompressConfig config){
36 | compressConfig = config;
37 | }
38 |
39 | public CompressConfig getCompressConfig() {
40 | if (compressConfig == null){
41 | compressConfig = CompressConfig.getDefault();
42 | }
43 | return compressConfig;
44 | }
45 |
46 | /**
47 | * 质量压缩
48 | */
49 | public Bitmap compressQuality(String path) {
50 | Bitmap inputBitmap = BitmapFactory.decodeFile(path);
51 | return CompressUtils.compressImage(inputBitmap);
52 | }
53 |
54 | /**
55 | * 质量压缩
56 | */
57 | public Bitmap compressSize(String path) {
58 | Bitmap inputBitmap = BitmapFactory.decodeFile(path);
59 | return CompressUtils.compressImage(inputBitmap);
60 | }
61 |
62 | /**
63 | * 采样率压缩 & 质量压缩
64 | */
65 | public Bitmap compressSizePath(String path) {
66 | BitmapFactory.Options options = new BitmapFactory.Options();
67 | //设置options.inJustDecodeBounds会返回整张图片或者图片的size
68 | //计算采样率只需要宽高
69 | options.inJustDecodeBounds = true;
70 | options.inPreferredConfig = getCompressConfig().getPixelConfig();
71 | //此处在option中已取得宽高
72 | BitmapFactory.decodeFile(path,options);
73 | //设置采样率
74 | options.inSampleSize = CompressUtils.calculateSampleSize(options);
75 | options.inJustDecodeBounds = false;
76 | Bitmap bitmap = BitmapFactory.decodeFile(path,options);
77 | Bitmap newBitmap = CompressUtils.compressByQuality(bitmap,100,options);
78 | return newBitmap;
79 | }
80 |
81 | }
82 |
--------------------------------------------------------------------------------
/CompressServer/src/main/java/com/yc/compress/utils/CompressConfig.java:
--------------------------------------------------------------------------------
1 | package com.yc.compress.utils;
2 |
3 | import android.graphics.Bitmap;
4 |
5 | /**
6 | *
7 | * @author yangchong
8 | * email : yangchong211@163.com
9 | * time : 2017/5/11
10 | * desc : 图片压缩配置类
11 | * revise :
12 | * GitHub :
13 | *
14 | */
15 | public final class CompressConfig {
16 |
17 | /**
18 | * 图片压缩格式
19 | */
20 | private Bitmap.CompressFormat comPressFormat= Bitmap.CompressFormat.JPEG;
21 | /**
22 | * 图片格式
23 | */
24 | private String fileSuffix=".jpg";
25 | /**
26 | * 图片压缩像素模式
27 | */
28 | private Bitmap.Config pixelConfig= Bitmap.Config.ARGB_8888;
29 | /**
30 | * 无论宽高,目标允许的最大像素,启用像素压缩时生效
31 | */
32 | private int maxPixel = 1280;
33 | /**
34 | * 图片压缩的目标大小,单位B(最终图片的大小会小于这个值),启用质量压缩时生效
35 | */
36 | private int targetSize = 200 * 1024;
37 | /**
38 | * 默认压缩质量为80
39 | */
40 | private int quality = 80;
41 | /**
42 | * 质量压缩最大值
43 | */
44 | private int maxSize;
45 | /**
46 | * 获取默认的配置
47 | */
48 | public static CompressConfig getDefault() {
49 | return new CompressConfig();
50 | }
51 |
52 | public int getTargetSize() {
53 | return targetSize;
54 | }
55 |
56 | public int getMaxPixel() {
57 | return maxPixel;
58 | }
59 |
60 | public Bitmap.Config getPixelConfig() {
61 | return pixelConfig;
62 | }
63 |
64 | public String getFileSuffix() {
65 | return fileSuffix;
66 | }
67 |
68 | public Bitmap.CompressFormat getComPressFormat() {
69 | return comPressFormat;
70 | }
71 |
72 | public int getQuality() {
73 | return quality;
74 | }
75 |
76 | public int getMaxSize() {
77 | return maxSize;
78 | }
79 |
80 | public static Builder builder() {
81 | return new Builder();
82 | }
83 |
84 | public static class Builder {
85 |
86 | private final CompressConfig config;
87 |
88 | private Builder() {
89 | config = new CompressConfig();
90 | }
91 |
92 | public Builder setTargetSize(int size) {
93 | config.targetSize = size;
94 | return this;
95 | }
96 |
97 | public Builder setMaxPixel(int pixel) {
98 | config.maxPixel = pixel;
99 | return this;
100 | }
101 |
102 | public Builder setQuality(int quality) {
103 | config.quality = quality;
104 | return this;
105 | }
106 |
107 | /**
108 | * 设置质量压缩最大值
109 | * @param maxSize 最大值
110 | */
111 | public Builder setMaxSize(int maxSize) {
112 | config.maxSize = maxSize;
113 | return this;
114 | }
115 |
116 | public Builder setBitmapConfig(Bitmap.Config bitmapConfig) {
117 | config.pixelConfig = bitmapConfig;
118 | return this;
119 | }
120 |
121 | public Builder setCompressFormat(Bitmap.CompressFormat format){
122 | config.comPressFormat = format;
123 | if (format== Bitmap.CompressFormat.JPEG){
124 | config.fileSuffix = ".jpg";
125 | }else if (format== Bitmap.CompressFormat.PNG){
126 | config.fileSuffix = ".png";
127 | }else {
128 | config.fileSuffix = ".webp";
129 | }
130 | return this;
131 | }
132 |
133 | public CompressConfig build() {
134 | return config;
135 | }
136 | }
137 |
138 |
139 | }
140 |
--------------------------------------------------------------------------------
/CompressServer/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | compress
3 |
4 |
--------------------------------------------------------------------------------
/CompressServer/图片README.md:
--------------------------------------------------------------------------------
1 | # 图片工具库
2 | #### 目录介绍
3 | - 01.基础概念介绍
4 | - 02.常见思路和做法
5 | - 03.Api调用说明
6 | - 04.遇到的坑分析
7 | - 05.其他问题说明
8 |
9 |
10 | ### 01.基础概念介绍
11 | #### 1.1 图片的常见格式
12 | - 第一种常见格式:PNG
13 | - 无法进行质量压缩
14 | - 第二种格式:JPG/JPEG
15 | - 最常见格式
16 | - 第三种格式:WEBP
17 | - 相比png,webp格式的图片更节省空间,可以减少Apk的大小。
18 | - 第四种格式:SVG
19 | - 如果担心太多的分辨率图片会导致Apk变大,那可以使用SVG矢量图,只需要一个图片,可以无损的放大与缩小。
20 | - 第五种格式:iconfont
21 | - 可以在iconfont网站下载图片,如果是自己的设计我们同样可以上传到iconfont自己的项目中,然后再下载代码。
22 | - 将资源中iconfont.ttf是我们需要导入到项目中的。我们需要把iconfont.ttf导入到项目的assets目录下。
23 | - 需要注意的是在xml中直接使用unicode是可以的,但是在Java中直接使用是不行的。
24 |
25 |
26 | #### 1.4 Bitmap像素是否可以更改
27 | - 两种创建Bitmap的方式,一种是使用BitmapFactory,一种是使用Bitmap静态方法。
28 | - 假如我有一张图片,绿色的颜色非常丰富,但绿色很暗,这个时候我想要修改该图片每个像素中的绿色值,用这两种方式创建的Bitmap都能直接修改吗?不能……
29 | - 所有使用 BitmapFactory创建的Bitmap都是不可更改其像素值的,只有通过Bitmap以下几种函数创建的Bitmap才能完成如上需求。
30 | - 只有这三个方法生成的Bitmap可以进行像素更改操作
31 | ``` java
32 | copy(Bitmap.Config config,boolean isMutable)
33 | createBitmap(int width,int height,Bitmap.Config config)
34 | createScaledBitmap(Bitmap src,int dstWidth,int dstHeight,boolean filter)
35 | ```
36 |
37 |
38 |
39 | #### 1.5 图片一些注意事项
40 | - 同样图片显示在大小不相同的ImageView上,内存是一样吗?
41 | - 图片占据内存空间大小与图片在界面上显示的大小没有关系。
42 | - 图片放在res不同目录,加载的内存是一样的吗?
43 | - 最终图片加载进内存所占据的大小会不一样,因为系统在加载 res 目录下的资源图片时,会根据图片存放的不同目录做一次分辨率的转换,而转换的规则是:新图的高度 = 原图高度 * (设备的 dpi / 目录对应的 dpi )
44 |
45 |
46 |
47 |
48 | ### 02.常见思路和做法
49 | #### 2.2 如何将jpg转png
50 | - 将jpg转png的方案如下
51 | - 第一种:直接修改文件的后缀名
52 | - 第二种:将jpg图片加载成bitmap,然后调用bitmap中的compress
53 | - 第三种:利用一些三方软件工具转码修改图片
54 |
55 |
56 |
57 | #### 2.3 如何将图片置灰
58 | - 大概的操作步骤
59 | - 第一步:获取原始图片的宽高,然后创建一个bitmap可变位图对象。
60 | - 第二步:创建画板canvas对象,然后创建画笔paint。然后调用canvas.drawBitmap方法绘制图片
61 | - 第三步:对画笔进行修饰,设置画笔颜色属性,这里使用到了ColorMatrix,核心就是设置饱和度为0,即可绘制灰色内容
62 |
63 |
64 |
65 |
66 | #### 2.4 判断图片旋转方向
67 | - 在Android中使用ImageView显示图片的时候发现图片显示不正,方向偏了或者倒过来了。
68 | - 解决这个问题很自然想到的两步走,首先是要自动识别图像方向,计算旋转角度,然后对图像进行旋转并显示。
69 | - 识别图像方向
70 | - 首先在这里提一个概念EXIF(Exchangeable Image File Format,可交换图像文件)。简而言之,Exif是一个标准,用于电子照相机(也包括手机、扫描器等)上,用来规范图片、声音、视屏以及它们的一些辅助标记格式。
71 | - Exif支持的格式如下:图像;压缩图像文件:JPEG、DCT;非压缩图像文件:TIFF;音频;RIFF、WAV
72 | - Android提供了对JPEG格式图像Exif接口支持,可以读取JPEG文件metadata信息,参见ExifInterface。这些Metadata信息总的来说大致分为三类:日期时间、空间信息(经纬度、高度)、Camera信息(孔径、焦距、旋转角、曝光量等等)。
73 | - 关于图像旋转
74 | - 获取了图片的旋转方向后,然后再设置图像旋转。最后Bitmap提供的静态createBitmap方法,可以对图片设置旋转角度。
75 |
76 |
77 | #### 2.5 保存图片且刷相册
78 |
79 |
80 |
81 | ### 03.Api调用说明
82 | #### 3.1 如何依赖该库
83 | - 依赖maven仓库如下所示
84 | ``` java
85 |
86 | ```
87 |
88 |
89 | #### 3.2 如何使用Api
90 | - 获取bitmap相关api
91 | ``` java
92 | //通过资源id获取bitmap位图
93 | Bitmap bitmap = AppBitmapUtils.getBitmap(this,R.drawable.bg_kites_min);
94 | //将图片设置成灰色
95 | Bitmap greyBitmap = AppBitmapUtils.greyBitmap(bitmap);
96 | //旋转Bitmap的角度,获取一张新的图片
97 | Bitmap rotatingImage = AppBitmapUtils.rotatingImage(bitmap, degree);
98 | ```
99 | - 图片保存到本地文件api
100 | ``` kotlin
101 | val image = AppFileUtils.getExternalFilePath(this, "image")
102 | val fileName = image + File.separator + "yc12345678.png"
103 | val saveBitmapAsPng = BitmapUtils.saveBitmapAsPng(greyBitmap, fileName)
104 |
105 | //把图片加入到系统图库中
106 | ImageSaveUtils.insertImage(ImageActivity.this,file);
107 | ```
108 | - 计算图片一些属性api
109 | ``` java
110 | //读取图片属性:旋转的角度
111 | int degree = PicCalculateUtils.readPictureDegree(this, path);
112 | ```
113 | - 将view转化为bitmap相关api
114 | ``` java
115 |
116 | ```
117 |
118 |
119 |
120 |
121 | ### 04.遇到的坑分析
122 | #### 4.1 刷新图片库弊端
123 | - 调用系统提供的插入图库的方法:
124 | ``` java
125 | sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"+ Environment.getExternalStorageDirectory())));
126 | ```
127 | - 上面那条广播是扫描整个sd卡的广播,如果你sd卡里面东西很多会扫描很久,所以这样子用户体现很不好。
128 | - 解决办法如下所示
129 | ``` java
130 | sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(new File("/sdcard/YC/image.jpg"))););
131 | ```
132 |
133 |
134 |
135 |
136 |
137 | ### 05.其他问题说明
138 | #### 5.1 保存图片到相册思考
139 | - 在本地保存了文件,然后插入图库。删除本地文件,图库中图片会消失吗?
140 |
141 |
142 |
143 | ### 参考和学习
144 | - 抖音 Android 性能优化:
145 | - https://juejin.cn/post/7096059314233671694
146 | - Android图片格式转换为JPG
147 | - https://blog.csdn.net/iblade/article/details/79153769
148 |
149 |
150 |
151 |
152 |
153 |
154 |
--------------------------------------------------------------------------------
/EasyBleServer/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/caches
5 | /.idea/libraries
6 | /.idea/modules.xml
7 | /.idea/workspace.xml
8 | /.idea/navEditor.xml
9 | /.idea/assetWizardSettings.xml
10 | .DS_Store
11 | /build
12 | /captures
13 | .externalNativeBuild
14 | .cxx
15 | .idea/
16 |
17 |
18 |
19 | # Built application files
20 | *.apk
21 | *.ap_
22 |
23 | # Files for the ART/Dalvik VM
24 | *.dex
25 |
26 | # Java class files
27 | *.class
28 |
29 | # Generated files
30 | bin/
31 | gen/
32 | out/
33 |
34 | # Gradle files
35 | .gradle/
36 | build/
37 |
38 | # Local configuration file (sdk path, etc)
39 | local.properties
40 |
41 | # Proguard folder generated by Eclipse
42 | proguard/
43 |
44 | # Log Files
45 | *.log
46 |
47 | # Android Studio Navigation editor temp files
48 | .navigation/
49 |
50 | # Android Studio captures folder
51 | captures/
52 |
53 | # Intellij
54 | *.iml
55 | .idea/workspace.xml
56 | .idea/tasks.xml
57 | .idea/gradle.xml
58 | .idea/dictionaries
59 | .idea/libraries
60 |
61 | # Keystore files
62 | *.jks
63 |
64 | # External native build folder generated in Android Studio 2.2 and later
65 | .externalNativeBuild
66 |
67 | # Google Services (e.g. APIs or Firebase)
68 | google-services.json
69 |
70 | # Freeline
71 | freeline.py
72 | freeline/
73 | freeline_project_description.json
74 | .idea/
75 |
76 |
77 |
--------------------------------------------------------------------------------
/EasyBleServer/README.md:
--------------------------------------------------------------------------------
1 | # 蓝牙工具库
2 | #### 目录介绍
3 | - 01.基础概念介绍
4 | - 02.常见思路做法
5 | - 03.Api调用说明
6 | - 04.遇到的坑分析
7 | - 05.该库性能分析
8 |
9 |
10 |
11 | ### 00.问题思考问答
12 | - 如何搜索蓝牙设备?搜索到很多设备后如何过滤公司的硬件设备?
13 | - 如何进行配对,如何判断配对是否成功?如何解除配对?
14 |
15 |
16 |
17 | ### 01.基础概念介绍
18 |
19 |
20 |
21 | #### 1.3 蓝牙核心关键类
22 | - BluetoothAdapter:表示本地蓝牙适配器(蓝牙无线装置),是所有蓝牙交互的入口点。借助该类,您可以发现其他蓝牙设备、查询已绑定(已配对)设备的列表、使用已知的 MAC 地址实例化 BluetoothDevice,以及通过创建 BluetoothServerSocket 侦听来自其他设备的通信。
23 | - BluetoothDevice:表示远程蓝牙设备。借助该类,您可以通过 BluetoothSocket 请求与某个远程设备建立连接,或查询有关该设备的信息,例如设备的名称、地址、类和绑定状态等。
24 | - BluetoothSocket:表示蓝牙套接字接口(类似于 TCP Socket)。这是允许应用使用 InputStream 和 OutputStream 与其他蓝牙设备交换数据的连接点。
25 | - BluetoothServerSocket:表示用于侦听传入请求的开放服务器套接字(类似于 TCP ServerSocket)。如要连接两台 Android 设备,其中一台设备必须使用此类开放一个服务器套接字。当远程蓝牙设备向此设备发出连接请求时,该设备接受连接,然后返回已连接的 BluetoothSocket。
26 | - BluetoothClass:描述蓝牙设备的一般特征和功能。这是一组只读属性,用于定义设备的类和服务。
27 | - BluetoothProfile:表示蓝牙配置文件的接口。蓝牙配置文件是适用于设备间蓝牙通信的无线接口规范。举个例子:免提配置文件。
28 | - BluetoothHeadset:提供蓝牙耳机支持,以便与手机配合使用。这包括蓝牙耳机配置文件和免提 (v1.5) 配置文件。
29 | - BluetoothA2dp:定义如何使用蓝牙立体声音频传输配置文件 (A2DP),通过蓝牙连接将高质量音频从一个设备流式传输至另一个设备。
30 | - BluetoothHealth:表示用于控制蓝牙服务的健康设备配置文件代理。
31 | - BluetoothHealthCallback:用于实现 BluetoothHealth 回调的抽象类。您必须扩展此类并实现回调方法,以接收关于应用注册状态和蓝牙通道状态变化的更新内容。
32 | - BluetoothHealthAppConfiguration:表示第三方蓝牙健康应用注册的应用配置,该配置旨在实现与远程蓝牙健康设备的通信。
33 | - BluetoothProfile.ServiceListener:当 BluetoothProfile 进程间通信 (IPC) 客户端连接到运行特定配置文件的内部服务或断开该服务连接时,向该客户端发送通知的接口。
34 |
35 |
36 | ### 02.常见思路和做法
37 | #### 2.1 蓝牙开发步骤
38 |
39 |
40 |
41 |
42 | ### 03.Api调用说明
43 |
44 |
45 |
46 | ### 04.遇到的坑分析
47 |
48 |
49 |
50 |
51 | ### 05.该库性能分析
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/EasyBleServer/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply from: rootProject.projectDir.absolutePath + "/yc.gradle"
3 | //迁移到jitpack
4 | apply plugin: 'com.github.dcendents.android-maven'
5 |
6 |
7 | android {
8 | compileSdkVersion rootProject.ext.android["compileSdkVersion"]
9 | //buildToolsVersion rootProject.ext.android["buildToolsVersion"]
10 |
11 | defaultConfig {
12 | minSdkVersion rootProject.ext.android["minSdkVersion"]
13 | targetSdkVersion rootProject.ext.android["targetSdkVersion"]
14 | versionCode rootProject.ext.android["versionCode"]
15 | versionName rootProject.ext.android["versionName"]
16 | multiDexEnabled true
17 | }
18 |
19 |
20 | buildTypes {
21 | release {
22 | minifyEnabled false
23 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
24 | }
25 | }
26 | }
27 |
28 | dependencies {
29 | implementation fileTree(dir: "libs", include: ["*.jar"])
30 | implementation(rootProject.ext.dependencies["appcompat"])
31 | implementation(rootProject.ext.dependencies["annotation"])
32 | //implementation project(path: ':ToolUtilsLib')
33 | //工具类utils
34 | implementation 'com.github.yangchong211.YCCommonLib:ToolUtilsLib:1.4.9'
35 | }
--------------------------------------------------------------------------------
/EasyBleServer/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/EasyBleServer/src/main/java/com/yc/easyble/callback/BleBaseCallback.java:
--------------------------------------------------------------------------------
1 | package com.yc.easyble.callback;
2 |
3 |
4 | import android.os.Handler;
5 |
6 | public abstract class BleBaseCallback {
7 |
8 | private String key;
9 | private Handler handler;
10 |
11 | public String getKey() {
12 | return key;
13 | }
14 |
15 | public void setKey(String key) {
16 | this.key = key;
17 | }
18 |
19 | public Handler getHandler() {
20 | return handler;
21 | }
22 |
23 | public void setHandler(Handler handler) {
24 | this.handler = handler;
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/EasyBleServer/src/main/java/com/yc/easyble/callback/BleGattCallback.java:
--------------------------------------------------------------------------------
1 |
2 | package com.yc.easyble.callback;
3 |
4 | import android.bluetooth.BluetoothGatt;
5 | import android.bluetooth.BluetoothGattCallback;
6 | import android.os.Build;
7 |
8 | import androidx.annotation.RequiresApi;
9 |
10 | import com.yc.easyble.data.BleDevice;
11 | import com.yc.easyble.exception.BleException;
12 |
13 |
14 | @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
15 | public abstract class BleGattCallback extends BluetoothGattCallback {
16 |
17 | public abstract void onStartConnect();
18 |
19 | public abstract void onConnectFail(BleDevice bleDevice, BleException exception);
20 |
21 | public abstract void onConnectSuccess(BleDevice bleDevice, BluetoothGatt gatt, int status);
22 |
23 | public abstract void onDisConnected(boolean isActiveDisConnected, BleDevice device, BluetoothGatt gatt, int status);
24 |
25 | }
--------------------------------------------------------------------------------
/EasyBleServer/src/main/java/com/yc/easyble/callback/BleIndicateCallback.java:
--------------------------------------------------------------------------------
1 | package com.yc.easyble.callback;
2 |
3 |
4 | import com.yc.easyble.exception.BleException;
5 |
6 | public abstract class BleIndicateCallback extends BleBaseCallback{
7 |
8 | public abstract void onIndicateSuccess();
9 |
10 | public abstract void onIndicateFailure(BleException exception);
11 |
12 | public abstract void onCharacteristicChanged(byte[] data);
13 | }
14 |
--------------------------------------------------------------------------------
/EasyBleServer/src/main/java/com/yc/easyble/callback/BleMtuChangedCallback.java:
--------------------------------------------------------------------------------
1 | package com.yc.easyble.callback;
2 |
3 |
4 | import com.yc.easyble.exception.BleException;
5 |
6 | public abstract class BleMtuChangedCallback extends BleBaseCallback {
7 |
8 | public abstract void onSetMTUFailure(BleException exception);
9 |
10 | public abstract void onMtuChanged(int mtu);
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/EasyBleServer/src/main/java/com/yc/easyble/callback/BleNotifyCallback.java:
--------------------------------------------------------------------------------
1 | package com.yc.easyble.callback;
2 |
3 |
4 | import com.yc.easyble.exception.BleException;
5 |
6 | public abstract class BleNotifyCallback extends BleBaseCallback {
7 |
8 | public abstract void onNotifySuccess();
9 |
10 | public abstract void onNotifyFailure(BleException exception);
11 |
12 | public abstract void onCharacteristicChanged(byte[] data);
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/EasyBleServer/src/main/java/com/yc/easyble/callback/BleReadCallback.java:
--------------------------------------------------------------------------------
1 | package com.yc.easyble.callback;
2 |
3 |
4 | import com.yc.easyble.exception.BleException;
5 |
6 | public abstract class BleReadCallback extends BleBaseCallback {
7 |
8 | public abstract void onReadSuccess(byte[] data);
9 |
10 | public abstract void onReadFailure(BleException exception);
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/EasyBleServer/src/main/java/com/yc/easyble/callback/BleRssiCallback.java:
--------------------------------------------------------------------------------
1 | package com.yc.easyble.callback;
2 |
3 |
4 | import com.yc.easyble.exception.BleException;
5 |
6 | public abstract class BleRssiCallback extends BleBaseCallback{
7 |
8 | public abstract void onRssiFailure(BleException exception);
9 |
10 | public abstract void onRssiSuccess(int rssi);
11 |
12 | }
--------------------------------------------------------------------------------
/EasyBleServer/src/main/java/com/yc/easyble/callback/BleScanAndConnectCallback.java:
--------------------------------------------------------------------------------
1 | package com.yc.easyble.callback;
2 |
3 |
4 | import com.yc.easyble.data.BleDevice;
5 |
6 | public abstract class BleScanAndConnectCallback extends BleGattCallback implements IBleScanCallback {
7 |
8 | public abstract void onScanFinished(BleDevice scanResult);
9 |
10 | public void onLeScan(BleDevice bleDevice) {
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/EasyBleServer/src/main/java/com/yc/easyble/callback/BleScanCallback.java:
--------------------------------------------------------------------------------
1 | package com.yc.easyble.callback;
2 |
3 |
4 | import com.yc.easyble.data.BleDevice;
5 |
6 | import java.util.List;
7 |
8 | public abstract class BleScanCallback implements IBleScanCallback {
9 |
10 | public abstract void onScanFinished(List scanResultList);
11 |
12 | public void onLeScan(BleDevice bleDevice) {
13 |
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/EasyBleServer/src/main/java/com/yc/easyble/callback/BleWriteCallback.java:
--------------------------------------------------------------------------------
1 | package com.yc.easyble.callback;
2 |
3 |
4 | import com.yc.easyble.exception.BleException;
5 |
6 | public abstract class BleWriteCallback extends BleBaseCallback{
7 |
8 | public abstract void onWriteSuccess(int current, int total, byte[] justWrite);
9 |
10 | public abstract void onWriteFailure(BleException exception);
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/EasyBleServer/src/main/java/com/yc/easyble/callback/IBleScanCallback.java:
--------------------------------------------------------------------------------
1 | package com.yc.easyble.callback;
2 |
3 | import com.yc.easyble.data.BleDevice;
4 |
5 |
6 | public interface IBleScanCallback {
7 |
8 | /**
9 | * 开始扫描
10 | *
11 | * @param success 是否成功
12 | */
13 | void onScanStarted(boolean success);
14 |
15 | /**
16 | * 扫描中
17 | *
18 | * @param bleDevice 蓝牙设备
19 | */
20 | void onScanning(BleDevice bleDevice);
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/EasyBleServer/src/main/java/com/yc/easyble/config/BleScanConfig.java:
--------------------------------------------------------------------------------
1 | package com.yc.easyble.config;
2 |
3 |
4 | import android.content.Context;
5 |
6 |
7 | /**
8 | *
9 | * @author yangchong
10 | * email : yangchong211@163.com
11 | * time : 2018/4/17
12 | * desc : 配置文件
13 | * revise :
14 | *
15 | */
16 | public final class BleScanConfig {
17 |
18 | private static final int DEFAULT_MAX_MULTIPLE_DEVICE = 7;
19 | private static final int DEFAULT_OPERATE_TIME = 5000;
20 |
21 | private final int maxConnectCount;
22 | private final int operateTimeout;
23 |
24 | public int getMaxConnectCount() {
25 | return maxConnectCount;
26 | }
27 |
28 | public int getOperateTimeout() {
29 | return operateTimeout;
30 | }
31 |
32 |
33 | private BleScanConfig(Builder builder) {
34 | maxConnectCount = builder.maxConnectCount;
35 | operateTimeout = builder.operateTimeout;
36 | }
37 |
38 | public static Builder newBuilder() {
39 | return new Builder();
40 | }
41 |
42 | public static final class Builder {
43 |
44 | private int maxConnectCount = DEFAULT_MAX_MULTIPLE_DEVICE;
45 | private int operateTimeout = DEFAULT_OPERATE_TIME;
46 |
47 | public Builder() {
48 |
49 | }
50 |
51 | public Builder setMaxConnectCount(int count) {
52 | if (count > DEFAULT_MAX_MULTIPLE_DEVICE) {
53 | count = DEFAULT_MAX_MULTIPLE_DEVICE;
54 | }
55 | this.maxConnectCount = count;
56 | return this;
57 | }
58 |
59 | public Builder setOperateTimeout(int count) {
60 | this.operateTimeout = count;
61 | return this;
62 | }
63 |
64 | public BleScanConfig build(Context context) {
65 | return new BleScanConfig(this);
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/EasyBleServer/src/main/java/com/yc/easyble/config/BleScanRuleConfig.java:
--------------------------------------------------------------------------------
1 | package com.yc.easyble.config;
2 |
3 |
4 | import com.yc.easyble.BleManager;
5 |
6 | import java.util.UUID;
7 |
8 | public final class BleScanRuleConfig {
9 |
10 | private UUID[] mServiceUuids = null;
11 | private String[] mDeviceNames = null;
12 | private String mDeviceMac = null;
13 | private boolean mAutoConnect = false;
14 | private boolean mFuzzy = false;
15 | private long mScanTimeOut = BleManager.DEFAULT_SCAN_TIME;
16 |
17 | public UUID[] getServiceUuids() {
18 | return mServiceUuids;
19 | }
20 |
21 | public String[] getDeviceNames() {
22 | return mDeviceNames;
23 | }
24 |
25 | public String getDeviceMac() {
26 | return mDeviceMac;
27 | }
28 |
29 | public boolean isAutoConnect() {
30 | return mAutoConnect;
31 | }
32 |
33 | public boolean isFuzzy() {
34 | return mFuzzy;
35 | }
36 |
37 | public long getScanTimeOut() {
38 | return mScanTimeOut;
39 | }
40 |
41 | public static class Builder {
42 |
43 | private UUID[] mServiceUuids = null;
44 | private String[] mDeviceNames = null;
45 | private String mDeviceMac = null;
46 | private boolean mAutoConnect = false;
47 | private boolean mFuzzy = false;
48 | private long mTimeOut = BleManager.DEFAULT_SCAN_TIME;
49 |
50 | public Builder setServiceUuids(UUID[] uuids) {
51 | this.mServiceUuids = uuids;
52 | return this;
53 | }
54 |
55 | public Builder setDeviceName(boolean fuzzy, String... name) {
56 | this.mFuzzy = fuzzy;
57 | this.mDeviceNames = name;
58 | return this;
59 | }
60 |
61 | public Builder setDeviceMac(String mac) {
62 | this.mDeviceMac = mac;
63 | return this;
64 | }
65 |
66 | public Builder setAutoConnect(boolean autoConnect) {
67 | this.mAutoConnect = autoConnect;
68 | return this;
69 | }
70 |
71 | public Builder setScanTimeOut(long timeOut) {
72 | this.mTimeOut = timeOut;
73 | return this;
74 | }
75 |
76 | void applyConfig(BleScanRuleConfig config) {
77 | config.mServiceUuids = this.mServiceUuids;
78 | config.mDeviceNames = this.mDeviceNames;
79 | config.mDeviceMac = this.mDeviceMac;
80 | config.mAutoConnect = this.mAutoConnect;
81 | config.mFuzzy = this.mFuzzy;
82 | config.mScanTimeOut = this.mTimeOut;
83 | }
84 |
85 | public BleScanRuleConfig build() {
86 | BleScanRuleConfig config = new BleScanRuleConfig();
87 | applyConfig(config);
88 | return config;
89 | }
90 |
91 | }
92 |
93 |
94 | }
95 |
--------------------------------------------------------------------------------
/EasyBleServer/src/main/java/com/yc/easyble/data/BleConnectStateParameter.java:
--------------------------------------------------------------------------------
1 | package com.yc.easyble.data;
2 |
3 |
4 | public class BleConnectStateParameter {
5 |
6 | private int status;
7 | private boolean isActive;
8 |
9 | public BleConnectStateParameter(int status) {
10 | this.status = status;
11 | }
12 |
13 | public int getStatus() {
14 | return status;
15 | }
16 |
17 | public void setStatus(int status) {
18 | this.status = status;
19 | }
20 |
21 | public boolean isActive() {
22 | return isActive;
23 | }
24 |
25 | public void setActive(boolean active) {
26 | isActive = active;
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/EasyBleServer/src/main/java/com/yc/easyble/data/BleDevice.java:
--------------------------------------------------------------------------------
1 | package com.yc.easyble.data;
2 |
3 |
4 | import android.bluetooth.BluetoothDevice;
5 | import android.os.Parcel;
6 | import android.os.Parcelable;
7 |
8 |
9 | public class BleDevice implements Parcelable {
10 |
11 | private BluetoothDevice mDevice;
12 | private byte[] mScanRecord;
13 | private int mRssi;
14 | private long mTimestampNanos;
15 |
16 | public BleDevice(BluetoothDevice device) {
17 | mDevice = device;
18 | }
19 |
20 | public BleDevice(BluetoothDevice device, int rssi, byte[] scanRecord, long timestampNanos) {
21 | mDevice = device;
22 | mScanRecord = scanRecord;
23 | mRssi = rssi;
24 | mTimestampNanos = timestampNanos;
25 | }
26 |
27 | protected BleDevice(Parcel in) {
28 | mDevice = in.readParcelable(BluetoothDevice.class.getClassLoader());
29 | mScanRecord = in.createByteArray();
30 | mRssi = in.readInt();
31 | mTimestampNanos = in.readLong();
32 | }
33 |
34 | @Override
35 | public void writeToParcel(Parcel dest, int flags) {
36 | dest.writeParcelable(mDevice, flags);
37 | dest.writeByteArray(mScanRecord);
38 | dest.writeInt(mRssi);
39 | dest.writeLong(mTimestampNanos);
40 | }
41 |
42 | @Override
43 | public int describeContents() {
44 | return 0;
45 | }
46 |
47 | public static final Creator CREATOR = new Creator() {
48 | @Override
49 | public BleDevice createFromParcel(Parcel in) {
50 | return new BleDevice(in);
51 | }
52 |
53 | @Override
54 | public BleDevice[] newArray(int size) {
55 | return new BleDevice[size];
56 | }
57 | };
58 |
59 | public String getName() {
60 | if (mDevice != null) {
61 | return mDevice.getName();
62 | }
63 | return null;
64 | }
65 |
66 | public String getMac() {
67 | if (mDevice != null) {
68 | return mDevice.getAddress();
69 | }
70 | return null;
71 | }
72 |
73 | public String getKey() {
74 | if (mDevice != null) {
75 | return mDevice.getName() + mDevice.getAddress();
76 | }
77 | return "";
78 | }
79 |
80 | public BluetoothDevice getDevice() {
81 | return mDevice;
82 | }
83 |
84 | public void setDevice(BluetoothDevice device) {
85 | this.mDevice = device;
86 | }
87 |
88 | public byte[] getScanRecord() {
89 | return mScanRecord;
90 | }
91 |
92 | public void setScanRecord(byte[] scanRecord) {
93 | this.mScanRecord = scanRecord;
94 | }
95 |
96 | public int getRssi() {
97 | return mRssi;
98 | }
99 |
100 | public void setRssi(int rssi) {
101 | this.mRssi = rssi;
102 | }
103 |
104 | public long getTimestampNanos() {
105 | return mTimestampNanos;
106 | }
107 |
108 | public void setTimestampNanos(long timestampNanos) {
109 | this.mTimestampNanos = timestampNanos;
110 | }
111 |
112 | }
113 |
--------------------------------------------------------------------------------
/EasyBleServer/src/main/java/com/yc/easyble/data/BleMsg.java:
--------------------------------------------------------------------------------
1 | package com.yc.easyble.data;
2 |
3 |
4 |
5 | public class BleMsg {
6 |
7 | // Scan
8 | public static final int MSG_SCAN_DEVICE = 0X00;
9 |
10 | // Connect
11 | public static final int MSG_CONNECT_FAIL = 0x01;
12 | public static final int MSG_DISCONNECTED = 0x02;
13 | public static final int MSG_RECONNECT = 0x03;
14 | public static final int MSG_DISCOVER_SERVICES = 0x04;
15 | public static final int MSG_DISCOVER_FAIL = 0x05;
16 | public static final int MSG_DISCOVER_SUCCESS = 0x06;
17 | public static final int MSG_CONNECT_OVER_TIME = 0x07;
18 |
19 | // Notify
20 | public static final int MSG_CHA_NOTIFY_START = 0x11;
21 | public static final int MSG_CHA_NOTIFY_RESULT = 0x12;
22 | public static final int MSG_CHA_NOTIFY_DATA_CHANGE = 0x13;
23 | public static final String KEY_NOTIFY_BUNDLE_STATUS = "notify_status";
24 | public static final String KEY_NOTIFY_BUNDLE_VALUE = "notify_value";
25 |
26 | // Indicate
27 | public static final int MSG_CHA_INDICATE_START = 0x21;
28 | public static final int MSG_CHA_INDICATE_RESULT = 0x22;
29 | public static final int MSG_CHA_INDICATE_DATA_CHANGE = 0x23;
30 | public static final String KEY_INDICATE_BUNDLE_STATUS = "indicate_status";
31 | public static final String KEY_INDICATE_BUNDLE_VALUE = "indicate_value";
32 |
33 | // Write
34 | public static final int MSG_CHA_WRITE_START = 0x31;
35 | public static final int MSG_CHA_WRITE_RESULT = 0x32;
36 | public static final int MSG_SPLIT_WRITE_NEXT = 0x33;
37 | public static final String KEY_WRITE_BUNDLE_STATUS = "write_status";
38 | public static final String KEY_WRITE_BUNDLE_VALUE = "write_value";
39 |
40 | // Read
41 | public static final int MSG_CHA_READ_START = 0x41;
42 | public static final int MSG_CHA_READ_RESULT = 0x42;
43 | public static final String KEY_READ_BUNDLE_STATUS = "read_status";
44 | public static final String KEY_READ_BUNDLE_VALUE = "read_value";
45 |
46 | // Rssi
47 | public static final int MSG_READ_RSSI_START = 0x51;
48 | public static final int MSG_READ_RSSI_RESULT = 0x52;
49 | public static final String KEY_READ_RSSI_BUNDLE_STATUS = "rssi_status";
50 | public static final String KEY_READ_RSSI_BUNDLE_VALUE = "rssi_value";
51 |
52 | // Mtu
53 | public static final int MSG_SET_MTU_START = 0x61;
54 | public static final int MSG_SET_MTU_RESULT = 0x62;
55 | public static final String KEY_SET_MTU_BUNDLE_STATUS = "mtu_status";
56 | public static final String KEY_SET_MTU_BUNDLE_VALUE = "mtu_value";
57 |
58 |
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/EasyBleServer/src/main/java/com/yc/easyble/data/BleScanState.java:
--------------------------------------------------------------------------------
1 | package com.yc.easyble.data;
2 |
3 |
4 | public enum BleScanState {
5 |
6 | /**
7 | * 空闲
8 | */
9 | STATE_IDLE(-1),
10 | /**
11 | * 正在扫描中
12 | */
13 | STATE_SCANNING(0X01);
14 |
15 | private final int code;
16 |
17 | BleScanState(int code) {
18 | this.code = code;
19 | }
20 |
21 | public int getCode() {
22 | return code;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/EasyBleServer/src/main/java/com/yc/easyble/data/BleWriteState.java:
--------------------------------------------------------------------------------
1 | package com.yc.easyble.data;
2 |
3 |
4 |
5 | public class BleWriteState {
6 |
7 | public static final int DATA_WRITE_SINGLE = 1;
8 | }
9 |
--------------------------------------------------------------------------------
/EasyBleServer/src/main/java/com/yc/easyble/exception/BleException.java:
--------------------------------------------------------------------------------
1 | package com.yc.easyble.exception;
2 |
3 | import java.io.Serializable;
4 |
5 |
6 | public abstract class BleException implements Serializable {
7 |
8 | private static final long serialVersionUID = 8004414918500865564L;
9 |
10 | public static final int ERROR_CODE_TIMEOUT = 100;
11 | public static final int ERROR_CODE_GATT = 101;
12 | public static final int ERROR_CODE_OTHER = 102;
13 |
14 | private int code;
15 | private String description;
16 |
17 | public BleException(int code, String description) {
18 | this.code = code;
19 | this.description = description;
20 | }
21 |
22 | public int getCode() {
23 | return code;
24 | }
25 |
26 | public BleException setCode(int code) {
27 | this.code = code;
28 | return this;
29 | }
30 |
31 | public String getDescription() {
32 | return description;
33 | }
34 |
35 | public BleException setDescription(String description) {
36 | this.description = description;
37 | return this;
38 | }
39 |
40 | @Override
41 | public String toString() {
42 | return "BleException { " +
43 | "code=" + code +
44 | ", description='" + description + '\'' +
45 | '}';
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/EasyBleServer/src/main/java/com/yc/easyble/exception/ConnectException.java:
--------------------------------------------------------------------------------
1 | package com.yc.easyble.exception;
2 |
3 | import android.bluetooth.BluetoothGatt;
4 |
5 |
6 | public class ConnectException extends BleException {
7 |
8 | private BluetoothGatt bluetoothGatt;
9 | private int gattStatus;
10 |
11 | public ConnectException(BluetoothGatt bluetoothGatt, int gattStatus) {
12 | super(ERROR_CODE_GATT, "Gatt Exception Occurred! ");
13 | this.bluetoothGatt = bluetoothGatt;
14 | this.gattStatus = gattStatus;
15 | }
16 |
17 | public int getGattStatus() {
18 | return gattStatus;
19 | }
20 |
21 | public ConnectException setGattStatus(int gattStatus) {
22 | this.gattStatus = gattStatus;
23 | return this;
24 | }
25 |
26 | public BluetoothGatt getBluetoothGatt() {
27 | return bluetoothGatt;
28 | }
29 |
30 | public ConnectException setBluetoothGatt(BluetoothGatt bluetoothGatt) {
31 | this.bluetoothGatt = bluetoothGatt;
32 | return this;
33 | }
34 |
35 | @Override
36 | public String toString() {
37 | return "ConnectException{" +
38 | "gattStatus=" + gattStatus +
39 | ", bluetoothGatt=" + bluetoothGatt +
40 | "} " + super.toString();
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/EasyBleServer/src/main/java/com/yc/easyble/exception/GattException.java:
--------------------------------------------------------------------------------
1 | package com.yc.easyble.exception;
2 |
3 |
4 | public class GattException extends BleException {
5 |
6 | private int gattStatus;
7 |
8 | public GattException(int gattStatus) {
9 | super(ERROR_CODE_GATT, "Gatt Exception Occurred! ");
10 | this.gattStatus = gattStatus;
11 | }
12 |
13 | public int getGattStatus() {
14 | return gattStatus;
15 | }
16 |
17 | public GattException setGattStatus(int gattStatus) {
18 | this.gattStatus = gattStatus;
19 | return this;
20 | }
21 |
22 | @Override
23 | public String toString() {
24 | return "GattException{" +
25 | "gattStatus=" + gattStatus +
26 | "} " + super.toString();
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/EasyBleServer/src/main/java/com/yc/easyble/exception/OtherException.java:
--------------------------------------------------------------------------------
1 | package com.yc.easyble.exception;
2 |
3 |
4 | public class OtherException extends BleException {
5 |
6 | public OtherException(String description) {
7 | super(ERROR_CODE_OTHER, description);
8 | }
9 |
10 | }
11 |
--------------------------------------------------------------------------------
/EasyBleServer/src/main/java/com/yc/easyble/exception/TimeoutException.java:
--------------------------------------------------------------------------------
1 | package com.yc.easyble.exception;
2 |
3 |
4 | public class TimeoutException extends BleException {
5 |
6 | public TimeoutException() {
7 | super(ERROR_CODE_TIMEOUT, "Timeout Exception Occurred!");
8 | }
9 |
10 | }
11 |
--------------------------------------------------------------------------------
/EasyBleServer/src/main/java/com/yc/easyble/utils/BleHelperUtils.java:
--------------------------------------------------------------------------------
1 | package com.yc.easyble.utils;
2 |
3 | import android.bluetooth.BluetoothDevice;
4 | import android.os.Build;
5 | import android.util.Log;
6 |
7 | import com.yc.easyble.BleManager;
8 |
9 | import java.lang.reflect.Method;
10 | import java.util.Set;
11 |
12 | public final class BleHelperUtils {
13 |
14 | private final static String TAG = "BleHelperUtils";
15 |
16 | /**
17 | * 在低于Android API 19时,配对的方法是隐藏的方法,所以只有通过反射方法实现。反射BluetoothDevice类中的createBond方法。
18 | * @param bluetoothDevice bluetoothDevice
19 | * @return true 执行绑定 false 未执行绑定
20 | */
21 | public static boolean boundDevice(BluetoothDevice bluetoothDevice) {
22 | if (bluetoothDevice == null) {
23 | Log.e(TAG, "boundDevice-->bluetoothDevice == null");
24 | return false;
25 | }
26 | try {
27 | Method createBondMethod = BluetoothDevice.class.getMethod("createBond");
28 | Boolean returnValue = (Boolean) createBondMethod.invoke(bluetoothDevice);
29 | if (returnValue == null){
30 | return false;
31 | }
32 | return returnValue;
33 | } catch (Exception e) {
34 | e.printStackTrace();
35 | }
36 | return true;
37 | }
38 |
39 | /**
40 | * 官方API,但是只支持Android API 19以上的设备。
41 | * @param bluetoothDevice bluetoothDevice
42 | * @return true 执行绑定 false 未执行绑定
43 | */
44 | public static boolean boundDeviceAPI(BluetoothDevice bluetoothDevice) {
45 | if (bluetoothDevice == null) {
46 | return false;
47 | }
48 | //注意:Android 4.4版本之后的API
49 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
50 | return bluetoothDevice.createBond();
51 | }
52 | return false;
53 | }
54 |
55 | /**
56 | * 解除配对的方法是隐藏的方法,所以只有通过反射方法实现。反射BluetoothDevice类中的removeBond方法。
57 | * 参考:/Settings/src/com/android/settings/bluetooth/CachedBluetoothDevice.java
58 | * @param bluetoothDevice bluetoothDevice
59 | * @return true 执行解除绑定 false 未执行解除绑定
60 | */
61 | public static boolean removeBond(BluetoothDevice bluetoothDevice) {
62 | if (bluetoothDevice == null) {
63 | Log.e(TAG, "boundDevice-->bluetoothDevice == null");
64 | return false;
65 | }
66 | try {
67 | Method createBondMethod = BluetoothDevice.class.getMethod("removeBond");
68 | Boolean returnValue = (Boolean) createBondMethod.invoke(bluetoothDevice);
69 | if (returnValue == null){
70 | return false;
71 | }
72 | return returnValue;
73 | } catch (Exception e) {
74 | e.printStackTrace();
75 | }
76 | return true;
77 | }
78 |
79 | /**
80 | * 判断设备是否配对
81 | * @param bluetoothDevice bluetoothDevice
82 | * @return
83 | */
84 | public static boolean findDeviceBonded(BluetoothDevice bluetoothDevice){
85 | //获取所有已经配对的设备
86 | Set bondedDevices =
87 | BleManager.getInstance().getBluetoothAdapter().getBondedDevices();
88 | if (bondedDevices != null && bondedDevices.size() > 0){
89 | for (BluetoothDevice device : bondedDevices) {
90 | if (device.getAddress().equals(bluetoothDevice.getAddress())){
91 | return true;
92 | }
93 | }
94 | }
95 | return false;
96 | }
97 |
98 | }
99 |
--------------------------------------------------------------------------------
/EasyBleServer/src/main/java/com/yc/easyble/utils/BleLog.java:
--------------------------------------------------------------------------------
1 | package com.yc.easyble.utils;
2 |
3 |
4 | import android.util.Log;
5 |
6 | public final class BleLog {
7 |
8 | public static boolean isPrint = true;
9 | private static final String defaultTag = "FastBle";
10 |
11 | public static void d(String msg) {
12 | if (isPrint && msg != null)
13 | Log.d(defaultTag, msg);
14 | }
15 |
16 | public static void i(String msg) {
17 | if (isPrint && msg != null)
18 | Log.i(defaultTag, msg);
19 | }
20 |
21 | public static void w(String msg) {
22 | if (isPrint && msg != null)
23 | Log.w(defaultTag, msg);
24 | }
25 |
26 | public static void e(String msg) {
27 | if (isPrint && msg != null)
28 | Log.e(defaultTag, msg);
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/EasyBleServer/src/main/java/com/yc/easyble/utils/BleLruHashMap.java:
--------------------------------------------------------------------------------
1 | package com.yc.easyble.utils;
2 |
3 |
4 | import com.yc.easyble.bluetooth.BleBluetooth;
5 |
6 | import java.util.LinkedHashMap;
7 |
8 | public class BleLruHashMap extends LinkedHashMap {
9 |
10 | private final int MAX_SIZE;
11 |
12 | public BleLruHashMap(int saveSize) {
13 | super((int) Math.ceil(saveSize / 0.75) + 1, 0.75f, true);
14 | MAX_SIZE = saveSize;
15 | }
16 |
17 | @Override
18 | protected boolean removeEldestEntry(java.util.Map.Entry eldest) {
19 | if (size() > MAX_SIZE && eldest.getValue() instanceof BleBluetooth) {
20 | ((BleBluetooth) eldest.getValue()).disconnect();
21 | }
22 | return size() > MAX_SIZE;
23 | }
24 |
25 | @Override
26 | public String toString() {
27 | StringBuilder sb = new StringBuilder();
28 | for (Entry entry : entrySet()) {
29 | sb.append(String.format("%s:%s ", entry.getKey(), entry.getValue()));
30 | }
31 | return sb.toString();
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/EasyBleServer/src/main/java/com/yc/easyble/utils/HexUtil.java:
--------------------------------------------------------------------------------
1 | package com.yc.easyble.utils;
2 |
3 | public class HexUtil {
4 |
5 | private static final char[] DIGITS_LOWER = {'0', '1', '2', '3', '4', '5',
6 | '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
7 |
8 | private static final char[] DIGITS_UPPER = {'0', '1', '2', '3', '4', '5',
9 | '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
10 |
11 | public static char[] encodeHex(byte[] data) {
12 | return encodeHex(data, true);
13 | }
14 |
15 | public static char[] encodeHex(byte[] data, boolean toLowerCase) {
16 | return encodeHex(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);
17 | }
18 |
19 | protected static char[] encodeHex(byte[] data, char[] toDigits) {
20 | if (data == null)
21 | return null;
22 | int l = data.length;
23 | char[] out = new char[l << 1];
24 | for (int i = 0, j = 0; i < l; i++) {
25 | out[j++] = toDigits[(0xF0 & data[i]) >>> 4];
26 | out[j++] = toDigits[0x0F & data[i]];
27 | }
28 | return out;
29 | }
30 |
31 |
32 | public static String encodeHexStr(byte[] data) {
33 | return encodeHexStr(data, true);
34 | }
35 |
36 | public static String encodeHexStr(byte[] data, boolean toLowerCase) {
37 | return encodeHexStr(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);
38 | }
39 |
40 |
41 | protected static String encodeHexStr(byte[] data, char[] toDigits) {
42 | return new String(encodeHex(data, toDigits));
43 | }
44 |
45 | public static String formatHexString(byte[] data) {
46 | return formatHexString(data, false);
47 | }
48 |
49 | public static String formatHexString(byte[] data, boolean addSpace) {
50 | if (data == null || data.length < 1)
51 | return null;
52 | StringBuilder sb = new StringBuilder();
53 | for (int i = 0; i < data.length; i++) {
54 | String hex = Integer.toHexString(data[i] & 0xFF);
55 | if (hex.length() == 1) {
56 | hex = '0' + hex;
57 | }
58 | sb.append(hex);
59 | if (addSpace)
60 | sb.append(" ");
61 | }
62 | return sb.toString().trim();
63 | }
64 |
65 | public static byte[] decodeHex(char[] data) {
66 | int len = data.length;
67 |
68 | if ((len & 0x01) != 0) {
69 | throw new RuntimeException("Odd number of characters.");
70 | }
71 |
72 | byte[] out = new byte[len >> 1];
73 |
74 | // two characters form the hex value.
75 | for (int i = 0, j = 0; j < len; i++) {
76 | int f = toDigit(data[j], j) << 4;
77 | j++;
78 | f = f | toDigit(data[j], j);
79 | j++;
80 | out[i] = (byte) (f & 0xFF);
81 | }
82 |
83 | return out;
84 | }
85 |
86 |
87 | protected static int toDigit(char ch, int index) {
88 | int digit = Character.digit(ch, 16);
89 | if (digit == -1) {
90 | throw new RuntimeException("Illegal hexadecimal character " + ch
91 | + " at index " + index);
92 | }
93 | return digit;
94 | }
95 |
96 |
97 | public static byte[] hexStringToBytes(String hexString) {
98 | if (hexString == null || hexString.equals("")) {
99 | return null;
100 | }
101 | hexString = hexString.trim();
102 | hexString = hexString.toUpperCase();
103 | int length = hexString.length() / 2;
104 | char[] hexChars = hexString.toCharArray();
105 | byte[] d = new byte[length];
106 | for (int i = 0; i < length; i++) {
107 | int pos = i * 2;
108 | d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
109 | }
110 | return d;
111 | }
112 |
113 | public static byte charToByte(char c) {
114 | return (byte) "0123456789ABCDEF".indexOf(c);
115 | }
116 |
117 | public static String extractData(byte[] data, int position) {
118 | return HexUtil.formatHexString(new byte[]{data[position]});
119 | }
120 |
121 | }
122 |
--------------------------------------------------------------------------------
/GalleryPagerLib/.gitignore:
--------------------------------------------------------------------------------
1 | # Built application files
2 | *.apk
3 | *.ap_
4 |
5 | # Files for the ART/Dalvik VM
6 | *.dex
7 |
8 | # Java class files
9 | *.class
10 |
11 | # Generated files
12 | bin/
13 | gen/
14 | out/
15 |
16 | # Gradle files
17 | .gradle/
18 | build/
19 |
20 | # Local configuration file (sdk path, etc)
21 | local.properties
22 |
23 | # Proguard folder generated by Eclipse
24 | proguard/
25 |
26 | # Log Files
27 | *.log
28 |
29 | # Android Studio Navigation editor temp files
30 | .navigation/
31 |
32 | # Android Studio captures folder
33 | captures/
34 |
35 | # Intellij
36 | *.iml
37 | .idea/workspace.xml
38 | .idea/tasks.xml
39 | .idea/gradle.xml
40 | .idea/dictionaries
41 | .idea/libraries
42 |
43 | # Keystore files
44 | *.jks
45 |
46 | # External native build folder generated in Android Studio 2.2 and later
47 | .externalNativeBuild
48 |
49 | # Google Services (e.g. APIs or Firebase)
50 | google-services.json
51 |
52 | # Freeline
53 | freeline.py
54 | freeline/
55 | freeline_project_description.json
56 |
--------------------------------------------------------------------------------
/GalleryPagerLib/.idea/.gitignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCServerLib/90383f44339525cc8761fcf3d82d12e64a9b00bc/GalleryPagerLib/.idea/.gitignore
--------------------------------------------------------------------------------
/GalleryPagerLib/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/GalleryPagerLib/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/GalleryPagerLib/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
--------------------------------------------------------------------------------
/GalleryPagerLib/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | //迁移到jitpack
3 | apply plugin: 'com.github.dcendents.android-maven'
4 |
5 |
6 | android {
7 | compileSdkVersion 29
8 | defaultConfig {
9 | minSdkVersion 16
10 | targetSdkVersion 29
11 | versionCode 15
12 | versionName "1.2.8"
13 | }
14 |
15 | buildTypes {
16 | release {
17 | minifyEnabled false
18 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
19 | }
20 | }
21 |
22 | lintOptions {
23 | abortOnError false
24 | }
25 | }
26 |
27 | dependencies {
28 | implementation fileTree(dir: 'libs', include: ['*.jar'])
29 | implementation 'com.github.chrisbanes:PhotoView:2.3.0'
30 | implementation 'com.google.android.material:material:1.2.0-alpha05'
31 | implementation 'androidx.appcompat:appcompat:1.2.0'
32 | implementation 'androidx.annotation:annotation:1.1.0'
33 | }
34 |
--------------------------------------------------------------------------------
/GalleryPagerLib/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /home/veinhorn/Android/Sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/GalleryPagerLib/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/GalleryPagerLib/src/main/java/com/yc/gallerypager/Constants.java:
--------------------------------------------------------------------------------
1 | package com.yc.gallerypager;
2 |
3 |
4 | public final class Constants {
5 | public static final String ZOOM = "zoom";
6 | public static final String IS_VIDEO = "isVideo";
7 | public static final String URL = "url";
8 | public static final String IS_LOCKED = "isLocked";
9 | public static final String IMAGE = "image";
10 | public static final String POSITION = "position";
11 |
12 | private Constants() {
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/GalleryPagerLib/src/main/java/com/yc/gallerypager/ImageFragment.java:
--------------------------------------------------------------------------------
1 | package com.yc.gallerypager;
2 |
3 | import android.os.Build;
4 | import android.os.Bundle;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 |
9 | import androidx.annotation.NonNull;
10 | import androidx.fragment.app.Fragment;
11 |
12 | import com.github.chrisbanes.photoview.PhotoView;
13 | import com.yc.gallerypager.inter.IMediaLoader;
14 |
15 | public class ImageFragment extends Fragment {
16 |
17 | private MediaInfo mMediaInfo;
18 |
19 | private SafeViewPager viewPager;
20 | private PhotoView photoView;
21 |
22 | private ScrollGalleryView.OnImageClickListener onImageClickListener;
23 | private ScrollGalleryView.OnImageLongClickListener onImageLongClickListener;
24 |
25 | private String transitionName;
26 |
27 | public void setTransitionName(String transitionName) {
28 | this.transitionName = transitionName;
29 | }
30 |
31 | public void setOnImageClickListener(ScrollGalleryView.OnImageClickListener onImageClickListener) {
32 | this.onImageClickListener = onImageClickListener;
33 | }
34 |
35 | public void setOnImageLongClickListener(ScrollGalleryView.OnImageLongClickListener onImageLongClickListener) {
36 | this.onImageLongClickListener = onImageLongClickListener;
37 | }
38 |
39 | public void setMediaInfo(MediaInfo mediaInfo) {
40 | mMediaInfo = mediaInfo;
41 | }
42 |
43 | @Override
44 | public View onCreateView(LayoutInflater inflater, ViewGroup container, final Bundle savedInstanceState) {
45 | super.onCreate(savedInstanceState);
46 | View rootView = inflater.inflate(R.layout.image_fragment, container, false);
47 | photoView = rootView.findViewById(R.id.photoView);
48 |
49 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
50 | photoView.setTransitionName(transitionName);
51 | if (onImageClickListener != null) {
52 | photoView.setOnClickListener(new View.OnClickListener() {
53 | @Override
54 | public void onClick(View view) {
55 | onImageClickListener.onClick(getPosition());
56 | }
57 | });
58 | }
59 | if (onImageLongClickListener != null) {
60 | photoView.setOnLongClickListener(new View.OnLongClickListener() {
61 | @Override
62 | public boolean onLongClick(View v) {
63 | onImageLongClickListener.onClick(getPosition());
64 | return true;
65 | }
66 | });
67 | }
68 |
69 | viewPager = (SafeViewPager) getActivity().findViewById(R.id.viewPager);
70 |
71 | if (savedInstanceState != null) {
72 | boolean isLocked = savedInstanceState.getBoolean(Constants.IS_LOCKED, false);
73 | viewPager.setLocked(isLocked);
74 | }
75 |
76 | loadImageToView();
77 |
78 | return rootView;
79 | }
80 |
81 | private int getPosition() {
82 | return getArguments().getInt(Constants.POSITION);
83 | }
84 |
85 | private void loadImageToView() {
86 | if (mMediaInfo != null) {
87 | mMediaInfo.getLoader().loadMedia(getActivity(), photoView, new IMediaLoader.SuccessCallback() {
88 | @Override
89 | public void onSuccess() {}
90 | });
91 | }
92 | }
93 |
94 | @Override
95 | public void onSaveInstanceState(@NonNull Bundle outState) {
96 | if (isViewPagerActive()) {
97 | outState.putBoolean(Constants.IS_LOCKED, viewPager.isLocked());
98 | }
99 | super.onSaveInstanceState(outState);
100 | }
101 |
102 | private boolean isViewPagerActive() {
103 | return viewPager != null;
104 | }
105 |
106 | private boolean isBackgroundImageActive() {
107 | return photoView != null && photoView.getDrawable() != null;
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/GalleryPagerLib/src/main/java/com/yc/gallerypager/MediaInfo.java:
--------------------------------------------------------------------------------
1 | package com.yc.gallerypager;
2 |
3 | import com.yc.gallerypager.inter.IMediaLoader;
4 |
5 |
6 | public class MediaInfo {
7 |
8 | private IMediaLoader mLoader;
9 |
10 | public static MediaInfo mediaLoader(IMediaLoader mediaLoader) {
11 | return new MediaInfo().setLoader(mediaLoader);
12 | }
13 |
14 | public IMediaLoader getLoader() {
15 | return mLoader;
16 | }
17 |
18 | public MediaInfo setLoader(IMediaLoader loader) {
19 | mLoader = loader;
20 | return this;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/GalleryPagerLib/src/main/java/com/yc/gallerypager/SafeViewPager.java:
--------------------------------------------------------------------------------
1 | package com.yc.gallerypager;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.view.MotionEvent;
6 | import androidx.viewpager.widget.ViewPager;
7 |
8 |
9 | public class SafeViewPager extends ViewPager {
10 |
11 | private boolean isLocked;
12 |
13 | public SafeViewPager(Context context) {
14 | super(context);
15 | isLocked = false;
16 | }
17 |
18 | public SafeViewPager(Context context, AttributeSet attrs) {
19 | super(context, attrs);
20 | isLocked = false;
21 | }
22 |
23 | @Override
24 | public boolean onInterceptTouchEvent(MotionEvent ev) {
25 | if(!isLocked) {
26 | try {
27 | return super.onInterceptTouchEvent(ev);
28 | } catch (IllegalArgumentException e) {
29 | e.printStackTrace();
30 | return false;
31 | }
32 | }
33 | return false;
34 | }
35 |
36 | @Override
37 | public boolean onTouchEvent(MotionEvent ev) {
38 | return !isLocked && super.onTouchEvent(ev);
39 | }
40 |
41 | public void setLocked(boolean isLocked) {
42 | this.isLocked = isLocked;
43 | }
44 |
45 | public boolean isLocked() {
46 | return isLocked;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/GalleryPagerLib/src/main/java/com/yc/gallerypager/SlidePagerAdapter.java:
--------------------------------------------------------------------------------
1 | package com.yc.gallerypager;
2 |
3 | import android.os.Bundle;
4 | import androidx.fragment.app.Fragment;
5 | import androidx.fragment.app.FragmentManager;
6 | import androidx.fragment.app.FragmentStatePagerAdapter;
7 | import androidx.viewpager.widget.PagerAdapter;
8 |
9 | import java.util.List;
10 |
11 | public class SlidePagerAdapter extends FragmentStatePagerAdapter {
12 |
13 | private List mListOfMedia;
14 |
15 | private boolean isZoom = false;
16 |
17 | private ScrollGalleryView.OnImageClickListener onImageClickListener;
18 | private ScrollGalleryView.OnImageLongClickListener onImageLongClickListener;
19 |
20 | private String transitionName;
21 |
22 | public SlidePagerAdapter(FragmentManager fm, List listOfMedia,
23 | boolean isZoom, ScrollGalleryView.OnImageClickListener onImageClickListener,
24 | ScrollGalleryView.OnImageLongClickListener onImageLongClickListener,
25 | String transitionName) {
26 | super(fm);
27 | this.mListOfMedia = listOfMedia;
28 | this.isZoom = isZoom;
29 | this.onImageClickListener = onImageClickListener;
30 | this.transitionName = transitionName;
31 |
32 | this.onImageLongClickListener = onImageLongClickListener;
33 | }
34 |
35 | @Override
36 | public Fragment getItem(int position) {
37 | Fragment fragment = null;
38 | if (position < mListOfMedia.size()) {
39 | MediaInfo mediaInfo = mListOfMedia.get(position);
40 | fragment = loadImageFragment(mediaInfo, position);
41 | if (position == 0)
42 | ((ImageFragment)fragment).setTransitionName(transitionName);
43 | }
44 | return fragment;
45 | }
46 |
47 | private Fragment loadImageFragment(MediaInfo mediaInfo, int position) {
48 | ImageFragment fragment = new ImageFragment();
49 | fragment.setRetainInstance(true);
50 | fragment.setMediaInfo(mediaInfo);
51 |
52 | if (onImageClickListener != null) {
53 | fragment.setOnImageClickListener(onImageClickListener);
54 | }
55 | if (onImageLongClickListener != null) {
56 | fragment.setOnImageLongClickListener(onImageLongClickListener);
57 | }
58 |
59 | Bundle bundle = new Bundle();
60 | bundle.putBoolean(Constants.ZOOM, isZoom);
61 | bundle.putInt("position", position);
62 |
63 | fragment.setArguments(bundle);
64 | return fragment;
65 | }
66 |
67 | public void removeItem(int position) {
68 | mListOfMedia.remove(position);
69 | notifyDataSetChanged();
70 | }
71 |
72 | @Override
73 | public int getCount() {
74 | return mListOfMedia.size();
75 | }
76 |
77 | @Override
78 | public int getItemPosition(Object object) {
79 | return PagerAdapter.POSITION_NONE;
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/GalleryPagerLib/src/main/java/com/yc/gallerypager/VideoPlayActivity.java:
--------------------------------------------------------------------------------
1 | package com.yc.gallerypager;
2 |
3 | import android.app.Activity;
4 | import android.media.MediaPlayer;
5 | import android.net.Uri;
6 | import android.os.Bundle;
7 | import android.view.View;
8 | import android.widget.MediaController;
9 | import android.widget.VideoView;
10 |
11 |
12 | public class VideoPlayActivity extends Activity {
13 |
14 | @Override
15 | protected void onCreate(Bundle savedInstanceState) {
16 | super.onCreate(savedInstanceState);
17 | String url = getIntent().getExtras().getString(Constants.URL);
18 | setContentView(R.layout.video_fragment);
19 | final VideoView videoView = (VideoView) findViewById(R.id.videoView);
20 | videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
21 | @Override
22 | public void onPrepared(MediaPlayer mp) {
23 | View progress = findViewById(R.id.videoProgress);
24 | progress.setVisibility(View.GONE);
25 |
26 | videoView.requestFocus();
27 | MediaController vidControl = new MediaController(VideoPlayActivity.this);
28 | vidControl.setAnchorView(videoView);
29 | videoView.setMediaController(vidControl);
30 | videoView.start();
31 | }
32 | });
33 | videoView.setVideoURI(Uri.parse(url));
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/GalleryPagerLib/src/main/java/com/yc/gallerypager/builder/BasicMediaHelper.java:
--------------------------------------------------------------------------------
1 | package com.yc.gallerypager.builder;
2 |
3 | import com.yc.gallerypager.MediaInfo;
4 | import com.yc.gallerypager.inter.IMediaHelper;
5 | import com.yc.gallerypager.loader.DefaultVideoLoader;
6 |
7 |
8 | public abstract class BasicMediaHelper implements IMediaHelper {
9 | @Override
10 | public MediaInfo video(String url, int placeholderViewId) {
11 | return MediaInfo.mediaLoader(new DefaultVideoLoader(url, placeholderViewId));
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/GalleryPagerLib/src/main/java/com/yc/gallerypager/builder/GallerySettings.java:
--------------------------------------------------------------------------------
1 | package com.yc.gallerypager.builder;
2 |
3 |
4 | import androidx.fragment.app.FragmentManager;
5 |
6 | import com.yc.gallerypager.impl.SettingsBuilderImpl;
7 | import com.yc.gallerypager.inter.ISettingsBuilder;
8 |
9 | public class GallerySettings {
10 | private int thumbnailSize;
11 | private boolean isZoomEnabled;
12 | private FragmentManager fragmentManager;
13 |
14 | public int getThumbnailSize() {
15 | return thumbnailSize;
16 | }
17 |
18 | public void setThumbnailSize(int thumbnailSize) {
19 | this.thumbnailSize = thumbnailSize;
20 | }
21 |
22 | public boolean isZoomEnabled() {
23 | return isZoomEnabled;
24 | }
25 |
26 | public void setZoomEnabled(boolean zoomEnabled) {
27 | isZoomEnabled = zoomEnabled;
28 | }
29 |
30 | public FragmentManager getFragmentManager() {
31 | return fragmentManager;
32 | }
33 |
34 | public void setFragmentManager(FragmentManager fragmentManager) {
35 | this.fragmentManager = fragmentManager;
36 | }
37 |
38 | public static ISettingsBuilder from(FragmentManager fm) {
39 | ISettingsBuilder builder = new SettingsBuilderImpl();
40 | builder.withFragmentManager(fm);
41 | return builder;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/GalleryPagerLib/src/main/java/com/yc/gallerypager/impl/GalleryBuilderImpl.java:
--------------------------------------------------------------------------------
1 | package com.yc.gallerypager.impl;
2 |
3 | import com.yc.gallerypager.MediaInfo;
4 | import com.yc.gallerypager.ScrollGalleryView;
5 | import com.yc.gallerypager.builder.GallerySettings;
6 | import com.yc.gallerypager.inter.IGalleryBuilder;
7 |
8 | import java.util.ArrayList;
9 | import java.util.List;
10 |
11 | public class GalleryBuilderImpl implements IGalleryBuilder {
12 | private ScrollGalleryView galleryView;
13 | private GallerySettings settings;
14 |
15 | private ScrollGalleryView.OnImageClickListener onImageClickListener;
16 | private ScrollGalleryView.OnImageLongClickListener onImageLongClickListener;
17 |
18 | private List medias;
19 |
20 | public GalleryBuilderImpl(ScrollGalleryView galleryView) {
21 | this.galleryView = galleryView;
22 | this.medias = new ArrayList<>();
23 | }
24 |
25 | @Override
26 | public IGalleryBuilder settings(GallerySettings settings) {
27 | this.settings = settings;
28 | return this;
29 | }
30 |
31 | @Override
32 | public IGalleryBuilder onImageClickListener(ScrollGalleryView.OnImageClickListener onImageClickListener) {
33 | this.onImageClickListener = onImageClickListener;
34 | return this;
35 | }
36 |
37 | @Override
38 | public IGalleryBuilder onImageLongClickListener(ScrollGalleryView.OnImageLongClickListener onImageLongClickListener) {
39 | this.onImageLongClickListener = onImageLongClickListener;
40 | return this;
41 | }
42 |
43 | @Override
44 | public IGalleryBuilder add(MediaInfo media) {
45 | this.medias.add(media);
46 | return this;
47 | }
48 |
49 | @Override
50 | public IGalleryBuilder add(List medias) {
51 | this.medias.addAll(medias);
52 | return this;
53 | }
54 |
55 | @Override
56 | public ScrollGalleryView build() {
57 | // check here all parameters
58 |
59 | return galleryView
60 | .setThumbnailSize(settings.getThumbnailSize())
61 | .setZoom(settings.isZoomEnabled())
62 | .addOnImageClickListener(onImageClickListener)
63 | .addOnImageLongClickListener(onImageLongClickListener)
64 | .setFragmentManager(settings.getFragmentManager())
65 | .addMedia(medias);
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/GalleryPagerLib/src/main/java/com/yc/gallerypager/impl/SettingsBuilderImpl.java:
--------------------------------------------------------------------------------
1 | package com.yc.gallerypager.impl;
2 |
3 | import androidx.fragment.app.FragmentManager;
4 |
5 | import com.yc.gallerypager.builder.GallerySettings;
6 | import com.yc.gallerypager.inter.ISettingsBuilder;
7 |
8 | public class SettingsBuilderImpl implements ISettingsBuilder {
9 | private GallerySettings gallerySettings;
10 |
11 | public SettingsBuilderImpl() {
12 | this.gallerySettings = new GallerySettings();
13 | }
14 |
15 | @Override
16 | public ISettingsBuilder thumbnailSize(int thumbnailSize) {
17 | gallerySettings.setThumbnailSize(thumbnailSize);
18 | return this;
19 | }
20 |
21 | @Override
22 | public ISettingsBuilder enableZoom(boolean isZoomEnabled) {
23 | gallerySettings.setZoomEnabled(isZoomEnabled);
24 | return this;
25 | }
26 |
27 | @Override
28 | public ISettingsBuilder withFragmentManager(FragmentManager fragmentManager) {
29 | gallerySettings.setFragmentManager(fragmentManager);
30 | return this;
31 | }
32 |
33 | @Override
34 | public GallerySettings build() {
35 | return gallerySettings;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/GalleryPagerLib/src/main/java/com/yc/gallerypager/inter/IGalleryBuilder.java:
--------------------------------------------------------------------------------
1 | package com.yc.gallerypager.inter;
2 |
3 | import com.yc.gallerypager.MediaInfo;
4 | import com.yc.gallerypager.ScrollGalleryView;
5 | import com.yc.gallerypager.builder.GallerySettings;
6 |
7 | import java.util.List;
8 |
9 | public interface IGalleryBuilder {
10 |
11 | IGalleryBuilder settings(GallerySettings settings);
12 |
13 | IGalleryBuilder onImageClickListener(ScrollGalleryView.OnImageClickListener listener);
14 |
15 | IGalleryBuilder onImageLongClickListener(ScrollGalleryView.OnImageLongClickListener listener);
16 |
17 | IGalleryBuilder add(MediaInfo media);
18 |
19 | IGalleryBuilder add(List medias);
20 |
21 | ScrollGalleryView build();
22 | }
23 |
--------------------------------------------------------------------------------
/GalleryPagerLib/src/main/java/com/yc/gallerypager/inter/IMediaHelper.java:
--------------------------------------------------------------------------------
1 | package com.yc.gallerypager.inter;
2 |
3 | import com.yc.gallerypager.MediaInfo;
4 |
5 | import java.util.List;
6 |
7 |
8 | public interface IMediaHelper {
9 |
10 | MediaInfo image(String url);
11 |
12 | List images(List urls);
13 |
14 | List images(String... urls);
15 |
16 | MediaInfo video(String url, int placeholderViewId);
17 | }
18 |
--------------------------------------------------------------------------------
/GalleryPagerLib/src/main/java/com/yc/gallerypager/inter/IMediaLoader.java:
--------------------------------------------------------------------------------
1 | package com.yc.gallerypager.inter;
2 |
3 | import android.content.Context;
4 | import android.widget.ImageView;
5 |
6 |
7 | public interface IMediaLoader {
8 |
9 | boolean isImage();
10 |
11 | void loadMedia(Context context, ImageView imageView, SuccessCallback callback);
12 |
13 | void loadThumbnail(Context context, ImageView thumbnailView, SuccessCallback callback);
14 |
15 | interface SuccessCallback {
16 | void onSuccess();
17 | }
18 | }
--------------------------------------------------------------------------------
/GalleryPagerLib/src/main/java/com/yc/gallerypager/inter/ISettingsBuilder.java:
--------------------------------------------------------------------------------
1 | package com.yc.gallerypager.inter;
2 |
3 | import androidx.fragment.app.FragmentManager;
4 | import com.yc.gallerypager.builder.GallerySettings;
5 |
6 | public interface ISettingsBuilder {
7 | ISettingsBuilder thumbnailSize(int thumbnailSize );
8 | ISettingsBuilder enableZoom(boolean isZoomEnabled);
9 | ISettingsBuilder withFragmentManager(FragmentManager fragmentManager);
10 | GallerySettings build();
11 | }
12 |
--------------------------------------------------------------------------------
/GalleryPagerLib/src/main/java/com/yc/gallerypager/loader/DefaultImageLoader.java:
--------------------------------------------------------------------------------
1 | package com.yc.gallerypager.loader;
2 |
3 | import android.content.Context;
4 | import android.graphics.Bitmap;
5 | import android.graphics.drawable.BitmapDrawable;
6 | import android.widget.ImageView;
7 |
8 | import com.yc.gallerypager.inter.IMediaLoader;
9 |
10 |
11 | public class DefaultImageLoader implements IMediaLoader {
12 |
13 | private int mId;
14 | private Bitmap mBitmap;
15 |
16 | public DefaultImageLoader(int id) {
17 | mId = id;
18 | }
19 |
20 | public DefaultImageLoader(Bitmap bitmap) {
21 | mBitmap = bitmap;
22 | }
23 |
24 | @Override
25 | public boolean isImage() {
26 | return true;
27 | }
28 |
29 | @Override
30 | public void loadMedia(Context context, ImageView imageView, SuccessCallback callback) {
31 | imageView.setImageBitmap(mBitmap);
32 | if (callback != null) {
33 | callback.onSuccess();
34 | }
35 | }
36 |
37 | @Override
38 | public void loadThumbnail(Context context, ImageView thumbnailView, SuccessCallback callback) {
39 | loadBitmap(context);
40 | thumbnailView.setImageBitmap(mBitmap);
41 | if (callback != null) {
42 | callback.onSuccess();
43 | }
44 | }
45 |
46 | private void loadBitmap(Context context) {
47 | if (mBitmap == null) {
48 | mBitmap = ((BitmapDrawable) context.getResources().getDrawable(mId)).getBitmap();
49 | }
50 | }
51 | }
--------------------------------------------------------------------------------
/GalleryPagerLib/src/main/java/com/yc/gallerypager/loader/DefaultVideoLoader.java:
--------------------------------------------------------------------------------
1 | package com.yc.gallerypager.loader;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 | import android.graphics.Bitmap;
6 | import android.graphics.drawable.BitmapDrawable;
7 | import android.view.View;
8 | import android.widget.ImageView;
9 |
10 | import com.yc.gallerypager.Constants;
11 | import com.yc.gallerypager.VideoPlayActivity;
12 | import com.yc.gallerypager.inter.IMediaLoader;
13 |
14 | public class DefaultVideoLoader implements IMediaLoader {
15 |
16 | private String url;
17 | private int mId;
18 | private Bitmap mBitmap;
19 |
20 |
21 | public DefaultVideoLoader(String url, int mId) {
22 | this.url = url;
23 | this.mId = mId;
24 | }
25 |
26 | @Override
27 | public boolean isImage() {
28 | return false;
29 | }
30 |
31 | @Override
32 | public void loadMedia(final Context context, ImageView imageView, SuccessCallback callback) {
33 | loadBitmap(context);
34 | imageView.setImageBitmap(mBitmap);
35 | imageView.setOnClickListener(new View.OnClickListener() {
36 | @Override
37 | public void onClick(View v) {
38 | displayVideo(context, url);
39 | }
40 | });
41 | }
42 |
43 | @Override
44 | public void loadThumbnail(Context context, ImageView thumbnailView, SuccessCallback callback) {
45 | loadBitmap(context);
46 | thumbnailView.setImageBitmap(mBitmap);
47 | callback.onSuccess();
48 | }
49 |
50 | private void displayVideo(Context context, String url) {
51 | Intent intent = new Intent(context, VideoPlayActivity.class);
52 | intent.putExtra(Constants.URL, url);
53 | context.startActivity(intent);
54 | }
55 |
56 | private void loadBitmap(Context context) {
57 | if (mBitmap == null) {
58 | mBitmap = ((BitmapDrawable) context.getResources().getDrawable(mId)).getBitmap();
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/GalleryPagerLib/src/main/res/drawable-hdpi/placeholder_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCServerLib/90383f44339525cc8761fcf3d82d12e64a9b00bc/GalleryPagerLib/src/main/res/drawable-hdpi/placeholder_image.png
--------------------------------------------------------------------------------
/GalleryPagerLib/src/main/res/drawable-hdpi/placeholder_video.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCServerLib/90383f44339525cc8761fcf3d82d12e64a9b00bc/GalleryPagerLib/src/main/res/drawable-hdpi/placeholder_video.png
--------------------------------------------------------------------------------
/GalleryPagerLib/src/main/res/drawable-xhdpi/placeholder_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCServerLib/90383f44339525cc8761fcf3d82d12e64a9b00bc/GalleryPagerLib/src/main/res/drawable-xhdpi/placeholder_image.png
--------------------------------------------------------------------------------
/GalleryPagerLib/src/main/res/drawable-xhdpi/placeholder_video.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCServerLib/90383f44339525cc8761fcf3d82d12e64a9b00bc/GalleryPagerLib/src/main/res/drawable-xhdpi/placeholder_video.png
--------------------------------------------------------------------------------
/GalleryPagerLib/src/main/res/drawable-xxhdpi/placeholder_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCServerLib/90383f44339525cc8761fcf3d82d12e64a9b00bc/GalleryPagerLib/src/main/res/drawable-xxhdpi/placeholder_image.png
--------------------------------------------------------------------------------
/GalleryPagerLib/src/main/res/drawable-xxhdpi/placeholder_video.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCServerLib/90383f44339525cc8761fcf3d82d12e64a9b00bc/GalleryPagerLib/src/main/res/drawable-xxhdpi/placeholder_video.png
--------------------------------------------------------------------------------
/GalleryPagerLib/src/main/res/drawable-xxxhdpi/placeholder_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCServerLib/90383f44339525cc8761fcf3d82d12e64a9b00bc/GalleryPagerLib/src/main/res/drawable-xxxhdpi/placeholder_image.png
--------------------------------------------------------------------------------
/GalleryPagerLib/src/main/res/drawable-xxxhdpi/placeholder_video.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCServerLib/90383f44339525cc8761fcf3d82d12e64a9b00bc/GalleryPagerLib/src/main/res/drawable-xxxhdpi/placeholder_video.png
--------------------------------------------------------------------------------
/GalleryPagerLib/src/main/res/layout/image_fragment.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
13 |
14 |
--------------------------------------------------------------------------------
/GalleryPagerLib/src/main/res/layout/scroll_gallery_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
10 |
11 |
19 |
20 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/GalleryPagerLib/src/main/res/layout/video_fragment.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
19 |
20 |
25 |
26 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/GalleryPagerLib/src/main/res/values-ru/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Загрузка…
3 |
4 |
--------------------------------------------------------------------------------
/GalleryPagerLib/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Loading…
3 | first_image_transition_name
4 |
5 |
--------------------------------------------------------------------------------
/GalleryViewLib/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/GalleryViewLib/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | //迁移到jitpack
3 | apply plugin: 'com.github.dcendents.android-maven'
4 |
5 | android {
6 | compileSdkVersion 29
7 | defaultConfig {
8 | minSdkVersion 16
9 | targetSdkVersion 29
10 | versionCode 16
11 | versionName "1.1.6"
12 | }
13 | buildTypes {
14 | release {
15 | minifyEnabled false
16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
17 | }
18 | }
19 | }
20 |
21 | dependencies {
22 | implementation fileTree(dir: 'libs', include: ['*.jar'])
23 | implementation 'androidx.appcompat:appcompat:1.2.0'
24 | implementation 'androidx.annotation:annotation:1.1.0'
25 | implementation 'androidx.recyclerview:recyclerview:1.1.0'
26 | implementation 'cn.yc:zoomImageLib:1.0.1'
27 | }
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/GalleryViewLib/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in C:\Users\PC\AppData\Local\Android\Sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/GalleryViewLib/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/GalleryViewLib/src/main/java/com/yc/gallerylib/gallery/GalleryFragment.java:
--------------------------------------------------------------------------------
1 | package com.yc.gallerylib.gallery;
2 |
3 | import android.content.Context;
4 | import android.graphics.Bitmap;
5 | import android.graphics.drawable.BitmapDrawable;
6 | import android.os.Bundle;
7 | import android.view.LayoutInflater;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 |
11 | import androidx.annotation.NonNull;
12 | import androidx.annotation.Nullable;
13 | import androidx.fragment.app.Fragment;
14 | import androidx.fragment.app.FragmentActivity;
15 |
16 | import com.yc.gallerylib.R;
17 | import com.ycbjie.zoomimagelib.view.ZoomImageView;
18 |
19 | /**
20 | *
21 | * @author yangchong
22 | * blog : https://github.com/yangchong211
23 | * time : 2017/05/30
24 | * desc : 支持滑动viewpager图片浏览控件,使用轻量级fragment
25 | * revise:
26 | *
27 | */
28 | public class GalleryFragment extends Fragment {
29 |
30 | private Bitmap mBitmap;
31 | private GalleryViewPager viewPager;
32 | private ZoomImageView backgroundImage;
33 | private FragmentActivity activity;
34 | private static final String IMAGE = "image";
35 | public static final String ZOOM = "zoom";
36 | public static final String ZOOM_SIZE = "zoom_size";
37 | private static final String IS_LOCKED = "isLocked";
38 |
39 | @Override
40 | public void onAttach(Context context) {
41 | super.onAttach(context);
42 | activity = (FragmentActivity) context;
43 | }
44 |
45 | @Override
46 | public void onDetach() {
47 | super.onDetach();
48 | activity = null;
49 | }
50 |
51 | public void setBitmap(Bitmap bitmap) {
52 | mBitmap = bitmap;
53 | }
54 |
55 | @Override
56 | public void onSaveInstanceState(@NonNull Bundle outState) {
57 | if (isViewPagerActive()) {
58 | outState.putBoolean(IS_LOCKED, viewPager.isLocked());
59 | }
60 | if (isBackgroundImageActive()) {
61 | outState.putParcelable(IMAGE, ((BitmapDrawable) backgroundImage.getDrawable()).getBitmap());
62 | }
63 | super.onSaveInstanceState(outState);
64 | }
65 |
66 |
67 | @Override
68 | public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
69 | super.onCreate(savedInstanceState);
70 | View rootView = inflater.inflate(R.layout.fragment_image_gallery, container, false);
71 | return rootView;
72 | }
73 |
74 | @Override
75 | public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
76 | super.onViewCreated(view, savedInstanceState);
77 | backgroundImage = view.findViewById(R.id.backgroundImage);
78 | viewPager = activity.findViewById(R.id.viewPager);
79 | if (savedInstanceState != null) {
80 | boolean isLocked = savedInstanceState.getBoolean(IS_LOCKED, false);
81 | viewPager.setLocked(isLocked);
82 | if (savedInstanceState.containsKey(IMAGE)) {
83 | backgroundImage.setImageBitmap((Bitmap) savedInstanceState.getParcelable(IMAGE));
84 | }
85 | createViewAttache(savedInstanceState);
86 | }
87 | loadImageToView();
88 | }
89 |
90 |
91 | private void loadImageToView() {
92 | backgroundImage.setImageBitmap(mBitmap);
93 | //注意不要设置setBackground
94 | //backgroundImage.setBitmap(mBitmap);
95 | //backgroundImage.setScaleType(ImageView.ScaleType.FIT_CENTER);
96 | }
97 |
98 | private void createViewAttache(Bundle savedInstanceState) {
99 | boolean zoom = savedInstanceState.getBoolean(ZOOM);
100 | int zoom_size = savedInstanceState.getInt(ZOOM_SIZE);
101 | if (zoom) {
102 | backgroundImage.setMaxScale(zoom_size);
103 | } else {
104 | backgroundImage.setMaxScale(1);
105 | }
106 | }
107 |
108 | private boolean isViewPagerActive() {
109 | return viewPager != null;
110 | }
111 |
112 | private boolean isBackgroundImageActive() {
113 | return backgroundImage != null && backgroundImage.getDrawable() != null;
114 | }
115 |
116 | }
117 |
--------------------------------------------------------------------------------
/GalleryViewLib/src/main/java/com/yc/gallerylib/gallery/GalleryViewPager.java:
--------------------------------------------------------------------------------
1 | package com.yc.gallerylib.gallery;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.view.MotionEvent;
6 |
7 | import androidx.viewpager.widget.ViewPager;
8 |
9 | /**
10 | *
11 | * @author yangchong
12 | * blog : https://github.com/yangchong211
13 | * time : 2017/05/30
14 | * desc : 自定义ViewPager
15 | * revise:
16 | *
17 | */
18 | public class GalleryViewPager extends ViewPager {
19 |
20 | private boolean isLocked;
21 | public GalleryViewPager(Context context) {
22 | super(context);
23 | isLocked = false;
24 | }
25 |
26 | public GalleryViewPager(Context context, AttributeSet attrs) {
27 | super(context, attrs);
28 | isLocked = false;
29 | }
30 |
31 | @Override
32 | public boolean onInterceptTouchEvent(MotionEvent ev) {
33 | if(!isLocked) {
34 | try {
35 | return super.onInterceptTouchEvent(ev);
36 | } catch (IllegalArgumentException e) {
37 | e.printStackTrace();
38 | return false;
39 | }
40 | }
41 | return false;
42 | }
43 |
44 | @Override
45 | public boolean onTouchEvent(MotionEvent ev) {
46 | return !isLocked && super.onTouchEvent(ev);
47 | }
48 |
49 | public void setLocked(boolean isLocked) {
50 | this.isLocked = isLocked;
51 | }
52 |
53 | public boolean isLocked() {
54 | return isLocked;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/GalleryViewLib/src/main/java/com/yc/gallerylib/gallery/ViewPagerAdapter.java:
--------------------------------------------------------------------------------
1 | package com.yc.gallerylib.gallery;
2 |
3 | import android.graphics.Bitmap;
4 | import android.os.Bundle;
5 |
6 | import androidx.fragment.app.Fragment;
7 | import androidx.fragment.app.FragmentManager;
8 | import androidx.fragment.app.FragmentStatePagerAdapter;
9 |
10 | import java.util.List;
11 |
12 | /**
13 | *
14 | * @author yangchong
15 | * blog : https://github.com/yangchong211
16 | * time : 2017/05/30
17 | * desc : 滑动viewpager的adapter
18 | * revise:
19 | *
20 | */
21 | public class ViewPagerAdapter extends FragmentStatePagerAdapter {
22 |
23 | private List mListOfMedia;
24 | private boolean isZoom = false;
25 | private int zoomSize;
26 |
27 | ViewPagerAdapter(FragmentManager fm, List listOfMedia, boolean isZoom, int zoomSize) {
28 | super(fm);
29 | this.mListOfMedia = listOfMedia;
30 | this.isZoom = isZoom;
31 | this.zoomSize = zoomSize;
32 | }
33 |
34 | @Override
35 | public Fragment getItem(int position) {
36 | Fragment fragment = null;
37 | if (position < mListOfMedia.size()) {
38 | Bitmap bitmap = mListOfMedia.get(position);
39 | fragment = loadImageFragment(bitmap);
40 | }
41 | return fragment;
42 | }
43 |
44 | private Fragment loadImageFragment(Bitmap bitmap) {
45 | GalleryFragment fragment = new GalleryFragment();
46 | fragment.setBitmap(bitmap);
47 | Bundle bundle = new Bundle();
48 | bundle.putBoolean(GalleryFragment.ZOOM, isZoom);
49 | bundle.putInt(GalleryFragment.ZOOM_SIZE,zoomSize);
50 | fragment.setArguments(bundle);
51 | return fragment;
52 | }
53 |
54 | @Override
55 | public int getCount() {
56 | return mListOfMedia!=null ? mListOfMedia.size() : 0;
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/GalleryViewLib/src/main/java/com/yc/gallerylib/recyclerView/OnGalleryListener.java:
--------------------------------------------------------------------------------
1 | package com.yc.gallerylib.recyclerView;
2 |
3 |
4 | /**
5 | *
6 | * @author yangchong
7 | * blog : https://github.com/yangchong211
8 | * time : 2018/12/10
9 | * desc : 自定义画廊listener监听
10 | * revise: 暂时先定义这几个监听事件
11 | *
12 | */
13 | public interface OnGalleryListener {
14 |
15 | /**
16 | * 初始化完成
17 | * 【播放视频初始化这个】
18 | */
19 | void onInitComplete();
20 |
21 | /**
22 | * 释放的监听【播放视频需要这个】
23 | * @param isNext 是否下一个
24 | * @param position 索引
25 | */
26 | void onPageRelease(boolean isNext, int position);
27 |
28 | /**
29 | * 选中的监听
30 | * @param position 索引
31 | */
32 | void onPageSelected(int position);
33 |
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/GalleryViewLib/src/main/res/layout/fragment_image_gallery.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
--------------------------------------------------------------------------------
/GalleryViewLib/src/main/res/layout/view_scroll_gallery.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
11 |
12 |
20 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/GalleryViewLib/src/main/res/layout/view_zoom_load.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
14 |
15 |
23 |
26 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/GalleryViewLib/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | YCGalleryLib
3 | 玩命加载……
4 |
5 |
--------------------------------------------------------------------------------
/GrpcServer/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/caches
5 | /.idea/libraries
6 | /.idea/modules.xml
7 | /.idea/workspace.xml
8 | /.idea/navEditor.xml
9 | /.idea/assetWizardSettings.xml
10 | .DS_Store
11 | /build
12 | /captures
13 | .externalNativeBuild
14 | .cxx
15 | .idea/
16 |
17 |
18 |
19 | # Built application files
20 | *.apk
21 | *.ap_
22 |
23 | # Files for the ART/Dalvik VM
24 | *.dex
25 |
26 | # Java class files
27 | *.class
28 |
29 | # Generated files
30 | bin/
31 | gen/
32 | out/
33 |
34 | # Gradle files
35 | .gradle/
36 | build/
37 |
38 | # Local configuration file (sdk path, etc)
39 | local.properties
40 |
41 | # Proguard folder generated by Eclipse
42 | proguard/
43 |
44 | # Log Files
45 | *.log
46 |
47 | # Android Studio Navigation editor temp files
48 | .navigation/
49 |
50 | # Android Studio captures folder
51 | captures/
52 |
53 | # Intellij
54 | *.iml
55 | .idea/workspace.xml
56 | .idea/tasks.xml
57 | .idea/gradle.xml
58 | .idea/dictionaries
59 | .idea/libraries
60 |
61 | # Keystore files
62 | *.jks
63 |
64 | # External native build folder generated in Android Studio 2.2 and later
65 | .externalNativeBuild
66 |
67 | # Google Services (e.g. APIs or Firebase)
68 | google-services.json
69 |
70 | # Freeline
71 | freeline.py
72 | freeline/
73 | freeline_project_description.json
74 | .idea/
75 |
76 |
77 |
--------------------------------------------------------------------------------
/GrpcServer/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply from: rootProject.projectDir.absolutePath + "/yc.gradle"
3 |
4 |
5 | android {
6 | compileSdkVersion rootProject.ext.android["compileSdkVersion"]
7 | //buildToolsVersion rootProject.ext.android["buildToolsVersion"]
8 |
9 | defaultConfig {
10 | minSdkVersion rootProject.ext.android["minSdkVersion"]
11 | targetSdkVersion rootProject.ext.android["targetSdkVersion"]
12 | versionCode rootProject.ext.android["versionCode"]
13 | versionName rootProject.ext.android["versionName"]
14 | multiDexEnabled true
15 | }
16 |
17 | buildTypes {
18 | release {
19 | minifyEnabled false
20 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
21 | }
22 | }
23 | compileOptions {
24 | sourceCompatibility JavaVersion.VERSION_1_8
25 | targetCompatibility JavaVersion.VERSION_1_8
26 | }
27 | }
28 |
29 | dependencies {
30 | implementation fileTree(dir: "libs", include: ["*.jar"])
31 | implementation(rootProject.ext.dependencies["appcompat"])
32 | implementation(rootProject.ext.dependencies["annotation"])
33 | implementation rootProject.ext.dependencies["gson"]
34 | //工具类utils
35 | api 'com.github.yangchong211.YCCommonLib:ToolUtilsLib:1.4.9'
36 | api 'com.github.yangchong211.YCCommonLib:DataCloneLib:1.4.9'
37 | //protobuf
38 | implementation 'io.grpc:grpc-okhttp:1.33.0'
39 | implementation 'io.grpc:grpc-protobuf-lite:1.33.0'
40 | implementation 'io.grpc:grpc-stub:1.33.0'
41 | implementation 'org.apache.tomcat:annotations-api:6.0.53'
42 | //implementation project(path: ':DataCloneLib')
43 | }
--------------------------------------------------------------------------------
/GrpcServer/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
--------------------------------------------------------------------------------
/GrpcServer/src/main/java/com/yc/grpcserver/BaseRequest.java:
--------------------------------------------------------------------------------
1 | package com.yc.grpcserver;
2 |
3 |
4 | import com.yc.dataclonelib.BaseParentBean;
5 |
6 | /**
7 | * 请求体的基类
8 | */
9 | public class BaseRequest extends BaseParentBean {
10 |
11 | //请求超时的时间,默认是10s
12 | protected long timeoutMil = 10 * 1000;
13 | //是否放在后台请求
14 | protected boolean isBackground = false;
15 | //是否开启压缩功能,开启的话传:gzip
16 | protected String onlyZip = "";
17 | //方法名
18 | protected String methodName = "";
19 | //默认的压缩方法
20 | public static final String G_ZIP = "gzip";
21 | public static final String NO_ZIP = "none";
22 |
23 | public BaseRequest(long timeoutMil, boolean isBackground) {
24 | this.timeoutMil = timeoutMil;
25 | this.isBackground = isBackground;
26 | }
27 |
28 | public BaseRequest() {
29 |
30 | }
31 |
32 | public BaseRequest(long timeoutMil, boolean isBackground, String onlyZip) {
33 | this.timeoutMil = timeoutMil;
34 | this.isBackground = isBackground;
35 | this.onlyZip = onlyZip;
36 | }
37 |
38 |
39 | public String getMethodName() {
40 | return methodName;
41 | }
42 |
43 | public void setMethodName(String methodName) {
44 | this.methodName = methodName;
45 | }
46 |
47 | public long getTimeoutMil() {
48 | return timeoutMil;
49 | }
50 |
51 | public void setTimeoutMil(long timeoutMil) {
52 | this.timeoutMil = timeoutMil;
53 | }
54 |
55 | public boolean isBackground() {
56 | return isBackground;
57 | }
58 |
59 | public void setBackground(boolean background) {
60 | isBackground = background;
61 | }
62 |
63 | public String getOnlyZip() {
64 | return onlyZip;
65 | }
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/GrpcServer/src/main/java/com/yc/grpcserver/BaseResponse.java:
--------------------------------------------------------------------------------
1 | package com.yc.grpcserver;
2 |
3 |
4 | import com.yc.dataclonelib.BaseParentBean;
5 |
6 | /**
7 | * 响应体的基类
8 | */
9 | public class BaseResponse extends BaseParentBean {
10 |
11 | protected int code;
12 | protected String data;
13 | protected String message;
14 | protected String methodName;
15 |
16 | public BaseResponse() {
17 |
18 | }
19 |
20 | public BaseResponse(int code, String data) {
21 | this.code = code;
22 | this.data = data;
23 | }
24 |
25 | public int getCode() {
26 | return code;
27 | }
28 |
29 | public void setCode(int code) {
30 | this.code = code;
31 | }
32 |
33 | public String getData() {
34 | return data;
35 | }
36 |
37 | public void setData(String data) {
38 | this.data = data;
39 | }
40 |
41 | public String getMethodName() {
42 | return methodName;
43 | }
44 |
45 | public void setMethodName(String methodName) {
46 | this.methodName = methodName;
47 | }
48 |
49 | public String getMessage() {
50 | return message;
51 | }
52 |
53 | public void setMessage(String message) {
54 | this.message = message;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/GrpcServer/src/main/java/com/yc/grpcserver/GrpcCallback.java:
--------------------------------------------------------------------------------
1 | package com.yc.grpcserver;
2 |
3 | /**
4 | * 统一请求回调
5 | */
6 | public interface GrpcCallback{
7 |
8 | /**
9 | * 成功的回调
10 | * @param result 成功字段
11 | */
12 | void onSuccess(T result);
13 |
14 | /**
15 | * 失败的回调
16 | *
17 | * @param code 状态码
18 | * @param msg 信息
19 | * @param ex 异常信息
20 | */
21 | void onFailed(int code, String msg, Throwable ex);
22 |
23 | /**
24 | * 完成的回调
25 | */
26 | void onFinish();
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/GrpcServer/src/main/java/com/yc/grpcserver/GrpcHelper.java:
--------------------------------------------------------------------------------
1 | package com.yc.grpcserver;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.text.TextUtils;
5 |
6 | import com.google.gson.Gson;
7 | import com.yc.toolutils.AppLogUtils;
8 |
9 | import java.lang.reflect.Type;
10 | import java.util.concurrent.TimeUnit;
11 |
12 | import io.grpc.stub.AbstractStub;
13 |
14 | public final class GrpcHelper {
15 |
16 | /**
17 | * 存根修饰
18 | *
19 | * @param stub 存根
20 | * @param request 请求
21 | * @return 新的存根
22 | */
23 | @SuppressLint("CheckResult")
24 | public static T createStub(T stub, BaseRequest request) {
25 | //开启压缩,如果单个方法设置过,单个方法优先
26 | if (!TextUtils.isEmpty(request.getOnlyZip())) {
27 | //单个方法设置了压缩
28 | if (request.getOnlyZip().equals(BaseRequest.G_ZIP)) {
29 | long timeoutMil = request.getTimeoutMil();
30 | AbstractStub abstractStub = stub
31 | .withDeadlineAfter(timeoutMil, TimeUnit.MILLISECONDS)
32 | .withCompression(BaseRequest.G_ZIP);
33 | return (T) abstractStub;
34 | }
35 | }
36 | long timeoutMil = request.getTimeoutMil();
37 | AbstractStub abstractStub = stub.withDeadlineAfter(timeoutMil, TimeUnit.MILLISECONDS);
38 | return (T) abstractStub;
39 | }
40 |
41 | /**
42 | * 响应对象转换
43 | *
44 | * @param response 响应体
45 | * @param type 类型
46 | * @param 类型
47 | * @return 返回对象
48 | */
49 | public static T translateResponse(Object response, Type type) {
50 | //创建gson对象
51 | Gson gson = new Gson();
52 | //先将GRPC对象转为Json字符串
53 | String jsonString = gson.toJson(response);
54 | //将Json字符串转为Bean通用对象,回调出去
55 | T t = toBean(jsonString, type);
56 | AppLogUtils.d(t.getClass().getSimpleName() + "-转换前的响应体" + jsonString);
57 | return t;
58 | }
59 |
60 | /**
61 | * 将字符串转为对象,如果对象是String类型,则会原路返回
62 | *
63 | * @param result 源字符串
64 | * @param type 类型
65 | * @param 类型
66 | * @return 转换后的对象
67 | */
68 | private static T toBean(String result, Type type) {
69 | if (type.toString().contains(String.class.getSimpleName())) {
70 | return (T) result;
71 | } else {
72 | Gson gson = new Gson();
73 | return gson.fromJson(result, type);
74 | }
75 | }
76 |
77 | /**
78 | * 处理响应体信息
79 | *
80 | * @param baseResponse 基类响应
81 | * @param netCallback 回调
82 | */
83 | public static BaseResponse handleResponse(BaseResponse baseResponse, GrpcCallback netCallback) {
84 | try {
85 | if (baseResponse != null) {
86 | if (baseResponse.getCode() == 0) {
87 | netCallback.onSuccess((T) baseResponse);
88 | AppLogUtils.d("Response:" + baseResponse.getClass().getName() + "is success");
89 | } else {
90 | netCallback.onFailed(baseResponse.getCode(), baseResponse.getMessage(), null);
91 | AppLogUtils.d("Response:" + baseResponse.getClass().getName() + "is failed errorInfo:"
92 | + baseResponse);
93 | }
94 | } else {
95 | String errMsg = "通道为空或响应为空,请检查网络";
96 | netCallback.onFailed(100, errMsg, null);
97 | AppLogUtils.d("Response is failed errorInfo:" + errMsg);
98 | }
99 | } finally {
100 | netCallback.onFinish();
101 | }
102 | return baseResponse;
103 | }
104 |
105 | }
106 |
--------------------------------------------------------------------------------
/GrpcServer/src/main/java/com/yc/grpcserver/GrpcStubManager.java:
--------------------------------------------------------------------------------
1 | package com.yc.grpcserver;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.text.TextUtils;
5 |
6 | import java.util.concurrent.TimeUnit;
7 |
8 | import io.grpc.stub.AbstractStub;
9 |
10 | public class GrpcStubManager {
11 |
12 | public static final String G_ZIP = "gzip";
13 | public static final String NO_ZIP = "none";
14 | //设置是否全局开启请求压缩,默认关闭的
15 | private static boolean useZip;
16 |
17 | public static boolean isUseZip() {
18 | return useZip;
19 | }
20 |
21 | public static void setUseZip(boolean _useZip) {
22 | useZip = _useZip;
23 | }
24 |
25 |
26 | /**
27 | * 存根修饰
28 | *
29 | * @param stub 存根
30 | * @param request 请求
31 | * @return 新的存根
32 | */
33 | @SuppressLint("CheckResult")
34 | public static > T createStub(T stub, BaseRequest request) {
35 | //开启压缩,如果单个方法设置过,单个方法优先
36 | if (!TextUtils.isEmpty(request.getOnlyZip())) {
37 | //单个方法设置了压缩
38 | if (request.getOnlyZip().equals(G_ZIP)) {
39 | return stub.withDeadlineAfter(request.getTimeoutMil(), TimeUnit.MILLISECONDS)
40 | .withCompression(G_ZIP);
41 | }
42 | } else {
43 | //如果单个方法没设置过,全局方法优先
44 | if (useZip) {
45 | return stub.withDeadlineAfter(request.getTimeoutMil(), TimeUnit.MILLISECONDS)
46 | .withCompression(G_ZIP);
47 | }
48 | }
49 | return stub.withDeadlineAfter(request.getTimeoutMil(), TimeUnit.MILLISECONDS);
50 | }
51 |
52 | }
53 |
--------------------------------------------------------------------------------
/GrpcServer/src/main/java/com/yc/grpcserver/GrpcToolUtils.java:
--------------------------------------------------------------------------------
1 | package com.yc.grpcserver;
2 |
3 | import java.util.regex.Pattern;
4 |
5 | public class GrpcToolUtils {
6 |
7 | /**
8 | * 判断是否是ip地址
9 | * @param input ip地址
10 | * @return ture表示是ip地址
11 | */
12 | public static boolean isIP(final CharSequence input) {
13 | //IP格式为四个三位数;且数字输入有严格限制。所以就要用到正则表达式判断。
14 | String REGEX_IP = "((2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)";
15 | return isMatch(REGEX_IP, input);
16 | }
17 |
18 | private static boolean isMatch(final String regex, final CharSequence input) {
19 | return input != null && input.length() > 0 && Pattern.matches(regex, input);
20 | }
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/GrpcServer/src/main/java/com/yc/grpcserver/LoggingInterceptor.java:
--------------------------------------------------------------------------------
1 | package com.yc.grpcserver;
2 |
3 | import android.util.Log;
4 |
5 | import io.grpc.CallOptions;
6 | import io.grpc.Channel;
7 | import io.grpc.ClientCall;
8 | import io.grpc.ClientInterceptor;
9 | import io.grpc.Metadata;
10 | import io.grpc.MethodDescriptor;
11 | import io.grpc.ServerCall;
12 | import io.grpc.ServerCallHandler;
13 | import io.grpc.ServerInterceptor;
14 |
15 | public class LoggingInterceptor implements ServerInterceptor, ClientInterceptor {
16 |
17 | private static final String TAG = "gRPC-yc";
18 |
19 | @Override
20 | public ClientCall interceptCall(
21 | MethodDescriptor method, CallOptions callOptions, Channel next) {
22 | // 在请求发送前记录日志
23 | Log.d(TAG,"Sending request: " + method.getFullMethodName());
24 | // 调用下一个拦截器或服务实现
25 | return next.newCall(method,callOptions);
26 | }
27 |
28 | @Override
29 | public ServerCall.Listener interceptCall(
30 | ServerCall call, Metadata headers, ServerCallHandler next) {
31 | // 在请求接收前记录日志
32 | Log.d(TAG,"Received request: " + call.getMethodDescriptor().getFullMethodName());
33 | // 调用下一个拦截器或服务实现
34 | return next.startCall(call,headers);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/GrpcServer/src/main/java/com/yc/grpcserver/RequestInterceptor.java:
--------------------------------------------------------------------------------
1 | package com.yc.grpcserver;
2 |
3 | import io.grpc.CallOptions;
4 | import io.grpc.Channel;
5 | import io.grpc.ClientCall;
6 | import io.grpc.ClientInterceptor;
7 | import io.grpc.ForwardingClientCall;
8 | import io.grpc.ForwardingClientCallListener;
9 | import io.grpc.Metadata;
10 | import io.grpc.MethodDescriptor;
11 | import io.grpc.Status;
12 |
13 | /**
14 | * 拦截
15 | */
16 | public class RequestInterceptor implements ClientInterceptor {
17 |
18 | @Override
19 | public ClientCall interceptCall(
20 | MethodDescriptor method,
21 | CallOptions callOptions,
22 | Channel next) {
23 | // 创建一个自定义的 ClientCall 实现,用于监听请求状态
24 | return new ForwardingClientCall.SimpleForwardingClientCall(next.newCall(method, callOptions)) {
25 | @Override
26 | public void start(Listener responseListener, Metadata headers) {
27 | // 在请求开始时执行自定义逻辑
28 | // 可以在这里记录请求开始时间、添加请求头等操作
29 | super.start(new ForwardingClientCallListener.SimpleForwardingClientCallListener(responseListener) {
30 | @Override
31 | public void onClose(Status status, Metadata trailers) {
32 | // 在请求关闭时执行自定义逻辑
33 | // 可以在这里记录请求结束时间、处理响应状态等操作
34 | super.onClose(status, trailers);
35 | }
36 | }, headers);
37 | }
38 | };
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/GrpcServer/src/main/java/com/yc/grpcserver/Tls12SocketFactory.java:
--------------------------------------------------------------------------------
1 | package com.yc.grpcserver;
2 |
3 | import java.io.IOException;
4 | import java.net.InetAddress;
5 | import java.net.Socket;
6 | import java.net.UnknownHostException;
7 |
8 | import javax.net.ssl.SSLSocket;
9 | import javax.net.ssl.SSLSocketFactory;
10 |
11 | /**
12 | * Enables TLS v1.2 when creating SSLSockets.
13 | * For some reason, android supports TLS v1.2 from API 16, but enables it by
14 | * default only from API 20.
15 | * @link https://developer.android.com/reference/javax/net/ssl/SSLSocket.html
16 | * @see SSLSocketFactory
17 | */
18 | public class Tls12SocketFactory extends SSLSocketFactory {
19 | private static final String[] TLS_V12_ONLY = {"TLSv1.2"};
20 |
21 | final SSLSocketFactory delegate;
22 |
23 | public Tls12SocketFactory(SSLSocketFactory base) {
24 | this.delegate = base;
25 | }
26 |
27 | @Override
28 | public String[] getDefaultCipherSuites() {
29 | return delegate.getDefaultCipherSuites();
30 | }
31 |
32 | @Override
33 | public String[] getSupportedCipherSuites() {
34 | return delegate.getSupportedCipherSuites();
35 | }
36 |
37 | @Override
38 | public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
39 | return patch(delegate.createSocket(s, host, port, autoClose));
40 | }
41 |
42 | @Override
43 | public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
44 | return patch(delegate.createSocket(host, port));
45 | }
46 |
47 | @Override
48 | public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
49 | return patch(delegate.createSocket(host, port, localHost, localPort));
50 | }
51 |
52 | @Override
53 | public Socket createSocket(InetAddress host, int port) throws IOException {
54 | return patch(delegate.createSocket(host, port));
55 | }
56 |
57 | @Override
58 | public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
59 | return patch(delegate.createSocket(address, port, localAddress, localPort));
60 | }
61 |
62 | private Socket patch(Socket s) {
63 | if (s instanceof SSLSocket) {
64 | ((SSLSocket) s).setEnabledProtocols(TLS_V12_ONLY);
65 | }
66 | return s;
67 | }
68 | }
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 28
5 | buildToolsVersion "28.0.3"
6 | defaultConfig {
7 | applicationId "com.yc.cn.ycgallery"
8 | minSdkVersion 16
9 | targetSdkVersion 28
10 | versionCode 1
11 | versionName "1.0"
12 | }
13 | buildTypes {
14 | release {
15 | minifyEnabled false
16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
17 | }
18 | }
19 |
20 | android {
21 | defaultConfig {
22 | multiDexEnabled true
23 | }
24 | }
25 | }
26 |
27 | dependencies {
28 | implementation fileTree(dir: 'libs', include: ['*.jar'])
29 | //noinspection GradleCompatible
30 | implementation 'androidx.appcompat:appcompat:1.2.0'
31 | implementation 'androidx.annotation:annotation:1.1.0'
32 | implementation 'androidx.recyclerview:recyclerview:1.1.0'
33 | implementation 'com.squareup.picasso:picasso:2.5.2'
34 | // implementation project(path: ':GalleryViewLib')
35 | // implementation project(path: ':GalleryPagerLib')
36 | implementation 'org.jsoup:jsoup:1.11.2'
37 | implementation 'cn.yc:zoomImageLib:1.0.1'
38 | implementation 'com.github.yangchong211.YCImageGallery:GalleryViewLib:1.1.6'
39 | implementation 'com.github.yangchong211.YCImageGallery:GalleryPagerLib:1.1.6'
40 | }
41 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in C:\Users\PC\AppData\Local\Android\Sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/app/src/main/assets/yc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCServerLib/90383f44339525cc8761fcf3d82d12e64a9b00bc/app/src/main/assets/yc.png
--------------------------------------------------------------------------------
/app/src/main/java/com/yc/cn/ycgallery/FiveActivity.java:
--------------------------------------------------------------------------------
1 | package com.yc.cn.ycgallery;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.content.res.TypedArray;
5 | import android.os.Bundle;
6 | import android.util.Log;
7 | import android.widget.TextView;
8 |
9 | import androidx.annotation.Nullable;
10 | import androidx.appcompat.app.AppCompatActivity;
11 | import androidx.recyclerview.widget.RecyclerView;
12 |
13 | import com.yc.gallerylib.recyclerView.GalleryRecyclerView;
14 | import com.yc.gallerylib.recyclerView.OnGalleryListener;
15 |
16 | import java.util.ArrayList;
17 |
18 |
19 | public class FiveActivity extends AppCompatActivity {
20 |
21 | private static final String TAG = "FiveActivity";
22 | private GalleryRecyclerView mRecyclerView;
23 | private ArrayList data = new ArrayList<>();
24 | private TextView tag;
25 |
26 | @Override
27 | protected void onCreate(@Nullable Bundle savedInstanceState) {
28 | super.onCreate(savedInstanceState);
29 | setContentView(R.layout.activity_five);
30 | tag = findViewById(R.id.tag);
31 | initRecyclerView();
32 |
33 | }
34 |
35 | @SuppressLint("SetTextI18n")
36 | private void initRecyclerView() {
37 | mRecyclerView = findViewById(R.id.recyclerView);
38 | final SnapAdapter adapter = new SnapAdapter(this);
39 | adapter.setData(getData());
40 | tag.setText(1 + "/" + adapter.getData().size());
41 | mRecyclerView
42 | //设置滑动速度
43 | .setFlingSpeed(10000)
44 | //设置adapter
45 | .setDataAdapter(adapter)
46 | //设置选中的索引
47 | .setSelectedPosition(2)
48 | //设置横向或者竖向,注意需要限制传入类型
49 | .setOrientation(RecyclerView.HORIZONTAL)
50 | //设置滚动监听事件
51 | .setOnGalleryListener(new OnGalleryListener() {
52 | @Override
53 | public void onInitComplete() {
54 | Log.e(TAG,"onInitComplete初始化完成");
55 | }
56 |
57 | @Override
58 | public void onPageRelease(boolean isNext,int position) {
59 | Log.e(TAG,"释放的监听,释放位置:"+position +" 下一页:"+isNext);
60 | if (isNext){
61 | Log.e(TAG,"释放的监听,释放位置:"+position +" 下一页:"+isNext);
62 | }else {
63 | Log.e(TAG,"释放的监听,释放位置:"+position +" 上一页:"+isNext);
64 | }
65 | }
66 |
67 | @SuppressLint("SetTextI18n")
68 | @Override
69 | public void onPageSelected(int position) {
70 | Log.e(TAG,"释放的监听,释放位置:"+position +" 当前页:"+position);
71 | tag.setText((position + 1) + "/" + adapter.getData().size());
72 | }
73 | })
74 | //装载
75 | .setUp();
76 | }
77 |
78 |
79 | private ArrayList getData(){
80 | data.clear();
81 | TypedArray bannerImage = getResources().obtainTypedArray(R.array.gallery_image);
82 | for (int i = 0; i < 12 ; i++) {
83 | int image = bannerImage.getResourceId(i, R.drawable.image1);
84 | data.add(image);
85 | }
86 | bannerImage.recycle();
87 | return data;
88 | }
89 |
90 |
91 |
92 | }
93 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yc/cn/ycgallery/FourActivity.java:
--------------------------------------------------------------------------------
1 | package com.yc.cn.ycgallery;
2 |
3 | import android.net.Uri;
4 | import android.os.AsyncTask;
5 | import android.os.Bundle;
6 | import android.util.Log;
7 | import android.view.View;
8 |
9 | import androidx.annotation.Nullable;
10 | import androidx.appcompat.app.AppCompatActivity;
11 |
12 | import com.squareup.picasso.Callback;
13 | import com.squareup.picasso.MemoryPolicy;
14 | import com.squareup.picasso.Picasso;
15 | import com.yc.gallerypager.MediaInfo;
16 | import com.yc.gallerypager.ScrollGalleryView;
17 |
18 | import org.jsoup.Jsoup;
19 | import org.jsoup.nodes.Element;
20 | import org.jsoup.select.Elements;
21 |
22 | import java.io.IOException;
23 | import java.util.ArrayList;
24 | import java.util.Collections;
25 | import java.util.List;
26 |
27 | public class FourActivity extends AppCompatActivity {
28 |
29 | private ScrollGalleryView scrollGalleryView;
30 |
31 |
32 | @Override
33 | protected void onCreate(@Nullable Bundle savedInstanceState) {
34 | super.onCreate(savedInstanceState);
35 | setContentView(R.layout.activity_four);
36 |
37 | scrollGalleryView = findViewById(R.id.scroll_gallery_view);
38 |
39 | List images = new ArrayList<>();
40 | images.add(R.drawable.image1);
41 | images.add(R.drawable.image2);
42 | images.add(R.drawable.image3);
43 | images.add(R.drawable.image4);
44 | images.add(R.drawable.image5);
45 | images.add(R.drawable.image6);
46 | images.add(R.drawable.image7);
47 | images.add(R.drawable.image8);
48 | images.add(R.drawable.image1);
49 | images.add(R.drawable.image2);
50 | images.add(R.drawable.image3);
51 | images.add(R.drawable.image4);
52 | images.add(R.drawable.image5);
53 | images.add(R.drawable.image6);
54 | images.add(R.drawable.image7);
55 | images.add(R.drawable.image8);
56 | images.add(R.drawable.image1);
57 | images.add(R.drawable.image2);
58 | images.add(R.drawable.image3);
59 | images.add(R.drawable.image4);
60 | images.add(R.drawable.image5);
61 | images.add(R.drawable.image6);
62 | images.add(R.drawable.image7);
63 | images.add(R.drawable.image8);
64 |
65 |
66 | scrollGalleryView
67 | .setThumbnailSize(200)
68 | .setZoom(true)
69 | .withHiddenThumbnails(false)
70 | .hideThumbnailsOnClick(true)
71 | .hideThumbnailsAfter(5000)
72 | .addOnImageClickListener(new ScrollGalleryView.OnImageClickListener() {
73 | @Override
74 | public void onClick(int position) {
75 |
76 | }
77 | })
78 | .setFragmentManager(getSupportFragmentManager());
79 | for (int i=0 ; i= Build.VERSION_CODES.LOLLIPOP) {
60 | startActivity(intent3, ActivityOptions.makeSceneTransitionAnimation(
61 | MainActivity.this).toBundle());
62 | }else {
63 | startActivity(intent3);
64 | }
65 | break;
66 | case R.id.tv_4:
67 | startActivity(new Intent(this, FourActivity.class));
68 | break;
69 | case R.id.tv_5:
70 | Intent intent5 = new Intent(this, FiveActivity.class);
71 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
72 | startActivity(intent5, ActivityOptions.makeSceneTransitionAnimation(
73 | MainActivity.this, tv_5, "YangChong").toBundle());
74 | }
75 | break;
76 | default:
77 | break;
78 | }
79 | }
80 |
81 |
82 | }
83 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yc/cn/ycgallery/PicassoImageLoader.java:
--------------------------------------------------------------------------------
1 | package com.yc.cn.ycgallery;
2 |
3 | import android.content.Context;
4 | import android.widget.ImageView;
5 |
6 | import com.squareup.picasso.Callback;
7 | import com.squareup.picasso.Picasso;
8 | import com.yc.gallerypager.inter.IMediaLoader;
9 |
10 | public class PicassoImageLoader implements IMediaLoader {
11 |
12 | private String url;
13 | private Integer thumbnailWidth;
14 | private Integer thumbnailHeight;
15 | private int image;
16 | private int type;
17 | public static final int LOCAL_IMAGE = 1;
18 | public static final int NETWORK_IMAGE = 2;
19 |
20 |
21 | public PicassoImageLoader(String url , int type) {
22 | this.url = url;
23 | this.type = type;
24 | }
25 |
26 | public PicassoImageLoader(int image ,int type) {
27 | this.image = image;
28 | this.type = type;
29 | }
30 |
31 | public PicassoImageLoader(String url, Integer thumbnailWidth, Integer thumbnailHeight) {
32 | this.url = url;
33 | this.thumbnailWidth = thumbnailWidth;
34 | this.thumbnailHeight = thumbnailHeight;
35 | }
36 |
37 | public PicassoImageLoader(int image, Integer thumbnailWidth, Integer thumbnailHeight) {
38 | this.image = image;
39 | this.thumbnailWidth = thumbnailWidth;
40 | this.thumbnailHeight = thumbnailHeight;
41 | }
42 |
43 |
44 | @Override
45 | public boolean isImage() {
46 | return true;
47 | }
48 |
49 | @Override
50 | public void loadMedia(Context context, final ImageView imageView, final IMediaLoader.SuccessCallback callback) {
51 | if (type==LOCAL_IMAGE){
52 | Picasso.with(context)
53 | .load(image)
54 | .placeholder(R.drawable.placeholder_image)
55 | .into(imageView, new ImageCallback(callback));
56 | } else {
57 | Picasso.with(context)
58 | .load(url)
59 | .placeholder(R.drawable.placeholder_image)
60 | .into(imageView, new ImageCallback(callback));
61 | }
62 |
63 | }
64 |
65 | @Override
66 | public void loadThumbnail(Context context, final ImageView thumbnailView, final IMediaLoader.SuccessCallback callback) {
67 | if (type==LOCAL_IMAGE){
68 | Picasso.with(context)
69 | .load(image)
70 | .resize(thumbnailWidth == null ? 100 : thumbnailWidth,
71 | thumbnailHeight == null ? 100 : thumbnailHeight)
72 | .placeholder(R.drawable.placeholder_image)
73 | .centerInside()
74 | .into(thumbnailView, new ImageCallback(callback));
75 | } else {
76 | Picasso.with(context)
77 | .load(url)
78 | .resize(thumbnailWidth == null ? 100 : thumbnailWidth,
79 | thumbnailHeight == null ? 100 : thumbnailHeight)
80 | .placeholder(R.drawable.placeholder_image)
81 | .centerInside()
82 | .into(thumbnailView, new ImageCallback(callback));
83 | }
84 | }
85 |
86 | private static class ImageCallback implements Callback {
87 | private final IMediaLoader.SuccessCallback callback;
88 |
89 | public ImageCallback(SuccessCallback callback) {
90 | this.callback = callback;
91 | }
92 |
93 | @Override public void onSuccess() {
94 | callback.onSuccess();
95 | }
96 |
97 | @Override
98 | public void onError() {
99 |
100 | }
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yc/cn/ycgallery/PicassoMediaHelper.java:
--------------------------------------------------------------------------------
1 | package com.yc.cn.ycgallery;
2 |
3 | import com.yc.gallerypager.MediaInfo;
4 | import com.yc.gallerypager.builder.BasicMediaHelper;
5 |
6 | import java.util.ArrayList;
7 | import java.util.Arrays;
8 | import java.util.List;
9 |
10 | public class PicassoMediaHelper extends BasicMediaHelper {
11 | @Override
12 | public MediaInfo image(String url) {
13 | return mediaInfo(url);
14 | }
15 |
16 | @Override
17 | public List images(List urls) {
18 | List medias = new ArrayList<>();
19 |
20 | for (String url : urls) {
21 | medias.add(mediaInfo(url));
22 | }
23 |
24 | return medias;
25 | }
26 |
27 | @Override
28 | public List images(String... urls) {
29 | return images(Arrays.asList(urls));
30 | }
31 |
32 | private MediaInfo mediaInfo(String url) {
33 | return MediaInfo.mediaLoader(new PicassoImageLoader(url,PicassoImageLoader.NETWORK_IMAGE));
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yc/cn/ycgallery/SecondActivity.java:
--------------------------------------------------------------------------------
1 | package com.yc.cn.ycgallery;
2 |
3 | import android.os.Bundle;
4 | import android.view.View;
5 |
6 | import androidx.annotation.Nullable;
7 | import androidx.appcompat.app.AppCompatActivity;
8 |
9 | import com.ycbjie.zoomimagelib.listener.OnZoomClickListener;
10 | import com.ycbjie.zoomimagelib.listener.OnZoomLongClickListener;
11 | import com.ycbjie.zoomimagelib.view.ZoomImageView;
12 |
13 |
14 | public class SecondActivity extends AppCompatActivity {
15 |
16 | private ZoomImageView imageView;
17 | private static final long ANIM_TIME = 200;
18 |
19 | @Override
20 | protected void onCreate(@Nullable Bundle savedInstanceState) {
21 | super.onCreate(savedInstanceState);
22 | setContentView(R.layout.activity_second);
23 |
24 | imageView = findViewById(R.id.image);
25 | imageView.setOnZoomClickListener(new OnZoomClickListener() {
26 | @Override
27 | public void onClick(View v) {
28 | finish();
29 | }
30 | });
31 | imageView.setOnZoomLongClickListener(new OnZoomLongClickListener() {
32 | @Override
33 | public boolean onLongClick(View v) {
34 | return false;
35 | }
36 | });
37 | imageView.setMaxScale(4);
38 | imageView.setImageResource(R.drawable.image1);
39 | //注意不要使用setBackground设置图片,它不支持缩放
40 | //imageView.setBackground();
41 | }
42 |
43 | @Override
44 | protected void onDestroy() {
45 | super.onDestroy();
46 | if (imageView!=null){
47 | //重置所有状态,清空mask,停止所有手势,停止所有动画
48 | imageView.reset();
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yc/cn/ycgallery/SnapAdapter.java:
--------------------------------------------------------------------------------
1 | package com.yc.cn.ycgallery;
2 |
3 |
4 | import android.content.Context;
5 | import android.graphics.Bitmap;
6 | import android.graphics.BitmapFactory;
7 | import android.util.Log;
8 | import android.view.LayoutInflater;
9 | import android.view.View;
10 | import android.view.ViewGroup;
11 | import android.widget.ImageView;
12 |
13 |
14 | import androidx.annotation.NonNull;
15 | import androidx.recyclerview.widget.RecyclerView;
16 |
17 | import com.ycbjie.zoomimagelib.view.ZoomImageView;
18 |
19 | import java.util.ArrayList;
20 | import java.util.List;
21 |
22 | public class SnapAdapter extends RecyclerView.Adapter {
23 |
24 |
25 | private Context mContext;
26 | SnapAdapter(Context context){
27 | this.mContext =context;
28 | }
29 |
30 | private List urlList = new ArrayList<>();
31 | public void setData(List list) {
32 | urlList.clear();
33 | this.urlList = list;
34 | }
35 |
36 | public List getData() {
37 | return urlList;
38 | }
39 |
40 | @NonNull
41 | @Override
42 | public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
43 | View view = LayoutInflater.from(mContext).inflate(R.layout.item_snap, parent, false);
44 | return new MyViewHolder(view);
45 | }
46 |
47 | @Override
48 | public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
49 | if (urlList == null || urlList.isEmpty())
50 | return;
51 | Integer url = urlList.get(position%urlList.size());
52 | Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(), url);
53 | holder.imageView.setImageBitmap(bitmap);
54 |
55 | //holder.imageView.setBackgroundResource(url);
56 | }
57 |
58 |
59 | class MyViewHolder extends RecyclerView.ViewHolder{
60 | ZoomImageView imageView;
61 | MyViewHolder(View itemView) {
62 | super(itemView);
63 | imageView = itemView.findViewById(R.id.iv_image);
64 | }
65 |
66 | }
67 |
68 | @Override
69 | public int getItemCount() {
70 | /*if (urlList.size() != 1) {
71 | Log.e("getItemCount","getItemCount---------");
72 | return Integer.MAX_VALUE; // 无限轮播
73 | } else {
74 | Log.e("getItemCount","getItemCount++++----");
75 | return urlList.size();
76 | }*/
77 |
78 | return urlList!=null ? urlList.size() : 0;
79 | }
80 |
81 | }
82 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yc/cn/ycgallery/ThirdActivity.java:
--------------------------------------------------------------------------------
1 | package com.yc.cn.ycgallery;
2 |
3 | import android.net.Uri;
4 | import android.os.Build;
5 | import android.os.Bundle;
6 | import android.transition.Transition;
7 | import android.transition.TransitionInflater;
8 | import android.view.Window;
9 |
10 | import androidx.annotation.Nullable;
11 | import androidx.appcompat.app.AppCompatActivity;
12 |
13 | import com.squareup.picasso.Callback;
14 | import com.squareup.picasso.MemoryPolicy;
15 | import com.squareup.picasso.Picasso;
16 | import com.ycbjie.zoomimagelib.view.ZoomImageView;
17 |
18 | public class ThirdActivity extends AppCompatActivity {
19 |
20 | private ZoomImageView imageView;
21 |
22 | @Override
23 | protected void onCreate(@Nullable Bundle savedInstanceState) {
24 | super.onCreate(savedInstanceState);
25 |
26 |
27 | // 设置contentFeature,可使用切换动画
28 |
29 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
30 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
31 | getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
32 | }
33 | Transition explode = null;
34 | if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
35 | explode = TransitionInflater.from(this).inflateTransition(android.R.transition.explode);
36 | }
37 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
38 | getWindow().setEnterTransition(explode);
39 | }
40 | }
41 |
42 |
43 |
44 | setContentView(R.layout.activity_third);
45 |
46 | imageView = findViewById(R.id.image);
47 | Uri parse = Uri.parse("file:///android_asset/yc.png");
48 | Picasso.with(this)
49 | .load(parse)
50 | .memoryPolicy(MemoryPolicy.NO_CACHE)
51 | .into(imageView, new Callback() {
52 | @Override
53 | public void onSuccess() {
54 |
55 | }
56 |
57 | @Override
58 | public void onError() {
59 |
60 | }
61 | });
62 |
63 |
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yc/cn/ycgallery/animations/MatrixEvaluator.java:
--------------------------------------------------------------------------------
1 | package com.yc.cn.ycgallery.animations;
2 |
3 | import android.animation.TypeEvaluator;
4 | import android.graphics.Matrix;
5 | import android.graphics.drawable.Drawable;
6 | import android.util.Property;
7 | import android.widget.ImageView;
8 |
9 |
10 | public class MatrixEvaluator implements TypeEvaluator {
11 |
12 |
13 |
14 | private float[] mTempStartValues = new float[9];
15 | private float[] mTempEndValues = new float[9];
16 | private Matrix mTempMatrix = new Matrix();
17 |
18 | /**
19 | * 当我们对ImageView的图像矩阵进行动画处理时,此属性将传递给Object动画器
20 | */
21 | static final Property ANIMATED_TRANSFORM_PROPERTY =
22 | new Property(Matrix.class, "animatedTransform") {
23 |
24 | /**
25 | * 这是复制粘贴表单ImageView动画转换方法在SDK中是不可见的
26 | */
27 | @Override
28 | public void set(ImageView imageView, Matrix matrix) {
29 | Drawable drawable = imageView.getDrawable();
30 | if (drawable == null) {
31 | return;
32 | }
33 | if (matrix == null) {
34 | drawable.setBounds(0, 0, imageView.getWidth(), imageView.getHeight());
35 | } else {
36 | drawable.setBounds(0, 0, drawable.getIntrinsicWidth(),
37 | drawable.getIntrinsicHeight());
38 | Matrix drawMatrix = imageView.getImageMatrix();
39 | if (drawMatrix == null) {
40 | drawMatrix = new Matrix();
41 | imageView.setImageMatrix(drawMatrix);
42 | }
43 | imageView.setImageMatrix(matrix);
44 | }
45 | imageView.invalidate();
46 | }
47 |
48 | @Override
49 | public Matrix get(ImageView object) {
50 | return null;
51 | }
52 | };
53 |
54 |
55 | @Override
56 | public Matrix evaluate(float fraction, Matrix startValue, Matrix endValue) {
57 | startValue.getValues(mTempStartValues);
58 | endValue.getValues(mTempEndValues);
59 | for (int i = 0; i < 9; i++) {
60 | float diff = mTempEndValues[i] - mTempStartValues[i];
61 | mTempEndValues[i] = mTempStartValues[i] + (fraction * diff);
62 | }
63 | mTempMatrix.setValues(mTempEndValues);
64 | return mTempMatrix;
65 | }
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yc/cn/ycgallery/animations/MatrixUtils.java:
--------------------------------------------------------------------------------
1 | package com.yc.cn.ycgallery.animations;
2 |
3 | import android.graphics.Matrix;
4 | import android.graphics.Rect;
5 | import android.graphics.drawable.Drawable;
6 | import android.util.Log;
7 | import android.widget.ImageView;
8 |
9 |
10 | public class MatrixUtils {
11 |
12 |
13 | public static Matrix getImageMatrix(ImageView imageView) {
14 | int left = imageView.getLeft();
15 | int top = imageView.getTop();
16 | int right = imageView.getRight();
17 | int bottom = imageView.getBottom();
18 | Rect bounds = new Rect(left, top, right, bottom);
19 | Drawable drawable = imageView.getDrawable();
20 | Matrix matrix;
21 | ImageView.ScaleType scaleType = imageView.getScaleType();
22 | if (scaleType == ImageView.ScaleType.FIT_XY) {
23 | matrix = imageView.getImageMatrix();
24 | if (!matrix.isIdentity()) {
25 | matrix = new Matrix(matrix);
26 | } else {
27 | int drawableWidth = drawable.getIntrinsicWidth();
28 | int drawableHeight = drawable.getIntrinsicHeight();
29 | if (drawableWidth > 0 && drawableHeight > 0) {
30 | float scaleX = ((float) bounds.width()) / drawableWidth;
31 | float scaleY = ((float) bounds.height()) / drawableHeight;
32 | matrix = new Matrix();
33 | matrix.setScale(scaleX, scaleY);
34 | } else {
35 | matrix = null;
36 | }
37 | }
38 | } else {
39 | matrix = new Matrix(imageView.getImageMatrix());
40 | }
41 | return matrix;
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yc/cn/ycgallery/animations/ScreenAnimation.java:
--------------------------------------------------------------------------------
1 | package com.yc.cn.ycgallery.animations;
2 |
3 | import android.content.Context;
4 |
5 |
6 | public abstract class ScreenAnimation {
7 |
8 | protected static final long IMAGE_TRANSLATION_DURATION = 1000;
9 |
10 | private final Context mContext;
11 |
12 | protected ScreenAnimation(Context context) {
13 | mContext = context;
14 | }
15 |
16 | protected int getStatusBarHeight() {
17 | int result = 0;
18 | int resourceId = mContext.getResources().getIdentifier("status_bar_height", "dimen", "android");
19 | if (resourceId > 0) {
20 | result = mContext.getResources().getDimensionPixelSize(resourceId);
21 | }
22 | return result;
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yc/cn/ycgallery/animations/SimpleAnimationListener.java:
--------------------------------------------------------------------------------
1 | package com.yc.cn.ycgallery.animations;
2 |
3 | import android.animation.Animator;
4 |
5 |
6 | public class SimpleAnimationListener implements Animator.AnimatorListener {
7 |
8 | /**
9 | * For overriding
10 | */
11 | @Override
12 | public void onAnimationStart(Animator animation) {}
13 |
14 | /**
15 | * For overriding
16 | */
17 | @Override
18 | public void onAnimationEnd(Animator animation) {
19 | }
20 |
21 | /**
22 | * For overriding
23 | */
24 | @Override
25 | public void onAnimationCancel(Animator animation) {
26 | }
27 |
28 | /**
29 | * For overriding
30 | */
31 | @Override
32 | public void onAnimationRepeat(Animator animation) {
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/screen_zoom_in.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
12 |
13 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/screen_zoom_out.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
12 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/slide_in_left.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/slide_in_right.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/slide_in_top.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
14 |
15 |
20 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/slide_out_left.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/slide_out_right.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/image1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCServerLib/90383f44339525cc8761fcf3d82d12e64a9b00bc/app/src/main/res/drawable-xhdpi/image1.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/image2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCServerLib/90383f44339525cc8761fcf3d82d12e64a9b00bc/app/src/main/res/drawable-xhdpi/image2.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/image3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCServerLib/90383f44339525cc8761fcf3d82d12e64a9b00bc/app/src/main/res/drawable-xhdpi/image3.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/image4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCServerLib/90383f44339525cc8761fcf3d82d12e64a9b00bc/app/src/main/res/drawable-xhdpi/image4.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/image5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCServerLib/90383f44339525cc8761fcf3d82d12e64a9b00bc/app/src/main/res/drawable-xhdpi/image5.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/image6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCServerLib/90383f44339525cc8761fcf3d82d12e64a9b00bc/app/src/main/res/drawable-xhdpi/image6.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/image7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCServerLib/90383f44339525cc8761fcf3d82d12e64a9b00bc/app/src/main/res/drawable-xhdpi/image7.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/image8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCServerLib/90383f44339525cc8761fcf3d82d12e64a9b00bc/app/src/main/res/drawable-xhdpi/image8.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/beauty1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCServerLib/90383f44339525cc8761fcf3d82d12e64a9b00bc/app/src/main/res/drawable-xxhdpi/beauty1.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/beauty10.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCServerLib/90383f44339525cc8761fcf3d82d12e64a9b00bc/app/src/main/res/drawable-xxhdpi/beauty10.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/beauty11.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCServerLib/90383f44339525cc8761fcf3d82d12e64a9b00bc/app/src/main/res/drawable-xxhdpi/beauty11.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/beauty12.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCServerLib/90383f44339525cc8761fcf3d82d12e64a9b00bc/app/src/main/res/drawable-xxhdpi/beauty12.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/beauty13.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCServerLib/90383f44339525cc8761fcf3d82d12e64a9b00bc/app/src/main/res/drawable-xxhdpi/beauty13.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/beauty2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCServerLib/90383f44339525cc8761fcf3d82d12e64a9b00bc/app/src/main/res/drawable-xxhdpi/beauty2.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/beauty3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCServerLib/90383f44339525cc8761fcf3d82d12e64a9b00bc/app/src/main/res/drawable-xxhdpi/beauty3.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/beauty4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCServerLib/90383f44339525cc8761fcf3d82d12e64a9b00bc/app/src/main/res/drawable-xxhdpi/beauty4.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/beauty5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCServerLib/90383f44339525cc8761fcf3d82d12e64a9b00bc/app/src/main/res/drawable-xxhdpi/beauty5.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/beauty6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCServerLib/90383f44339525cc8761fcf3d82d12e64a9b00bc/app/src/main/res/drawable-xxhdpi/beauty6.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/beauty7.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCServerLib/90383f44339525cc8761fcf3d82d12e64a9b00bc/app/src/main/res/drawable-xxhdpi/beauty7.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/beauty8.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCServerLib/90383f44339525cc8761fcf3d82d12e64a9b00bc/app/src/main/res/drawable-xxhdpi/beauty8.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/beauty9.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCServerLib/90383f44339525cc8761fcf3d82d12e64a9b00bc/app/src/main/res/drawable-xxhdpi/beauty9.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable/shape_b3666666_bg_3.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_first.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
12 |
13 |
21 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_five.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 |
15 |
16 |
17 |
25 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_four.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
21 |
22 |
30 |
31 |
39 |
40 |
48 |
49 |
50 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_second.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_third.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_snap.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_main.xml:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCServerLib/90383f44339525cc8761fcf3d82d12e64a9b00bc/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCServerLib/90383f44339525cc8761fcf3d82d12e64a9b00bc/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCServerLib/90383f44339525cc8761fcf3d82d12e64a9b00bc/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCServerLib/90383f44339525cc8761fcf3d82d12e64a9b00bc/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/default_video.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCServerLib/90383f44339525cc8761fcf3d82d12e64a9b00bc/app/src/main/res/mipmap-xxxhdpi/default_video.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCServerLib/90383f44339525cc8761fcf3d82d12e64a9b00bc/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/transition/activity_explode.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/array.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | - 1.坚持读书,写作,源于内心的动力
6 | - 2.展翅翱翔,青春我们一路前行
7 | - 3.欢迎订阅喜马拉雅听书
8 |
9 |
10 |
11 |
12 | - @drawable/beauty1
13 | - @drawable/beauty2
14 | - @drawable/beauty3
15 | - @drawable/beauty4
16 | - @drawable/beauty5
17 | - @drawable/beauty6
18 | - @drawable/beauty7
19 | - @drawable/beauty8
20 | - @drawable/beauty9
21 | - @drawable/beauty10
22 | - @drawable/beauty11
23 | - @drawable/beauty12
24 | - @drawable/beauty13
25 | - @drawable/beauty11
26 | - @drawable/beauty12
27 |
28 |
29 |
30 |
31 |
32 | - @drawable/image1
33 | - @drawable/image2
34 | - @drawable/image3
35 | - @drawable/beauty7
36 | - @drawable/image4
37 | - @drawable/image5
38 | - @drawable/beauty13
39 | - @drawable/image6
40 | - @drawable/image7
41 | - @drawable/beauty12
42 | - @drawable/image8
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | YCGallery
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
16 |
17 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | apply from: "yc.gradle"
2 |
3 | buildscript {
4 | apply from: 'yc.gradle'
5 | repositories {
6 | google()
7 | jcenter()
8 | maven {
9 | url 'https://maven.google.com/'
10 | name 'Google'
11 | }
12 | //添加阿里云镜像
13 | maven { url "https://maven.aliyun.com/repository/public" }
14 | maven { url "https://maven.aliyun.com/repository/google" }
15 | maven { url "https://maven.aliyun.com/repository/jcenter" }
16 | maven { url 'https://jitpack.io' }
17 | mavenCentral()
18 | }
19 | dependencies {
20 | classpath "com.android.tools.build:gradle:$buildVersion"
21 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
22 | //使用gRPC网络请求需要的插件
23 | classpath "com.google.protobuf:protobuf-gradle-plugin:0.9.1"
24 | //jitpack
25 | classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
26 | //jetpack
27 | classpath "androidx.navigation:navigation-safe-args-gradle-plugin:2.0.0"
28 | //自定义插件
29 | //classpath 'com.github.yangchong211.YCAppTool:ServiceLoaderPlugin:1.4.4'
30 | //classpath 'com.github.yangchong211.YCAppTool:BuildTimeCostPlugin:1.4.4'
31 |
32 |
33 | }
34 | }
35 |
36 | allprojects {
37 | repositories {
38 | google()
39 | jcenter()
40 | maven {
41 | url 'https://maven.google.com/'
42 | name 'Google'
43 | }
44 | maven { url 'https://jitpack.io' }
45 | maven { url 'https://gitee.com/liuchaoya/libcommon/raw/master/repository/' }
46 | //添加阿里云镜像
47 | maven { url "https://maven.aliyun.com/repository/public" }
48 | maven { url "https://maven.aliyun.com/repository/google" }
49 | maven { url "https://maven.aliyun.com/repository/jcenter" }
50 | mavenCentral()
51 | }
52 | }
53 |
54 | task clean(type: Delete) {
55 | delete rootProject.buildDir
56 | }
57 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | org.gradle.jvmargs=-Xmx1536m
13 | android.useAndroidX = true
14 | android.enableJetifier = true
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
19 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCServerLib/90383f44339525cc8761fcf3d82d12e64a9b00bc/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':GalleryViewLib'
2 | include ':GalleryPagerLib'
3 | include ':GrpcServer'
4 | include ':CompressServer'
5 | include ':EasyBleServer'
6 | include ':AppGrpc'
7 |
--------------------------------------------------------------------------------