├── .gitignore ├── .idea ├── .gitignore ├── AndroidProjectSystem.xml ├── compiler.xml ├── deploymentTargetDropDown.xml ├── deploymentTargetSelector.xml ├── gradle.xml ├── kotlinc.xml ├── migrations.xml ├── misc.xml ├── runConfigurations.xml └── vcs.xml ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── woncan │ │ └── devicegithubsdk │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── woncan │ │ │ └── devicegithubsdk │ │ │ ├── DeviceAdapter.java │ │ │ └── MainActivity.java │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ └── ic_launcher_background.xml │ │ ├── layout │ │ ├── activity_main.xml │ │ └── item_device.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-anydpi-v33 │ │ └── ic_launcher.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── values-night │ │ └── themes.xml │ │ ├── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── themes.xml │ │ └── xml │ │ ├── backup_rules.xml │ │ └── data_extraction_rules.xml │ └── test │ └── java │ └── com │ └── woncan │ └── devicegithubsdk │ └── ExampleUnitTest.java ├── build.gradle ├── devicelib ├── .gitignore ├── build.gradle ├── consumer-rules.pro ├── libs │ ├── arm64-v8a │ │ ├── libcmcc_sdk.so │ │ ├── libdevice.so │ │ ├── libqxinertial.so │ │ ├── libqxrtk_hal.so │ │ ├── libqxwz_sdk_core.so │ │ ├── libsdk_core_jni.so │ │ └── libsixents-core-sdk.so │ ├── armeabi-v7a │ │ ├── libcmcc_sdk.so │ │ ├── libdevice.so │ │ ├── libqxinertial.so │ │ ├── libqxrtk_hal.so │ │ ├── libqxwz_sdk_core.so │ │ ├── libsdk_core_jni.so │ │ └── libsixents-core-sdk.so │ ├── cmcc.jar │ ├── device.jar │ ├── qx.jar │ └── sixents.jar ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── woncan │ │ └── devicelib │ │ └── ExampleInstrumentedTest.java │ └── main │ └── AndroidManifest.xml ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── jitpack.yml ├── readme ├── README_CN.md ├── bean.md └── errCode.md └── settings.gradle /.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 | local.properties 16 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | -------------------------------------------------------------------------------- /.idea/AndroidProjectSystem.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/deploymentTargetDropDown.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/deploymentTargetSelector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 20 | 21 | -------------------------------------------------------------------------------- /.idea/kotlinc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/migrations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16 | 17 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Device 2 | 3 | Device SDK说明 4 | 5 | ##### Gradle集成SDK 6 | 7 | ###### 1.1在Project的build.gradle文件中配置repositories,添加maven仓库地址(新版本Android studio需要在settings.gradle里面配置) 8 | ``` 9 | repositories { 10 | maven { url "https://jitpack.io" } 11 | } 12 | ``` 13 | 14 | ###### 在主工程的build.gradle文件配置dependencies 15 | 16 | [![](https://jitpack.io/v/woncan/device.svg)](https://jitpack.io/#woncan/device) 17 | ``` 18 | dependencies { 19 | implementation 'com.github.woncan:device:latest.release' 20 | } 21 | ``` 22 | 23 | ##### 添加混淆配置 24 | ``` 25 | -keep class com.woncan.device.**{*;} 26 | -keep class com.cmcc.sy.hap.** { *;} 27 | -keep class com.qxwz.sdk.** { *;} 28 | -keep class com.sixents.sdk.** { *;} 29 | ``` 30 | ### 使用 31 | 32 | 33 | 34 | #### 搜索设备 35 | **以下方式选择其一** 36 | - 搜索所有设备 37 | ``` 38 | ScanManager.scanDevice(this, device -> { 39 | }); 40 | ``` 41 | - 搜索蓝牙设备 42 | ``` 43 | ScanManager.scanBluetoothDevice(this, device -> { 44 | }); 45 | ``` 46 | - 搜索串口设备 47 | ``` 48 | ScanManager.scanSerialDevice(this, device -> { 49 | }); 50 | ``` 51 | #### 关闭搜索 52 | ``` 53 | ScanManager.stopScan(context); 54 | ``` 55 | 56 | #### 连接并配置设备 57 | ``` 58 | //连接设备 59 | device.connect(context); 60 | 61 | //设置数据频率 62 | device.setInterval(DeviceInterval.HZ_5); 63 | 64 | //配置Ntrip账号 65 | device.setAccount("ip",port,"account","password","mountPoint"); 66 | 67 | //配置激光开关 68 | device.setLaserState(true); 69 | 70 | ``` 71 | 72 | #### 注册回调 73 | ``` 74 | //设备状态 75 | device.registerSatesListener(new DeviceStatesListener() { 76 | @Override 77 | public void onConnectionStateChange(boolean isConnect) { 78 | //连接状态 79 | } 80 | 81 | @Override 82 | public void onDeviceAccountChange(@NonNull DeviceNtripAccount account) { 83 | //写入设备的Ntrip账号 84 | } 85 | 86 | @Override 87 | public void onDeviceInfoChange(@NonNull DeviceInfo deviceInfo) { 88 | //设备信息 89 | } 90 | 91 | @Override 92 | public void onLaserStateChange(boolean isOpen) { 93 | //激光开关 94 | } 95 | }); 96 | 97 | //设备定位 98 | device.registerLocationListener(new WLocationListener() { 99 | @Override 100 | public void onReceiveLocation(@NonNull WLocation wLocation) { 101 | //定位信息 102 | } 103 | 104 | @Override 105 | public void onError(int i, @NonNull String s) { 106 | //错误信息 107 | } 108 | }); 109 | 110 | //卫星数据 111 | device.registerSatelliteListener(new SatelliteListener() { 112 | @Override 113 | public void onReceiveSatellite(List list) { 114 | //卫星数据 115 | } 116 | }); 117 | //NMEA数据 118 | device.setNMEAEnable(NMEA.GSV , true); 119 | device.setNMEAEnable(NMEA.GSA , true); 120 | device.setNMEAEnable(NMEA.GLL , true); 121 | device.setNMEAEnable(NMEA.GMC , true); 122 | device.setNMEAEnable(NMEA.VTG , true); 123 | 124 | device.setNMEAListener(new NMEAListener() { 125 | @Override 126 | public void onReceiveNMEA(String s) { 127 | //NMEA数据 128 | } 129 | }); 130 | ``` 131 | - [WLocation](https://github.com/woncan/device/blob/master/readme/bean.md#WLocation) 132 | - [SatelliteInfo](https://github.com/woncan/device/blob/master/readme/bean.md#SatelliteInfo) 133 | - [errCode](https://github.com/woncan/device/blob/master/readme/errCode.md) 134 | #### 静态记录 135 | ``` 136 | //开启RTCM 137 | device.openRTCM(new RTCM[]{RTCM.RTCM1074}, RTCMInterval.SECOND_3); 138 | //注册监听 139 | device.registerRTCMAListener(new RTCMListener() { 140 | @Override 141 | public void onReceiveRTCM(int[] type, byte[] bytes) { 142 | //type:RTCM类型 bytes:RTCM数据 143 | } 144 | 145 | @Override 146 | public void onReceiveSFR(byte[] bytes) { 147 | //SFR数据 148 | } 149 | }); 150 | //记录完毕后关闭RTCM 或者 重启设备 151 | device.closeRTCM(); 152 | ``` 153 | #### 断开连接 154 | ``` 155 | device.disconnect(); 156 | 157 | ``` 158 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'com.android.application' 3 | id 'org.jetbrains.kotlin.android' 4 | } 5 | 6 | android { 7 | namespace 'com.woncan.devicegithubsdk' 8 | compileSdk 34 9 | 10 | defaultConfig { 11 | applicationId "com.woncan.devicegithubsdk" 12 | minSdk 21 13 | targetSdk 34 14 | versionCode 1 15 | versionName "1.0" 16 | 17 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 18 | } 19 | 20 | buildTypes { 21 | release { 22 | minifyEnabled false 23 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 24 | } 25 | } 26 | compileOptions { 27 | sourceCompatibility JavaVersion.VERSION_1_8 28 | targetCompatibility JavaVersion.VERSION_1_8 29 | } 30 | viewBinding{ 31 | enabled = true 32 | } 33 | 34 | } 35 | 36 | dependencies { 37 | 38 | implementation 'androidx.appcompat:appcompat:1.6.1' 39 | implementation 'com.google.android.material:material:1.9.0' 40 | implementation 'androidx.constraintlayout:constraintlayout:2.1.4' 41 | implementation 'androidx.activity:activity:1.8.0' 42 | testImplementation 'junit:junit:4.13.2' 43 | androidTestImplementation 'androidx.test.ext:junit:1.1.5' 44 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' 45 | implementation 'io.github.cymchad:BaseRecyclerViewAdapterHelper:3.0.14' 46 | implementation project(path: ':devicelib') 47 | // implementation 'com.github.woncan:device:1.0.0' 48 | } -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /app/src/androidTest/java/com/woncan/devicegithubsdk/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.woncan.devicegithubsdk; 2 | 3 | import android.content.Context; 4 | 5 | import androidx.test.platform.app.InstrumentationRegistry; 6 | import androidx.test.ext.junit.runners.AndroidJUnit4; 7 | 8 | import org.junit.Test; 9 | import org.junit.runner.RunWith; 10 | 11 | import static org.junit.Assert.*; 12 | 13 | /** 14 | * Instrumented test, which will execute on an Android device. 15 | * 16 | * @see Testing documentation 17 | */ 18 | @RunWith(AndroidJUnit4.class) 19 | public class ExampleInstrumentedTest { 20 | @Test 21 | public void useAppContext() { 22 | // Context of the app under test. 23 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); 24 | assertEquals("com.woncan.devicegithubsdk", appContext.getPackageName()); 25 | } 26 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 14 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /app/src/main/java/com/woncan/devicegithubsdk/DeviceAdapter.java: -------------------------------------------------------------------------------- 1 | package com.woncan.devicegithubsdk; 2 | 3 | import com.chad.library.adapter.base.BaseQuickAdapter; 4 | import com.chad.library.adapter.base.viewholder.BaseViewHolder; 5 | import com.woncan.device.Device; 6 | 7 | public class DeviceAdapter extends BaseQuickAdapter { 8 | 9 | private DeviceAdapter(int layoutResId) { 10 | super(layoutResId); 11 | } 12 | 13 | public DeviceAdapter() { 14 | this(R.layout.item_device); 15 | } 16 | 17 | @Override 18 | protected void convert(BaseViewHolder helper, Device item) { 19 | helper.setText(R.id.item_bluetooth_name, item.getName()); 20 | 21 | } 22 | 23 | 24 | } -------------------------------------------------------------------------------- /app/src/main/java/com/woncan/devicegithubsdk/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.woncan.devicegithubsdk; 2 | 3 | import static java.lang.Thread.sleep; 4 | 5 | import android.Manifest; 6 | import android.annotation.SuppressLint; 7 | import android.content.pm.PackageManager; 8 | import android.os.Build; 9 | import android.os.Bundle; 10 | import android.text.method.ScrollingMovementMethod; 11 | import android.util.Log; 12 | import android.widget.Toast; 13 | 14 | import androidx.activity.result.ActivityResultLauncher; 15 | import androidx.activity.result.contract.ActivityResultContracts; 16 | import androidx.annotation.NonNull; 17 | import androidx.appcompat.app.AppCompatActivity; 18 | import androidx.recyclerview.widget.LinearLayoutManager; 19 | 20 | import com.woncan.device.Device; 21 | import com.woncan.device.NMEA; 22 | import com.woncan.device.ScanManager; 23 | import com.woncan.device.bean.DeviceInfo; 24 | import com.woncan.device.bean.DeviceNtripAccount; 25 | import com.woncan.device.bean.WLocation; 26 | import com.woncan.device.device.DeviceInterval; 27 | import com.woncan.device.listener.DeviceStatesListener; 28 | import com.woncan.device.listener.WLocationListener; 29 | import com.woncan.device.util.LogUtil; 30 | import com.woncan.devicegithubsdk.databinding.ActivityMainBinding; 31 | 32 | import java.util.ArrayList; 33 | import java.util.List; 34 | import java.util.Locale; 35 | 36 | public class MainActivity extends AppCompatActivity { 37 | public static final String TAG = "WONCAN_DEVICE_MAIN"; 38 | 39 | private ActivityMainBinding binding; 40 | 41 | @SuppressLint("MissingPermission") 42 | @Override 43 | protected void onCreate(Bundle savedInstanceState) { 44 | super.onCreate(savedInstanceState); 45 | DeviceAdapter adapter = new DeviceAdapter(); 46 | 47 | binding = ActivityMainBinding.inflate(getLayoutInflater()); 48 | setContentView(binding.getRoot()); 49 | 50 | binding.tvLog.setMovementMethod(ScrollingMovementMethod.getInstance()); 51 | binding.btnSearch.setOnClickListener(v -> { 52 | //搜索所有设备 53 | if (!requestPermission()) { 54 | Toast.makeText(this, "需要蓝牙和定位权限", Toast.LENGTH_SHORT).show(); 55 | return; 56 | } 57 | adapter.setNewInstance(null); 58 | adapter.addData(ScanManager.getPhoneDevice()); 59 | ScanManager.scanDevice(this, device -> { 60 | Log.i(TAG, "onCreate: " + device.getName()); 61 | if (!adapter.getData().contains(device)) { 62 | adapter.addData(device); 63 | } 64 | }); 65 | }); 66 | 67 | binding.recyclerView.setLayoutManager(new LinearLayoutManager(this)); 68 | binding.recyclerView.setAdapter(adapter); 69 | adapter.setOnItemClickListener((adapter1, view, position) -> { 70 | ScanManager.stopScan(MainActivity.this); 71 | connect(adapter.getItem(position)); 72 | }); 73 | } 74 | 75 | 76 | private void connect(Device device) { 77 | LogUtil.INSTANCE.setShowLog(true); 78 | device.registerSatesListener(new DeviceStatesListener() { 79 | @Override 80 | public void onConnectionStateChange(boolean isConnect) { 81 | binding.tvLog.append(isConnect ? "设备已连接\n" : "断开连接\n"); 82 | } 83 | 84 | @Override 85 | public void onDeviceAccountChange(@NonNull DeviceNtripAccount account) { 86 | super.onDeviceAccountChange(account); 87 | 88 | } 89 | 90 | @Override 91 | public void onDeviceInfoChange(@NonNull DeviceInfo deviceInfo) { 92 | binding.tvDeviceInfo.setText(String.format(Locale.CHINA, "型号:%s\n设备ID:%s\n产品名:%s", deviceInfo.getModel(), deviceInfo.getDeviceID(), deviceInfo.getProductNameZH())); 93 | } 94 | 95 | @Override 96 | public void onLaserStateChange(boolean isOpen) { 97 | 98 | } 99 | }); 100 | 101 | device.registerLocationListener(new WLocationListener() { 102 | @Override 103 | public void onReceiveLocation(@NonNull WLocation wLocation) { 104 | Log.i(TAG, "onReceiveLocation: wLocation"); 105 | binding.tvLocation.setText(String.format(Locale.CHINA, "纬度:%.8f\n经度:%.8f\n海拔:%.3f\n解状态:%d", wLocation.getLatitude(), wLocation.getLongitude(), wLocation.getAltitude(), wLocation.getFixStatus())); 106 | } 107 | 108 | @Override 109 | public void onError(int i, @NonNull String s) { 110 | binding.tvLog.append(String.format(Locale.CHINA, "onError:%d %s\n", i, s)); 111 | } 112 | }); 113 | // device.setNMEAListener(s -> Log.i(TAG, "onReceiveNMEA: "+s)); 114 | // device.openRTCM(new RTCM[]{RTCM.RTCM1074}, RTCMInterval.SECOND_3); 115 | // device.registerRTCMAListener(new RTCMListener() { 116 | // @Override 117 | // public void onReceiveRTCM(int[] ints, byte[] bytes) { 118 | // 119 | // } 120 | // 121 | // @Override 122 | // public void onReceiveSFR(byte[] bytes) { 123 | // 124 | // } 125 | // }); 126 | // device.registerSatelliteListener(new SatelliteListener() { 127 | // @Override 128 | // public void onReceiveSatellite(List list) { 129 | // 130 | // } 131 | // }); 132 | 133 | // device.closeRTCM(); 134 | // device.setLaserState(true); 135 | // int port=1; 136 | device.setNMEAEnable(NMEA.GGA , true); 137 | device.setNMEAEnable(NMEA.GSV , true); 138 | device.setNMEAEnable(NMEA.GSA , true); 139 | device.setNMEAEnable(NMEA.GLL , true); 140 | device.setNMEAEnable(NMEA.GMC , true); 141 | device.setNMEAEnable(NMEA.VTG , true); 142 | 143 | device.setNMEAListener(s -> { 144 | 145 | }); 146 | device.connect(this); 147 | new Thread(() -> { 148 | try { 149 | sleep(2000); 150 | } catch (InterruptedException e) { 151 | throw new RuntimeException(e); 152 | } 153 | device.setInterval(DeviceInterval.HZ_5); 154 | }).start(); 155 | 156 | // device.setAccount("",0,"","",""); 157 | } 158 | 159 | 160 | private final ActivityResultLauncher resultLauncher = 161 | registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), isGranted -> { 162 | }); 163 | 164 | 165 | private boolean requestPermission() { 166 | 167 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { 168 | return true; 169 | } 170 | List list = new ArrayList<>(); 171 | if (checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 172 | list.add(Manifest.permission.ACCESS_COARSE_LOCATION); 173 | } 174 | if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 175 | list.add(Manifest.permission.ACCESS_FINE_LOCATION); 176 | } 177 | if (checkSelfPermission(Manifest.permission.BLUETOOTH) != PackageManager.PERMISSION_GRANTED) { 178 | list.add(Manifest.permission.BLUETOOTH); 179 | } 180 | if (checkSelfPermission(Manifest.permission.BLUETOOTH_ADMIN) != PackageManager.PERMISSION_GRANTED) { 181 | list.add(Manifest.permission.BLUETOOTH_ADMIN); 182 | } 183 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { 184 | if (checkSelfPermission(Manifest.permission.BLUETOOTH_SCAN) != PackageManager.PERMISSION_GRANTED) { 185 | list.add(Manifest.permission.BLUETOOTH_SCAN); 186 | } 187 | } 188 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { 189 | if (checkSelfPermission(Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) { 190 | list.add(Manifest.permission.BLUETOOTH_CONNECT); 191 | } 192 | } 193 | 194 | resultLauncher.launch(list.toArray(new String[0])); 195 | return list.size() == 0; 196 | } 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 15 | 18 | 21 | 22 | 23 | 24 | 30 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 16 | 17 |