使用 JSCH 将 ssh 日志打印到列表 (android)
Printing ssh log to a list using JSCH (android)
我一直在尝试通过将包含目录名称的 log.i 字符串值添加到数组中,然后使用数组适配器通过列表显示。但是,当我尝试 运行 应用程序时,它会打印包含我的目录名称的日志,但不会在 listView 上打印任何内容。有帮助吗?
这是我的代码:
import android.os.AsyncTask;
import android.os.Bundle;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.util.ArrayList;
import java.util.Properties;
import android.view.Menu;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import android.app.Activity;
import android.util.Log;
import android.widget.ListView;
import android.widget.Toast;
public class MainActivity extends Activity {
private String user = "root"; //username
private String pass = "password"; //password
private String host = "hostname"; //hostname
private int portNum = 22; //replace port number
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new AsyncTask<Integer, Void, Void>() {
@Override
protected Void doInBackground(Integer... params) {
try {
executeRemoteCommand(user, pass, host, portNum);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}.execute(1);
}
public String executeRemoteCommand(String username, String password, String hostname, int port)
throws Exception {
//declare list and array
final ListView list = (ListView)findViewById(R.id.choose_sound_listView);
ArrayList<String> soundNames = new ArrayList<String>();
JSch jsch = new JSch();
Session session = jsch.getSession(username, hostname, port);
session.setPassword(password);
// Avoid asking for key confirmation
Properties prop = new Properties();
prop.put("StrictHostKeyChecking", "no");
session.setConfig(prop);
session.connect();
Channel channel = session.openChannel("shell");
channel.connect();
DataInputStream dataIn = new DataInputStream(channel.getInputStream());
DataOutputStream dataOut = new DataOutputStream(channel.getOutputStream());
// send ls command to the server
dataOut.writeBytes("ls\r\n");
dataOut.flush();
// and print the response
String line = dataIn.readLine();
String out = line + "\n";
// loop to add log string values to array
for (int i = 0; i < 10; i++) {
line = dataIn.readLine();
out += line + "\n";
Log.i("SSH", ": " + line);
//add to array
soundNames.add(line);
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_expandable_list_item_1, android.R.id.text1
, soundNames);
list.setAdapter(adapter);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1,
int position, long arg3) {
// Show Alert
Toast.makeText(getApplicationContext(),
"Alert", Toast.LENGTH_LONG)
.show();
}
});
dataIn.close();
dataOut.close();
channel.disconnect();
session.disconnect();
return out;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
}
不要在后台线程中设置适配器。另外我根据Jsch Exec example修改了你的executeRemoteCommand
。这些是我的修改:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ListView list = (ListView)findViewById(R.id.choose_sound_listView);
new AsyncTask<Void, Void, List<String>>() {
@Override
protected List<String> doInBackground(Void... params) {
try {
return executeRemoteCommand(user, pass, host, portNum);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
public void onPostExecute(List<String> soundNames){
ArrayAdapter<String> adapter = new ArrayAdapter<String>(MainActivity.this,android.R.layout.simple_expandable_list_item_1, android.R.id.text1, soundNames);
list.setAdapter(adapter);
}
}.execute();
}
public List<String> executeRemoteCommand(String username, String password, String hostname, int port) throws Exception {
List<String> soundNames = new ArrayList<String>();
JSch jsch = new JSch();
Session session = jsch.getSession(username, hostname, port);
session.setPassword(password);
// Avoid asking for key confirmation
Properties prop = new Properties();
prop.put("StrictHostKeyChecking", "no");
session.setConfig(prop);
session.connect();
String command = "ls -la | awk '{ print }'";
Channel channel = session.openChannel("exec");
((ChannelExec) channel).setCommand(command);
((ChannelExec) channel).setErrStream(System.err);
InputStream in = channel.getInputStream();
System.out.println("Connect to session...");
channel.connect();
StringBuffer buffer = new StringBuffer();
//This is the recommended way to read the output
byte[] tmp = new byte[1024];
while (true) {
while (in.available() > 0) {
int i = in.read(tmp, 0, 1024);
if (i < 0) {
break;
}
buffer.append(new String(tmp, 0, i));
}
if (channel.isClosed()) {
System.out.println("exit-status: " + channel.getExitStatus());
break;
}
try {
Thread.sleep(1000);
} catch (Exception ee) {
}
}
channel.disconnect();
session.disconnect();
Scanner scanner = new Scanner(buffer.toString());
while (scanner.hasNextLine()){
String line = scanner.nextLine();
soundNames.add(line);
Log.i("SSH", ": " + line);
}
return soundNames;
}
我一直在尝试通过将包含目录名称的 log.i 字符串值添加到数组中,然后使用数组适配器通过列表显示。但是,当我尝试 运行 应用程序时,它会打印包含我的目录名称的日志,但不会在 listView 上打印任何内容。有帮助吗?
这是我的代码:
import android.os.AsyncTask;
import android.os.Bundle;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.util.ArrayList;
import java.util.Properties;
import android.view.Menu;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import android.app.Activity;
import android.util.Log;
import android.widget.ListView;
import android.widget.Toast;
public class MainActivity extends Activity {
private String user = "root"; //username
private String pass = "password"; //password
private String host = "hostname"; //hostname
private int portNum = 22; //replace port number
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new AsyncTask<Integer, Void, Void>() {
@Override
protected Void doInBackground(Integer... params) {
try {
executeRemoteCommand(user, pass, host, portNum);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}.execute(1);
}
public String executeRemoteCommand(String username, String password, String hostname, int port)
throws Exception {
//declare list and array
final ListView list = (ListView)findViewById(R.id.choose_sound_listView);
ArrayList<String> soundNames = new ArrayList<String>();
JSch jsch = new JSch();
Session session = jsch.getSession(username, hostname, port);
session.setPassword(password);
// Avoid asking for key confirmation
Properties prop = new Properties();
prop.put("StrictHostKeyChecking", "no");
session.setConfig(prop);
session.connect();
Channel channel = session.openChannel("shell");
channel.connect();
DataInputStream dataIn = new DataInputStream(channel.getInputStream());
DataOutputStream dataOut = new DataOutputStream(channel.getOutputStream());
// send ls command to the server
dataOut.writeBytes("ls\r\n");
dataOut.flush();
// and print the response
String line = dataIn.readLine();
String out = line + "\n";
// loop to add log string values to array
for (int i = 0; i < 10; i++) {
line = dataIn.readLine();
out += line + "\n";
Log.i("SSH", ": " + line);
//add to array
soundNames.add(line);
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_expandable_list_item_1, android.R.id.text1
, soundNames);
list.setAdapter(adapter);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1,
int position, long arg3) {
// Show Alert
Toast.makeText(getApplicationContext(),
"Alert", Toast.LENGTH_LONG)
.show();
}
});
dataIn.close();
dataOut.close();
channel.disconnect();
session.disconnect();
return out;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
}
不要在后台线程中设置适配器。另外我根据Jsch Exec example修改了你的executeRemoteCommand
。这些是我的修改:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ListView list = (ListView)findViewById(R.id.choose_sound_listView);
new AsyncTask<Void, Void, List<String>>() {
@Override
protected List<String> doInBackground(Void... params) {
try {
return executeRemoteCommand(user, pass, host, portNum);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
public void onPostExecute(List<String> soundNames){
ArrayAdapter<String> adapter = new ArrayAdapter<String>(MainActivity.this,android.R.layout.simple_expandable_list_item_1, android.R.id.text1, soundNames);
list.setAdapter(adapter);
}
}.execute();
}
public List<String> executeRemoteCommand(String username, String password, String hostname, int port) throws Exception {
List<String> soundNames = new ArrayList<String>();
JSch jsch = new JSch();
Session session = jsch.getSession(username, hostname, port);
session.setPassword(password);
// Avoid asking for key confirmation
Properties prop = new Properties();
prop.put("StrictHostKeyChecking", "no");
session.setConfig(prop);
session.connect();
String command = "ls -la | awk '{ print }'";
Channel channel = session.openChannel("exec");
((ChannelExec) channel).setCommand(command);
((ChannelExec) channel).setErrStream(System.err);
InputStream in = channel.getInputStream();
System.out.println("Connect to session...");
channel.connect();
StringBuffer buffer = new StringBuffer();
//This is the recommended way to read the output
byte[] tmp = new byte[1024];
while (true) {
while (in.available() > 0) {
int i = in.read(tmp, 0, 1024);
if (i < 0) {
break;
}
buffer.append(new String(tmp, 0, i));
}
if (channel.isClosed()) {
System.out.println("exit-status: " + channel.getExitStatus());
break;
}
try {
Thread.sleep(1000);
} catch (Exception ee) {
}
}
channel.disconnect();
session.disconnect();
Scanner scanner = new Scanner(buffer.toString());
while (scanner.hasNextLine()){
String line = scanner.nextLine();
soundNames.add(line);
Log.i("SSH", ": " + line);
}
return soundNames;
}