我的问题是,我正在通过终端运行一些adb命令。我写了一个工具;这将使事情变得容易。回到问题所在,为了使命令运行,我必须在终端上输入“密码”。那么,我该如何做才能使“密码”部分出现在JOptionPane.showInputDialog框上?
这是我到目前为止的内容:
import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.io.IOException; import javax.swing.JFileChooser; import javax.swing.JOptionPane; import javax.swing.filechooser.FileNameExtensionFilter; public class flash implements ActionListener { private File runfile; @Override public void actionPerformed(ActionEvent arg0) { { JFileChooser adbflashfile = new JFileChooser("/home/local/ANT/arthm/Desktop/os"); FileNameExtensionFilter filter = new FileNameExtensionFilter(".py", "py"); adbflashfile.setFileFilter(filter); int returnVal = adbflashfile.showOpenDialog(null); if (returnVal == JFileChooser.APPROVE_OPTION) { runfile = adbflashfile.getSelectedFile(); try { Runtime.getRuntime().exec("sudo python ./flashimage.py"); } catch (IOException e1) { e1.printStackTrace(); } //This is where a real application would open the file. System.out.println("File: " + runfile.getName() + "."); } else { JOptionPane.showMessageDialog(null, "Open command cancelled by user."); } System.out.println(returnVal); } }; }
您可以“读取”过程输入,并在“检测到”密码提示时显示,JOptionPane并要求用户输入密码。
JOptionPane
在开始该过程之前,您“可以”提示用户输入密码,因为您知道需要将其发送给该过程。
您可能仍然需要监视进程的输出,以确定何时需要发送密码。
让我们从…开始
Runtime.getRuntime().exec("sudo python ./flashimage.py");
您完全忽略了Process。您也不处理输出,但是您没有办法向流程提供输入…
Process
通常,Runtime#exec充其量是有问题的。您最好使用ProcessBuilder....
Runtime#exec
ProcessBuilder
// Build the command to be executed. Note that each parameter becomes // it's own argument, this deals with parameters that contain spaces // much better then Runtime#exec alone... ProcessBuilder pb = new ProcessBuilder("sudo", "python", "./flashimage.py"); pb.redirectError(); InputStream is = null; try { Process p = pb.start(); is = p.getInputStream(); StringBuilder output = new StringBuilder(80); int in = -1; while ((in = is.read()) != -1) { if (in != '\n') { output.append((char)in); // You will need to define PASSWORD_PROMPT if (PASSWORD_PROMPT.equals(output.toString())) { String text = JOptionPane.showInputDialog("Password"); OutputStream os = p.getOutputStream(); os.write(text.getBytes()); } } else { System.out.println(output.toString()); output.delete(0, output.length()); } } } catch (IOException exp) { exp.printStackTrace(); } finally { try { is.close(); } catch (Exception e) { } }
现在,毫无疑问,有人会指出(至少)这种方法有两个问题……
JOptionPane.showInputDialog("Password");
JTextField
String
相反,我们应该使用JPasswordField并将结果char数组转换为byte数组…
JPasswordField
char
byte
JPasswordField password = new JPasswordField(10); JLabel label = new JLabel("Password: "); JPanel panel = new JPanel(); panel.add(label); panel.add(password); int option = JOptionPane.showConfirmDialog(null, panel, "Password", JOptionPane.OK_CANCEL_OPTION); if (option == JOptionPane.OK_OPTION) { char[] userPassword = password.getPassword(); byte[] bytes = new byte[userPassword.length * 2]; for (int i = 0; i < userPassword.length; i++) { bytes[i * 2] = (byte) (userPassword[i] >> 8); bytes[i * 2 + 1] = (byte) userPassword[i]; } os.write(bytes); }