java - 扫描我的二维码后即可进行下一个 Activity

标签 java android sockets kotlin serversocket

我的 Android 经验有限,并且有一个非常基本的疑问。我的场景如下:

我目前有 2 个应用程序,一个是 QR 码扫描仪,另一个是显示 QR 码的应用程序。这些将在多个设备上运行。发生的通信步骤如下:

之前的设置:

  1. 有一个 firebase 数据库,其中包含用于生成 QR 码的字符串。
  2. 设备 2 从 Firebase 数据库读取代码并将其显示在屏幕上(第二个应用)。

设备通信:

  1. 设备 1 具有扫描仪应用,设备 2 的屏幕上显示二维码。
  2. 设备 1 现在扫描设备 2 的 QR 码,并通过某种逻辑验证 QR 码是否有效。
  3. 如果 QR 码有效,则会发生以下情况:

设备 1 计算新的 QR 码并将其放入 Firebase 数据库中。

设备 2 现在应该从显示 QR 码转移到另一个 Activity ,该 Activity 具有扫描其他设备的 QR 码并验证它们是否正确的逻辑。

设备 3 及以上版本必须显示 Firebase 数据库中的新 QR 码,现在可以由设备 1 和 2 扫描。

注意:UI 上的二维码更新必须持续进行,直到出现某种指示使设备进入二维码扫描阶段。

正在运行的事情:

  1. 应用程序的 2 个 Activity (二维码显示和二维码扫描)独立运行。
  2. 每当 Firebase 数据库更新时,用户界面上的二维码都会更新。

不工作的事情:

  1. 一旦 QR 码被视为有效,就会从 QR 码显示转为扫描。

我尝试过的事情:

  1. 在 QR 码显示应用程序上创建服务器套接字实现,该应用程序作为我的主 Activity 调用的服务运行。客户端套接字实现(作为服务放置)位于 QR 码扫描器上,一旦 QR 码被认为有效,它将向监听服务器套接字发送数据。 (问题是既没有发送也没有接收数据)。
  2. 在 QR 码显示应用程序上创建服务器套接字实现,该应用程序作为我的主 Activity 调用的服务运行。客户端套接字实现(放置在 UI 线程上)位于 QR 码扫描器上,一旦 QR 码被认为有效,它将向监听服务器套接字发送数据。(问题是既没有发送也没有接收到数据)

我很困惑我的方法是否正确。有更好的方法吗?我的服务代码如下:

设备 2 - 二维码显示应用程序:

Service
public class MyService extends Service {
    private static final String TAG = "MyService";

    private T_Client client;

    @Override
    public void onDestroy() {
        Log.v(TAG, "onDestroy");
        if (client != null) {
            try {
                client.stopClient();
            } catch (Exception e) {
                Log.e(TAG, "Error on close: " + e);
            }
        }
        super.onDestroy();
        Toast.makeText(this, "Service stopped", Toast.LENGTH_LONG).show();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.v(TAG, "onStartCommand");

        client = new T_Client();
        client.start();

        Toast.makeText(this, "Service started", Toast.LENGTH_LONG).show();

        return START_STICKY;
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return null;
    }

}
Display Server Implementation (Called T_Client)
public class T_Client extends Thread {
    private static final String TAG = "T_Client";

    private Socket sock = null;
    private boolean running = false;
    private ObjectInputStream in;
    private ObjectOutputStream out;
    private Object objIn;

    public void send(String _msg) {
        if (out != null) {
            try {
                out.writeObject(_msg);
                out.flush();
                Log.i("Send Method", "Outgoing : " + _msg.toString());
            } catch (IOException ex) {
                Log.e("Send Method", ex.toString());
            }
        }
    }

    public void stopClient() {
        Log.v(TAG,"stopClient method run");
        running = false;
    }

    @Override
    public void run() {
        running = true;
        try {
            ServerSocket sock1 = new ServerSocket(9999);
            try {
                Log.i(TAG, "C: Connected.");
                while (running) {
                    sock = sock1.accept();
                    out = new ObjectOutputStream(sock.getOutputStream());
                    in = new ObjectInputStream(sock.getInputStream());
                    objIn = in.readObject();
                    Log.i("Object Read Class", objIn.getClass().toString());
                    Log.i("Object Read", objIn.toString());
                    /* Currently commented because startActivity not recognised
                    if (objIn != null) {
                        Intent dialogIntent = new Intent();
                        dialogIntent.setClass(this, MainActivity.class);
                        dialogIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        startActivity(dialogIntent);
                    }
                    Atleast the data should get read here
                    */
                    System.out.println("Object Read Class" + objIn.getClass().toString());
                    System.out.println("Object Read" + objIn.toString());
                }
                Log.e("RESPONSE FROM SERVER", "S: Received Message: '" + objIn + "'");
            } catch (Exception e) {
                Log.e(TAG, "S: Error", e);
            } finally {
                out.close();
                in.close();
                sock.close();
                Log.i(TAG, "Closing socket: " + sock);
            }
        } catch (Exception e) {
            Log.e(TAG, "C: Error", e);
        }
    }
}

Intent intent=new Intent(getContext().getApplicationContext(),MyService.class);
getContext().startService(intent);

扫描仪应用程序:(用 Kotlin 编写)

Scanner Client Implementation (Called T_Server)
internal class T_Server : Thread() {

    private var sock: Socket? = null
    private var running = false
    private var out: ObjectOutputStream? = null
    private val objIn: Any? = null
    var blockchain_kotlin_copy = SecondActivity().blockchain_kotlin_copy
    fun send(_msg: String) {
        if (out != null) {
            try {
                out!!.writeObject(_msg)
                out!!.flush()
                Log.i("Send Method", "Outgoing : $_msg")
            } catch (ex: IOException) {
                Log.e("Send Method", ex.toString())
            }

        }
    }

    fun stopClient() {
        Log.v(TAG, "stopClient method run")
        running = false
    }

    override fun run() {
        running = true
        try {
            val sock1 = ServerSocket(9999)
            try {
                Log.i(TAG, "C: Connected.")
                while (running) {
                    sock = sock1.accept()
                    try {
                    out = ObjectOutputStream(sock!!.getOutputStream())
                    out!!.writeObject(blockchain_kotlin_copy)
                    out!!.flush()
                    out!!.reset()
                    Log.i("Send Method", "Outgoing : $blockchain_kotlin_copy")
                    println("Out is being sent")
                    println("$blockchain_kotlin_copy")
                } catch (ex: IOException) {
                        Log.e("Send Method", ex.toString())
                    }
                }
            } catch (e: Exception) {
                Log.e(TAG, "S: Error", e)
            } finally {
                out!!.close()
                sock!!.close()
                Log.i(TAG, "Closing socket: " + sock!!)
            }
        } catch (e: Exception) {
            Log.e(TAG, "C: Error", e)
        }

    }

    companion object {
        private val TAG = "T_Server"
    }
}
Service
public class MyService extends Service {
    private static final String TAG = "MyService";

    private T_Server client;

    @Override
    public void onDestroy() {
        Log.v(TAG, "onDestroy");
        if (client != null) {
            try {
                client.stopClient();
            } catch (Exception e) {
                Log.e(TAG, "Error on close: " + e);
            }
        }
        super.onDestroy();
        Toast.makeText(this, "Service stopped", Toast.LENGTH_LONG).show();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.v(TAG, "onStartCommand");

        client = new T_Server();
        client.start();

        Toast.makeText(this, "Service started", Toast.LENGTH_LONG).show();

        return START_STICKY;
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return null;
    }

}
Main Activity
val intent = Intent(this, MyService::class.java)
this.startService(intent)

最佳答案

听起来您可能对 Firebase Device-to-Device notification 感兴趣。你可以这样做

  1. 设备 X 显示二维码
  2. 某些设备 Y 读取设备 X 的二维码,并且 if(verified) sendNotificationToDevice(X)
  3. 设备 X 进入扫描仪 Activity 以从其他设备 Z 读取数据。

除了上面的链接之外,还有许多有关如何实现 Device-to-Device notification 的 YouTube 教程和 Medium 博客文章.

关于java - 扫描我的二维码后即可进行下一个 Activity ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59037877/

相关文章:

android - 尝试在 BarEntry 数组上添加值时出错

sockets - 使用一个套接字进行对等通信

javascript - Node.js:通过 unix 套接字发送 GET 请求

java - 是否可以通过 JBoss EL 解析器在 EL 中使用对象作为函数参数?

java - 如何使 JFrame 背景和 JPanel 透明,只显示图像

android - 如何按顺序一个接一个地播放视频?

java - Android - onBackPressed() 不会被调用

java - 在java中通过客户端服务器网络将进程输出打印到JTextArea

java - 为什么 System.arraycopy 不是驼峰命名法?

java - SQLite 查询在 Java 中非常慢