Drew 6 yıl önce
ebeveyn
işleme
fb427baf12

+ 1 - 0
app/build.gradle

@@ -34,4 +34,5 @@ dependencies {
     implementation 'com.jakewharton:butterknife:10.2.0'
     annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.0'
     implementation 'com.kaopiz:kprogresshud:1.2.0'
+    implementation 'org.greenrobot:eventbus:3.1.1'
 }

BIN
app/release/app-release.apk


+ 7 - 0
app/src/main/AndroidManifest.xml

@@ -3,6 +3,8 @@
     xmlns:tools="http://schemas.android.com/tools"
     package="com.ht.gate">
 
+    <uses-permission android:name="android.permission.INTERNET" />
+
     <application
         android:allowBackup="true"
         android:icon="@mipmap/ic_launcher"
@@ -12,6 +14,11 @@
         android:theme="@style/AppTheme"
         tools:ignore="GoogleAppIndexingWarning"
         tools:replace="android:supportsRtl">
+        <service
+            android:name=".DoorService"
+            android:enabled="true"
+            android:exported="true"></service>
+
         <activity android:name=".LaunchActivity">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />

+ 123 - 0
app/src/main/java/com/ht/gate/DoorService.java

@@ -0,0 +1,123 @@
+package com.ht.gate;
+
+import android.app.Service;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Binder;
+import android.os.Handler;
+import android.util.Log;
+import android.widget.Toast;
+
+import org.greenrobot.eventbus.EventBus;
+
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+
+public class DoorService extends Service {
+    private static final String TAG = "DoorService";
+
+    private static final int MSG_SEND_MSG = 1;
+
+    private DatagramSocket socket;
+    private InetAddress serverAddress;
+    private String host;
+    private int port;
+    private SharedPreferences sharedPreferences;
+    private String status = "closed";
+
+    public class DoorBinder extends Binder {
+        public DoorService getService() {
+            return DoorService.this;
+        }
+    }
+
+    private DoorBinder mBinder = new DoorBinder();
+
+    private Handler mHandler = new Handler(msg -> {
+        switch (msg.what) {
+        }
+        return true;
+    });
+
+
+    public DoorService() {
+    }
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        sharedPreferences = getSharedPreferences(SettingsActivity.PREF_NAME_SETTINGS, MODE_PRIVATE);
+        restartSocket();
+    }
+
+    public void restartSocket() {
+        if (socket != null) {
+            socket.close();
+        }
+        String address = sharedPreferences.getString(SettingsActivity.PREF_KEY_ADDRESS, "");
+        try {
+            host = address.split(":")[0];
+            port = Integer.parseInt(address.split(":")[1]);
+            serverAddress = InetAddress.getByName(host);
+            socket = new DatagramSocket(12345);
+            startReceive();
+            Log.d(TAG, "socket opened");
+        } catch (Exception e) {
+            e.printStackTrace();
+            Toast.makeText(this, "门禁地址设置错误", Toast.LENGTH_SHORT).show();
+        }
+    }
+
+    public void startReceive() {
+        new Thread(() -> {
+            while (socket != null && !socket.isClosed()) {
+                try {
+                    Thread.sleep(300);
+                    byte[] data = new byte[1024];
+                    DatagramPacket packet = new DatagramPacket(data, data.length);
+                    socket.receive(packet);
+                    String result = new String(packet.getData(), packet.getOffset(), packet.getLength());
+                    Log.i(TAG, "UDP result: " + result);
+                    EventBus.getDefault().post(result);
+                    status = result;
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        }).start();
+    }
+
+    @Override
+    public DoorBinder onBind(Intent intent) {
+        Log.d(TAG, "onBind");
+        return mBinder;
+    }
+
+    @Override
+    public boolean onUnbind(Intent intent) {
+        Log.d(TAG, "onUnbind");
+        return super.onUnbind(intent);
+    }
+
+    public void openDoor() {
+        if (socket != null) {
+            new Thread(() -> {
+                try {
+                    String spaceId = sharedPreferences.getString(SettingsActivity.PREF_KEY_SPACE_ID, "");
+                    byte[] data = spaceId.getBytes();
+                    Log.d(TAG, "UDP发送消息:" + spaceId);
+                    DatagramPacket packet = new DatagramPacket(data, data.length, serverAddress, port);
+                    socket.send(packet);
+                } catch (Exception e) {
+                    Log.d(TAG, "UDP发送失败");
+                    e.printStackTrace();
+                }
+            }).start();
+        }
+    }
+
+    public String getStatus() {
+        return status;
+    }
+}

+ 87 - 3
app/src/main/java/com/ht/gate/MainActivity.java

@@ -2,17 +2,27 @@ package com.ht.gate;
 
 import androidx.appcompat.app.AppCompatActivity;
 
+import android.content.ComponentName;
 import android.content.Intent;
+import android.content.ServiceConnection;
 import android.content.SharedPreferences;
 import android.os.Bundle;
+import android.os.IBinder;
+import android.util.Log;
 import android.view.View;
 import android.widget.TextView;
+import android.widget.Toast;
+
+import org.greenrobot.eventbus.EventBus;
+import org.greenrobot.eventbus.Subscribe;
+import org.greenrobot.eventbus.ThreadMode;
 
 import butterknife.BindView;
 import butterknife.ButterKnife;
 import butterknife.OnClick;
 
 public class MainActivity extends AppCompatActivity {
+    private static final String TAG = "MainActivity";
 
     @BindView(R.id.unlock_view)
     UnlockView unlockView;
@@ -20,6 +30,22 @@ public class MainActivity extends AppCompatActivity {
     TextView tvSpaceName;
 
     private SharedPreferences sharedPreferences;
+    private DoorService.DoorBinder mDoorBinder;
+
+    private ServiceConnection connection = new ServiceConnection() {
+        @Override
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            Log.d(TAG, "onServiceConnected");
+            mDoorBinder = (DoorService.DoorBinder) service;
+            updateStatus();
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName name) {
+            Log.d(TAG, "onServiceDisconnected");
+            mDoorBinder = null;
+        }
+    };
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -29,8 +55,49 @@ public class MainActivity extends AppCompatActivity {
         sharedPreferences = getSharedPreferences(SettingsActivity.PREF_NAME_SETTINGS, MODE_PRIVATE);
         unlockView.setUnlockListener(() -> {
             PasswordDialog passwordDialog = new PasswordDialog(MainActivity.this);
+            passwordDialog.setListener(new PasswordDialog.DialogListener() {
+                @Override
+                public void onCancel(PasswordDialog dialog) {
+                    dialog.dismiss();
+                }
+
+                @Override
+                public void onConfirm(PasswordDialog dialog, String password) {
+                    if (password.equals("8888")) {
+                        dialog.dismiss();
+                        if (mDoorBinder != null) {
+                            mDoorBinder.getService().openDoor();
+                        }
+                        startActivity(new Intent(MainActivity.this, WelcomeActivity.class));
+                    } else {
+                        Toast.makeText(MainActivity.this, "密码错误", Toast.LENGTH_SHORT).show();
+                    }
+                }
+            });
             passwordDialog.show();
         });
+        bindService(new Intent(this, DoorService.class), connection, BIND_AUTO_CREATE);
+    }
+
+    @OnClick(R.id.btn_settings)
+    void onClickSettings() {
+        startActivity(new Intent(this, SettingsActivity.class));
+    }
+
+    @Subscribe(threadMode = ThreadMode.MAIN)
+    public void onMessageEvent(String msg) {
+        updateStatus();
+    }
+
+    private void updateStatus() {
+        if (mDoorBinder != null) {
+            String status = mDoorBinder.getService().getStatus();
+            if ("opened".equals(status)) {
+                unlockView.setUnlocked(true);
+            } else if ("closed".equals(status)) {
+                unlockView.setUnlocked(false);
+            }
+        }
     }
 
     @Override
@@ -42,10 +109,27 @@ public class MainActivity extends AppCompatActivity {
                 | View.SYSTEM_UI_FLAG_IMMERSIVE;
         decorView.setSystemUiVisibility(uiOptions);
         tvSpaceName.setText(sharedPreferences.getString(SettingsActivity.PREF_KEY_SPACE_NAME, ""));
+        updateStatus();
     }
 
-    @OnClick(R.id.btn_settings)
-    void onClickSettings() {
-        startActivity(new Intent(this, SettingsActivity.class));
+    @Override
+    public void onStart() {
+        super.onStart();
+        EventBus.getDefault().register(this);
+    }
+
+    @Override
+    public void onStop() {
+        super.onStop();
+        EventBus.getDefault().unregister(this);
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        if (connection != null) {
+            Log.d(TAG, "destroy and unbind service");
+            unbindService(connection);
+        }
     }
 }

+ 16 - 7
app/src/main/java/com/ht/gate/PasswordDialog.java

@@ -21,6 +21,12 @@ public class PasswordDialog extends AppCompatDialog {
 
     private final int MSG_HIDE_PASSWORD = 1;
 
+    public interface DialogListener {
+        void onCancel(PasswordDialog dialog);
+
+        void onConfirm(PasswordDialog dialog, String password);
+    }
+
     @BindView(R.id.keyboard_view)
     CustomKeyboardView keyboardView;
     @BindView(R.id.tv1)
@@ -35,6 +41,7 @@ public class PasswordDialog extends AppCompatDialog {
     private TextView[] textViews;
     private String password = "";
     private String passwordStr = "";
+    private DialogListener listener;
 
     private Handler mHandler = new Handler(msg -> {
         switch (msg.what) {
@@ -50,6 +57,10 @@ public class PasswordDialog extends AppCompatDialog {
         super(context, R.style.DialogStyle);
     }
 
+    public void setListener(DialogListener listener) {
+        this.listener = listener;
+    }
+
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -84,16 +95,14 @@ public class PasswordDialog extends AppCompatDialog {
             public void onKey(int primaryCode, int[] keyCodes) {
                 switch (primaryCode) {
                     case CustomKeyboardView.KEYCODE_CANCEL:
-                        dismiss();
+                        if (listener != null) {
+                            listener.onCancel(PasswordDialog.this);
+                        }
                         break;
                     case CustomKeyboardView.KEYCODE_DONE:
-                        if (password.equals("8888")) {
-                            dismiss();
-                            getContext().startActivity(new Intent(getContext(), WelcomeActivity.class));
-                        } else {
-                            Toast.makeText(getContext(), "密码错误", Toast.LENGTH_SHORT).show();
+                        if (listener != null) {
+                            listener.onConfirm(PasswordDialog.this, password);
                         }
-
                         break;
                     case CustomKeyboardView.KEYCODE_DELETE:
                         if (password.length() > 0) {

+ 38 - 5
app/src/main/java/com/ht/gate/SettingsActivity.java

@@ -3,9 +3,14 @@ package com.ht.gate;
 import androidx.appcompat.app.AppCompatActivity;
 
 import android.annotation.SuppressLint;
+import android.content.ComponentName;
 import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.ServiceConnection;
 import android.content.SharedPreferences;
 import android.os.Bundle;
+import android.os.IBinder;
+import android.util.Log;
 import android.view.View;
 import android.widget.TextView;
 
@@ -15,6 +20,8 @@ import butterknife.OnClick;
 
 @SuppressLint("SetTextI18n")
 public class SettingsActivity extends AppCompatActivity {
+    private static final String TAG = "SettingsActivity";
+
     @BindView(R.id.tv_title)
     TextView tvTitle;
     @BindView(R.id.tv_space_id)
@@ -22,15 +29,29 @@ public class SettingsActivity extends AppCompatActivity {
     @BindView(R.id.tv_space_name)
     TextView tvSpaceName;
     @BindView(R.id.tv_address)
-    TextView tvAddreess;
+    TextView tvAddress;
 
     public static final String PREF_NAME_SETTINGS = "settings";
     public static final String PREF_KEY_SPACE_ID = "spaceId";
     public static final String PREF_KEY_SPACE_NAME = "spaceName";
     public static final String PREF_KEY_ADDRESS = "address";
 
-
     private SharedPreferences sharedPreferences;
+    private DoorService.DoorBinder mDoorBinder;
+
+    private ServiceConnection connection = new ServiceConnection() {
+        @Override
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            Log.d(TAG, "onServiceConnected");
+            mDoorBinder = (DoorService.DoorBinder) service;
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName name) {
+            Log.d(TAG, "onServiceDisconnected");
+            mDoorBinder = null;
+        }
+    };
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -38,6 +59,7 @@ public class SettingsActivity extends AppCompatActivity {
         setContentView(R.layout.activity_settings);
         ButterKnife.bind(this);
         sharedPreferences = getSharedPreferences(PREF_NAME_SETTINGS, MODE_PRIVATE);
+        bindService(new Intent(this, DoorService.class), connection, BIND_AUTO_CREATE);
     }
 
     @Override
@@ -51,7 +73,15 @@ public class SettingsActivity extends AppCompatActivity {
         tvTitle.setText("财富管理室" + sharedPreferences.getString(PREF_KEY_SPACE_NAME, ""));
         tvSpaceId.setText(sharedPreferences.getString(PREF_KEY_SPACE_ID, ""));
         tvSpaceName.setText(sharedPreferences.getString(PREF_KEY_SPACE_NAME, ""));
-        tvAddreess.setText(sharedPreferences.getString(PREF_KEY_ADDRESS, ""));
+        tvAddress.setText(sharedPreferences.getString(PREF_KEY_ADDRESS, ""));
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        if (connection != null) {
+            unbindService(connection);
+        }
     }
 
     @OnClick(R.id.btn_back)
@@ -114,7 +144,7 @@ public class SettingsActivity extends AppCompatActivity {
     void changeAddress() {
         new PromptBuilder(this)
                 .setTitle("输入空间门禁地址")
-                .setValue(tvAddreess.getText().toString())
+                .setValue(tvAddress.getText().toString())
                 .setPositiveButton("确定")
                 .setNegativeButton("取消")
                 .setPromptListener(new PromptBuilder.PromptListener() {
@@ -126,10 +156,13 @@ public class SettingsActivity extends AppCompatActivity {
                     @Override
                     public void onConfirm(DialogInterface dialog, String value) {
                         dialog.dismiss();
-                        tvAddreess.setText(value);
+                        tvAddress.setText(value);
                         sharedPreferences.edit()
                                 .putString(PREF_KEY_ADDRESS, value)
                                 .apply();
+                        if (mDoorBinder != null) {
+                            mDoorBinder.getService().restartSocket();
+                        }
                     }
                 })
                 .show();

+ 1 - 1
app/src/main/java/com/ht/gate/UnlockView.java

@@ -221,7 +221,7 @@ public class UnlockView extends View {
                 if (down) {
                     distance += event.getX() - lastX;
                     lastX = event.getX();
-                    if (distance >= getWidth() - padding * 2 - (getHeight() - padding * 2) && !preUnlock) {
+                    if (distance >= getWidth() - padding * 2 - (getHeight() - padding * 2) && !preUnlock && !unlocked) {
                         preUnlock = true;
                         if (unlockListener != null) {
                             unlockListener.onUnlock();

+ 74 - 7
app/src/main/java/com/ht/gate/WelcomeActivity.java

@@ -2,23 +2,49 @@ package com.ht.gate;
 
 import androidx.appcompat.app.AppCompatActivity;
 
+import android.content.ComponentName;
 import android.content.Intent;
+import android.content.ServiceConnection;
 import android.content.SharedPreferences;
 import android.os.Bundle;
+import android.os.IBinder;
+import android.util.Log;
 import android.view.View;
 import android.widget.TextView;
 
+import org.greenrobot.eventbus.EventBus;
+import org.greenrobot.eventbus.Subscribe;
+import org.greenrobot.eventbus.ThreadMode;
+
 import butterknife.BindView;
 import butterknife.ButterKnife;
 import butterknife.OnClick;
 
 public class WelcomeActivity extends AppCompatActivity {
+    private static final String TAG = "WelcomeActivity";
+
     @BindView(R.id.unlock_view)
     UnlockView unlockView;
     @BindView(R.id.tv_space_name)
     TextView tvSpaceName;
 
     private SharedPreferences sharedPreferences;
+    private DoorService.DoorBinder mDoorBinder;
+
+    private ServiceConnection connection = new ServiceConnection() {
+        @Override
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            Log.d(TAG, "onServiceConnected");
+            mDoorBinder = (DoorService.DoorBinder) service;
+            updateStatus();
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName name) {
+            Log.d(TAG, "onServiceDisconnected");
+            mDoorBinder = null;
+        }
+    };
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -26,12 +52,36 @@ public class WelcomeActivity extends AppCompatActivity {
         setContentView(R.layout.activity_welcome);
         ButterKnife.bind(this);
         sharedPreferences = getSharedPreferences(SettingsActivity.PREF_NAME_SETTINGS, MODE_PRIVATE);
-        unlockView.setUnlockListener(new UnlockView.UnlockListener() {
-            @Override
-            public void onUnlock() {
-                unlockView.setUnlocked(true);
+        unlockView.setUnlockListener(() -> {
+            if (mDoorBinder != null) {
+                mDoorBinder.getService().openDoor();
             }
         });
+        bindService(new Intent(this, DoorService.class), connection, BIND_AUTO_CREATE);
+    }
+
+    @OnClick(R.id.btn_settings)
+    void onClickSettings() {
+        startActivity(new Intent(this, SettingsActivity.class));
+    }
+
+    @Subscribe(threadMode = ThreadMode.MAIN)
+    public void onMessageEvent(String msg) {
+        updateStatus();
+        if ("closed".equals(msg)) {
+            finish();
+        }
+    }
+
+    private void updateStatus() {
+        if (mDoorBinder != null) {
+            String status = mDoorBinder.getService().getStatus();
+            if ("opened".equals(status)) {
+                unlockView.setUnlocked(true);
+            } else if ("closed".equals(status)) {
+                unlockView.setUnlocked(false);
+            }
+        }
     }
 
     @Override
@@ -43,10 +93,27 @@ public class WelcomeActivity extends AppCompatActivity {
                 | View.SYSTEM_UI_FLAG_IMMERSIVE;
         decorView.setSystemUiVisibility(uiOptions);
         tvSpaceName.setText(sharedPreferences.getString(SettingsActivity.PREF_KEY_SPACE_NAME, ""));
+        updateStatus();
     }
 
-    @OnClick(R.id.btn_settings)
-    void onClickSettings() {
-        startActivity(new Intent(this, SettingsActivity.class));
+    @Override
+    public void onStart() {
+        super.onStart();
+        EventBus.getDefault().register(this);
+    }
+
+    @Override
+    public void onStop() {
+        super.onStop();
+        EventBus.getDefault().unregister(this);
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        if (connection != null) {
+            Log.d(TAG, "destroy and unbind service");
+            unbindService(connection);
+        }
     }
 }