【问题标题】:Send SSH commands with android app [duplicate]使用 android 应用程序发送 SSH 命令 [重复]
【发布时间】:2017-11-03 23:45:09
【问题描述】:

我正在尝试通过 WiFi 从我的 android 手机向 Raspberry Pi 发送命令。这就是我所做的:我已经将 RPi 设置为 wifi 接入点,现在我可以使用 android 手机连接到它。

现在我已经在 Android Studio 中编写了一个简单的应用程序来使用 SSH 发送命令。但不幸的是,它不起作用。以下是我的代码:

MainActivity.java

package example_company.controller1;

import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.Snackbar;
import android.graphics.Color;

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);    
    }

    public void onClick11 (View v) {
        new AsyncTask<Integer, Void, Void>(){
            @Override
            protected Void doInBackground(Integer... params) {
                try {
                    executeSSHcommand();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return null;
            }
        }.execute(1);
    }

    public void executeSSHcommand(){
        String user = "pi";
        String password = "raspberry";
        String host = "192.168.0.1";
        int port=22;
        try{

            JSch jsch = new JSch();
            Session session = jsch.getSession(user, host, port);
            session.setPassword(password);
            session.setConfig("StrictHostKeyChecking", "no");
            session.setTimeout(10000);
            session.connect();
            ChannelExec channel = (ChannelExec)session.openChannel("exec");
            channel.setCommand("omxd n");
            channel.connect();
            channel.disconnect();

        }
        catch(JSchException e){

        }
    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="example_company.controller1.MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!" />

    <Button
        android:text="NEXT"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true"
        android:id="@+id/button"
        android:onClick="onCLick11" />

</RelativeLayout>

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="example_company.controller1">

    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

那么,怎么了!?我错过了什么!?

我们非常感谢您的帮助和支持。

编辑 1

按照类似问题的建议,我在channel.connect();channel.disconnect(); 之间添加了try{Thread.sleep(1000);}catch(Exception ee){}。但没有帮助。还是同样的问题。当我按下按钮时,什么也没有发生。

编辑 2

以下是gradle build的消息:

Information:Gradle tasks [:app:assembleDebug]
Error:warning: Ignoring InnerClasses attribute for an anonymous inner class
Error:(com.jcraft.jsch.Channel$1) that doesn't come with an
Error:associated EnclosingMethod attribute. This class was probably produced by a
Error:compiler that did not target the modern .class file format. The recommended
Error:solution is to recompile the class from source, using an up-to-date compiler
Error:and without specifying any "-target" type options. The consequence of ignoring
Error:this warning is that reflective operations on this class will incorrectly
Error:indicate that it is *not* an inner class.
Error:warning: Ignoring InnerClasses attribute for an anonymous inner class
Error:(com.jcraft.jsch.ChannelSftp$1) that doesn't come with an
Error:associated EnclosingMethod attribute. This class was probably produced by a
Error:compiler that did not target the modern .class file format. The recommended
Error:solution is to recompile the class from source, using an up-to-date compiler
Error:and without specifying any "-target" type options. The consequence of ignoring
Error:this warning is that reflective operations on this class will incorrectly
Error:indicate that it is *not* an inner class.
Error:warning: Ignoring InnerClasses attribute for an anonymous inner class
Error:(com.jcraft.jsch.ChannelSftp$2) that doesn't come with an
Error:associated EnclosingMethod attribute. This class was probably produced by a
Error:compiler that did not target the modern .class file format. The recommended
Error:solution is to recompile the class from source, using an up-to-date compiler
Error:and without specifying any "-target" type options. The consequence of ignoring
Error:this warning is that reflective operations on this class will incorrectly
Error:indicate that it is *not* an inner class.
Error:warning: Ignoring InnerClasses attribute for an anonymous inner class
Error:(com.jcraft.jsch.ChannelSftp$3) that doesn't come with an
Error:associated EnclosingMethod attribute. This class was probably produced by a
Error:compiler that did not target the modern .class file format. The recommended
Error:solution is to recompile the class from source, using an up-to-date compiler
Error:and without specifying any "-target" type options. The consequence of ignoring
Error:this warning is that reflective operations on this class will incorrectly
Error:indicate that it is *not* an inner class.
Error:warning: Ignoring InnerClasses attribute for an anonymous inner class
Error:(com.jcraft.jsch.ConfigRepository$1) that doesn't come with an
Error:associated EnclosingMethod attribute. This class was probably produced by a
Error:compiler that did not target the modern .class file format. The recommended
Error:solution is to recompile the class from source, using an up-to-date compiler
Error:and without specifying any "-target" type options. The consequence of ignoring
Error:this warning is that reflective operations on this class will incorrectly
Error:indicate that it is *not* an inner class.
Error:warning: Ignoring InnerClasses attribute for an anonymous inner class
Error:(com.jcraft.jsch.ConfigRepository$2) that doesn't come with an
Error:associated EnclosingMethod attribute. This class was probably produced by a
Error:compiler that did not target the modern .class file format. The recommended
Error:solution is to recompile the class from source, using an up-to-date compiler
Error:and without specifying any "-target" type options. The consequence of ignoring
Error:this warning is that reflective operations on this class will incorrectly
Error:indicate that it is *not* an inner class.
Error:warning: Ignoring InnerClasses attribute for an anonymous inner class
Error:(com.jcraft.jsch.JSch$1) that doesn't come with an
Error:associated EnclosingMethod attribute. This class was probably produced by a
Error:compiler that did not target the modern .class file format. The recommended
Error:solution is to recompile the class from source, using an up-to-date compiler
Error:and without specifying any "-target" type options. The consequence of ignoring
Error:this warning is that reflective operations on this class will incorrectly
Error:indicate that it is *not* an inner class.
Error:warning: Ignoring InnerClasses attribute for an anonymous inner class
Error:(com.jcraft.jsch.Util$1) that doesn't come with an
Error:associated EnclosingMethod attribute. This class was probably produced by a
Error:compiler that did not target the modern .class file format. The recommended
Error:solution is to recompile the class from source, using an up-to-date compiler
Error:and without specifying any "-target" type options. The consequence of ignoring
Error:this warning is that reflective operations on this class will incorrectly
Error:indicate that it is *not* an inner class.
Information:BUILD SUCCESSFUL
Information:Total time: 1 mins 8.318 secs
Information:64 errors
Information:0 warnings
Information:See complete output in console

【问题讨论】:

  • unfortunately it's not working. 这不是好的信息。告诉更多。应该发生什么?相反会发生什么?你的代码能跑多远?为什么不使用日志语句?
  • catch(JSchException e){ }。不要让那个捕捉块空着,因为现在你永远不会知道是否有捕捉。将正常代码放入日志并为异常敬酒。你的应用会崩溃吗?
  • channel.connect(); channel.disconnect(); ?这么快?你不想等待回复吗?
  • @greenapps 感谢您的 cmets。当按下按钮时,它应该通过 SSH 将命令omxd n 发送到具有指定 IP、用户名、密码和端口的 RPi。但它不发送。 logcat 也没有显示任何内容。
  • @greenapps 我正在使用与此类似的代码:stackoverflow.com/questions/41050989/…

标签: android ssh raspberry-pi jsch


【解决方案1】:

我通过改变两件事解决了这个问题:

  1. 在连接线和断开线之间添加try{Thread.sleep(1000);}catch(Exception ee){}。我没有使用 1000,而是使用了更高的值,例如 10000。
  2. RPi 中正在监听 android 的进程已死!我用 JuiceSSH 实现了这一点。所以,在 RPi 中解决了这个过程的问题后,它就变得活跃起来了。

经过这两项更改后,android 应用程序完美运行。

感谢@greenapps 和@MartinPrikryl 的帮助。

【讨论】:

  • Thread.sleep(1000) - 这是一个 hack,而不是解决方案。请参阅重复问题的答案以获得真正的解决方案。
猜你喜欢
  • 1970-01-01
  • 2011-09-12
  • 1970-01-01
  • 1970-01-01
  • 2015-05-30
  • 2013-06-03
  • 1970-01-01
  • 1970-01-01
  • 2015-12-14
相关资源
最近更新 更多