Search code examples
javaandroidlistviewsshjsch

Printing ssh log to a list using JSCH (android)


I've been trying to print the items in my directory in a listView by adding the log.i string values which contains the names of my directory into an array and then using an array adapter to print them via listView. However, when I try to run the app, it prints the log containing the names of my directory, but it doesn't print anything on the listView. Any help?

Here's my code:

    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;
        }
    }

Solution

  • Do not set the adapter in a background thread. Also I modified your executeRemoteCommand according to Jsch Exec example. These are my modifications:

    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 $9}'";
    
        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;
    }