Search code examples
androidsftpnetworkonmainthread

My app is unable to download a file with sftp


I'm building an android app to get a .jpg file from a linux host (Raspberry Pi) with sftp. The following is my code. But when I press the button, it toasts Connection Error.

MainActivity.java

package com.example.picture_controller_2;

import android.graphics.drawable.Drawable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.app.Activity;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
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 com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.SftpException;
import android.view.View;
import android.os.AsyncTask;
import android.widget.ImageView;
import android.widget.Toast;

public class Button2Activity extends AppCompatActivity {

    private ImageView iv1;
    private Drawable ddd;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_button2);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    }

    public void show_picture_func (View v) {

        iv1 = (ImageView) findViewById(R.id.imageView1);    

                String SFTPHOST = "192.168.0.1";
                int SFTPPORT =22;
                String SFTPUSER = "pi";
                String SFTPPASS = "raspberry";
                String SFTPWORKINGDIR = "/home/pi/imgs/";

                Session session = null;
                Channel channel = null;
                ChannelSftp channelSftp = null;

                try {
                    JSch jsch = new JSch();
                    session = jsch.getSession(SFTPUSER, SFTPHOST, SFTPPORT);
                    session.setPassword(SFTPPASS);
                    session.setConfig("StrictHostKeyChecking", "no");
                    session.setTimeout(1000);
                    session.connect();
                    channel = session.openChannel("sftp");
                    channel.connect();
                    channelSftp = (ChannelSftp) channel;
                    channelSftp.cd(SFTPWORKINGDIR);
                    byte[] buffer = new byte[1024];
                    BufferedInputStream bis = new BufferedInputStream(channelSftp.get("/home/pi/imgs/AAP.jpg"));


                    Drawable ddd = Drawable.createFromStream(bis,"ddd");

                    Toast.makeText(getApplicationContext(), "Connection OK", Toast.LENGTH_LONG).show();
                } catch (Exception ex) {
                    Toast.makeText(getApplicationContext(), "Connection Error", Toast.LENGTH_LONG).show();
                    ex.printStackTrace();
                }

        iv1.setImageDrawable(ddd);
        Toast.makeText(getApplicationContext(), "Picture Success", Toast.LENGTH_LONG).show();
    }

}

So, what am I missing?

Update1

The following are the logcat messages when I press the button:

11-09 18:26:59.008 16361-16361/ir.sapna_co.adalux_controller_2 W/System.err: android.os.NetworkOnMainThreadException
11-09 18:26:59.008 16361-16361/ir.sapna_co.adalux_controller_2 W/System.err:     at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1315)
11-09 18:26:59.008 16361-16361/ir.sapna_co.adalux_controller_2 W/System.err:     at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:111)
11-09 18:26:59.008 16361-16361/ir.sapna_co.adalux_controller_2 W/System.err:     at java.net.SocketOutputStream.write(SocketOutputStream.java:157)
11-09 18:26:59.008 16361-16361/ir.sapna_co.adalux_controller_2 W/System.err:     at com.jcraft.jsch.IO.put(IO.java:64)
11-09 18:26:59.008 16361-16361/ir.sapna_co.adalux_controller_2 W/System.err:     at com.jcraft.jsch.Session.connect(Session.java:256)
11-09 18:26:59.008 16361-16361/ir.sapna_co.adalux_controller_2 W/System.err:     at com.jcraft.jsch.Session.connect(Session.java:183)
11-09 18:26:59.008 16361-16361/ir.sapna_co.adalux_controller_2 W/System.err:     at ir.sapna_co.adalux_controller_2.Button2Activity.show_picture_func(Button2Activity.java:65)
11-09 18:26:59.008 16361-16361/ir.sapna_co.adalux_controller_2 W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
11-09 18:26:59.008 16361-16361/ir.sapna_co.adalux_controller_2 W/System.err:     at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
11-09 18:26:59.008 16361-16361/ir.sapna_co.adalux_controller_2 W/System.err:     at android.view.View.performClick(View.java:5646)
11-09 18:26:59.009 16361-16361/ir.sapna_co.adalux_controller_2 W/System.err:     at android.view.View$PerformClick.run(View.java:22459)
11-09 18:26:59.009 16361-16361/ir.sapna_co.adalux_controller_2 W/System.err:     at android.os.Handler.handleCallback(Handler.java:761)
11-09 18:26:59.009 16361-16361/ir.sapna_co.adalux_controller_2 W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:98)
11-09 18:26:59.009 16361-16361/ir.sapna_co.adalux_controller_2 W/System.err:     at android.os.Looper.loop(Looper.java:156)
11-09 18:26:59.009 16361-16361/ir.sapna_co.adalux_controller_2 W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:6531)
11-09 18:26:59.009 16361-16361/ir.sapna_co.adalux_controller_2 W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
11-09 18:26:59.009 16361-16361/ir.sapna_co.adalux_controller_2 W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:941)
11-09 18:26:59.009 16361-16361/ir.sapna_co.adalux_controller_2 W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:831)
11-09 18:26:59.012 16361-16361/ir.sapna_co.adalux_controller_2 I/HwPointEventFilter: do not support AFT because of no config
11-09 18:26:59.058 16361-16361/ir.sapna_co.adalux_controller_2 I/HwPointEventFilter: do not support AFT because of no config

Solution

  • Wrap your network code of show_picture_func inside an AsyncTask and do your UI stuff inside the onPostExecute method:

    public void show_picture_func (View v) {
        new AsyncTask<Void, Void, Void>() {
    
                Drawable ddd = null;
    
                protected Void doInBackground(Void... unused) {
                        // Background Code
                        String SFTPHOST = "192.168.0.1";
                        int SFTPPORT =22;
                        String SFTPUSER = "pi";
                        String SFTPPASS = "raspberry";
                        String SFTPWORKINGDIR = "/home/pi/imgs/";
    
                        Session session = null;
                        Channel channel = null;
                        ChannelSftp channelSftp = null;
    
                        try {
                            JSch jsch = new JSch();
                            session = jsch.getSession(SFTPUSER, SFTPHOST, SFTPPORT);
                            session.setPassword(SFTPPASS);
                            session.setConfig("StrictHostKeyChecking", "no");
                            session.setTimeout(1000);
                            session.connect();
                            channel = session.openChannel("sftp");
                            channel.connect();
                            channelSftp = (ChannelSftp) channel;
                            channelSftp.cd(SFTPWORKINGDIR);
                            byte[] buffer = new byte[1024];
                            BufferedInputStream bis = new BufferedInputStream(channelSftp.get("/home/pi/imgs/AAP.jpg"));
    
                            ddd = Drawable.createFromStream(bis,"ddd");
                        } catch (Exception ex) {
                            ex.printStackTrace();
                        }
    
    
                        return null;
                }
                protected void onPostExecute(Void unused) {
                        // Post Code
                        iv1.setImageDrawable(ddd);
                        Toast.makeText(getApplicationContext(), "Picture Success", Toast.LENGTH_LONG).show();
                }
        }.execute();
    }