【问题标题】:Receiving image through sockets on androidstudio通过 android studio 上的套接字接收图像
【发布时间】:2023-03-05 10:55:01
【问题描述】:

我在 Android Studio 上编写了一段代码,用于从套接字服务器接收图像,并且每次单击按钮时应用程序都会连接到服务器。

但是,当我运行应用程序并单击按钮时,什么都没有显示,但服务器会发送一条消息说照片已发送。当我再次单击按钮时,第二次(服务器未连接)图像立即弹出。

我认为问题在于当我单击一次按钮时线程并没有完全关闭,但是如果我再次单击它,线程会强制关闭并启动一个新线程以显示图像。

主要活动java文件的代码是:

    package com.example.myapplication;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.Socket;




public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private TextView mTextViewReplyFromServer;
    private EditText mEditTextSendMessage;
    private ImageView mImg;
    private byte [] imgbyte;
    Handler updateConversationHandler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button buttonSend = (Button) findViewById(R.id.btn_send);

        mEditTextSendMessage = (EditText) findViewById(R.id.edt_send_message);
        mTextViewReplyFromServer = (TextView) findViewById(R.id.tv_reply_from_server);
        mImg = (ImageView)findViewById(R.id.imageView);

        String filepath = "/sdcard/DCIM/img.jpeg";




    }

    @Override
    public void onClick(View v) {

        switch (v.getId()) {

            case R.id.btn_send:
                Thread fst = new Thread(new ServerThread());
                fst.start();
                break;
        }
    }

    public class ServerThread implements Runnable {
        byte [] line;
        Bitmap bitmap;
            public void run() {
                try {
                    Socket client = new Socket("192.168.1.145", 5560);
                        while (true) {
                            // LISTEN FOR INCOMING CLIENTS
                            try {
                                int bytesRead;
                                int current = 0;
                                int filesize=215320;
                                byte [] mybytearray2  = new byte [filesize];
                                InputStream is = client.getInputStream();
                                FileOutputStream fos = new FileOutputStream("/sdcard/DCIM/img.jpg"); // destination path and name of file
                                //FileOutputStream fos = new FileOutputStream("/storage/sdcard0/Pictures/Screenshots/");
                                BufferedOutputStream bos = new BufferedOutputStream(fos);
                                bytesRead = is.read(mybytearray2,0,mybytearray2.length);
                                current = bytesRead;


                                do {
                                    bytesRead =
                                            is.read(mybytearray2, current, (mybytearray2.length-current));
                                    if(bytesRead >= 0) current += bytesRead;
                                } while(bytesRead > -1);

                                bos.write(mybytearray2, 0 , current);
                                bos.flush();
                               // bitmap = BitmapFactory.decodeByteArray(mybytearray2 , 0, mybytearray2.length);
                               // mImg.setImageBitmap(bitmap);
                                //System.out.println(end-start);
                                updateConversationHandler.post(new updateUIThread(mybytearray2));
                                bos.close();
                                client.close();



                                break;
                            } catch (Exception e) {
                                        e.printStackTrace();
                            }
                        }
                } catch (Exception e) {
                            e.printStackTrace();
                        }
                }
            }
    class updateUIThread implements Runnable {
        private byte[] byteArray;//private String msg;

        public updateUIThread(byte[] array){    //public updateUIThread(String str) {
            this.byteArray=array;   //this.msg = str;
        }

        @Override
        public void run() {
            Bitmap bitmap = BitmapFactory.decodeByteArray(byteArray , 0, byteArray .length);
            mImg.setImageBitmap(bitmap);//text.setText(text.getText().toString()+"Client Says: "+ msg + "\n");
        }
    }
    }

有没有办法在收到图片后立即终止线程?

我的图像也显示在 android 模拟器上,但没有显示在我的手机上。这可能是什么原因?

编辑:如果我在 oncreate 部分启动线程,图像会在应用程序启动后立即弹出

编辑:python 服务器代码:

import socket
from time import sleep
from time import time

host = ''
port = 5560

filePath = "/media/pi/ESD-USB/image.jpg"

def setupServer():
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    print("Socket created.")
    try:
        s.bind((host, port))
    except socket.error as msg:
        print(msg)
    print("Socket bind comlete.")
    return s

def setupConnection():
    s.listen(1) # Allows one connection at a time.
    conn, address = s.accept()
    print("Connected to: " + address[0] + ":" + str(address[1]))
    return conn

def sendPic(s, filePath):
    print(filePath)
    pic = open(filePath, 'rb')
    chunk = pic.read()
    size = len(chunk)
    print (size)
    t = time()
    print("Sending Picture")
    s.sendall(chunk)
    pic.close()
    print("Done sending")
    print("Elapsed time = " + str(time() - t) + 's')
    s.close()
    return "Done sending"



def backup(filePath):
    conn = setupConnection()
    response = sendPic(conn, filePath)
    return response


        

s = setupServer()


while True:
    print(filePath)
    backup(filePath)
    print("Everything should be backed up now.")
    break

【问题讨论】:

  • to receive images from a socket server AND the server sends a message saying the photo is received 不匹配。
  • @blackapps 我的错,服务器说照片已发送。
  • but the server sends a message saying the photo is sent. 服务器将该消息发送给谁?给你的客户?接收该消息的代码在哪里?
  • mImg.setImageBitmap(bitmap); 不能在线程的run()中设置ui。
  • 为什么要使用处理程序和可运行程序来打印堆栈跟踪?没有意义。只需打印它们。

标签: java android sockets


【解决方案1】:

我知道该怎么做。 while 循环导致了一个问题,我像 blackapps 建议的那样实现了 runonui 线程。

工作代码如下所示:

package com.example.myapplication;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.Socket;


public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private TextView mTextViewReplyFromServer;
    private EditText mEditTextSendMessage;
    private ImageView mImg;
    private byte [] imgbyte;
    private Handler handler = new Handler();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button buttonSend = (Button) findViewById(R.id.btn_send);

        mEditTextSendMessage = (EditText) findViewById(R.id.edt_send_message);
        mTextViewReplyFromServer = (TextView) findViewById(R.id.tv_reply_from_server);
        mImg = (ImageView)findViewById(R.id.imageView);

        String filepath = "/sdcard/DCIM/img.jpeg";



    }

    @Override
    public void onClick(View v) {
        Thread fst = new Thread(new ServerThread());
        fst.start();
    }

    public class ServerThread implements Runnable {
        byte [] line;
        Bitmap bitmap;
        public void run() {
            try {
                Socket client = new Socket("192.168.1.145", 5560);
                    try {
                        int bytesRead;
                        int current = 0;
                        int filesize = 300000;
                        byte [] mybytearray2  = new byte [filesize];
                        InputStream is = client.getInputStream();
                        FileOutputStream fos = new FileOutputStream("/sdcard/DCIM/img.jpg"); // destination path and name of file
                        //FileOutputStream fos = new FileOutputStream("/storage/sdcard0/Pictures/Screenshots/");
                        BufferedOutputStream bos = new BufferedOutputStream(fos);
                        bytesRead = is.read(mybytearray2,0,mybytearray2.length);
                        current = bytesRead;


                        do {
                            bytesRead =
                                    is.read(mybytearray2, current, (mybytearray2.length-current));
                            if(bytesRead >= 0) current += bytesRead;
                        } while(bytesRead > -1);

                        bos.write(mybytearray2, 0 , current);
                        bos.flush();
                        bitmap = BitmapFactory.decodeByteArray(mybytearray2 , 0, mybytearray2.length);
                        long end = System.currentTimeMillis();
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {

                                mImg.setImageBitmap(bitmap);

                            }
                        });
                        bos.close();
                        client.close();
                    } catch (Exception e) {
                        handler.post(new Runnable() {
                            @Override
                            public void run() {
                                e.printStackTrace();
                            }
                        });
                        e.printStackTrace();
                    }
            } catch (Exception e) {
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        e.printStackTrace();
                    }
                });
                e.printStackTrace();
            }
        }
    }
}

对我来说,下一步是将图像的文件大小从 python 服务器发送到 android 应用程序。还要弄清楚为什么我的图像没有出现在实际的 android 上,而是出现在模拟器上。

【讨论】:

  • 请.. 没有处理程序和可运行程序来打印堆栈跟踪。
猜你喜欢
  • 2014-03-25
  • 2014-08-16
  • 2017-02-25
  • 1970-01-01
  • 2014-07-17
  • 2022-01-18
  • 2015-03-22
  • 2012-06-08
  • 1970-01-01
相关资源
最近更新 更多