diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index 097f9f9..0000000 --- a/.gitattributes +++ /dev/null @@ -1,9 +0,0 @@ -# -# https://help.github.com/articles/dealing-with-line-endings/ -# -# Linux start script should use lf -/gradlew text eol=lf - -# These are Windows script files and should use crlf -*.bat text eol=crlf - diff --git a/.gitignore b/.gitignore index 1b6985c..aa724b7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,15 @@ -# Ignore Gradle project-specific cache directory +*.iml .gradle - -# Ignore Gradle build output directory -build +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild +.cxx +local.properties diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/AndroidProjectSystem.xml b/.idea/AndroidProjectSystem.xml new file mode 100644 index 0000000..4a53bee --- /dev/null +++ b/.idea/AndroidProjectSystem.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..7643783 --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,123 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..79ee123 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..b86273d --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml new file mode 100644 index 0000000..b268ef3 --- /dev/null +++ b/.idea/deploymentTargetSelector.xml @@ -0,0 +1,10 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/deviceManager.xml b/.idea/deviceManager.xml new file mode 100644 index 0000000..91f9558 --- /dev/null +++ b/.idea/deviceManager.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..639c779 --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,19 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/migrations.xml b/.idea/migrations.xml new file mode 100644 index 0000000..f8051a6 --- /dev/null +++ b/.idea/migrations.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..b2c751a --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..16660f1 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,17 @@ + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 8aa6f17..51800b5 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -1,22 +1,25 @@ plugins { - id("com.android.application") - kotlin("android") + alias(libs.plugins.android.application) + alias(libs.plugins.kotlin.android) + alias(libs.plugins.kotlin.compose) } android { - namespace = "com.example.androidsshclient" - compileSdk = 34 + namespace = "com.example.androidssh" + compileSdk = 36 defaultConfig { - applicationId = "com.example.androidsshclient" - minSdk = 21 - targetSdk = 34 + applicationId = "com.example.androidssh" + minSdk = 28 + targetSdk = 36 versionCode = 1 versionName = "1.0" + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } buildTypes { - getByName("release") { + release { isMinifyEnabled = false proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), @@ -24,31 +27,40 @@ android { ) } } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_17 - targetCompatibility = JavaVersion.VERSION_17 + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 } - kotlinOptions { - jvmTarget = "17" + jvmTarget = "11" + } + buildFeatures { + compose = true } - - buildToolsVersion = "34.0.0" } dependencies { + implementation("com.google.android.material:material:1.11.0") + implementation("androidx.appcompat:appcompat:1.7.0") implementation("androidx.core:core-ktx:1.12.0") - implementation("androidx.appcompat:appcompat:1.6.1") - implementation("com.google.android.material:material:1.10.0") - implementation("androidx.constraintlayout:constraintlayout:2.1.4") - - // SSH библиотека - implementation("com.github.mwiede:jsch:0.2.11") - - // Корутины для асинхронности - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3") - - // Для работы с терминалом - implementation("com.jcraft:jzlib:1.1.3") // Для лучшей поддержки терминала -} + implementation("com.jcraft:jsch:0.1.55") + + implementation(libs.androidx.core.ktx) + implementation(libs.androidx.lifecycle.runtime.ktx) + implementation(libs.androidx.activity.compose) + implementation(platform(libs.androidx.compose.bom)) + implementation(libs.androidx.compose.ui) + implementation(libs.androidx.compose.ui.graphics) + implementation(libs.androidx.compose.ui.tooling.preview) + implementation(libs.androidx.compose.material3) + + testImplementation(libs.junit) + + androidTestImplementation(libs.androidx.junit) + androidTestImplementation(libs.androidx.espresso.core) + androidTestImplementation(platform(libs.androidx.compose.bom)) + androidTestImplementation(libs.androidx.compose.ui.test.junit4) + + debugImplementation(libs.androidx.compose.ui.tooling) + debugImplementation(libs.androidx.compose.ui.test.manifest) +} \ No newline at end of file diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/app/src/androidTest/java/com/example/androidssh/ExampleInstrumentedTest.kt b/app/src/androidTest/java/com/example/androidssh/ExampleInstrumentedTest.kt new file mode 100644 index 0000000..320a7d9 --- /dev/null +++ b/app/src/androidTest/java/com/example/androidssh/ExampleInstrumentedTest.kt @@ -0,0 +1,24 @@ +package com.example.androidssh + +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.ext.junit.runners.AndroidJUnit4 + +import org.junit.Test +import org.junit.runner.RunWith + +import org.junit.Assert.* + +/** + * Instrumented test, which will execute on an Android device. + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +@RunWith(AndroidJUnit4::class) +class ExampleInstrumentedTest { + @Test + fun useAppContext() { + // Context of the app under test. + val appContext = InstrumentationRegistry.getInstrumentation().targetContext + assertEquals("com.example.androidssh", appContext.packageName) + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 2e87ced..f7e8794 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,33 +1,23 @@ - - + - - - + + android:allowBackup="true" + android:label="@string/app_name" + android:icon="@mipmap/ic_launcher" + android:theme="@style/Theme.AndroidSSH"> - - - + + - - - - diff --git a/app/src/main/java/com/example/androidssh/MainActivity.kt b/app/src/main/java/com/example/androidssh/MainActivity.kt new file mode 100644 index 0000000..ed51b2e --- /dev/null +++ b/app/src/main/java/com/example/androidssh/MainActivity.kt @@ -0,0 +1,94 @@ +package com.example.androidssh + +import android.os.Bundle +import android.widget.Button +import android.widget.EditText +import android.view.View +import android.widget.TextView +import android.widget.ScrollView +import androidx.appcompat.app.AppCompatActivity +import com.jcraft.jsch.ChannelExec +import com.jcraft.jsch.JSch +import java.io.BufferedReader +import java.io.InputStreamReader +import java.util.Properties +import kotlin.concurrent.thread + +class MainActivity : AppCompatActivity() { + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_main) + + val scrollView = findViewById(R.id.scrollView) + val etHost = findViewById(R.id.etHost) + val etPort = findViewById(R.id.etPort) + val etUser = findViewById(R.id.etUser) + val etPassword = findViewById(R.id.etPassword) + val etCommand = findViewById(R.id.etCommand) + val btnConnect = findViewById