diff --git a/app/build.gradle b/app/build.gradle
index 1b2233c..55fe990 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -7,7 +7,7 @@ android {
defaultConfig {
applicationId "de.jg_cody.Teraplex"
- minSdkVersion 19
+ minSdkVersion 21
targetSdkVersion 30
versionCode 1
versionName "1.0"
@@ -33,7 +33,7 @@ android {
dependencies {
implementation 'androidx.appcompat:appcompat:1.3.0'
- implementation 'com.google.android.material:material:1.3.0'
+ implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.0-beta02'
implementation 'androidx.navigation:navigation-fragment:2.3.5'
implementation 'androidx.navigation:navigation-ui:2.3.5'
@@ -42,8 +42,8 @@ dependencies {
implementation 'com.jcraft:jsch:0.1.55'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
testImplementation 'junit:junit:4.13.2'
- androidTestImplementation 'androidx.test.ext:junit:1.1.2'
- androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
+ androidTestImplementation 'androidx.test.ext:junit:1.1.3'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.github.martin-stone:hsv-alpha-color-picker-android:3.0.1'
}
diff --git a/app/src/main/java/de/jg_cody/Teraplex/MainActivity.java b/app/src/main/java/de/jg_cody/Teraplex/MainActivity.java
index 6eb1945..ca8735b 100644
--- a/app/src/main/java/de/jg_cody/Teraplex/MainActivity.java
+++ b/app/src/main/java/de/jg_cody/Teraplex/MainActivity.java
@@ -37,7 +37,6 @@ import android.widget.ImageView;
import android.widget.ListView;
import android.widget.Switch;
-import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.view.GravityCompat;
@@ -142,7 +141,7 @@ public class MainActivity extends AppCompatActivity {
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
mAppBarConfiguration = new AppBarConfiguration.Builder(
- R.id.nav_home, R.id.nav_einstellungen, R.id.nav_zeitsteuerung, R.id.nav_tabs, R.id.nav_über, R.id.nav_konsole)
+ R.id.nav_home, R.id.nav_einstellungen, R.id.nav_zeitsteuerung, R.id.nav_tabs, R.id.nav_über, R.id.nav_terminal)
.setOpenableLayout(drawer)
.build();
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
diff --git a/app/src/main/java/de/jg_cody/Teraplex/ui/Konsole/KonsoleFragment.java b/app/src/main/java/de/jg_cody/Teraplex/ui/Konsole/KonsoleFragment.java
deleted file mode 100644
index 5e2fd4f..0000000
--- a/app/src/main/java/de/jg_cody/Teraplex/ui/Konsole/KonsoleFragment.java
+++ /dev/null
@@ -1,183 +0,0 @@
-package de.jg_cody.Teraplex.ui.Konsole;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.SharedPreferences;
-import android.graphics.BitmapFactory;
-import android.graphics.drawable.BitmapDrawable;
-import android.media.MediaPlayer;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Vibrator;
-import android.util.Base64;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.Button;
-import android.widget.EditText;
-import android.widget.ImageView;
-import android.widget.Toast;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.RequiresApi;
-import androidx.fragment.app.Fragment;
-import androidx.lifecycle.ViewModelProvider;
-
-import java.util.Objects;
-
-import de.jg_cody.Teraplex.MainActivity;
-import de.jg_cody.Teraplex.R;
-import de.jg_cody.Teraplex.SSH_connection;
-
-import static de.jg_cody.Teraplex.ui.home.HomeFragment.ip;
-import static de.jg_cody.Teraplex.ui.home.HomeFragment.password;
-import static de.jg_cody.Teraplex.ui.home.HomeFragment.user;
-
-public class KonsoleFragment extends Fragment {
-
- public static String command;
-
- public static EditText befehlInput;
- Button SendCommandButton;
- Button shutdown_Button;
- Button reboot_Button;
-
- private KonsoleViewModel konsoleViewModel;
-
- public View onCreateView(@NonNull LayoutInflater inflater,
- ViewGroup container, Bundle savedInstanceState) {
- konsoleViewModel =
- new ViewModelProvider(this).get(KonsoleViewModel.class);
- View root = inflater.inflate(R.layout.fragment_konsole, container, false);
- SharedPreferences p = requireContext().getSharedPreferences("appsettings", Activity.MODE_PRIVATE);
- String Background = p.getString("Background", null);
- if (Background != null) {
- ImageView I = root.findViewById(R.id.Background);
- byte[] BA = Base64.decode(Background, Base64.DEFAULT);
- I.setImageDrawable(new BitmapDrawable(getResources(), MainActivity.scaleCenterCrop(BitmapFactory.decodeByteArray(BA, 0, BA.length), MainActivity.getScreenHeight(), MainActivity.getScreenWidth())));
- I.setScaleType(ImageView.ScaleType.CENTER_CROP);
- }
- befehlInput = (EditText) root.findViewById(R.id.befehlInput);
- SendCommandButton = (Button) root.findViewById(R.id.SendCommandButton);
- SendCommandButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- Vibrator vr = (Vibrator) v.getContext().getSystemService(Context.VIBRATOR_SERVICE);
- assert vr != null;
- vr.vibrate(100);
- try {
- if (befehlInput.getText().toString().trim().length() == 0) {
- MediaPlayer mp = MediaPlayer.create(getContext(), R.raw.state_change_confirm_up);
- mp.start();
- AlertDialog mDialog = new AlertDialog.Builder(getContext())
- .setTitle(getString(R.string.invalid))
- .setMessage(getString(R.string.inputfields_cant_be_empty))
-
- // Specifying a listener allows you to take an action before dismissing the dialog.
- // The dialog is automatically dismissed when a dialog button is clicked.
- .setPositiveButton(android.R.string.yes, null )
- .create();
- Objects.requireNonNull(mDialog.getWindow()).setBackgroundDrawableResource(R.drawable.button_round);
- mDialog.getWindow().getAttributes().windowAnimations = R.style.DialogAnimation; //style id
- mDialog.show();
- } else {
- command = befehlInput.getText().toString();
- Toast.makeText(getContext(), "Kommando gesendet...", Toast.LENGTH_SHORT).show();
- Toast.makeText(root.getContext(), command, Toast.LENGTH_SHORT).show();
- SSH_connection.executeRemoteCommand(ip, user, password, command);
- }
- } catch (Exception ignored) {
- }
- }
-
- });
- reboot_Button = (Button) root.findViewById(R.id.reboot);
- reboot_Button.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- Vibrator vr = (Vibrator) v.getContext().getSystemService(Context.VIBRATOR_SERVICE);
- assert vr != null;
- vr.vibrate(100);
- MediaPlayer mp = MediaPlayer.create(getContext(), R.raw.state_change_confirm_up);
- mp.start();
- AlertDialog mDialog = new AlertDialog.Builder(getContext())
- .setTitle(getString(R.string.restart_server))
- .setMessage(getString(R.string.are_you_sure))
-
- // Specifying a listener allows you to take an action before dismissing the dialog.
- // The dialog is automatically dismissed when a dialog button is clicked.
- .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- Vibrator vr = (Vibrator) v.getContext().getSystemService(Context.VIBRATOR_SERVICE);
- assert vr != null;
- vr.vibrate(100);
- try {
- MediaPlayer mp = MediaPlayer.create(getContext(), R.raw.state_change_confirm_down);
- mp.start();
- Toast.makeText(getContext(), "Reboot wird ausgeführt...", Toast.LENGTH_SHORT).show();
- SSH_connection.executeRemoteCommand(ip, user, password, "reboot");
- } catch (Exception ignored) {
- }
-
- // Continue with delete operation
- }
- })
-
- // A null listener allows the button to dismiss the dialog and take no further action.
- .setNegativeButton(android.R.string.no, null)
- .create();
- Objects.requireNonNull(mDialog.getWindow()).setBackgroundDrawableResource(R.drawable.button_round);
- mDialog.getWindow().getAttributes().windowAnimations = R.style.DialogAnimation; //style id
- mDialog.show();
-
-
-
-
- }
- });
- shutdown_Button = (Button) root.findViewById(R.id.shutdown);
- shutdown_Button.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- Vibrator vr = (Vibrator) v.getContext().getSystemService(Context.VIBRATOR_SERVICE);
- assert vr != null;
- vr.vibrate(100);
- MediaPlayer mp = MediaPlayer.create(getContext(), R.raw.state_change_confirm_up);
- mp.start();
- AlertDialog mDialog = new AlertDialog.Builder(getContext())
- .setTitle(getString(R.string.shutdown_server))
- .setMessage(getString(R.string.are_you_sure))
-
- // Specifying a listener allows you to take an action before dismissing the dialog.
- // The dialog is automatically dismissed when a dialog button is clicked.
- .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- Vibrator vr = (Vibrator) v.getContext().getSystemService(Context.VIBRATOR_SERVICE);
- assert vr != null;
- vr.vibrate(100);
- try {
- MediaPlayer mp = MediaPlayer.create(getContext(), R.raw.state_change_confirm_down);
- mp.start();
- Toast.makeText(getContext(), "Server wird heruntergefahren...", Toast.LENGTH_SHORT).show();
- SSH_connection.executeRemoteCommand(ip, user, password, "shutdown now");
- } catch (Exception ignored) {
- }
-
- // Continue with delete operation
- }
- })
-
- // A null listener allows the button to dismiss the dialog and take no further action.
- .setNegativeButton(android.R.string.no, null)
- .create();
- Objects.requireNonNull(mDialog.getWindow()).setBackgroundDrawableResource(R.drawable.button_round);
- mDialog.getWindow().getAttributes().windowAnimations = R.style.DialogAnimation; //style id
- mDialog.show();
-
- }
- });
- return root;
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/de/jg_cody/Teraplex/ui/Konsole/KonsoleViewModel.java b/app/src/main/java/de/jg_cody/Teraplex/ui/Konsole/KonsoleViewModel.java
deleted file mode 100644
index 97126c1..0000000
--- a/app/src/main/java/de/jg_cody/Teraplex/ui/Konsole/KonsoleViewModel.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package de.jg_cody.Teraplex.ui.Konsole;
-
-import androidx.lifecycle.ViewModel;
-
-public class KonsoleViewModel extends ViewModel {
-
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/de/jg_cody/Teraplex/ui/Terminal/Terminal.java b/app/src/main/java/de/jg_cody/Teraplex/ui/Terminal/Terminal.java
new file mode 100644
index 0000000..21351bf
--- /dev/null
+++ b/app/src/main/java/de/jg_cody/Teraplex/ui/Terminal/Terminal.java
@@ -0,0 +1,115 @@
+package de.jg_cody.Teraplex.ui.Terminal;
+
+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
+/**
+ * This program enables you to connect to sshd server and get the shell prompt.
+ * $ CLASSPATH=.:../build javac Shell.java
+ * $ CLASSPATH=.:../build java Shell
+ * You will be asked username, hostname and passwd.
+ * If everything works fine, you will get the shell prompt. Output may
+ * be ugly because of lacks of terminal-emulation, but you can issue commands.
+ */
+
+import com.jcraft.jsch.Channel;
+import com.jcraft.jsch.JSch;
+import com.jcraft.jsch.Session;
+import com.jcraft.jsch.UIKeyboardInteractive;
+import com.jcraft.jsch.UserInfo;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+
+import de.jg_cody.Teraplex.ui.home.HomeFragment;
+
+public class Terminal {
+ private Session session;
+ private JSch jsch;
+ private ByteArrayOutputStream Output;
+ private PipedOutputStream Input;
+
+
+ public Terminal() {
+
+ try {
+ JSch jsch = new JSch();
+ Session session = jsch.getSession(HomeFragment.user, HomeFragment.ip, 22);
+ session.setPassword(HomeFragment.password);
+
+ session.setUserInfo(new MyUserInfo() {
+ @Override
+ public String getPassword() {
+ return super.getPassword();
+ }
+ });
+
+ session.setConfig("StrictHostKeyChecking", "no");
+ session.connect(30000);
+
+ Channel channel = session.openChannel("shell");
+
+
+ Input = new PipedOutputStream();
+
+ channel.setInputStream(new PipedInputStream(Input));
+
+ Output = new ByteArrayOutputStream();
+
+ channel.setOutputStream(Output);
+
+
+
+
+ channel.connect(3 * 1000);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public String getTerminalOutput(){
+ return new String(Output.toByteArray());
+ }
+ public void sendTerminalCommand(String terminalcommand){
+ try {
+ Input.write((terminalcommand+"\n").getBytes());
+ Input.flush();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public static abstract class MyUserInfo
+ implements UserInfo, UIKeyboardInteractive {
+ public String getPassword() {
+ return null;
+ }
+
+ public boolean promptYesNo(String str) {
+ return false;
+ }
+
+ public String getPassphrase() {
+ return null;
+ }
+
+ public boolean promptPassphrase(String message) {
+ return false;
+ }
+
+ public boolean promptPassword(String message) {
+ return false;
+ }
+
+ public void showMessage(String message) {
+ }
+
+ public String[] promptKeyboardInteractive(String destination,
+ String name,
+ String instruction,
+ String[] prompt,
+ boolean[] echo) {
+ return null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/de/jg_cody/Teraplex/ui/Terminal/TerminalFragment.java b/app/src/main/java/de/jg_cody/Teraplex/ui/Terminal/TerminalFragment.java
new file mode 100644
index 0000000..a38e908
--- /dev/null
+++ b/app/src/main/java/de/jg_cody/Teraplex/ui/Terminal/TerminalFragment.java
@@ -0,0 +1,83 @@
+package de.jg_cody.Teraplex.ui.Terminal;
+
+import android.os.Bundle;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.EditText;
+import android.widget.ScrollView;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.fragment.app.Fragment;
+import androidx.lifecycle.ViewModelProvider;
+
+import de.jg_cody.Teraplex.R;
+
+public class TerminalFragment extends Fragment {
+
+ public static String command;
+
+ EditText terminal_edit_text;
+ TextView terminal_textView;
+ Terminal terminal;
+ ScrollView scrollView;
+
+ private TerminalViewModel terminalViewModel;
+
+ public View onCreateView(@NonNull LayoutInflater inflater,
+ ViewGroup container, Bundle savedInstanceState) {
+ terminalViewModel =
+ new ViewModelProvider(this).get(TerminalViewModel.class);
+ View root = inflater.inflate(R.layout.fragment_terminal, container, false);
+ scrollView = (ScrollView) root.findViewById((R.id.scrollView));
+ terminal_edit_text = (EditText) root.findViewById(R.id.terminal_edit_text);
+ terminal_edit_text.setOnKeyListener(new View.OnKeyListener() {
+ @Override
+ public boolean onKey(View view, int keyCode, KeyEvent keyEvent) {
+ if ((keyEvent.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) {
+ terminal.sendTerminalCommand(terminal_edit_text.getText().toString());
+
+
+ }
+ return true;
+ }
+ });
+ terminal_textView = (TextView) root.findViewById(R.id.terminal_textView);
+ new Thread() {
+ public void run() {
+ terminal = new Terminal();
+ while (true) {
+ try {
+ getActivity().runOnUiThread(new Runnable() {
+
+ @Override
+ public void run() {
+ boolean atBottom = scrollView.getChildAt(0).getBottom() <= (scrollView.getHeight() + scrollView.getScrollY());
+ terminal_textView.setText(terminal.getTerminalOutput());
+ System.out.println(atBottom);
+
+ terminal_textView.invalidate();
+ scrollView.invalidate();
+ scrollView.fullScroll(View.FOCUS_DOWN);
+
+ }
+ });
+ Thread.sleep(250);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }.start();
+
+
+ return root;
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/de/jg_cody/Teraplex/ui/Terminal/TerminalViewModel.java b/app/src/main/java/de/jg_cody/Teraplex/ui/Terminal/TerminalViewModel.java
new file mode 100644
index 0000000..46a8d3b
--- /dev/null
+++ b/app/src/main/java/de/jg_cody/Teraplex/ui/Terminal/TerminalViewModel.java
@@ -0,0 +1,8 @@
+package de.jg_cody.Teraplex.ui.Terminal;
+
+import androidx.lifecycle.ViewModel;
+
+public class TerminalViewModel extends ViewModel {
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/de/jg_cody/Teraplex/ui/home/HomeFragment.java b/app/src/main/java/de/jg_cody/Teraplex/ui/home/HomeFragment.java
index 85c8790..6dcd9a4 100644
--- a/app/src/main/java/de/jg_cody/Teraplex/ui/home/HomeFragment.java
+++ b/app/src/main/java/de/jg_cody/Teraplex/ui/home/HomeFragment.java
@@ -3,6 +3,7 @@ package de.jg_cody.Teraplex.ui.home;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
+import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
@@ -27,6 +28,7 @@ import java.util.Objects;
import de.jg_cody.Teraplex.MainActivity;
import de.jg_cody.Teraplex.R;
+import de.jg_cody.Teraplex.SSH_connection;
public class HomeFragment extends Fragment {
@@ -35,6 +37,8 @@ public class HomeFragment extends Fragment {
public static EditText ipInput;
public static EditText userInput;
public static EditText passwordInput;
+ Button reboot_Button;
+ Button shutdown_Button;
Button loginButton;
Button logoutButton;
Button wlan_aus_Button;
@@ -74,14 +78,20 @@ public class HomeFragment extends Fragment {
passwordInput = (EditText) root.findViewById(R.id.loginpasswordInput);
ipInput = (EditText) root.findViewById(R.id.ipInput);
loginButton = (Button) root.findViewById(R.id.loginButton);
+ reboot_Button = (Button) root.findViewById(R.id.reboot);
+ shutdown_Button = (Button) root.findViewById(R.id.shutdown);
SharedPreferences t = requireContext().getSharedPreferences("appsettings", Context.MODE_PRIVATE);
if (user == null || ip == null) {
loginButton.setVisibility(View.VISIBLE);
+ reboot_Button.setVisibility(View.GONE);
+ shutdown_Button.setVisibility(View.GONE);
} else {
loginButton.setVisibility(View.INVISIBLE);
ipInput.setVisibility(View.GONE);
userInput.setVisibility(View.GONE);
passwordInput.setVisibility(View.GONE);
+ reboot_Button.setVisibility(View.VISIBLE);
+ shutdown_Button.setVisibility(View.VISIBLE);
}
loginButton.setOnClickListener(new View.OnClickListener() {
@Override
@@ -112,6 +122,8 @@ public class HomeFragment extends Fragment {
Toast.makeText(getContext(), getString(R.string.login_saved), Toast.LENGTH_SHORT).show();
if (user == null || ip == null) {
login_data.setText("");
+ reboot_Button.setVisibility(View.GONE);
+ shutdown_Button.setVisibility(View.GONE);
} else {
login_data.setText(getString(R.string.sie_sind_als_angemeldet).replace("{IP}", ip).replace("{USERNAME}", user));
logoutButton.setVisibility(View.VISIBLE);
@@ -119,6 +131,8 @@ public class HomeFragment extends Fragment {
ipInput.setVisibility(View.GONE);
userInput.setVisibility(View.GONE);
passwordInput.setVisibility(View.GONE);
+ reboot_Button.setVisibility(View.VISIBLE);
+ shutdown_Button.setVisibility(View.VISIBLE);
}
}
}
@@ -129,8 +143,12 @@ public class HomeFragment extends Fragment {
ipInput.setVisibility(View.VISIBLE);
userInput.setVisibility(View.VISIBLE);
passwordInput.setVisibility(View.VISIBLE);
+ reboot_Button.setVisibility(View.GONE);
+ shutdown_Button.setVisibility(View.GONE);
} else {
logoutButton.setVisibility(View.VISIBLE);
+ reboot_Button.setVisibility(View.VISIBLE);
+ shutdown_Button.setVisibility(View.VISIBLE);
}
logoutButton.setOnClickListener(new View.OnClickListener() {
@Override
@@ -143,7 +161,91 @@ public class HomeFragment extends Fragment {
requireActivity().finish();
}
});
+ reboot_Button = (Button) root.findViewById(R.id.reboot);
+ reboot_Button.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Vibrator vr = (Vibrator) v.getContext().getSystemService(Context.VIBRATOR_SERVICE);
+ assert vr != null;
+ vr.vibrate(100);
+ MediaPlayer mp = MediaPlayer.create(getContext(), R.raw.state_change_confirm_up);
+ mp.start();
+ AlertDialog mDialog = new AlertDialog.Builder(getContext())
+ .setTitle(getString(R.string.restart_server))
+ .setMessage(getString(R.string.are_you_sure))
+ // Specifying a listener allows you to take an action before dismissing the dialog.
+ // The dialog is automatically dismissed when a dialog button is clicked.
+ .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ Vibrator vr = (Vibrator) v.getContext().getSystemService(Context.VIBRATOR_SERVICE);
+ assert vr != null;
+ vr.vibrate(100);
+ try {
+ MediaPlayer mp = MediaPlayer.create(getContext(), R.raw.state_change_confirm_down);
+ mp.start();
+ Toast.makeText(getContext(), "Reboot wird ausgeführt...", Toast.LENGTH_SHORT).show();
+ SSH_connection.executeRemoteCommand(ip, user, password, "reboot");
+ } catch (Exception ignored) {
+ }
+
+ // Continue with delete operation
+ }
+ })
+
+ // A null listener allows the button to dismiss the dialog and take no further action.
+ .setNegativeButton(android.R.string.no, null)
+ .create();
+ Objects.requireNonNull(mDialog.getWindow()).setBackgroundDrawableResource(R.drawable.button_round);
+ mDialog.getWindow().getAttributes().windowAnimations = R.style.DialogAnimation; //style id
+ mDialog.show();
+
+
+
+
+ }
+ });
+ shutdown_Button = (Button) root.findViewById(R.id.shutdown);
+ shutdown_Button.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Vibrator vr = (Vibrator) v.getContext().getSystemService(Context.VIBRATOR_SERVICE);
+ assert vr != null;
+ vr.vibrate(100);
+ MediaPlayer mp = MediaPlayer.create(getContext(), R.raw.state_change_confirm_up);
+ mp.start();
+ AlertDialog mDialog = new AlertDialog.Builder(getContext())
+ .setTitle(getString(R.string.shutdown_server))
+ .setMessage(getString(R.string.are_you_sure))
+
+ // Specifying a listener allows you to take an action before dismissing the dialog.
+ // The dialog is automatically dismissed when a dialog button is clicked.
+ .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ Vibrator vr = (Vibrator) v.getContext().getSystemService(Context.VIBRATOR_SERVICE);
+ assert vr != null;
+ vr.vibrate(100);
+ try {
+ MediaPlayer mp = MediaPlayer.create(getContext(), R.raw.state_change_confirm_down);
+ mp.start();
+ Toast.makeText(getContext(), "Server wird heruntergefahren...", Toast.LENGTH_SHORT).show();
+ SSH_connection.executeRemoteCommand(ip, user, password, "shutdown now");
+ } catch (Exception ignored) {
+ }
+
+ // Continue with delete operation
+ }
+ })
+
+ // A null listener allows the button to dismiss the dialog and take no further action.
+ .setNegativeButton(android.R.string.no, null)
+ .create();
+ Objects.requireNonNull(mDialog.getWindow()).setBackgroundDrawableResource(R.drawable.button_round);
+ mDialog.getWindow().getAttributes().windowAnimations = R.style.DialogAnimation; //style id
+ mDialog.show();
+
+ }
+ });
return root;
}
}
diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml
index 55ffca5..aaa2e24 100644
--- a/app/src/main/res/layout/fragment_home.xml
+++ b/app/src/main/res/layout/fragment_home.xml
@@ -9,6 +9,35 @@
android:hapticFeedbackEnabled="true"
tools:context=".ui.home.HomeFragment">
+
+
+
+
+ app:layout_constraintTop_toTopOf="@+id/text_home"
+ app:layout_constraintVertical_bias="0.0" />
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_terminal.xml b/app/src/main/res/layout/fragment_terminal.xml
new file mode 100644
index 0000000..8dec980
--- /dev/null
+++ b/app/src/main/res/layout/fragment_terminal.xml
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/menu/activity_main_drawer.xml b/app/src/main/res/menu/activity_main_drawer.xml
index ff974d1..1831727 100644
--- a/app/src/main/res/menu/activity_main_drawer.xml
+++ b/app/src/main/res/menu/activity_main_drawer.xml
@@ -14,7 +14,7 @@
android:icon="@drawable/home_black_24dp"
android:title="@string/menu_home" />
+ tools:layout="@layout/fragment_terminal" />