Browse Source

运动强度和基础数据

Signed-off-by: duanchangpeng <838560574@qq.com>
duanchangpeng 4 năm trước cách đây
mục cha
commit
d426777898

+ 139 - 0
.idea/codeStyles/Project.xml

@@ -0,0 +1,139 @@
+<component name="ProjectCodeStyleConfiguration">
+  <code_scheme name="Project" version="173">
+    <JetCodeStyleSettings>
+      <option name="PACKAGES_TO_USE_STAR_IMPORTS">
+        <value>
+          <package name="java.util" alias="false" withSubpackages="false" />
+          <package name="kotlinx.android.synthetic" alias="false" withSubpackages="true" />
+          <package name="io.ktor" alias="false" withSubpackages="true" />
+        </value>
+      </option>
+      <option name="PACKAGES_IMPORT_LAYOUT">
+        <value>
+          <package name="" alias="false" withSubpackages="true" />
+          <package name="java" alias="false" withSubpackages="true" />
+          <package name="javax" alias="false" withSubpackages="true" />
+          <package name="kotlin" alias="false" withSubpackages="true" />
+          <package name="" alias="true" withSubpackages="true" />
+        </value>
+      </option>
+      <option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
+    </JetCodeStyleSettings>
+    <codeStyleSettings language="XML">
+      <option name="FORCE_REARRANGE_MODE" value="1" />
+      <indentOptions>
+        <option name="CONTINUATION_INDENT_SIZE" value="4" />
+      </indentOptions>
+      <arrangement>
+        <rules>
+          <section>
+            <rule>
+              <match>
+                <AND>
+                  <NAME>xmlns:android</NAME>
+                  <XML_ATTRIBUTE />
+                  <XML_NAMESPACE>^$</XML_NAMESPACE>
+                </AND>
+              </match>
+            </rule>
+          </section>
+          <section>
+            <rule>
+              <match>
+                <AND>
+                  <NAME>xmlns:.*</NAME>
+                  <XML_ATTRIBUTE />
+                  <XML_NAMESPACE>^$</XML_NAMESPACE>
+                </AND>
+              </match>
+              <order>BY_NAME</order>
+            </rule>
+          </section>
+          <section>
+            <rule>
+              <match>
+                <AND>
+                  <NAME>.*:id</NAME>
+                  <XML_ATTRIBUTE />
+                  <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
+                </AND>
+              </match>
+            </rule>
+          </section>
+          <section>
+            <rule>
+              <match>
+                <AND>
+                  <NAME>.*:name</NAME>
+                  <XML_ATTRIBUTE />
+                  <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
+                </AND>
+              </match>
+            </rule>
+          </section>
+          <section>
+            <rule>
+              <match>
+                <AND>
+                  <NAME>name</NAME>
+                  <XML_ATTRIBUTE />
+                  <XML_NAMESPACE>^$</XML_NAMESPACE>
+                </AND>
+              </match>
+            </rule>
+          </section>
+          <section>
+            <rule>
+              <match>
+                <AND>
+                  <NAME>style</NAME>
+                  <XML_ATTRIBUTE />
+                  <XML_NAMESPACE>^$</XML_NAMESPACE>
+                </AND>
+              </match>
+            </rule>
+          </section>
+          <section>
+            <rule>
+              <match>
+                <AND>
+                  <NAME>.*</NAME>
+                  <XML_ATTRIBUTE />
+                  <XML_NAMESPACE>^$</XML_NAMESPACE>
+                </AND>
+              </match>
+              <order>BY_NAME</order>
+            </rule>
+          </section>
+          <section>
+            <rule>
+              <match>
+                <AND>
+                  <NAME>.*</NAME>
+                  <XML_ATTRIBUTE />
+                  <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
+                </AND>
+              </match>
+              <order>ANDROID_ATTRIBUTE_ORDER</order>
+            </rule>
+          </section>
+          <section>
+            <rule>
+              <match>
+                <AND>
+                  <NAME>.*</NAME>
+                  <XML_ATTRIBUTE />
+                  <XML_NAMESPACE>.*</XML_NAMESPACE>
+                </AND>
+              </match>
+              <order>BY_NAME</order>
+            </rule>
+          </section>
+        </rules>
+      </arrangement>
+    </codeStyleSettings>
+    <codeStyleSettings language="kotlin">
+      <option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
+    </codeStyleSettings>
+  </code_scheme>
+</component>

+ 5 - 0
.idea/codeStyles/codeStyleConfig.xml

@@ -0,0 +1,5 @@
+<component name="ProjectCodeStyleConfiguration">
+  <state>
+    <option name="USE_PER_PROJECT_SETTINGS" value="true" />
+  </state>
+</component>

+ 7 - 1
README.md

@@ -1,3 +1,9 @@
 # watch
 
-Kotlin watch 
+Kotlin watch 
+
+1.数据渲染
+2.心律图跑起来
+3.bottonNav fragment
+4.首页每个小部件拆fragment
+5.设置界面要整起来

+ 1 - 0
app/build.gradle

@@ -56,6 +56,7 @@ dependencies {
     implementation fileTree(dir: 'libs', include: ['*.jar'])
     implementation(name: 'chileaf_wear_sdk_2.0.0', ext: 'aar')
     implementation 'androidx.legacy:legacy-support-v4:1.0.0'
+    implementation 'androidx.viewpager:viewpager:1.0.0'
     testImplementation 'junit:junit:4.13'
     androidTestImplementation 'androidx.test.ext:junit:1.1.2'
     androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'

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

@@ -35,5 +35,6 @@
         <activity android:name=".ui.activity.ViewPageActivity" />
         <activity android:name=".ui.activity.LoginActivity" />
         <activity android:name=".ui.activity.SettingActivity" />
+        <activity android:name=".ui.activity.OneActivity" />
     </application>
 </manifest>

+ 24 - 0
app/src/main/java/com/example/watch/ui/activity/BaseData.kt

@@ -0,0 +1,24 @@
+package com.example.watch.ui.activity
+
+class BaseData {
+    val heigh = 146
+    val sex = 1
+    val age = 6
+    val weight = 41
+    val head = "123.jpg"
+    val peaceHr = 90
+
+    public fun calcActivity(Hr: Int, Sex: Int, Weight: Int, Age: Int, T: Int): String {
+        var res = "0"
+        var calc:Double
+        if (Sex == 1) {
+            calc = (((-55.0969 + (0.6309 * Hr) + (0.1988 * Weight) + (0.2017 * Age)) / 4.184)*60 *T)
+        } else {
+            calc = (((-20.4022 + (0.4472 * Hr) + (0.1263 * Weight) + (0.074 * Age)) / 4.184)*60 *T)
+        }
+//        强度最大100
+        calc = if(calc >= 100.0) 100.0 else calc
+        res = calc.toInt().toString()
+        return res
+    }
+}

+ 29 - 4
app/src/main/java/com/example/watch/ui/activity/MainActivity.kt

@@ -33,7 +33,7 @@ import com.yanzhenjie.permission.runtime.Permission
 import kotlinx.android.synthetic.main.activity_main.*
 import org.w3c.dom.Text
 import timber.log.Timber
-
+import com.example.watch.ui.activity.BaseData
 
 class MainActivity : AppCompatActivity(), ScannerFragment.OnDeviceSelectedListener,
     WearManagerCallbacks {
@@ -60,6 +60,7 @@ class MainActivity : AppCompatActivity(), ScannerFragment.OnDeviceSelectedListen
         initView();
 
         setStatusBarColor()
+
 //        首次加载
         FirstRun()
 
@@ -71,6 +72,9 @@ class MainActivity : AppCompatActivity(), ScannerFragment.OnDeviceSelectedListen
 
 //        切换tab
         turnTabPage()
+
+//        填写基础身体数据
+        setDeafultData()
     }
 
     fun setStatusBarColor() {
@@ -143,10 +147,13 @@ class MainActivity : AppCompatActivity(), ScannerFragment.OnDeviceSelectedListen
     private fun FirstRun() {
         val sharedPreferences = getSharedPreferences("FirstRun", 0)
         val first_run = sharedPreferences.getBoolean("First", true)
+//        val first_run = true
         if (first_run) {
             sharedPreferences.edit().putBoolean("First", false).commit()
-            val ViewPageActivityIntent = Intent(this, ViewPageActivity::class.java)
-            startActivity(ViewPageActivityIntent)
+//            val ViewPageActivityIntent = Intent(this, ViewPageActivity::class.java)
+//            startActivity(ViewPageActivityIntent)
+            val OneActivityIntent = Intent(this, OneActivity::class.java)
+            startActivity(OneActivityIntent)
         } else {
             setContentView(R.layout.activity_main)
         }
@@ -355,7 +362,25 @@ class MainActivity : AppCompatActivity(), ScannerFragment.OnDeviceSelectedListen
 //    男:((-55.0969 +(0.6309×HR)+(0.1988 xW)+(0.2017×A))/ 4.184)×60 xT
 //    女:((-20.4022 +(0.4472×HR) - (0.1263 xW)+(0.074×A))/ 4.184)×60 xT
 //    其中,HR =心率(次/分钟) W =体重(公斤) A=年龄(岁) T =锻炼持续时间的时间(以小时计)
-        findViewById<TextView>(R.id.activLevel).text = "10"
+    this.findViewById<TextView>(R.id.activLevel).text = BaseData().calcActivity(heartRate,BaseData().sex,BaseData().weight,BaseData().age,1)
+//    todo 全部卡路里
+//    this.findViewById<TextView>(R.id.calNum).text = ().toString()
+//    todo 运动卡路里
+
+//     todo CK
+
+}
+
+    fun setDeafultData(){
+        this.findViewById<TextView>(R.id.height).text =  BaseData().heigh.toString()
+//        var sex = if (BaseData().sex == 1) "男" else "女"
+//        this.findViewById<TextView>(R.id.sex).text = sex
+        this.findViewById<TextView>(R.id.age).text =  BaseData().age.toString()
+        this.findViewById<TextView>(R.id.weight).text =  BaseData().weight.toString()
+        this.findViewById<TextView>(R.id.peaceHr).text =  BaseData().peaceHr.toString()
+
+        this.findViewById<TextView>(R.id.activLevel).text = "--"
+        this.findViewById<TextView>(R.id.heartReal).text = "--"
     }
 }
 

+ 35 - 0
app/src/main/java/com/example/watch/ui/activity/MyPagerAdapter.kt

@@ -0,0 +1,35 @@
+package com.example.watch.ui.activity
+
+import android.view.View
+import android.view.ViewGroup
+import android.view.WindowManager
+
+import androidx.viewpager.widget.PagerAdapter
+import com.example.watch.R
+
+
+class MyPagerAdapter : PagerAdapter {
+    private var viewLists: ArrayList<View>? = null
+
+    constructor() {}
+    constructor(viewLists: ArrayList<View>?) : super() {
+        this.viewLists = viewLists
+    }
+
+    override fun getCount(): Int {
+        return viewLists!!.size
+    }
+
+    override fun isViewFromObject(view: View, `object`: Any): Boolean {
+        return view === `object`
+    }
+
+    override fun instantiateItem(container: ViewGroup, position: Int): Any {
+        container.addView(viewLists!![position])
+        return viewLists!![position]
+    }
+
+    override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
+        container.removeView(viewLists!![position])
+    }
+}

+ 73 - 0
app/src/main/java/com/example/watch/ui/activity/OneActivity.kt

@@ -0,0 +1,73 @@
+package com.example.watch.ui.activity
+
+import android.content.Intent
+import android.os.Bundle
+import android.util.Log
+import android.view.View
+import android.view.WindowManager
+import androidx.appcompat.app.AppCompatActivity
+import androidx.viewpager.widget.ViewPager
+import com.example.watch.R
+
+
+class OneActivity : AppCompatActivity() {
+    private var vpager_one: ViewPager? = null
+    private var aList: ArrayList<View>? = null
+    private var mAdapter: MyPagerAdapter? = null
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        setContentView(R.layout.activity_one)
+        setStatusBarColor(1)
+        vpager_one = findViewById<View>(R.id.vpager_one) as ViewPager
+        aList = ArrayList<View>()
+        val li = layoutInflater
+        aList!!.add(li.inflate(R.layout.view_one, null, false))
+        aList!!.add(li.inflate(R.layout.view_two, null, false))
+        aList!!.add(li.inflate(R.layout.view_three, null, false))
+        mAdapter = MyPagerAdapter(aList)
+        vpager_one!!.adapter = mAdapter
+
+        setStatusBarColor(0)
+//        监听滚动事件
+        vpager_one!!.setOnPageChangeListener(object : ViewPager.OnPageChangeListener {
+            override fun onPageScrollStateChanged(state: Int) {
+            }
+
+            override fun onPageScrolled(
+                position: Int,
+                positionOffset: Float,
+                positionOffsetPixels: Int
+            ) {
+            }
+
+            override fun onPageSelected(position: Int) {
+                //判断滑动后选择的页面设置相应的RadioButton被选中
+                println("position" + position)
+                when (position) {
+                    //这里的btn_one two the 分别是布局中的三个RadioButton的id,直接调用其方法进行设置
+                    0 -> setStatusBarColor(0)
+                    1 -> setStatusBarColor(1)
+                    2 -> setStatusBarColor(2)
+                }
+            }
+
+        })
+    }
+
+    fun enterClick(view: View?) {
+        startActivity(Intent(this, MainActivity::class.java))
+    }
+
+    fun setStatusBarColor(number: Number) {
+        val window = window
+        window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
+        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
+        when (number) {
+            0 -> window.statusBarColor = resources.getColor(R.color.pink)
+            1 -> window.statusBarColor = resources.getColor(R.color.yellow)
+            2 -> window.statusBarColor = resources.getColor(R.color.green)
+        }
+
+    }
+
+}

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

@@ -0,0 +1,470 @@
+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.BaseAdapter;
+import android.widget.Button;
+import android.widget.ListView;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import androidx.annotation.NonNull;
+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.ScanRecord;
+import com.android.chileaf.bluetooth.scanner.ScanResult;
+import com.example.watch.R;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import timber.log.Timber;
+
+
+/**
+ * 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 {@link OnDeviceSelectedListener} which is
+ * implemented by activity in order to receive selected device. The scanning will continue to scan
+ * for 5 seconds and then stop.
+ */
+public class ScannerFragment extends DialogFragment {
+
+    private static final long SCAN_DURATION = 5000;
+    private static final int REQUEST_PERMISSION_REQ_CODE = 34;
+    private static final String[] FILTER_NAMES = new String[]{"CL831", "SE2"};
+
+    private BluetoothAdapter mBluetoothAdapter;
+    private OnDeviceSelectedListener mListener;
+    private DeviceListAdapter mAdapter;
+    private final Handler mHandler = new Handler();
+
+    private Button mScanButton;
+
+    private View mPermissionRationale;
+
+    private boolean mIsScanning = false;
+
+    public static ScannerFragment getInstance() {
+        final ScannerFragment fragment = new ScannerFragment();
+        final Bundle args = new Bundle();
+        fragment.setArguments(args);
+        return fragment;
+    }
+
+    /**
+     * Interface required to be implemented by activity.
+     */
+    public interface OnDeviceSelectedListener {
+        /**
+         * Fired when user selected the device.
+         *
+         * @param device the device to connect to
+         * @param name   the device name. Unfortunately on some devices {@link BluetoothDevice#getName()}
+         *               always returns <code>null</code>, i.e. Sony Xperia Z1 (C6903) with Android 4.3.
+         *               The name has to be parsed manually form the Advertisement packet.
+         */
+        void onDeviceSelected(final BluetoothDevice device, final String name);
+
+        /**
+         * Fired when scanner dialog has been cancelled without selecting a device.
+         */
+        default void onDialogCanceled() {
+        }
+    }
+
+    /**
+     * This will make sure that {@link OnDeviceSelectedListener} interface is implemented by activity.
+     */
+    @Override
+    public void onAttach(final Context context) {
+        super.onAttach(context);
+        try {
+            this.mListener = (OnDeviceSelectedListener) context;
+        } catch (final ClassCastException e) {
+            throw new ClassCastException(context.toString() + " must implement OnDeviceSelectedListener");
+        }
+    }
+
+    @Override
+    public void onCreate(final Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        final BluetoothManager manager = (BluetoothManager) requireContext().getSystemService(Context.BLUETOOTH_SERVICE);
+        if (manager != null) {
+            mBluetoothAdapter = manager.getAdapter();
+        }
+    }
+
+    @Override
+    public void onDestroyView() {
+        stopScan();
+        super.onDestroyView();
+    }
+
+    @NonNull
+    @Override
+    public Dialog onCreateDialog(final Bundle savedInstanceState) {
+        final AlertDialog.Builder builder = new AlertDialog.Builder(requireContext());
+        final View dialogView = LayoutInflater.from(getActivity()).inflate(R.layout.fragment_device_scan, null);
+        final ListView listview = dialogView.findViewById(android.R.id.list);
+
+        listview.setEmptyView(dialogView.findViewById(android.R.id.empty));
+        listview.setAdapter(mAdapter = new DeviceListAdapter(getActivity()));
+
+        builder.setTitle(R.string.scanner_title);
+        final AlertDialog dialog = builder.setView(dialogView).create();
+        listview.setOnItemClickListener((parent, view, position, id) -> {
+            stopScan();
+            dialog.dismiss();
+            final ExtendedBluetoothDevice d = (ExtendedBluetoothDevice) mAdapter.getItem(position);
+            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(v -> {
+            if (v.getId() == R.id.action_cancel) {
+                if (mIsScanning) {
+                    dialog.cancel();
+                } else {
+                    startScan();
+                }
+            }
+        });
+
+        addBoundDevices();
+        if (savedInstanceState == null)
+            startScan();
+        return dialog;
+    }
+
+    @Override
+    public void onCancel(DialogInterface dialog) {
+        super.onCancel(dialog);
+        mListener.onDialogCanceled();
+    }
+
+    @Override
+    public void onRequestPermissionsResult(final int requestCode, final @NonNull String[] permissions, final @NonNull int[] grantResults) {
+        switch (requestCode) {
+            case 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.setVisibility(View.VISIBLE);
+                    Toast.makeText(getActivity(), R.string.no_required_permission, Toast.LENGTH_SHORT).show();
+                }
+                break;
+            }
+        }
+    }
+
+    /**
+     * 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 void 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.getVisibility() == View.GONE) {
+                mPermissionRationale.setVisibility(View.VISIBLE);
+                return;
+            }
+
+            requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, REQUEST_PERMISSION_REQ_CODE);
+            return;
+        }
+
+        // Hide the rationale message, we don't need it anymore.
+        if (mPermissionRationale != null)
+            mPermissionRationale.setVisibility(View.GONE);
+
+        mAdapter.clearDevices();
+        mScanButton.setText(R.string.scanner_action_cancel);
+
+        WearManager.getInstance(getActivity()).startScan(scanCallback);
+
+        mIsScanning = true;
+        mHandler.postDelayed(() -> {
+            if (mIsScanning) {
+                stopScan();
+            }
+        }, SCAN_DURATION);
+    }
+
+    /**
+     * Stop scan if user tap Cancel button
+     */
+    private void stopScan() {
+        if (mIsScanning) {
+            mScanButton.setText(R.string.scanner_action_scan);
+            WearManager.getInstance(getActivity()).stopScan();
+            mIsScanning = false;
+        }
+    }
+
+    private ScanCallback scanCallback = new ScanCallback() {
+        @Override
+        public void onBatchScanResults(final List<ScanResult> results) {
+            mAdapter.update(results);
+        }
+    };
+
+    private void addBoundDevices() {
+        final Set<BluetoothDevice> devices = mBluetoothAdapter.getBondedDevices();
+        mAdapter.addBondedDevices(devices);
+    }
+
+    private static class DeviceListAdapter extends BaseAdapter {
+        private static final int TYPE_TITLE = 0;
+        private static final int TYPE_ITEM = 1;
+        private static final int TYPE_EMPTY = 2;
+
+        private final ArrayList<ExtendedBluetoothDevice> mListBondedValues = new ArrayList<>();
+        private final ArrayList<ExtendedBluetoothDevice> mListValues = new ArrayList<>();
+        private final Context mContext;
+
+        public DeviceListAdapter(final Context context) {
+            mContext = context;
+        }
+
+        /**
+         * Sets a list of bonded devices.
+         *
+         * @param devices list of bonded devices.
+         */
+        private void addBondedDevices(final Set<BluetoothDevice> devices) {
+            final List<ExtendedBluetoothDevice> bondedDevices = mListBondedValues;
+            for (BluetoothDevice device : devices) {
+                if (matchDeviceName(device.getName())) {
+                    bondedDevices.add(new ExtendedBluetoothDevice(device));
+                }
+            }
+            notifyDataSetChanged();
+        }
+
+        private boolean matchDeviceName(String name) {
+            if (name != null && !TextUtils.isEmpty(name)) {
+                for (String filterName : 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
+         */
+        private void update(final List<ScanResult> results) {
+            for (final ScanResult result : results) {
+                Timber.e(result.toString());
+                final ExtendedBluetoothDevice device = findDevice(result);
+                if (device == null) {
+                    if (hasPairAddress(result)) {
+                        mListValues.add(new ExtendedBluetoothDevice(result));
+                    }
+                } else if (result.getScanRecord() != null) {
+                    device.name = result.getScanRecord().getDeviceName();
+                    device.rssi = result.getRssi();
+                }
+            }
+            notifyDataSetChanged();
+        }
+
+        private boolean hasPairAddress(ScanResult result) {
+            ScanRecord record = result.getScanRecord();
+            String name = record != null ? record.getDeviceName() : "";
+            return matchDeviceName(name);
+        }
+
+        private ExtendedBluetoothDevice findDevice(final ScanResult result) {
+            for (final ExtendedBluetoothDevice device : mListBondedValues)
+                if (device.matches(result) && hasPairAddress(result))
+                    return device;
+            for (final ExtendedBluetoothDevice device : mListValues)
+                if (device.matches(result))
+                    return device;
+            return null;
+        }
+
+        private void clearDevices() {
+            mListValues.clear();
+            notifyDataSetChanged();
+        }
+
+        @Override
+        public int getCount() {
+            final int bondedCount = mListBondedValues.size() + 1; // 1 for the title
+            final int availableCount = mListValues.isEmpty() ? 2 : mListValues.size() + 1; // 1 for title, 1 for empty text
+            if (bondedCount == 1)
+                return availableCount;
+            return bondedCount + availableCount;
+        }
+
+        @Override
+        public Object getItem(int position) {
+            final int bondedCount = mListBondedValues.size() + 1; // 1 for the title
+            if (mListBondedValues.isEmpty()) {
+                if (position == 0)
+                    return R.string.scanner_subtitle_not_bonded;
+                else
+                    return mListValues.get(position - 1);
+            } else {
+                if (position == 0)
+                    return R.string.scanner_subtitle_bonded;
+                if (position < bondedCount)
+                    return mListBondedValues.get(position - 1);
+                if (position == bondedCount)
+                    return R.string.scanner_subtitle_not_bonded;
+                return mListValues.get(position - bondedCount - 1);
+            }
+        }
+
+        @Override
+        public int getViewTypeCount() {
+            return 3;
+        }
+
+        @Override
+        public boolean areAllItemsEnabled() {
+            return false;
+        }
+
+        @Override
+        public boolean isEnabled(int position) {
+            return getItemViewType(position) == TYPE_ITEM;
+        }
+
+        @Override
+        public int getItemViewType(int position) {
+            if (position == 0)
+                return TYPE_TITLE;
+
+            if (!mListBondedValues.isEmpty() && position == mListBondedValues.size() + 1)
+                return TYPE_TITLE;
+
+            if (position == getCount() - 1 && mListValues.isEmpty())
+                return TYPE_EMPTY;
+
+            return TYPE_ITEM;
+        }
+
+        @Override
+        public long getItemId(int position) {
+            return position;
+        }
+
+        @Override
+        public View getView(int position, View oldView, ViewGroup parent) {
+            final LayoutInflater inflater = LayoutInflater.from(mContext);
+            final int type = getItemViewType(position);
+
+            View view = oldView;
+            switch (type) {
+                case TYPE_EMPTY:
+                    if (view == null) {
+                        view = new TextView(mContext);
+                        final TextView empty = (TextView) view;
+                        empty.setGravity(Gravity.CENTER_HORIZONTAL);
+                        empty.setText(mContext.getString(R.string.scanner_empty));
+                    }
+                    break;
+                case TYPE_TITLE:
+                    if (view == null) {
+                        view = new TextView(mContext);
+                    }
+                    final TextView title = (TextView) view;
+                    title.setGravity(Gravity.CENTER_HORIZONTAL);
+                    title.setText((Integer) getItem(position));
+                    break;
+                default:
+                    if (view == null) {
+                        view = inflater.inflate(R.layout.item_device_list, parent, false);
+                        final ViewHolder holder = new ViewHolder();
+                        holder.name = view.findViewById(R.id.name);
+                        holder.address = view.findViewById(R.id.address);
+                        holder.signal = view.findViewById(R.id.rssi);
+                        view.setTag(holder);
+                    }
+
+                    final ExtendedBluetoothDevice device = (ExtendedBluetoothDevice) getItem(position);
+                    final ViewHolder holder = (ViewHolder) view.getTag();
+                    final String name = device.name;
+                    holder.name.setText(name != null ? name : mContext.getString(R.string.not_available));
+                    holder.address.setText(device.device.getAddress());
+                    if (!device.isBonded || device.rssi != ExtendedBluetoothDevice.NO_RSSI) {
+                        holder.signal.setText(device.rssi + "dBm");
+                        holder.signal.setVisibility(View.VISIBLE);
+                    } else {
+                        holder.signal.setVisibility(View.GONE);
+                    }
+                    break;
+            }
+            return view;
+        }
+
+        private class ViewHolder {
+            private TextView name;
+            private TextView address;
+            private TextView signal;
+        }
+    }
+
+    private static class ExtendedBluetoothDevice {
+
+        private static final int NO_RSSI = -1000;
+
+        private String name;
+        private int rssi;
+        private boolean isBonded;
+        private final BluetoothDevice device;
+
+        private ExtendedBluetoothDevice(final ScanResult scanResult) {
+            this.device = scanResult.getDevice();
+            this.name = scanResult.getScanRecord() != null ? scanResult.getScanRecord().getDeviceName() : null;
+            this.rssi = scanResult.getRssi();
+            this.isBonded = false;
+        }
+
+        private ExtendedBluetoothDevice(final BluetoothDevice device) {
+            this.device = device;
+            this.name = device.getName();
+            this.rssi = NO_RSSI;
+            this.isBonded = true;
+        }
+
+        private boolean matches(final ScanResult scanResult) {
+            return device.getAddress().equals(scanResult.getDevice().getAddress());
+        }
+    }
+}

+ 0 - 111
app/src/main/java/com/example/watch/ui/activity/ble.kt

@@ -1,111 +0,0 @@
-package com.example.watch.ui.activity
-
-import android.bluetooth.BluetoothAdapter
-import android.bluetooth.BluetoothDevice
-import android.bluetooth.BluetoothManager
-import android.bluetooth.le.BluetoothLeScanner
-import android.bluetooth.le.ScanCallback
-import android.bluetooth.le.ScanResult
-import android.content.Context
-import android.content.Intent
-import android.os.Handler
-import android.widget.Button
-import android.widget.Toast
-import androidx.appcompat.app.AppCompatActivity
-import androidx.core.app.ActivityCompat.startActivityForResult
-import com.example.watch.R
-
-class ble {
-    //    声明变量
-//    private val REQUEST_BLUETOOTH_TURN_ON = 1
-//    private val BLE_SCAN_PERIOD: Long = 10000
-//    private lateinit var bleAdapter: BluetoothAdapter
-//    private lateinit var bleManager: BluetoothManager
-//    private lateinit var bleScanner: BluetoothLeScanner
-//    private lateinit var bleScanCallback: BleScanCallback
-//    private var bleScanResults = mutableMapOf<String?, BluetoothDevice?>()
-//    private lateinit var bleScanHandler: Handler
-//
-//    val connectBtn = findViewById<Button>(R.id.CONNECT)
-//
-//    connectBtn.setOnClickListener {
-//        bleScanHandler = Handler()
-//        //蓝牙管理,这是系统服务可以通过getSystemService(BLUETOOTH_SERVICE)的方法获取实例
-//        bleManager = getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
-//        //通过蓝牙管理实例获取适配器,然后通过扫描方法(scan)获取设备(device)
-//        bleAdapter = bleManager.adapter
-//        if (!bleAdapter.isEnabled) {
-//            val bluetoothTurnOn = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
-//            startActivityForResult(bluetoothTurnOn, REQUEST_BLUETOOTH_TURN_ON)
-//        } else {
-//            bleStartScan.run()
-//        }
-//    }
-//
-//    //start scan
-//    private val bleStartScan = Runnable {
-//        bleScanner = bleAdapter.bluetoothLeScanner
-//        bleScanCallback = BleScanCallback(bleScanResults)
-//        bleScanCallback.setContext(this.applicationContext)
-//        bleScanner.startScan(bleScanCallback)
-//        Toast.makeText(this.applicationContext, "蓝牙BLE扫描开始", Toast.LENGTH_SHORT).show()
-//        bleScanHandler.postDelayed(bleStopScan, this.BLE_SCAN_PERIOD)
-//    }
-//
-//    private val bleStopScan = Runnable {
-//        if (bleScanner != null) {
-//            bleScanner.stopScan(bleScanCallback)
-//        }
-//        Toast.makeText(this.applicationContext, "蓝牙BLE扫描结束", Toast.LENGTH_SHORT).show()
-//    }
-//
-//    class BleScanCallback(resultMap: MutableMap<String?, BluetoothDevice?>) : ScanCallback() {
-//        var resultOfScan = resultMap
-//        private var context: Context? = null
-//
-//        fun setContext(context: Context) {
-//            this.context = context
-//        }
-//
-//        override fun onScanResult(callbackType: Int, result: ScanResult?) {
-//            addScanResult(result)
-//        }
-//
-//        override fun onBatchScanResults(results: MutableList<ScanResult>?) {
-//            results?.forEach { result -> addScanResult(result) }
-//        }
-//
-//        override fun onScanFailed(errorCode: Int) {
-//            Toast.makeText(this.context, "蓝牙BLE扫描失败" + "Error Code: " + errorCode, Toast.LENGTH_SHORT).show()
-//        }
-//
-//        fun addScanResult(scanResult: ScanResult?) {
-//            val bleDevice = scanResult?.device
-//            val deviceAddress = bleDevice?.address
-//            if (!resultOfScan.contains(deviceAddress)) {
-//                resultOfScan.put(deviceAddress, bleDevice)
-//                if (this.context != null) {
-//                    Toast.makeText(this.context, bleDevice?.name + ": " + bleDevice?.address, Toast.LENGTH_SHORT).show()
-//                }
-//            }
-//        }
-//    }
-//
-//    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
-//        super.onActivityResult(requestCode, resultCode, data)
-//        when (requestCode) {
-//            REQUEST_BLUETOOTH_TURN_ON -> {
-//                when (resultCode) {
-//                    AppCompatActivity.RESULT_OK -> {
-//                        Toast.makeText(this.applicationContext, "蓝牙开启成功", Toast.LENGTH_SHORT).show()
-//                        bleStartScan.run()
-//                    }
-//                    AppCompatActivity.RESULT_CANCELED -> {
-//                        Toast.makeText(this.applicationContext, "蓝牙开启失败", Toast.LENGTH_SHORT).show()
-//                    }
-//                }
-//            }
-//        }
-//    }
-
-}

BIN
app/src/main/res/drawable/btn_help.png


BIN
app/src/main/res/drawable/help3.png


+ 6 - 5
app/src/main/res/layout/activity_main.xml

@@ -72,6 +72,7 @@
                                 android:layout_alignParentRight="true"
                                 android:text="%"
                                 android:layout_marginTop="10dp"
+                                android:paddingLeft="10dp"
                                 android:textColor="@color/white"
                                 android:textSize="20dp" />
                         </RelativeLayout>
@@ -167,7 +168,7 @@
                                     android:layout_alignParentRight="true"
                                     android:layout_centerHorizontal="true"
                                     android:layout_marginTop="17dp"
-                                    android:layout_marginRight="15dp"
+                                    android:layout_marginRight="5dp"
                                     android:gravity="center"
                                     android:src="@drawable/heart" />
                             </RelativeLayout>
@@ -215,7 +216,7 @@
                         android:orientation="vertical">
 
                         <TextView
-                            android:id="@+id/textView13"
+                            android:id="@+id/height"
                             android:layout_width="match_parent"
                             android:layout_height="wrap_content"
                             android:gravity="center"
@@ -252,7 +253,7 @@
                         android:orientation="vertical">
 
                         <TextView
-                            android:id="@+id/textView15"
+                            android:id="@+id/age"
                             android:layout_width="match_parent"
                             android:layout_height="wrap_content"
                             android:gravity="center"
@@ -288,7 +289,7 @@
                         android:orientation="vertical">
 
                         <TextView
-                            android:id="@+id/textView17"
+                            android:id="@+id/weight"
                             android:layout_width="match_parent"
                             android:layout_height="wrap_content"
                             android:gravity="center"
@@ -324,7 +325,7 @@
                         android:orientation="vertical">
 
                         <TextView
-                            android:id="@+id/textView19"
+                            android:id="@+id/peaceHr"
                             android:layout_width="match_parent"
                             android:layout_height="wrap_content"
                             android:gravity="center"

+ 13 - 0
app/src/main/res/layout/activity_one.xml

@@ -0,0 +1,13 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/LinearLayout1"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    tools:context=".ui.activity.OneActivity">
+    <androidx.viewpager.widget.ViewPager
+        android:id="@+id/vpager_one"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center" />
+</LinearLayout>  

+ 8 - 0
app/src/main/res/layout/view_one.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@drawable/help1"
+    android:gravity="center"
+    android:orientation="vertical">
+</LinearLayout>

+ 28 - 0
app/src/main/res/layout/view_three.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="match_parent"
+    android:layout_height="match_parent"
+    android:background="@drawable/help3"
+    android:gravity="center"
+    android:orientation="vertical">
+
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_gravity="bottom"
+        android:gravity="bottom"
+        android:orientation="vertical">
+
+        <Button
+            android:id="@+id/btn_enter_index"
+            android:layout_width="100dp"
+            android:layout_height="35dp"
+            android:layout_gravity="bottom|center"
+            android:background="@drawable/btn_help"
+            android:text="进入体验"
+            android:onClick="enterClick"
+            android:layout_marginBottom="35dp"
+            android:textColor="#768E00" />
+    </LinearLayout>
+</LinearLayout>

+ 10 - 0
app/src/main/res/layout/view_two.xml

@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@drawable/help2"
+    android:gravity="center"
+    android:orientation="vertical">
+
+
+</LinearLayout>

+ 2 - 0
app/src/main/res/values/colors.xml

@@ -14,4 +14,6 @@
     <color name="overlay">#800000</color>
     <color name="pink">#E75296</color>
     <color name="blue">#028FE1</color>
+    <color name="yellow">#F8BD2C</color>
+    <color name="green">#AACC03</color>
 </resources>

+ 8 - 8
app/src/main/res/values/strings.xml

@@ -15,7 +15,7 @@
     <string name="action_connect">链接中</string>
     <string name="action_disconnect">Disconnect</string>
     <string name="not_available">--</string>
-    <string name="battery">Battery:%d%%</string>
+    <string name="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>
@@ -26,18 +26,18 @@
     <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="scanner_empty">没有设备</string>
+    <string name="scanner_action_cancel">取消</string>
+    <string name="scanner_subtitle_bonded">可信设备:</string>
+    <string name="scanner_subtitle_not_bonded">有效设备:</string>
+    <string name="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_title">本地权限被拒绝</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>
     <!-- TODO: Remove or change this placeholder text -->
-    <string name="hello_blank_fragment">Hello blank fragment</string>
+    <string name="hello_blank_fragment">您好</string>
 
 </resources>