扫描我的QR码后,移至下一个活动

时间:2019-11-25 18:16:36

标签: java android sockets kotlin serversocket

我的Android体验有限,并且有一个非常基本的疑问。我的情况如下:

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

先前设置:

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

设备通讯:

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

设备1计算出一个新的QR码并将其放置在Firebase数据库中。

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

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

注意:UI上的QR Code更新必须一直进行,直到有某种指示使设备进入QR Code Scanning阶段为止。

有效的东西:

  1. 应用程序的2个活动(QR Code Display和QR Code Scanning)独立运行。
  2. 每当Firebase数据库更新时,UI上的QR码更新。

不起作用的东西:

  1. 在认为QR码有效后,从QR码显示移至扫描。

我尝试过的事情:

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

我对自己的方法是否正确感到非常困惑。有更好的方法吗?我的服务代码如下:

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

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)

1 个答案:

答案 0 :(得分:1)

听起来您可能对Firebase Device-to-Device notification感兴趣。您可以执行以下操作

  1. 设备X显示QR码
  2. 某些设备Y从设备X和if(verified) sendNotificationToDevice(X)读取QR码
  3. 设备X移至“扫描仪”活动以从其他设备Z读取。

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