From c6037412e7e9d40e9a0b92ef2629071944a5d109 Mon Sep 17 00:00:00 2001 From: JG-Cody Date: Thu, 15 Jul 2021 21:11:19 +0200 Subject: [PATCH] shutdown- and restart-button moved to homefragment removed consolefragment added working terminal --- app/build.gradle | 8 +- .../de/jg_cody/Teraplex/MainActivity.java | 3 +- .../Teraplex/ui/Konsole/KonsoleFragment.java | 183 ------------------ .../Teraplex/ui/Konsole/KonsoleViewModel.java | 8 - .../Teraplex/ui/Terminal/Terminal.java | 115 +++++++++++ .../ui/Terminal/TerminalFragment.java | 83 ++++++++ .../ui/Terminal/TerminalViewModel.java | 8 + .../Teraplex/ui/home/HomeFragment.java | 102 ++++++++++ app/src/main/res/layout/fragment_home.xml | 54 +++++- app/src/main/res/layout/fragment_konsole.xml | 159 --------------- app/src/main/res/layout/fragment_terminal.xml | 63 ++++++ .../main/res/menu/activity_main_drawer.xml | 2 +- .../main/res/navigation/mobile_navigation.xml | 6 +- 13 files changed, 430 insertions(+), 364 deletions(-) delete mode 100644 app/src/main/java/de/jg_cody/Teraplex/ui/Konsole/KonsoleFragment.java delete mode 100644 app/src/main/java/de/jg_cody/Teraplex/ui/Konsole/KonsoleViewModel.java create mode 100644 app/src/main/java/de/jg_cody/Teraplex/ui/Terminal/Terminal.java create mode 100644 app/src/main/java/de/jg_cody/Teraplex/ui/Terminal/TerminalFragment.java create mode 100644 app/src/main/java/de/jg_cody/Teraplex/ui/Terminal/TerminalViewModel.java delete mode 100644 app/src/main/res/layout/fragment_konsole.xml create mode 100644 app/src/main/res/layout/fragment_terminal.xml 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"> +