Bläddra i källkod

登录页面

Signed-off-by: duanchangpeng <838560574@qq.com>
duanchangpeng 5 år sedan
förälder
incheckning
7739828e71

+ 5 - 0
.idea/jarRepositories.xml

@@ -21,5 +21,10 @@
       <option name="name" value="Google" />
       <option name="url" value="https://dl.google.com/dl/android/maven2/" />
     </remote-repository>
+    <remote-repository>
+      <option name="id" value="maven" />
+      <option name="name" value="maven" />
+      <option name="url" value="https://jitpack.io" />
+    </remote-repository>
   </component>
 </project>

+ 7 - 1
app/build.gradle

@@ -29,6 +29,7 @@ android {
         }
     }
     repositories {
+        maven { url 'https://jitpack.io' }
         flatDir {
             dirs 'libs'
         }
@@ -54,7 +55,12 @@ dependencies {
     implementation 'androidx.gridlayout:gridlayout:1.0.0'
     implementation fileTree(dir: 'libs', include: ['*.jar'])
     implementation(name: 'chileaf_wear_sdk_2.0.0', ext: 'aar')
-    testImplementation 'junit:junit:4.+'
+    testImplementation 'junit:junit:4.13'
     androidTestImplementation 'androidx.test.ext:junit:1.1.2'
     androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
+    implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
+    implementation 'com.jakewharton.timber:timber:4.7.1'
+    implementation 'com.yanzhenjie:permission:2.0.3'
+    implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.50'
+
 }

+ 5 - 0
app/src/main/java/com/example/watch/ui/R.kt

@@ -0,0 +1,5 @@
+package com.example.watch.ui
+
+class R {
+
+}

+ 50 - 0
app/src/main/java/com/example/watch/ui/activity/LoadingDialog.kt

@@ -0,0 +1,50 @@
+package com.example.watch.ui.activity
+
+import android.app.Activity
+import android.content.Context
+import android.os.Bundle
+import android.text.TextUtils
+import android.view.LayoutInflater
+import android.view.View
+import android.widget.TextView
+import androidx.appcompat.app.AppCompatDialog
+import com.example.watch.R
+
+class LoadingDialog @JvmOverloads constructor(builder: com.example.watch.ui.activity.LoadingDialog.Builder, context: Context? = builder.context, theme: Int = R.style.DialogStyle) : AppCompatDialog(context, theme) {
+    private val mRoot: View
+    override fun onCreate(savedInstanceState: Bundle) {
+        super.onCreate(savedInstanceState)
+        setContentView(mRoot)
+    }
+
+    class Builder private constructor(val context: Context) {
+        var message: String? = null
+        fun setMessage(message: String?): com.example.watch.ui.activity.LoadingDialog.Builder {
+            this.message = message
+            return this
+        }
+
+        fun build(): LoadingDialog {
+            return LoadingDialog(this)
+        }
+    }
+
+    companion object {
+        fun Builder(activity: Activity?): com.example.watch.ui.activity.LoadingDialog.Builder {
+            return com.example.watch.ui.activity.LoadingDialog.Builder(activity)
+        }
+    }
+
+    init {
+        mRoot = LayoutInflater.from(context).inflate(R.layout.dialog_loading, null)
+        val tvLoading = mRoot.findViewById<TextView>(R.id.tv_loading)
+        if (!TextUtils.isEmpty(builder.message)) {
+            tvLoading.visibility = View.VISIBLE
+            tvLoading.setText(builder.message)
+        } else {
+            tvLoading.visibility = View.GONE
+        }
+        setCanceledOnTouchOutside(false)
+        setCancelable(false)
+    }
+}

+ 61 - 6
app/src/main/java/com/example/watch/ui/activity/LoginActivity.kt

@@ -1,26 +1,81 @@
 package com.example.watch.ui.activity
 
-import android.content.Intent
 import android.os.Bundle
 import android.view.View
 import android.widget.Button
+import android.widget.EditText
+import android.widget.LinearLayout
 import android.widget.Toast
 import androidx.appcompat.app.AppCompatActivity
 import com.example.watch.R
+import java.util.regex.Pattern
 
-class LoginActivity : AppCompatActivity(), View.OnClickListener {
+class LoginActivity : AppCompatActivity() {
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
         setContentView(R.layout.login_layout)
-        val ButtonLogin = findViewById<Button>(R.id.go_on)
-        ButtonLogin.setOnClickListener(this)
+//        获取验证码
+        getVoild()
+
+
+    }
+
+//    override fun onClick(v: View?) {
+//        val text_number = findViewById<EditText>(R.id.account)
+//        val number: String = text_number.getText().toString()
+//        if (number.length == 0) {
+//            return Toast.makeText(this, "手机号码不能为空", Toast.LENGTH_LONG).show()
+//        }
+////        if(!checkPhone(number)){
+////            return Toast.makeText(this, "手机号码格式不正确", Toast.LENGTH_LONG).show()
+////        }
+////        hideLayout();
+//
+//    }
+
+    //    获取验证码
+    fun getVoild() {
+        val ButtonGoOn = findViewById<Button>(R.id.go_on)
+        ButtonGoOn.setOnClickListener { v ->
+            val text_number = findViewById<EditText>(R.id.account)
+        val number: String = text_number.getText().toString()
+        if (number.length == 0) {
+             Toast.makeText(this, "手机号码不能为空", Toast.LENGTH_LONG).show()
+            return@setOnClickListener
+        }
+        if(!checkPhone(number)){
+            Toast.makeText(this, "手机号码格式不正确", Toast.LENGTH_LONG).show()
+            return@setOnClickListener
+        }
+            hideLayout()
+            volidLogin()
+        }
     }
 
-    override fun onClick(v: View?) {
-        Toast.makeText(this, "点击了", Toast.LENGTH_SHORT).show()
+    //  隐藏手机输入部分
+    fun hideLayout() {
+        val account_layout = findViewById<LinearLayout>(R.id.account_layout)
+        account_layout.setVisibility(View.GONE); // 隐藏
+        val go_on_layout = findViewById<LinearLayout>(R.id.go_on_layout)
+        go_on_layout.setVisibility(View.GONE); // 隐藏
     }
 
+    fun volidLogin() {
+        val ButtonLogin = findViewById<Button>(R.id.login_btn)
+        ButtonLogin.setOnClickListener { v ->
+            hideLayout();
+        }
+
+    }
+
+}
 
+//检查手机号格式
+fun checkPhone(number: String): Boolean {
+    val regExp = "^((13[0-9])|(15[^4])|(18[0-9])|(17[0-8])|(14[5-9])|(166)|(19[8,9])|)\\d{8}$"
+    val p = Pattern.compile(regExp)
+    val m = p.matcher(number)
+    return m.matches()
 }
 
 

+ 211 - 23
app/src/main/java/com/example/watch/ui/activity/MainActivity.kt

@@ -1,17 +1,40 @@
 package com.example.watch.ui.activity
 
 import android.bluetooth.BluetoothAdapter
+import android.bluetooth.BluetoothDevice
+import android.bluetooth.BluetoothManager
+import android.content.Context
+import android.content.DialogInterface
 import android.content.Intent
+import android.content.pm.PackageManager
+import android.net.Uri
 import android.os.Bundle
+import android.os.Handler
+import android.os.Looper
+import android.provider.Settings
+import android.provider.Settings.SettingNotFoundException
 import android.widget.Button
+import android.widget.TextView
 import android.widget.Toast
+import androidx.appcompat.app.AlertDialog
 import androidx.appcompat.app.AppCompatActivity
 import com.android.chileaf.WearManager
 import com.example.watch.R
+import com.yanzhenjie.permission.AndPermission
+import com.yanzhenjie.permission.runtime.Permission
+import timber.log.Timber
 
 
 class MainActivity : AppCompatActivity() {
-
+    private val mDeviceConnected = false
+    private val mTvAppVersion: TextView? = null
+    private val mTvDeviceName: TextView? = null
+    private val mTvVersion: TextView? = null
+    private val mTvRssi: TextView? = null
+    private val mTvBattery: TextView? = null
+    private val mTvSport: TextView? = null
+    private val mTvHeartRate: TextView? = null
+    private val mBtnConnect: Button? = null
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
 
@@ -22,33 +45,42 @@ class MainActivity : AppCompatActivity() {
         login()
 
 //        连接心率带
-//        linkHeartBand()
+        linkHeartBand()
+
 
     }
 
 
     private fun linkHeartBand() {
-        val that = this;
-        val linkHeartBandBtn = findViewById<Button>(R.id.linkBtn)
-        linkHeartBandBtn.setOnClickListener {
-            val mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter()
-            if (mBluetoothAdapter == null) {
-                Toast.makeText(this, "当前设备不支持蓝牙!", Toast.LENGTH_SHORT).show()
-            }
-            if (!mBluetoothAdapter.isEnabled) {
-                val enableBtIntent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
-                val REQUEST_ENABLE_BT = 1;
-                startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT)
-            }else{
-                val mBluetoothLeScanner = mBluetoothAdapter.bluetoothLeScanner
+        val chainBtn = findViewById<Button>(R.id.chainBtn)
+        chainBtn.setOnClickListener {
+//            val mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter()
+//            if (mBluetoothAdapter == null) {
+//                Toast.makeText(this, "当前设备不支持蓝牙!", Toast.LENGTH_SHORT).show()
+//            }
+//            if (!mBluetoothAdapter.isEnabled) {
+//                val enableBtIntent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
+//                val REQUEST_ENABLE_BT = 1;
+//                startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT)
+//            } else {
+//                Toast.makeText(this, "开始扫描蓝牙设备啦!", Toast.LENGTH_SHORT).show()
+////                showDeviceScanningDialog()
+//                showBLEDialog()
+//            }
 
+            if (isBLEEnabled()) {
+                if (!mDeviceConnected) {
+                    showDeviceScanningDialog()
+                } else {
+                    mManager!!.disConnect()
                 }
+            } else {
+                showBLEDialog()
+            }
         }
     }
 
 
-
-
     private fun initView() {
 
 //        val navBatton = findViewById<Button>(R.id.navigation_second)
@@ -61,11 +93,11 @@ class MainActivity : AppCompatActivity() {
     }
 
     private fun login() {
-        //        val login = 1
-//        if(login == 1){
-//            val LoginActivityIntent = Intent(this, LoginActivity::class.java)
-//            startActivity(LoginActivityIntent)
-//        }
+        val login = 1
+        if (login == 1) {
+            val LoginActivityIntent = Intent(this, LoginActivity::class.java)
+            startActivity(LoginActivityIntent)
+        }
     }
 
     private fun FirstRun() {
@@ -80,5 +112,161 @@ class MainActivity : AppCompatActivity() {
         }
     }
 
+    private var mManager: WearManager? = null
+    private var mLoading: LoadingDialog? = null
+    private var mHandler = Handler(Looper.getMainLooper())
+
+    private fun showLoading() {
+        showLoading(getString(R.string.loading))
+    }
+
+
+    private fun showLoading(message: String?) {
+        mLoading = LoadingDialog.Builder(this)
+                .setMessage(message)
+                .build()
+        mLoading!!.show()
+    }
+
+    private fun showLoadingAutoDismiss(delay: Long) {
+        showLoading()
+        mHandler.postDelayed(Runnable { hideLoading() }, delay)
+    }
+
+    private fun hideLoading() {
+        if (mLoading != null && mLoading!!.isShowing()) {
+            mLoading!!.dismiss()
+        }
+    }
+
+    private fun showToast(message: String?) {
+        runOnUiThread { Toast.makeText(this, message, Toast.LENGTH_SHORT).show() }
+    }
+
+    private fun ensureBLESupported() {
+        if (!packageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
+            Toast.makeText(this, R.string.no_ble, Toast.LENGTH_LONG).show()
+            finish()
+        }
+    }
+
+    private fun isBLEEnabled(): Boolean {
+        val bluetoothManager = getSystemService(BLUETOOTH_SERVICE) as BluetoothManager
+        val adapter = bluetoothManager.adapter
+        return adapter != null && adapter.isEnabled
+    }
+
+    private fun showBLEDialog() {
+        val enableIntent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
+        startActivity(enableIntent)
+    }
+
+
+    //Scan device
+    private fun showDeviceScanningDialog() {
+        if (isLocationEnabled(this)) {
+            AndPermission.with(this)
+                    .runtime()
+                    .permission(
+                        Permission.ACCESS_FINE_LOCATION,
+                        Permission.ACCESS_COARSE_LOCATION,
+                        Permission.ACCESS_BACKGROUND_LOCATION
+                    )
+                    .onGranted { permissions ->
+                        runOnUiThread {
+                            val dialog: ScannerFragment = ScannerFragment.getInstance()
+                            dialog.show(supportFragmentManager, "scan_fragment")
+                        }
+                    }
+                .onDenied({ permissions ->
+                    if (AndPermission.hasAlwaysDeniedPermission(this@MainActivity, permissions)) {
+                        AlertDialog.Builder(this)
+                            .setTitle(getString(R.string.permission_required))
+                            .setMessage(getString(R.string.permission_location_info))
+                            .setPositiveButton("OK") { dialog: DialogInterface?, which: Int -> onPermissionSettings() }
+                            .setNegativeButton("Cancel", null)
+                            .show()
+                    }
+                })
+                    .start()
+        } else {
+            AlertDialog.Builder(this)
+                    .setTitle(getString(R.string.location_permission_title))
+                    .setMessage(getString(R.string.location_permission_info))
+                    .setPositiveButton("OK") { dialog: DialogInterface?, which: Int -> onEnableLocation() }
+                    .setNegativeButton("Cancel", null)
+                    .show()
+        }
+    }
+
+    fun isLocationEnabled(context: Context): Boolean {
+        var locationMode = Settings.Secure.LOCATION_MODE_OFF
+        try {
+            locationMode = Settings.Secure.getInt(
+                context.contentResolver,
+                Settings.Secure.LOCATION_MODE
+            )
+        } catch (e: SettingNotFoundException) {
+            // do nothing
+        }
+        return locationMode != Settings.Secure.LOCATION_MODE_OFF
+        return true
+    }
+
+    fun onEnableLocation() {
+        val intent = Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)
+        startActivity(intent)
+    }
+
+    fun onPermissionSettings() {
+        val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
+        intent.data = Uri.fromParts("package", packageName, null)
+        startActivity(intent)
+    }
+
+    private fun defaultUI() {
+        mTvDeviceName?.setText("Device name")
+        mTvVersion?.setText("Version:--")
+        mTvRssi?.setText("Rssi:--")
+        mTvBattery?.setText("Battery:--")
+        mTvSport?.setText("Sport:--")
+        mTvHeartRate?.setText("Heart Rate:--")
+        mBtnConnect?.setText(getString(R.string.action_connect))
+    }
+
+
+    private fun getVersionName(): String? {
+        try {
+            val packageInfo = packageManager.getPackageInfo(packageName, 0)
+            return packageInfo.versionName
+        } catch (e: Exception) {
+            e.printStackTrace()
+        }
+        return null
+    }
+
+    fun onDeviceSelected(device: BluetoothDevice?, name: String?) {
+        mManager!!.connect(device, false)
+        mTvDeviceName?.setText(getString(R.string.device_name, name))
+    }
+
+    fun onError(device: BluetoothDevice, message: String, errorCode: Int) {
+        Timber.e("onError: ($errorCode)")
+        showToast("$message ($errorCode)")
+    }
+
+    fun onDeviceNotSupported(device: BluetoothDevice) {
+        showToast(getString(R.string.not_supported))
+    }
+
+    fun onSoftwareVersion(device: BluetoothDevice, software: String) {
+        runOnUiThread { mTvVersion?.setText("Version:$software") }
+    }
+
+    fun onRssiRead(device: BluetoothDevice, rssi: Int) {
+        runOnUiThread { mTvRssi?.setText("Rssi:" + rssi + "dBm") }
+    }
+}
+
+
 
-}

+ 458 - 0
app/src/main/java/com/example/watch/ui/activity/ScannerFragment.kt

@@ -0,0 +1,458 @@
+package com.example.watch.ui.activity
+
+import android.Manifest
+import android.app.Dialog
+import android.bluetooth.BluetoothAdapter
+import android.bluetooth.BluetoothDevice
+import android.bluetooth.BluetoothManager
+import android.content.Context
+import android.content.DialogInterface
+import android.content.pm.PackageManager
+import android.os.Bundle
+import android.os.Handler
+import android.text.TextUtils
+import android.view.Gravity
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.*
+import androidx.appcompat.app.AlertDialog
+import androidx.core.app.ActivityCompat
+import androidx.core.content.ContextCompat
+import androidx.fragment.app.DialogFragment
+import com.android.chileaf.WearManager
+import com.android.chileaf.bluetooth.scanner.ScanCallback
+import com.android.chileaf.bluetooth.scanner.ScanResult
+import com.example.watch.R
+import com.example.watch.ui.activity.ScannerFragment.OnDeviceSelectedListener
+import timber.log.Timber
+import java.util.*
+
+/**
+ * ScannerFragment class scan required BLE devices and shows them in a list. This class scans and filter
+ * devices with standard BLE Service UUID and devices with custom BLE Service UUID. It contains a
+ * list and a button to scan/cancel. There is a interface [OnDeviceSelectedListener] which is
+ * implemented by activity in order to receive selected device. The scanning will continue to scan
+ * for 5 seconds and then stop.
+ */
+class ScannerFragment : DialogFragment() {
+    private var mBluetoothAdapter: BluetoothAdapter? = null
+    private var mListener: OnDeviceSelectedListener? = null
+    private var mAdapter: DeviceListAdapter? = null
+    private val mHandler = Handler()
+    private var mScanButton: Button? = null
+    private var mPermissionRationale: View? = null
+    private var mIsScanning = false
+    
+    fun getInstance(): ScannerFragment? {
+        val fragment = ScannerFragment()
+        val args = Bundle()
+        fragment.arguments = args
+        return fragment
+    }
+
+    /**
+     * Interface required to be implemented by activity.
+     */
+    interface OnDeviceSelectedListener {
+        /**
+         * Fired when user selected the device.
+         *
+         * @param device the device to connect to
+         * @param name   the device name. Unfortunately on some devices [BluetoothDevice.getName]
+         * always returns `null`, i.e. Sony Xperia Z1 (C6903) with Android 4.3.
+         * The name has to be parsed manually form the Advertisement packet.
+         */
+        fun onDeviceSelected(device: BluetoothDevice?, name: String?)
+
+        /**
+         * Fired when scanner dialog has been cancelled without selecting a device.
+         */
+        fun onDialogCanceled() {}
+    }
+
+    /**
+     * This will make sure that [OnDeviceSelectedListener] interface is implemented by activity.
+     */
+    override fun onAttach(context: Context) {
+        super.onAttach(context)
+        try {
+            mListener = context as OnDeviceSelectedListener
+        } catch (e: ClassCastException) {
+            throw ClassCastException("$context must implement OnDeviceSelectedListener")
+        }
+    }
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        val manager =
+            requireContext().getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
+        if (manager != null) {
+            mBluetoothAdapter = manager.adapter
+        }
+    }
+
+    override fun onDestroyView() {
+        stopScan()
+        super.onDestroyView()
+    }
+
+    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
+        val builder = AlertDialog.Builder(requireContext())
+        val dialogView: View =
+            LayoutInflater.from(activity).inflate(R.layout.fragment_device_scan, null)
+        val listview = dialogView.findViewById<ListView>(R.id.list)
+        listview.emptyView = dialogView.findViewById(R.id.empty)
+        listview.adapter = activity?.let {
+            DeviceListAdapter(it)
+                .also({ mAdapter = it })
+        }
+        builder.setTitle(R.string.scanner_title)
+        val dialog = builder.setView(dialogView).create()
+        listview.onItemClickListener =
+            AdapterView.OnItemClickListener { parent: AdapterView<*>?, view: View?, position: Int, id: Long ->
+                stopScan()
+                dialog.dismiss()
+                val d: ExtendedBluetoothDevice =
+                    mAdapter?.getItem(position) as ExtendedBluetoothDevice
+                mListener?.onDeviceSelected(d.device, d.name)
+            }
+        mPermissionRationale =
+            dialogView.findViewById(R.id.permission_rationale) // this is not null only on API23+
+        mScanButton = dialogView.findViewById(R.id.action_cancel)
+        mScanButton?.setOnClickListener(View.OnClickListener { v: View ->
+            if (v.id == R.id.action_cancel) {
+                if (mIsScanning) {
+                    dialog.cancel()
+                } else {
+                    startScan()
+                }
+            }
+        })
+        addBoundDevices()
+        if (savedInstanceState == null) startScan()
+        return dialog
+    }
+
+    override fun onCancel(dialog: DialogInterface) {
+        super.onCancel(dialog)
+            mListener?.onDialogCanceled()
+    }
+
+    override fun onRequestPermissionsResult(
+        requestCode: Int,
+        permissions: Array<String>,
+        grantResults: IntArray
+    ) {
+        when (requestCode) {
+            REQUEST_PERMISSION_REQ_CODE -> {
+                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+                    // We have been granted the Manifest.permission.ACCESS_COARSE_LOCATION permission. Now we may proceed with scanning.
+                    startScan()
+                } else {
+                    mPermissionRationale!!.visibility = View.VISIBLE
+                    Toast.makeText(activity, R.string.no, Toast.LENGTH_SHORT)
+                        .show()
+                }
+            }
+        }
+    }
+
+    /**
+     * Scan for 5 seconds and then stop scanning when a BluetoothLE device is found then mLEScanCallback
+     * is activated This will perform regular scan for custom BLE Service UUID and then filter out.
+     * using class ScannerServiceParser
+     */
+    private fun startScan() {
+        // Since Android 6.0 we need to obtain either Manifest.permission.ACCESS_COARSE_LOCATION or Manifest.permission.ACCESS_FINE_LOCATION to be able to scan for
+        // Bluetooth LE devices. This is related to beacons as proximity devices.
+        // On API older than Marshmallow the following code does nothing.
+        if (ContextCompat.checkSelfPermission(
+                requireContext(),
+                Manifest.permission.ACCESS_COARSE_LOCATION
+            ) != PackageManager.PERMISSION_GRANTED
+        ) {
+            // When user pressed Deny and still wants to use this functionality, show the rationale
+            if (ActivityCompat.shouldShowRequestPermissionRationale(
+                    requireActivity(),
+                    Manifest.permission.ACCESS_COARSE_LOCATION
+                ) && mPermissionRationale!!.visibility == View.GONE
+            ) {
+                mPermissionRationale!!.visibility = View.VISIBLE
+                return
+            }
+            requestPermissions(
+                arrayOf(Manifest.permission.ACCESS_COARSE_LOCATION),
+                REQUEST_PERMISSION_REQ_CODE
+            )
+            return
+        }
+
+        // Hide the rationale message, we don't need it anymore.
+        if (mPermissionRationale != null) mPermissionRationale!!.visibility = View.GONE
+        mAdapter?.clearDevices()
+        mScanButton?.setText(R.string.scanner_action_cancel)
+        WearManager.getInstance(activity).startScan(scanCallback)
+        mIsScanning = true
+        mHandler.postDelayed({
+            if (mIsScanning) {
+                stopScan()
+            }
+        }, SCAN_DURATION)
+    }
+
+    /**
+     * Stop scan if user tap Cancel button
+     */
+    private fun stopScan() {
+        if (mIsScanning) {
+            mScanButton?.setText(R.string.scanner_action_scan)
+            WearManager.getInstance(activity).stopScan()
+            mIsScanning = false
+        }
+    }
+
+    private val scanCallback: ScanCallback = object : ScanCallback() {
+        override fun onBatchScanResults(results: List<ScanResult>) {
+            mAdapter?.update(results)
+        }
+    }
+
+    private fun addBoundDevices() {
+        val devices = mBluetoothAdapter!!.bondedDevices
+        mAdapter?.addBondedDevices(devices)
+    }
+
+    private class DeviceListAdapter(private val mContext: Context) :
+        BaseAdapter() {
+        private val mListBondedValues: ArrayList<com.example.watch.ui.activity.ScannerFragment.ExtendedBluetoothDevice> =
+            ArrayList<com.example.watch.ui.activity.ScannerFragment.ExtendedBluetoothDevice>()
+        private val mListValues: ArrayList<com.example.watch.ui.activity.ScannerFragment.ExtendedBluetoothDevice> =
+            ArrayList<com.example.watch.ui.activity.ScannerFragment.ExtendedBluetoothDevice>()
+
+        /**
+         * Sets a list of bonded devices.
+         *
+         * @param devices list of bonded devices.
+         */
+        fun addBondedDevices(devices: Set<BluetoothDevice>) {
+            val bondedDevices: MutableList<com.example.watch.ui.activity.ScannerFragment.ExtendedBluetoothDevice> =
+                mListBondedValues
+            for (device in devices) {
+                if (matchDeviceName(device.name)) {
+                    bondedDevices.add(
+                        com.example.watch.ui.activity.ScannerFragment.ExtendedBluetoothDevice(
+                            device
+                        )
+                    )
+                }
+            }
+            notifyDataSetChanged()
+        }
+
+        private fun matchDeviceName(name: String?): Boolean {
+            if (name != null && !TextUtils.isEmpty(name)) {
+                for (filterName in FILTER_NAMES) {
+                    if (name.toUpperCase().startsWith(filterName)) {
+                        return true
+                    }
+                }
+            }
+            return false
+        }
+
+        /**
+         * Updates the list of not bonded devices.
+         *
+         * @param results list of results from the scanner
+         */
+        fun update(results: List<ScanResult>) {
+            for (result in results) {
+                Timber.e(result.toString())
+                val device: com.example.watch.ui.activity.ScannerFragment.ExtendedBluetoothDevice? =
+                    findDevice(result)
+                if (device == null) {
+                    if (hasPairAddress(result)) {
+                        mListValues.add(
+                            com.example.watch.ui.activity.ScannerFragment.ExtendedBluetoothDevice(
+                                result
+                            )
+                        )
+                    }
+                } else if (result.scanRecord != null) {
+                    device.name = result.scanRecord!!.deviceName
+                    device.rssi = result.rssi
+                }
+            }
+            notifyDataSetChanged()
+        }
+
+        private fun hasPairAddress(result: ScanResult): Boolean {
+            val record = result.scanRecord
+            val name = if (record != null) record.deviceName else ""
+            return matchDeviceName(name)
+        }
+
+        private fun findDevice(result: ScanResult): com.example.watch.ui.activity.ScannerFragment.ExtendedBluetoothDevice? {
+            for (device in mListBondedValues) if (device.matches(result) && hasPairAddress(result)) return device
+            for (device in mListValues) if (device.matches(result)) return device
+            return null
+        }
+
+        fun clearDevices() {
+            mListValues.clear()
+            notifyDataSetChanged()
+        }
+
+        override fun getCount(): Int {
+            val bondedCount = mListBondedValues.size + 1 // 1 for the title
+            val availableCount =
+                if (mListValues.isEmpty()) 2 else mListValues.size + 1 // 1 for title, 1 for empty text
+            return if (bondedCount == 1) availableCount else bondedCount + availableCount
+        }
+
+        override fun getItem(position: Int): Any {
+            val bondedCount = mListBondedValues.size + 1 // 1 for the title
+            return if (mListBondedValues.isEmpty()) {
+                if (position == 0) R.string.scanner_subtitle_not_bonded else mListValues[position - 1]
+            } else {
+                if (position == 0) return R.string.scanner_subtitle_bonded
+                if (position < bondedCount) return mListBondedValues[position - 1]
+                if (position == bondedCount) R.string.scanner_subtitle_not_bonded else mListValues[position - bondedCount - 1]
+            }
+        }
+
+        override fun getViewTypeCount(): Int {
+            return 3
+        }
+
+        override fun areAllItemsEnabled(): Boolean {
+            return false
+        }
+
+        override fun isEnabled(position: Int): Boolean {
+            return getItemViewType(position) == com.example.watch.ui.activity.ScannerFragment.DeviceListAdapter.Companion.TYPE_ITEM
+        }
+
+        override fun getItemViewType(position: Int): Int {
+            if (position == 0) return com.example.watch.ui.activity.ScannerFragment.DeviceListAdapter.Companion.TYPE_TITLE
+            if (!mListBondedValues.isEmpty() && position == mListBondedValues.size + 1) return com.example.watch.ui.activity.ScannerFragment.DeviceListAdapter.Companion.TYPE_TITLE
+            return if (position == count - 1 && mListValues.isEmpty()) com.example.watch.ui.activity.ScannerFragment.DeviceListAdapter.Companion.TYPE_EMPTY else com.example.watch.ui.activity.ScannerFragment.DeviceListAdapter.Companion.TYPE_ITEM
+        }
+
+        override fun getItemId(position: Int): Long {
+            return position.toLong()
+        }
+
+        override fun getView(position: Int, oldView: View, parent: ViewGroup): View {
+            val inflater = LayoutInflater.from(mContext)
+            val type = getItemViewType(position)
+            var view = oldView
+            when (type) {
+                com.example.watch.ui.activity.ScannerFragment.DeviceListAdapter.Companion.TYPE_EMPTY -> if (view == null) {
+                    view = TextView(mContext)
+                    val empty = view
+                    empty.gravity = Gravity.CENTER_HORIZONTAL
+                    empty.text = mContext.getString(R.string.scanner_empty)
+                }
+                com.example.watch.ui.activity.ScannerFragment.DeviceListAdapter.Companion.TYPE_TITLE -> {
+                    if (view == null) {
+                        view = TextView(mContext)
+                    }
+                    val title = view as TextView
+                    title.gravity = Gravity.CENTER_HORIZONTAL
+                    title.setText((getItem(position) as Int))
+                }
+                else -> {
+//                    if (view == null) {
+//                        view = inflater.inflate(R.layout.item_device_list, parent, false)
+//                        val holder: com.example.watch.ui.activity.ScannerFragment.DeviceListAdapter.ViewHolder =
+//                            com.example.watch.ui.activity.ScannerFragment.DeviceListAdapter.ViewHolder()
+//
+//                        holder.name = view.findViewById<TextView>(R.id.name)
+//                        holder.address = view.findViewById<TextView>(R.id.address)
+//                        holder.signal = view.findViewById<TextView>(R.id.rssi)
+//                        view.tag = holder
+//                    }
+                    val device: com.example.watch.ui.activity.ScannerFragment.ExtendedBluetoothDevice =
+                        getItem(position) as com.example.watch.ui.activity.ScannerFragment.ExtendedBluetoothDevice
+                    val holder: com.example.watch.ui.activity.ScannerFragment.DeviceListAdapter.ViewHolder =
+                        view.tag as com.example.watch.ui.activity.ScannerFragment.DeviceListAdapter.ViewHolder
+                    val name: String? = device.name
+                    holder.name?.setText(name ?: mContext.getString(R.string.not_available))
+                    holder.address?.setText(device.device.getAddress())
+                    if (!device.isBonded || device.rssi != com.example.watch.ui.activity.ScannerFragment.ExtendedBluetoothDevice.Companion.NO_RSSI) {
+                        holder.signal?.setText(device.rssi.toString() + "dBm")
+                        holder.signal?.setVisibility(View.VISIBLE)
+                    } else {
+                        holder.signal?.setVisibility(View.GONE)
+                    }
+                }
+            }
+            return view
+        }
+
+        private inner class ViewHolder {
+            var name: TextView? = null
+            var address: TextView? = null
+            var signal: TextView? = null
+        }
+
+        companion object {
+            private const val TYPE_TITLE = 0
+            private const val TYPE_ITEM = 1
+            private const val TYPE_EMPTY = 2
+        }
+    }
+
+    private class ExtendedBluetoothDevice {
+        var name: String?
+        var rssi: Int
+        var isBonded: Boolean
+        val device: BluetoothDevice
+
+        constructor(scanResult: ScanResult) {
+            device = scanResult.device
+            name = if (scanResult.scanRecord != null) scanResult.scanRecord!!.deviceName else null
+            rssi = scanResult.rssi
+            isBonded = false
+        }
+
+        constructor(device: BluetoothDevice) {
+            this.device = device
+            name = device.name
+            rssi =
+                com.example.watch.ui.activity.ScannerFragment.ExtendedBluetoothDevice.Companion.NO_RSSI
+            isBonded = true
+        }
+
+        fun matches(scanResult: ScanResult): Boolean {
+            return device.address == scanResult.device.address
+        }
+
+        companion object {
+            const val NO_RSSI = -1000
+        }
+    }
+
+    companion object {
+        @JvmName("getInstance1")
+        fun getInstance(): ScannerFragment {
+            val fragment = ScannerFragment()
+            val args = Bundle()
+            fragment.arguments = args
+            return fragment
+        }
+
+        private const val SCAN_DURATION: Long = 5000
+        private const val REQUEST_PERMISSION_REQ_CODE = 34
+        private val FILTER_NAMES = arrayOf("CL831", "SE2")
+        val instance: ScannerFragment
+            get() {
+                val fragment = ScannerFragment()
+                val args = Bundle()
+                fragment.arguments = args
+                return fragment
+            }
+    }
+}

+ 127 - 0
app/src/main/java/com/example/watch/ui/activity/SecurityCodeView.kt

@@ -0,0 +1,127 @@
+package com.example.watch.ui.activity
+
+import android.content.Context
+import android.text.Editable
+import android.text.TextWatcher
+import android.util.AttributeSet
+import android.view.KeyEvent
+import android.view.View
+import android.view.View.OnKeyListener
+import android.widget.EditText
+import android.widget.RelativeLayout
+import android.widget.TextView
+import com.example.watch.R
+
+
+/**
+ * Created by xiaviv on 16/9/27.
+ */
+class SecurityCodeView @JvmOverloads constructor(context: Context?, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : RelativeLayout(context, attrs, defStyleAttr) {
+    private val editText: EditText
+    private val TextViews: Array<TextView?>
+    private val stringBuffer = StringBuffer()
+    private var count = 4
+
+    /**
+     * 获取输入文本
+     *
+     * @return
+     */
+    var editContent: String? = null
+        private set
+
+    private fun setListener() {
+        editText.addTextChangedListener(object : TextWatcher {
+            override fun beforeTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {}
+            override fun onTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {}
+            override fun afterTextChanged(editable: Editable) {
+                //如果字符不为""时才进行操作
+                if (editable.toString() != "") {
+                    if (stringBuffer.length > 3) {
+                        //当文本长度大于3位时editText置空
+                        editText.setText("")
+                        return
+                    } else {
+                        //将文字添加到StringBuffer中
+                        stringBuffer.append(editable)
+                        editText.setText("") //添加后将EditText置空
+                        count = stringBuffer.length
+                        editContent = stringBuffer.toString()
+                        if (stringBuffer.length == 4) {
+                            //文字长度位4  则调用完成输入的监听
+                            if (inputCompleteListener != null) {
+                                inputCompleteListener!!.inputComplete()
+                            }
+                        }
+                    }
+                    for (i in 0 until stringBuffer.length) {
+                        TextViews[i]!!.text = editContent!![i].toString()
+                        TextViews[i]!!.setBackgroundResource(R.drawable.bg_user_verify_code_blue)
+                    }
+                }
+            }
+        })
+        editText.setOnKeyListener(OnKeyListener { v, keyCode, event ->
+            if (keyCode == KeyEvent.KEYCODE_DEL
+                    && event.action == KeyEvent.ACTION_DOWN) {
+                return@OnKeyListener if (onKeyDelete()) true else true
+            }
+            false
+        })
+    }
+
+    fun onKeyDelete(): Boolean {
+        if (count == 0) {
+            count = 4
+            return true
+        }
+        if (stringBuffer.length > 0) {
+            //删除相应位置的字符
+            stringBuffer.delete(count - 1, count)
+            count--
+            editContent = stringBuffer.toString()
+            TextViews[stringBuffer.length]!!.text = ""
+            TextViews[stringBuffer.length]!!.setBackgroundResource(R.drawable.bg_user_verify_code_grey)
+            if (inputCompleteListener != null) inputCompleteListener!!.deleteContent(true) //有删除就通知manger
+        }
+        return false
+    }
+
+    /**
+     * 清空输入内容
+     */
+    fun clearEditText() {
+        stringBuffer.delete(0, stringBuffer.length)
+        editContent = stringBuffer.toString()
+        for (i in TextViews.indices) {
+            TextViews[i]!!.text = ""
+            TextViews[i]!!.setBackgroundResource(R.drawable.bg_user_verify_code_grey)
+        }
+    }
+
+    override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
+        return super.onKeyDown(keyCode, event)
+    }
+
+    private var inputCompleteListener: InputCompleteListener? = null
+    fun setInputCompleteListener(inputCompleteListener: InputCompleteListener?) {
+        this.inputCompleteListener = inputCompleteListener
+    }
+
+    interface InputCompleteListener {
+        fun inputComplete()
+        fun deleteContent(isDelete: Boolean)
+    }
+
+    init {
+        TextViews = arrayOfNulls(4)
+        inflate(context, R.layout.view_security_code, this)
+        editText = findViewById<View>(R.id.et) as EditText
+        TextViews[0] = findViewById<View>(R.id.item_code_iv1) as TextView
+        TextViews[1] = findViewById<View>(R.id.item_code_iv2) as TextView
+        TextViews[2] = findViewById<View>(R.id.item_code_iv3) as TextView
+        TextViews[3] = findViewById<View>(R.id.item_code_iv4) as TextView
+        editText.isCursorVisible = false //将光标隐藏
+        setListener()
+    }
+}

+ 12 - 0
app/src/main/res/drawable/bg_user_verify_code_blue.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <solid android:color="@android:color/transparent" />
+    <stroke
+        android:width="1dp"
+        android:color="@color/pink" />
+    <corners android:radius="4dp" />
+    <size
+        android:width="47dp"
+        android:height="47dp"/>
+</shape>

+ 12 - 0
app/src/main/res/drawable/bg_user_verify_code_grey.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <solid android:color="@android:color/transparent" />
+    <stroke
+        android:width="1dp"
+        android:color="#333" />
+    <corners android:radius="4dp" />
+    <size
+        android:width="47dp"
+        android:height="47dp"/>
+</shape>

+ 9 - 0
app/src/main/res/drawable/dialog_loading_bg.xml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+       android:shape="rectangle"
+    >
+    <solid android:color="@android:color/white"/>
+    <corners
+        android:radius="8dp"
+        />
+</shape>

+ 10 - 0
app/src/main/res/drawable/shape_rectangle_bg.xml

@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <solid android:color="#fff" />
+    <stroke
+        android:width="1dp"
+        android:color="#d3d3d3" />
+    <corners android:radius="4dp" />
+
+</shape>

+ 23 - 14
app/src/main/res/layout/activity_main.xml

@@ -35,7 +35,7 @@
                     android:layout_height="58dp"
                     android:layout_weight="1"
                     android:gravity="center"
-                    android:text="心率带已连接  电量 39%"
+                    android:text="心率带已连接  电量 0%"
                     android:textColor="@color/white" />
 
                 <LinearLayout
@@ -60,7 +60,7 @@
                                 android:layout_height="82dp"
                                 android:layout_weight="1"
                                 android:gravity="center"
-                                android:text="38"
+                                android:text="0"
                                 android:textColor="@color/white"
                                 android:textSize="50dp" />
 
@@ -71,6 +71,7 @@
                                 android:layout_alignParentTop="true"
                                 android:layout_alignParentRight="true"
                                 android:text="%"
+                                android:layout_marginTop="10dp"
                                 android:textColor="@color/white"
                                 android:textSize="20dp" />
                         </RelativeLayout>
@@ -106,23 +107,29 @@
                             android:layout_weight="1"
                             android:orientation="horizontal">
 
+                            <RelativeLayout
+                                android:layout_width="match_parent"
+                                android:layout_height="match_parent">
                             <TextView
                                 android:id="@+id/textView10"
-                                android:layout_width="100dp"
+                                android:layout_width="match_parent"
                                 android:layout_height="match_parent"
                                 android:layout_weight="1"
-                                android:gravity="center_vertical|right"
+                                android:layout_gravity="center"
+                                android:gravity="center_vertical|center"
                                 android:text="王仪涵"
                                 android:textColor="@color/white" />
                             <ImageView
                                 android:id="@+id/sex"
-                                android:layout_width="38dp"
+                                android:layout_width="18dp"
                                 android:layout_height="18dp"
-                                android:layout_weight="1"
-                                android:layout_centerHorizontal="true"
-                                android:gravity="center"
+                                android:gravity="center_vertical|left"
                                 android:layout_gravity="center"
+                                android:layout_alignParentRight="true"
+                                android:layout_marginTop="25dp"
+                                android:layout_marginRight="20dp"
                                 android:src="@drawable/male" />
+                            </RelativeLayout>
                         </LinearLayout>
                     </LinearLayout>
 
@@ -148,7 +155,7 @@
                                     android:layout_height="82dp"
                                     android:layout_weight="1"
                                     android:gravity="center"
-                                    android:text="38"
+                                    android:text="0"
                                     android:textColor="@color/white"
                                     android:textSize="50dp" />
 
@@ -591,11 +598,13 @@
             android:layout_weight="1"
             android:orientation="horizontal">
 
-            <SurfaceView
-                android:id="@+id/surfaceView2"
-                android:layout_width="wrap_content"
-                android:layout_height="73dp"
-                android:layout_weight="1" />
+            <com.github.mikephil.charting.charts.LineChart
+                android:id="@+id/lineChart"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:background="#ffffff"
+                android:layout_weight="1"
+                android:layout_margin="16dp"/>
         </LinearLayout>
 
         <com.google.android.material.bottomnavigation.BottomNavigationView

+ 28 - 0
app/src/main/res/layout/dialog_loading.xml

@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:background="@drawable/dialog_loading_bg"
+    android:gravity="center"
+    android:orientation="vertical">
+
+    <ProgressBar
+        android:id="@+id/pb_loading"
+        android:layout_width="25dp"
+        android:layout_height="25dp"
+        android:layout_marginTop="15dp" />
+
+    <TextView
+        android:id="@+id/tv_loading"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        android:layout_marginStart="35dp"
+        android:layout_marginTop="15dp"
+        android:layout_marginEnd="35dp"
+        android:layout_marginBottom="20dp"
+        android:singleLine="true"
+        android:text="@string/loading"
+        android:textColor="@color/black"
+        android:textSize="16sp" />
+</LinearLayout>

+ 33 - 0
app/src/main/res/layout/fragment_device_scan.xml

@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    style="?android:attr/buttonBarStyle"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+
+    <TextView
+        android:id="@+id/permission_rationale"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginBottom="8dp"
+        android:paddingStart="26dp"
+        android:paddingEnd="26dp"
+        android:text="@string/scanner_permission_rationale"
+        android:visibility="gone" />
+
+    <ListView
+        android:id="@+id/list"
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:layout_weight="1"
+        android:scrollbarStyle="outsideOverlay"
+        tools:listitem="@layout/item_device_list" />
+
+    <Button
+        android:id="@+id/action_cancel"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/scanner_action_scan" />
+
+</LinearLayout>

+ 40 - 0
app/src/main/res/layout/item_device_list.xml

@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="?android:attr/listPreferredItemHeightSmall"
+    android:orientation="vertical"
+    android:padding="6dp">
+
+    <TextView
+        android:id="@+id/rssi"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentEnd="true"
+        android:layout_centerVertical="true"
+        tools:ignore="contentDescription" />
+
+    <TextView
+        android:id="@+id/name"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentStart="true"
+        android:textColor="#000000"
+        android:textSize="14sp" />
+
+    <TextView
+        android:id="@+id/address"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@id/name"
+        android:textColor="#000000"
+        android:textSize="12sp" />
+    <TextView
+        android:id="@+id/empty"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@id/name"
+        android:textColor="#000000"
+        android:textSize="12sp" />
+
+</RelativeLayout>

+ 73 - 13
app/src/main/res/layout/login_layout.xml

@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<androidx.constraintlayout.widget.ConstraintLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
@@ -8,48 +7,109 @@
     <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="match_parent"
+        android:background="@drawable/login"
         android:orientation="vertical"
         tools:layout_editor_absoluteX="86dp"
-        tools:layout_editor_absoluteY="168dp"
-        android:background="@drawable/login"
-        >
+        tools:layout_editor_absoluteY="168dp">
 
         <LinearLayout
+            android:id="@+id/account_layout"
             android:layout_width="match_parent"
             android:layout_height="221dp"
-            android:layout_marginTop="250dp"
+            android:layout_gravity="center"
+            android:layout_marginTop="300dp"
             android:layout_weight="1"
-            android:orientation="vertical">
+            android:gravity="center"
+            android:orientation="horizontal">
+
+            <View
+                android:layout_width="1dip"
+                android:layout_height="fill_parent"
+                android:layout_gravity="center_horizontal"
+                android:background="#E2E2E2" />
 
             <EditText
+                android:id="@+id/account"
                 android:layout_width="fill_parent"
                 android:layout_height="wrap_content"
+                android:layout_marginLeft="20dp"
+                android:layout_marginRight="20dp"
+                android:foregroundTint="#D90E0E"
                 android:hint="@string/account"
                 android:inputType="text"
                 android:selectAllOnFocus="true"
-                android:singleLine="true"
-                android:textColorHint="#ccc"
+                android:singleLine="false"
                 android:textColor="#000"
+                android:textColorHint="#ccc"
                 android:textScaleX="1"
-                android:layout_marginLeft="20dp"
-                android:layout_marginRight="20dp"/>
+                android:theme="@style/MyEditText" />
         </LinearLayout>
 
         <LinearLayout
+            android:id="@+id/go_on_layout"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
+            android:layout_marginRight="20dp"
             android:layout_weight="2"
             android:gravity="right"
             android:orientation="vertical">
 
             <Button
                 android:id="@+id/go_on"
-                android:layout_width="100dp"
-                android:layout_height="48dp"
+                android:layout_width="70dp"
+                android:layout_height="36dp"
                 android:background="@drawable/login_button"
                 android:onClick="go_on_click"
                 android:text="@string/go_on"
+                android:textColor="#fff"
                 tools:ignore="OnClick" />
         </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="200dp"
+            android:layout_marginLeft="30dp"
+            android:layout_marginTop="300dp"
+            android:layout_marginRight="30dp"
+            android:orientation="vertical">
+
+            <com.example.watch.ui.activity.SecurityCodeView
+                android:id="@+id/edit_security_code"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="24dp"
+                android:layout_marginTop="21dp"
+                android:layout_marginRight="24dp"
+                android:gravity="center_horizontal"
+                tools:ignore="MissingClass" />
+
+            <TextView
+                android:id="@+id/tv_text"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="20dp"
+                android:layout_marginTop="30dp"
+                android:layout_marginRight="20dp"
+                android:text="@string/tv_user_agreement"
+                android:textColor="#AACC03" />
+
+            <LinearLayout
+                android:id="@+id/login_button_layout"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:layout_marginRight="20dp"
+                android:layout_weight="2"
+                android:gravity="right"
+                android:orientation="vertical">
+                <Button
+                    android:id="@+id/login_btn"
+                    android:layout_width="70dp"
+                    android:layout_height="36dp"
+                    android:background="@drawable/login_button"
+                    android:text="@string/login_btn"
+                    android:textColor="#fff"
+                    tools:ignore="OnClick" />
+            </LinearLayout>
+        </LinearLayout>
     </LinearLayout>
 </androidx.constraintlayout.widget.ConstraintLayout>

+ 50 - 0
app/src/main/res/layout/view_security_code.xml

@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content">
+
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="45dp"
+        android:orientation="horizontal">
+
+        <TextView
+            android:id="@+id/item_code_iv1"
+            style="@style/text_editStyle" />
+
+        <View
+            android:layout_width="0dp"
+            android:layout_height="1dp"
+            android:layout_weight="1" />
+
+        <TextView
+            android:id="@+id/item_code_iv2"
+            style="@style/text_editStyle" />
+
+        <View
+            android:layout_width="0dp"
+            android:layout_height="1dp"
+            android:layout_weight="1" />
+
+        <TextView
+            android:id="@+id/item_code_iv3"
+            style="@style/text_editStyle" />
+
+        <View
+            android:layout_width="0dp"
+            android:layout_height="1dp"
+            android:layout_weight="1" />
+
+        <TextView
+            android:id="@+id/item_code_iv4"
+            style="@style/text_editStyle" />
+
+    </LinearLayout>
+
+    <EditText
+        android:id="@+id/et"
+        android:layout_width="match_parent"
+        android:layout_height="46dp"
+        android:background="@android:color/transparent"
+        android:inputType="number" />
+</RelativeLayout>

+ 6 - 1
app/src/main/res/values/colors.xml

@@ -7,5 +7,10 @@
     <color name="teal_700">#FF018786</color>
     <color name="black">#000000</color>
     <color name="white">#FFFFFFFF</color>
-    <color name="focused">#333333</color>
+    <color name="colorPrimary">#008577</color>
+    <color name="colorPrimaryDark">#00574B</color>
+    <color name="colorAccent">#D81B60</color>
+    <color name="background">#DEDEDE</color>
+    <color name="overlay">#800000</color>
+    <color name="pink">#E75296</color>
 </resources>

+ 28 - 0
app/src/main/res/values/strings.xml

@@ -10,4 +10,32 @@
     <string name="enter_main">进入主页</string>
     <string name="go_on">继续</string>
     <string name="account">请输入手机号</string>
+    <string name="no_ble">当前的设备呀不支持蓝牙呢</string>
+    <string name="loading">加载中</string>
+    <string name="action_connect">链接中</string>
+    <string name="action_disconnect">Disconnect</string>
+    <string name="not_available">--</string>
+    <string name="battery">Battery:%d%%</string>
+    <string name="sport">Step:%d \nDistance:%.1fm \nCalories:%.1fCAL</string>
+    <string name="heart_rate">Heart Rate:%d bpm</string>
+    <string name="device_name">设备名:%s</string>
+    <string name="not_supported">不支持此设备</string>
+    <string name="scanner_permission_rationale">赋权扫描</string>
+    <string name="item_device_list">设备清单</string>
+    <string name="scanner_action_scan">开始扫描</string>
+    <string name="scanner_title">扫描名</string>
+    <string name="action_cancel">取消扫描</string>
+    <string name="no_required_permission">设备均不允许</string>
+    <string name="scanner_empty">No device found</string>
+    <string name="scanner_action_cancel">Cancel</string>
+    <string name="scanner_subtitle_bonded">Bonded devices:</string>
+    <string name="scanner_subtitle_not_bonded">Available devices:</string>
+    <string name="permission_required">Permission required</string>
+    <string name="permission_location_info">Starting from Android 6.0 Marshmallow the system requires location permission in order to scan for Bluetooth LE devices.</string>
+    <string name="location_permission_title">Location permission required</string>
+    <string name="location_permission_info">From Android 6.0 Marshmallow onwards the application requires Location permission in order to scan for Bluetooth Low Energy devices.</string>
+    <string name="no">无</string>
+    <string name="tv_user_agreement">验证码已发送到您的手机</string>
+    <string name="login_btn">登录</string>
+
 </resources>

+ 59 - 0
app/src/main/res/values/styles.xml

@@ -0,0 +1,59 @@
+<resources>
+
+    <!-- Base application theme. -->
+    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
+        <!-- Customize your theme here. -->
+        <item name="colorPrimary">@color/colorPrimary</item>
+        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
+        <item name="colorAccent">@color/colorAccent</item>
+    </style>
+
+    <style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
+
+    <style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
+
+    <style name="AppCompat.Toolbar" parent="Widget.AppCompat.ActionBar">
+        <item name="contentInsetStart">0dp</item>
+        <item name="contentInsetEnd">0dp</item>
+    </style>
+
+    <style name="DialogStyle" parent="@style/Theme.AppCompat.Dialog">
+        <item name="android:windowFrame">@null</item>
+        <item name="android:windowNoTitle">true</item>
+        <item name="android:windowIsFloating">true</item>
+        <item name="android:windowIsTranslucent">true</item>
+        <item name="android:backgroundDimEnabled">true</item>
+        <item name="android:windowContentOverlay">@null</item>
+        <item name="android:background">@android:color/transparent</item>
+        <item name="android:windowBackground">@android:color/transparent</item>
+    </style>
+
+    <style name="h_divider_line">
+        <item name="android:layout_height">1px</item>
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:background">@android:color/darker_gray</item>
+    </style>
+
+    <style name="v_divider_line">
+        <item name="android:layout_width">1dp</item>
+        <item name="android:layout_height">match_parent</item>
+        <item name="android:background">@android:color/darker_gray</item>
+    </style>
+
+    <style name="MyEditText" parent="Theme.AppCompat.Light">
+        <item name="colorControlNormal">@color/pink</item>
+        <item name="colorControlActivated">@color/pink</item>
+    </style>
+
+    <style name="text_editStyle" >
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:layout_width">wrap_content</item>
+        <item name="android:gravity">center</item>
+        <item name="android:background">@drawable/bg_user_verify_code_blue</item>
+        <item name="android:textColor">@color/pink</item>
+        <item name="android:textSize">24sp</item>
+        <item name="android:textStyle">bold</item>
+
+    </style>
+
+</resources>