私はこの簡単な例から何かを作ろうとしています:
私はAndroid電話からSSHを使用してLinuxサーバーに接続できるかどうかを確認したいのですが、機能しません...
これが私のメインコードです:
package com.example.ssh;
import Java.util.Properties;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import Android.os.Bundle;
import Android.app.Activity;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
try
{
JSch jsch = new JSch();
Session session = jsch.getSession("root","192.168.0.26", 22);
session.setPassword("xxxxx");
// Avoid asking for key confirmation
Properties prop = new Properties();
prop.put("StrictHostKeyChecking", "no");
session.setConfig(prop);
session.connect();
}
catch (Exception e)
{
System.out.println(e.getMessage());
}
}
}
私は何を間違えましたか?エラーメッセージがなく、LinuxにSSH接続が表示されません。ライブラリjschとjzlibを追加しました。 PuTTYセッションに接続しても問題ありません。
EDIT1:実際、問題の解決方法がわからなくても機能しない理由を説明するエラーを見つけました。エラーは:
Android.os.NetworkOnMainThreadException
つまり、アプリがメインスレッドでネットワーク操作を実行できないことを意味しているようです...
そのコードを別のスレッドで実行する必要があるので、UIスレッドをハングアップさせないことが、その例外の意味です。 UIスレッドがネットワーク呼び出しを実行している場合、UIを再描画できないため、アプリがネットワーク呼び出しの終了を待機している間、UIが応答しないフリーズされたUIがユーザーに表示されます。 Androidは、このようなユーザーエクスペリエンスの悪さを避けたいので、この例外をスローして、このようなことを行うのを防ぎます。
OnCreate()メソッドは、SSH接続を実行するために別のスレッド(生のスレッドではなくAsyncTaskを使用することをお勧めします)を呼び出す必要があります。その後、結果をUIスレッドにポストバックし、UIスレッドからアプリケーションのUIを安全に更新できます。
http://developer.Android.com/reference/Android/os/AsyncTask.html
chubbsondubsのソリューションは完璧です。この問題のために作成したコードを、簡単な解決策を求めている人たちにも共有したいと思います。
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new AsyncTask<Integer, Void, Void>(){
@Override
protected Void doInBackground(Integer... params) {
try {
executeRemoteCommand("root", "myPW","192.168.0.26", 22);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}.execute(1);
}
public static String executeRemoteCommand(String username,String password,String hostname,int port)
throws Exception {
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();
// SSH Channel
ChannelExec channelssh = (ChannelExec)
session.openChannel("exec");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
channelssh.setOutputStream(baos);
// Execute command
channelssh.setCommand("lsusb > /home/pi/test.txt");
channelssh.connect();
channelssh.disconnect();
return baos.toString();
}
A Kotlin ソリューション:
import Android.os.AsyncTask
import Android.os.Bundle
import Android.support.v7.app.AppCompatActivity
import com.jcraft.jsch.ChannelExec
import com.jcraft.jsch.JSch
import Java.io.ByteArrayOutputStream
import Java.util.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
SshTask().execute()
}
class SshTask : AsyncTask<Void, Void, String>() {
override fun doInBackground(vararg p0: Void?): String {
val output = executeRemoteCommand("demo", "password", "test.rebex.net")
print(output)
return output
}
}
}
fun executeRemoteCommand(username: String,
password: String,
hostname: String,
port: Int = 22): String {
val jsch = JSch()
val session = jsch.getSession(username, hostname, port)
session.setPassword(password)
// Avoid asking for key confirmation.
val properties = Properties()
properties.put("StrictHostKeyChecking", "no")
session.setConfig(properties)
session.connect()
// Create SSH Channel.
val sshChannel = session.openChannel("exec") as ChannelExec
val outputStream = ByteArrayOutputStream()
sshChannel.outputStream = outputStream
// Execute command.
sshChannel.setCommand("ls")
sshChannel.connect()
// Sleep needed in order to wait long enough to get result back.
Thread.sleep(1_000)
sshChannel.disconnect()
session.disconnect()
return outputStream.toString()
}
build.gradle
追加:
dependencies {
...
compile group: 'com.jcraft', name: 'jsch', version: '0.1.54'
}