This commit is contained in:
flowerstonezl
2026-01-19 17:08:49 +08:00
commit 056289625c
1486 changed files with 110768 additions and 0 deletions

View File

@@ -0,0 +1,91 @@
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id("org.jetbrains.kotlin.plugin.serialization")
}
android {
namespace = "com.skylink.app"
compileSdk = 34
defaultConfig {
applicationId = "com.skylink.app"
minSdk = 24
targetSdk = 34
versionCode = 1
versionName = "1.0.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary = true
}
}
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
debug {
isDebuggable = true
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
buildFeatures {
compose = false
viewBinding = true
}
packaging {
resources {
excludes += "/META-INF/{AL2.0,LGPL2.1}"
}
}
}
dependencies {
// Android Core
implementation("androidx.core:core-ktx:1.12.0")
implementation("androidx.appcompat:appcompat:1.6.1")
implementation("com.google.android.material:material:1.11.0")
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
// Kotlin & Coroutines
implementation("org.jetbrains.kotlin:kotlin-stdlib:1.9.20")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")
// Serialization
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.2")
// Networking
implementation("com.squareup.okhttp3:okhttp:4.11.0")
// Lifecycle
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.2")
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2")
// Navigation
implementation("androidx.navigation:navigation-fragment-ktx:2.7.5")
implementation("androidx.navigation:navigation-ui-ktx:2.7.5")
// Fragment
implementation("androidx.fragment:fragment-ktx:1.6.2")
// Testing
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
}

View File

@@ -0,0 +1,81 @@
// Generated by view binder compiler. Do not edit!
package com.skylink.app.databinding;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.FragmentContainerView;
import androidx.viewbinding.ViewBinding;
import androidx.viewbinding.ViewBindings;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.skylink.app.R;
import java.lang.NullPointerException;
import java.lang.Override;
import java.lang.String;
public final class ActivityMainBinding implements ViewBinding {
@NonNull
private final LinearLayout rootView;
@NonNull
public final BottomNavigationView bottomNavigation;
@NonNull
public final FragmentContainerView navHostFragment;
private ActivityMainBinding(@NonNull LinearLayout rootView,
@NonNull BottomNavigationView bottomNavigation,
@NonNull FragmentContainerView navHostFragment) {
this.rootView = rootView;
this.bottomNavigation = bottomNavigation;
this.navHostFragment = navHostFragment;
}
@Override
@NonNull
public LinearLayout getRoot() {
return rootView;
}
@NonNull
public static ActivityMainBinding inflate(@NonNull LayoutInflater inflater) {
return inflate(inflater, null, false);
}
@NonNull
public static ActivityMainBinding inflate(@NonNull LayoutInflater inflater,
@Nullable ViewGroup parent, boolean attachToParent) {
View root = inflater.inflate(R.layout.activity_main, parent, false);
if (attachToParent) {
parent.addView(root);
}
return bind(root);
}
@NonNull
public static ActivityMainBinding bind(@NonNull View rootView) {
// The body of this method is generated in a way you would not otherwise write.
// This is done to optimize the compiled bytecode for size and performance.
int id;
missingId: {
id = R.id.bottom_navigation;
BottomNavigationView bottomNavigation = ViewBindings.findChildViewById(rootView, id);
if (bottomNavigation == null) {
break missingId;
}
id = R.id.nav_host_fragment;
FragmentContainerView navHostFragment = ViewBindings.findChildViewById(rootView, id);
if (navHostFragment == null) {
break missingId;
}
return new ActivityMainBinding((LinearLayout) rootView, bottomNavigation, navHostFragment);
}
String missingId = rootView.getResources().getResourceName(id);
throw new NullPointerException("Missing required view with ID: ".concat(missingId));
}
}

View File

@@ -0,0 +1,123 @@
// Generated by view binder compiler. Do not edit!
package com.skylink.app.databinding;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.viewbinding.ViewBinding;
import androidx.viewbinding.ViewBindings;
import com.skylink.app.R;
import java.lang.NullPointerException;
import java.lang.Override;
import java.lang.String;
public final class FragmentHomeBinding implements ViewBinding {
@NonNull
private final LinearLayout rootView;
@NonNull
public final TextView gpsText;
@NonNull
public final Button recordButton;
@NonNull
public final Button saveButton;
@NonNull
public final TextView statsText;
@NonNull
public final TextView statusText;
@NonNull
public final ImageView videoImage;
private FragmentHomeBinding(@NonNull LinearLayout rootView, @NonNull TextView gpsText,
@NonNull Button recordButton, @NonNull Button saveButton, @NonNull TextView statsText,
@NonNull TextView statusText, @NonNull ImageView videoImage) {
this.rootView = rootView;
this.gpsText = gpsText;
this.recordButton = recordButton;
this.saveButton = saveButton;
this.statsText = statsText;
this.statusText = statusText;
this.videoImage = videoImage;
}
@Override
@NonNull
public LinearLayout getRoot() {
return rootView;
}
@NonNull
public static FragmentHomeBinding inflate(@NonNull LayoutInflater inflater) {
return inflate(inflater, null, false);
}
@NonNull
public static FragmentHomeBinding inflate(@NonNull LayoutInflater inflater,
@Nullable ViewGroup parent, boolean attachToParent) {
View root = inflater.inflate(R.layout.fragment_home, parent, false);
if (attachToParent) {
parent.addView(root);
}
return bind(root);
}
@NonNull
public static FragmentHomeBinding bind(@NonNull View rootView) {
// The body of this method is generated in a way you would not otherwise write.
// This is done to optimize the compiled bytecode for size and performance.
int id;
missingId: {
id = R.id.gps_text;
TextView gpsText = ViewBindings.findChildViewById(rootView, id);
if (gpsText == null) {
break missingId;
}
id = R.id.record_button;
Button recordButton = ViewBindings.findChildViewById(rootView, id);
if (recordButton == null) {
break missingId;
}
id = R.id.save_button;
Button saveButton = ViewBindings.findChildViewById(rootView, id);
if (saveButton == null) {
break missingId;
}
id = R.id.stats_text;
TextView statsText = ViewBindings.findChildViewById(rootView, id);
if (statsText == null) {
break missingId;
}
id = R.id.status_text;
TextView statusText = ViewBindings.findChildViewById(rootView, id);
if (statusText == null) {
break missingId;
}
id = R.id.video_image;
ImageView videoImage = ViewBindings.findChildViewById(rootView, id);
if (videoImage == null) {
break missingId;
}
return new FragmentHomeBinding((LinearLayout) rootView, gpsText, recordButton, saveButton,
statsText, statusText, videoImage);
}
String missingId = rootView.getResources().getResourceName(id);
throw new NullPointerException("Missing required view with ID: ".concat(missingId));
}
}

View File

@@ -0,0 +1,158 @@
// Generated by view binder compiler. Do not edit!
package com.skylink.app.databinding;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.ScrollView;
import android.widget.Spinner;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.viewbinding.ViewBinding;
import androidx.viewbinding.ViewBindings;
import com.skylink.app.R;
import java.lang.NullPointerException;
import java.lang.Override;
import java.lang.String;
public final class FragmentSettingsBinding implements ViewBinding {
@NonNull
private final ScrollView rootView;
@NonNull
public final Button clearButton;
@NonNull
public final EditText hostInput;
@NonNull
public final Button multiplePingButton;
@NonNull
public final Spinner pingCountSpinner;
@NonNull
public final ProgressBar pingProgress;
@NonNull
public final TextView resultText;
@NonNull
public final Button singlePingButton;
@NonNull
public final Spinner timeoutSpinner;
@NonNull
public final EditText udpPortInput;
private FragmentSettingsBinding(@NonNull ScrollView rootView, @NonNull Button clearButton,
@NonNull EditText hostInput, @NonNull Button multiplePingButton,
@NonNull Spinner pingCountSpinner, @NonNull ProgressBar pingProgress,
@NonNull TextView resultText, @NonNull Button singlePingButton,
@NonNull Spinner timeoutSpinner, @NonNull EditText udpPortInput) {
this.rootView = rootView;
this.clearButton = clearButton;
this.hostInput = hostInput;
this.multiplePingButton = multiplePingButton;
this.pingCountSpinner = pingCountSpinner;
this.pingProgress = pingProgress;
this.resultText = resultText;
this.singlePingButton = singlePingButton;
this.timeoutSpinner = timeoutSpinner;
this.udpPortInput = udpPortInput;
}
@Override
@NonNull
public ScrollView getRoot() {
return rootView;
}
@NonNull
public static FragmentSettingsBinding inflate(@NonNull LayoutInflater inflater) {
return inflate(inflater, null, false);
}
@NonNull
public static FragmentSettingsBinding inflate(@NonNull LayoutInflater inflater,
@Nullable ViewGroup parent, boolean attachToParent) {
View root = inflater.inflate(R.layout.fragment_settings, parent, false);
if (attachToParent) {
parent.addView(root);
}
return bind(root);
}
@NonNull
public static FragmentSettingsBinding bind(@NonNull View rootView) {
// The body of this method is generated in a way you would not otherwise write.
// This is done to optimize the compiled bytecode for size and performance.
int id;
missingId: {
id = R.id.clear_button;
Button clearButton = ViewBindings.findChildViewById(rootView, id);
if (clearButton == null) {
break missingId;
}
id = R.id.host_input;
EditText hostInput = ViewBindings.findChildViewById(rootView, id);
if (hostInput == null) {
break missingId;
}
id = R.id.multiple_ping_button;
Button multiplePingButton = ViewBindings.findChildViewById(rootView, id);
if (multiplePingButton == null) {
break missingId;
}
id = R.id.ping_count_spinner;
Spinner pingCountSpinner = ViewBindings.findChildViewById(rootView, id);
if (pingCountSpinner == null) {
break missingId;
}
id = R.id.ping_progress;
ProgressBar pingProgress = ViewBindings.findChildViewById(rootView, id);
if (pingProgress == null) {
break missingId;
}
id = R.id.result_text;
TextView resultText = ViewBindings.findChildViewById(rootView, id);
if (resultText == null) {
break missingId;
}
id = R.id.single_ping_button;
Button singlePingButton = ViewBindings.findChildViewById(rootView, id);
if (singlePingButton == null) {
break missingId;
}
id = R.id.timeout_spinner;
Spinner timeoutSpinner = ViewBindings.findChildViewById(rootView, id);
if (timeoutSpinner == null) {
break missingId;
}
id = R.id.udp_port_input;
EditText udpPortInput = ViewBindings.findChildViewById(rootView, id);
if (udpPortInput == null) {
break missingId;
}
return new FragmentSettingsBinding((ScrollView) rootView, clearButton, hostInput,
multiplePingButton, pingCountSpinner, pingProgress, resultText, singlePingButton,
timeoutSpinner, udpPortInput);
}
String missingId = rootView.getResources().getResourceName(id);
throw new NullPointerException("Missing required view with ID: ".concat(missingId));
}
}

View File

@@ -0,0 +1,20 @@
{
"version": 3,
"artifactType": {
"type": "APK",
"kind": "Directory"
},
"applicationId": "com.skylink.app",
"variantName": "debug",
"elements": [
{
"type": "SINGLE",
"filters": [],
"attributes": [],
"versionCode": 1,
"versionName": "1.0.0",
"outputFile": "app-debug.apk"
}
],
"elementType": "File"
}

View File

@@ -0,0 +1,2 @@
#- File Locator -
listingFile=../../apk/debug/output-metadata.json

View File

@@ -0,0 +1,2 @@
appMetadataVersion=1.1
androidGradlePluginVersion=8.2.0

View File

@@ -0,0 +1,10 @@
{
"version": 3,
"artifactType": {
"type": "COMPATIBLE_SCREEN_MANIFEST",
"kind": "Directory"
},
"applicationId": "com.skylink.app",
"variantName": "debug",
"elements": []
}

View File

@@ -0,0 +1 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?><Layout layout="activity_main" modulePackage="com.skylink.app" filePath="app\src\main\res\layout\activity_main.xml" directory="layout" isMerge="false" isBindingData="false" rootNodeType="android.widget.LinearLayout"><Targets><Target tag="layout/activity_main_0" view="LinearLayout"><Expressions/><location startLine="1" startOffset="0" endLine="34" endOffset="14"/></Target><Target id="@+id/nav_host_fragment" view="androidx.fragment.app.FragmentContainerView"><Expressions/><location startLine="15" startOffset="8" endLine="21" endOffset="50"/></Target><Target id="@+id/bottom_navigation" view="com.google.android.material.bottomnavigation.BottomNavigationView"><Expressions/><location startLine="25" startOffset="4" endLine="32" endOffset="42"/></Target></Targets></Layout>

View File

@@ -0,0 +1 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?><Layout layout="fragment_home" modulePackage="com.skylink.app" filePath="app\src\main\res\layout\fragment_home.xml" directory="layout" isMerge="false" isBindingData="false" rootNodeType="android.widget.LinearLayout"><Targets><Target tag="layout/fragment_home_0" view="LinearLayout"><Expressions/><location startLine="1" startOffset="0" endLine="74" endOffset="14"/></Target><Target id="@+id/status_text" view="TextView"><Expressions/><location startLine="10" startOffset="4" endLine="17" endOffset="43"/></Target><Target id="@+id/video_image" view="ImageView"><Expressions/><location startLine="20" startOffset="4" endLine="27" endOffset="55"/></Target><Target id="@+id/gps_text" view="TextView"><Expressions/><location startLine="30" startOffset="4" endLine="37" endOffset="43"/></Target><Target id="@+id/stats_text" view="TextView"><Expressions/><location startLine="40" startOffset="4" endLine="46" endOffset="43"/></Target><Target id="@+id/save_button" view="Button"><Expressions/><location startLine="56" startOffset="8" endLine="62" endOffset="43"/></Target><Target id="@+id/record_button" view="Button"><Expressions/><location startLine="64" startOffset="8" endLine="70" endOffset="45"/></Target></Targets></Layout>

View File

@@ -0,0 +1 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?><Layout layout="fragment_settings" modulePackage="com.skylink.app" filePath="app\src\main\res\layout\fragment_settings.xml" directory="layout" isMerge="false" isBindingData="false" rootNodeType="android.widget.ScrollView"><Targets><Target tag="layout/fragment_settings_0" view="ScrollView"><Expressions/><location startLine="1" startOffset="0" endLine="213" endOffset="12"/></Target><Target id="@+id/udp_port_input" view="EditText"><Expressions/><location startLine="38" startOffset="12" endLine="45" endOffset="75"/></Target><Target id="@+id/host_input" view="EditText"><Expressions/><location startLine="79" startOffset="12" endLine="86" endOffset="75"/></Target><Target id="@+id/ping_count_spinner" view="Spinner"><Expressions/><location startLine="103" startOffset="12" endLine="107" endOffset="75"/></Target><Target id="@+id/timeout_spinner" view="Spinner"><Expressions/><location startLine="124" startOffset="12" endLine="128" endOffset="75"/></Target><Target id="@+id/single_ping_button" view="Button"><Expressions/><location startLine="140" startOffset="12" endLine="147" endOffset="73"/></Target><Target id="@+id/multiple_ping_button" view="Button"><Expressions/><location startLine="149" startOffset="12" endLine="156" endOffset="74"/></Target><Target id="@+id/ping_progress" view="ProgressBar"><Expressions/><location startLine="160" startOffset="8" endLine="165" endOffset="42"/></Target><Target id="@+id/clear_button" view="Button"><Expressions/><location startLine="191" startOffset="16" endLine="197" endOffset="43"/></Target><Target id="@+id/result_text" view="TextView"><Expressions/><location startLine="200" startOffset="12" endLine="208" endOffset="53"/></Target></Targets></Layout>

Some files were not shown because too many files have changed in this diff Show More