| apply plugin: 'com.android.application' | apply plugin: 'com.android.application' | ||||
| apply plugin: 'com.jakewharton.butterknife' | apply plugin: 'com.jakewharton.butterknife' | ||||
| android { | android { | ||||
| compileSdkVersion 29 | |||||
| buildToolsVersion "29.0.2" | |||||
| compileSdkVersion 31 | |||||
| defaultConfig { | defaultConfig { | ||||
| applicationId "aicare.net.cn.sdk.ailinksdkdemoandroid" | applicationId "aicare.net.cn.sdk.ailinksdkdemoandroid" | ||||
| minSdkVersion 19 | minSdkVersion 19 | ||||
| targetSdkVersion 29 | |||||
| versionCode 15 | |||||
| versionName "1.10.2" | |||||
| targetSdkVersion 31 | |||||
| versionCode 16 | |||||
| versionName "1.10.3" | |||||
| testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" | ||||
| } | } | ||||
| buildTypes { | buildTypes { | ||||
| } | } | ||||
| compileOptions { | compileOptions { | ||||
| sourceCompatibility 1.8 | |||||
| targetCompatibility 1.8 | |||||
| sourceCompatibility '1.8' | |||||
| targetCompatibility '1.8' | |||||
| } | } | ||||
| sourceSets { | sourceSets { | ||||
| main { | main { | ||||
| dependencies { | dependencies { | ||||
| implementation fileTree(dir: 'libs', include: ['*.jar']) | implementation fileTree(dir: 'libs', include: ['*.jar']) | ||||
| implementation 'androidx.appcompat:appcompat:1.2.0' | |||||
| implementation 'androidx.appcompat:appcompat:1.4.2' | |||||
| implementation 'androidx.constraintlayout:constraintlayout:2.0.4' | implementation 'androidx.constraintlayout:constraintlayout:2.0.4' | ||||
| testImplementation 'junit:junit:4.12' | testImplementation 'junit:junit:4.12' | ||||
| implementation 'com.github.elinkthings:AILinkSDKRepositoryAndroid:1.10.2'//蓝牙核心库 | |||||
| implementation 'com.github.elinkthings:AILinkSDKRepositoryAndroid:1.10.3'//蓝牙核心库 | |||||
| implementation 'com.github.elinkthings:AILinkSDKOtaLibraryAndroid:1.0.3'//OTA库,需要依赖核心库 | implementation 'com.github.elinkthings:AILinkSDKOtaLibraryAndroid:1.0.3'//OTA库,需要依赖核心库 | ||||
| implementation 'com.github.elinkthings:AILinkSDKParsingLibraryAndroid:1.6.8'//蓝牙解析库 | implementation 'com.github.elinkthings:AILinkSDKParsingLibraryAndroid:1.6.8'//蓝牙解析库 | ||||
| implementation 'androidx.recyclerview:recyclerview:1.1.0' | implementation 'androidx.recyclerview:recyclerview:1.1.0' | 
| xmlns:tools="http://schemas.android.com/tools"> | xmlns:tools="http://schemas.android.com/tools"> | ||||
| <!--兼容6.0以上的手机Ble--> | |||||
| <uses-permission-sdk-23 android:name="android.permission.ACCESS_COARSE_LOCATION" /> | |||||
| <uses-permission-sdk-23 android:name="android.permission.ACCESS_FINE_LOCATION" /> | |||||
| <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" /> | <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" /> | ||||
| <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> | <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> | ||||
| <uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> | <uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> | ||||
| <uses-permission android:name="android.permission.INTERNET" /> | <uses-permission android:name="android.permission.INTERNET" /> | ||||
| <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> | <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> | ||||
| <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> | <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> | ||||
| <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> | |||||
| <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> | |||||
| <!--兼容6.0以上的手机Ble--> | |||||
| <uses-permission-sdk-23 android:name="android.permission.ACCESS_COARSE_LOCATION" /> | |||||
| <uses-permission-sdk-23 android:name="android.permission.ACCESS_FINE_LOCATION" /> | |||||
| <uses-permission | |||||
| android:name="android.permission.BLUETOOTH" | |||||
| android:maxSdkVersion="30" /> | |||||
| <uses-permission | |||||
| android:name="android.permission.BLUETOOTH_ADMIN" | |||||
| android:maxSdkVersion="30" /> | |||||
| <!--android12还需要增加如下权限,也需求动态申请--> | |||||
| <uses-permission android:name="android.permission.BLUETOOTH_SCAN" | |||||
| android:usesPermissionFlags="neverForLocation" | |||||
| tools:targetApi="s"/> | |||||
| <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" /> | |||||
| <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> | |||||
| <!--android10,11需要后台扫描的,需要添加如下权限--> | |||||
| <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" /> | |||||
| <uses-feature | |||||
| android:name="android.hardware.bluetooth_le" | |||||
| android:required="false" /> | |||||
| <uses-feature | |||||
| android:name="android.hardware.bluetooth" | |||||
| android:required="false" /> | |||||
| <!--OTA需要读写文件--> | <!--OTA需要读写文件--> | ||||
| <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> | <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> | ||||
| <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> | <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> | ||||
| <uses-feature | |||||
| android:name="android.hardware.bluetooth_le" | |||||
| android:required="true"/> | |||||
| <application | <application | ||||
| android:allowBackup="true" | android:allowBackup="true" | ||||
| android:usesCleartextTraffic="true" | android:usesCleartextTraffic="true" | ||||
| android:theme="@style/AppTheme" | android:theme="@style/AppTheme" | ||||
| tools:targetApi="q"> | tools:targetApi="q"> | ||||
| <activity android:name=".MainActivity"> | |||||
| <activity android:name=".MainActivity" | |||||
| android:exported="true"> | |||||
| <intent-filter> | <intent-filter> | ||||
| <action android:name="android.intent.action.VIEW" /> | <action android:name="android.intent.action.VIEW" /> | ||||
| <action android:name="android.intent.action.MAIN" /> | <action android:name="android.intent.action.MAIN" /> | 
| package aicare.net.cn.sdk.ailinksdkdemoandroid; | package aicare.net.cn.sdk.ailinksdkdemoandroid; | ||||
| import android.Manifest; | |||||
| import android.app.Activity; | |||||
| import android.annotation.SuppressLint; | |||||
| import android.bluetooth.BluetoothAdapter; | import android.bluetooth.BluetoothAdapter; | ||||
| import android.content.ComponentName; | |||||
| import android.content.Context; | |||||
| import android.content.Intent; | import android.content.Intent; | ||||
| import android.content.ServiceConnection; | |||||
| import android.content.pm.PackageManager; | |||||
| import android.location.LocationManager; | |||||
| import android.os.Bundle; | |||||
| import android.os.Handler; | |||||
| import android.os.IBinder; | |||||
| import android.os.Looper; | |||||
| import android.os.Message; | import android.os.Message; | ||||
| import android.provider.Settings; | |||||
| import android.text.TextUtils; | import android.text.TextUtils; | ||||
| import android.view.View; | import android.view.View; | ||||
| import android.widget.AdapterView; | import android.widget.AdapterView; | ||||
| import com.pingwang.bluetoothlib.listener.CallbackDisIm; | import com.pingwang.bluetoothlib.listener.CallbackDisIm; | ||||
| import com.pingwang.bluetoothlib.listener.OnCallbackBle; | import com.pingwang.bluetoothlib.listener.OnCallbackBle; | ||||
| import com.pingwang.bluetoothlib.listener.OnScanFilterListener; | import com.pingwang.bluetoothlib.listener.OnScanFilterListener; | ||||
| import com.pingwang.bluetoothlib.server.ELinkBleServer; | |||||
| import com.pingwang.bluetoothlib.utils.BleLog; | import com.pingwang.bluetoothlib.utils.BleLog; | ||||
| import com.pingwang.bluetoothlib.utils.BleStrUtils; | import com.pingwang.bluetoothlib.utils.BleStrUtils; | ||||
| import java.util.Map; | import java.util.Map; | ||||
| import java.util.UUID; | import java.util.UUID; | ||||
| import aicare.net.cn.sdk.ailinksdkdemoandroid.base.BleAppBaseActivity; | |||||
| import aicare.net.cn.sdk.ailinksdkdemoandroid.config.BleDeviceConfig; | import aicare.net.cn.sdk.ailinksdkdemoandroid.config.BleDeviceConfig; | ||||
| import aicare.net.cn.sdk.ailinksdkdemoandroid.dialog.LoadingIosDialogFragment; | import aicare.net.cn.sdk.ailinksdkdemoandroid.dialog.LoadingIosDialogFragment; | ||||
| import aicare.net.cn.sdk.ailinksdkdemoandroid.find.FindDeviceNewActivity; | import aicare.net.cn.sdk.ailinksdkdemoandroid.find.FindDeviceNewActivity; | ||||
| import aicare.net.cn.sdk.ailinksdkdemoandroid.modules.share_charger.ShareChargerActivity; | import aicare.net.cn.sdk.ailinksdkdemoandroid.modules.share_charger.ShareChargerActivity; | ||||
| import aicare.net.cn.sdk.ailinksdkdemoandroid.modules.share_condom.ShareCondomActivity; | import aicare.net.cn.sdk.ailinksdkdemoandroid.modules.share_condom.ShareCondomActivity; | ||||
| import aicare.net.cn.sdk.ailinksdkdemoandroid.modules.share_socket.ShareSocketActivity; | import aicare.net.cn.sdk.ailinksdkdemoandroid.modules.share_socket.ShareSocketActivity; | ||||
| import aicare.net.cn.sdk.ailinksdkdemoandroid.utils.CheckPermissionUtils; | |||||
| import androidx.annotation.NonNull; | import androidx.annotation.NonNull; | ||||
| import androidx.annotation.Nullable; | |||||
| import androidx.appcompat.app.AppCompatActivity; | |||||
| import androidx.core.app.ActivityCompat; | |||||
| import cn.net.aicare.modulelibrary.module.RopeSkipping.RopeSkippingBleData; | import cn.net.aicare.modulelibrary.module.RopeSkipping.RopeSkippingBleData; | ||||
| import cn.net.aicare.modulelibrary.module.scooter.SkateboardBleConfig; | import cn.net.aicare.modulelibrary.module.scooter.SkateboardBleConfig; | ||||
| * 2019/3/6<br> | * 2019/3/6<br> | ||||
| * java类作用描述 | * java类作用描述 | ||||
| */ | */ | ||||
| public class ShowBleActivity extends AppCompatActivity implements OnCallbackBle, OnScanFilterListener { | |||||
| public class ShowBleActivity extends BleAppBaseActivity implements OnCallbackBle, OnScanFilterListener { | |||||
| public static final int REQUEST_PERMISSION_CODE = 1500; | |||||
| private static String TAG = ShowBleActivity.class.getName(); | private static String TAG = ShowBleActivity.class.getName(); | ||||
| private final int REFRESH_DATA = 3; | private final int REFRESH_DATA = 3; | ||||
| private List<String> mList; | private List<String> mList; | ||||
| private ArrayAdapter listAdapter; | private ArrayAdapter listAdapter; | ||||
| private ELinkBleServer mBluetoothService; | |||||
| /** | |||||
| * 服务Intent | |||||
| */ | |||||
| private Intent bindIntent; | |||||
| private Context mContext; | |||||
| private int mType; | private int mType; | ||||
| private String mNoEncryptionMac = ""; | private String mNoEncryptionMac = ""; | ||||
| private String mFilterName = ""; | private String mFilterName = ""; | ||||
| private int mCid; | private int mCid; | ||||
| private int mVid; | private int mVid; | ||||
| private int mPid; | private int mPid; | ||||
| private Handler mHandler = new Handler(Looper.getMainLooper()) { | |||||
| @Override | |||||
| public void handleMessage(Message msg) { | |||||
| switch (msg.what) { | |||||
| case BIND_SERVER_OK: | |||||
| @Override | |||||
| protected void uiHandlerMessage(Message msg) { | |||||
| switch (msg.what) { | |||||
| break; | |||||
| case BIND_SERVER_OK: | |||||
| case REFRESH_DATA: | |||||
| listAdapter.notifyDataSetChanged(); | |||||
| break; | |||||
| } | |||||
| break; | |||||
| case REFRESH_DATA: | |||||
| listAdapter.notifyDataSetChanged(); | |||||
| break; | |||||
| } | } | ||||
| }; | |||||
| } | |||||
| @Override | |||||
| protected int getLayoutId() { | |||||
| return R.layout.activity_show_ble; | |||||
| } | |||||
| @Override | @Override | ||||
| protected void onCreate(@Nullable Bundle savedInstanceState) { | |||||
| super.onCreate(savedInstanceState); | |||||
| setContentView(R.layout.activity_show_ble); | |||||
| Intent mUserService = new Intent(this.getApplicationContext(), ELinkBleServer.class); | |||||
| //核心用户服务 | |||||
| startService(mUserService); | |||||
| mContext = this; | |||||
| protected void initData() { | |||||
| mType = getIntent().getIntExtra("type", 0); | mType = getIntent().getIntExtra("type", 0); | ||||
| if (0 == mType) { | if (0 == mType) { | ||||
| finish(); | finish(); | ||||
| return; | |||||
| } | } | ||||
| init(); | |||||
| initData(); | |||||
| } | |||||
| private void initData() { | |||||
| bindService(); | |||||
| } | } | ||||
| private void init() { | |||||
| @Override | |||||
| protected void initView() { | |||||
| mList = new ArrayList<>(); | mList = new ArrayList<>(); | ||||
| ListView listView = findViewById(R.id.listview); | ListView listView = findViewById(R.id.listview); | ||||
| Button btn = findViewById(R.id.btn); | Button btn = findViewById(R.id.btn); | ||||
| mBluetoothService.scanLeDevice(0, map, BleConfig.UUID_SERVER_AILINK, SkateboardBleConfig.UUID_BROADCAST); | mBluetoothService.scanLeDevice(0, map, BleConfig.UUID_SERVER_AILINK, SkateboardBleConfig.UUID_BROADCAST); | ||||
| } else { | } else { | ||||
| //0000FEE7=手表 | //0000FEE7=手表 | ||||
| mBluetoothService.scanLeDevice(0, BleConfig.UUID_SERVER_AILINK, UUID | |||||
| .fromString("0000FEE7-0000-1000-8000-00805F9B34FB"), SkateboardBleConfig.UUID_BROADCAST); | |||||
| mBluetoothService.scanLeDevice(0, BleConfig.UUID_SERVER_AILINK, UUID.fromString("0000FEE7-0000-1000-8000-00805F9B34FB"), SkateboardBleConfig.UUID_BROADCAST); | |||||
| } | } | ||||
| mList.clear(); | mList.clear(); | ||||
| listAdapter.notifyDataSetChanged(); | listAdapter.notifyDataSetChanged(); | ||||
| startActivity(intent); | startActivity(intent); | ||||
| finish(); | finish(); | ||||
| } else if (BleDeviceConfig.TOOTHBRUSH_BLE==mType){ | |||||
| } else if (BleDeviceConfig.TOOTHBRUSH_BLE == mType) { | |||||
| mBluetoothService.stopScan(); | mBluetoothService.stopScan(); | ||||
| Intent intent = new Intent(); | Intent intent = new Intent(); | ||||
| intent.setClass(ShowBleActivity.this, ToothBrushBleActivity.class); | intent.setClass(ShowBleActivity.this, ToothBrushBleActivity.class); | ||||
| intent.putExtra("mac", mac); | intent.putExtra("mac", mac); | ||||
| startActivity(intent); | startActivity(intent); | ||||
| finish(); | finish(); | ||||
| }else { | |||||
| } else { | |||||
| if (mCid == BleDeviceConfig.BLE_BOOLD_OXYGEN && mVid == 0x0012) { | if (mCid == BleDeviceConfig.BLE_BOOLD_OXYGEN && mVid == 0x0012) { | ||||
| //vid=12的不用握手校验,不加密 | //vid=12的不用握手校验,不加密 | ||||
| mNoEncryptionMac = mac; | mNoEncryptionMac = mac; | ||||
| } | } | ||||
| //---------------------------------服务--------------------------------------------------- | |||||
| @Override | |||||
| protected void initListener() { | |||||
| private void bindService() { | |||||
| BleLog.i(TAG, "绑定服务"); | |||||
| if (bindIntent == null) { | |||||
| bindIntent = new Intent(mContext, ELinkBleServer.class); | |||||
| if (mFhrSCon != null) | |||||
| this.bindService(bindIntent, mFhrSCon, Context.BIND_AUTO_CREATE); | |||||
| } | |||||
| } | } | ||||
| private void unbindService() { | |||||
| if (mBluetoothService != null) | |||||
| mBluetoothService.stopForeground();//停止前台服务 | |||||
| CallbackDisIm.getInstance().removeListener(this); | |||||
| if (mFhrSCon != null) { | |||||
| BleLog.i(TAG, "解绑服务"); | |||||
| this.unbindService(mFhrSCon); | |||||
| //---------------------------------服务--------------------------------------------------- | |||||
| @Override | |||||
| public void onServiceSuccess() { | |||||
| if (mBluetoothService!=null) { | |||||
| mBluetoothService.setOnCallback(ShowBleActivity.this); | |||||
| mBluetoothService.setOnScanFilterListener(ShowBleActivity.this); | |||||
| mHandler.sendEmptyMessage(BIND_SERVER_OK); | |||||
| } | } | ||||
| bindIntent = null; | |||||
| CallbackDisIm.getInstance().addListListener(this); | |||||
| } | } | ||||
| @Override | |||||
| public void onServiceErr() { | |||||
| /** | |||||
| * 服务连接与界面的连接 | |||||
| */ | |||||
| private ServiceConnection mFhrSCon = new ServiceConnection() { | |||||
| @Override | |||||
| public void onServiceConnected(ComponentName name, IBinder service) { | |||||
| BleLog.i(TAG, "服务与界面建立连接成功"); | |||||
| //与服务建立连接 | |||||
| mBluetoothService = ((ELinkBleServer.BluetoothBinder) service).getService(); | |||||
| if (mBluetoothService != null) { | |||||
| mBluetoothService.setOnCallback(ShowBleActivity.this); | |||||
| mBluetoothService.setOnScanFilterListener(ShowBleActivity.this); | |||||
| mBluetoothService.initForegroundService(1, R.mipmap.ic_launcher, "前台服务", MainActivity.class); | |||||
| mBluetoothService.startForeground();//启动前台服务 | |||||
| mHandler.sendEmptyMessage(BIND_SERVER_OK); | |||||
| } | |||||
| } | |||||
| } | |||||
| @Override | |||||
| public void onServiceDisconnected(ComponentName name) { | |||||
| BleLog.i(TAG, "服务与界面连接断开"); | |||||
| //与服务断开连接 | |||||
| mBluetoothService = null; | |||||
| } | |||||
| }; | |||||
| @Override | |||||
| public void unbindServices() { | |||||
| CallbackDisIm.getInstance().removeListener(this); | |||||
| } | |||||
| @Override | @Override | ||||
| //TODO 过滤后的设备 | //TODO 过滤后的设备 | ||||
| } | } | ||||
| @Override | |||||
| protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { | |||||
| super.onActivityResult(requestCode, resultCode, data); | |||||
| if (requestCode == REQUEST_PERMISSION_CODE) { | |||||
| checkPermission(); | |||||
| } | |||||
| } | |||||
| //--------------------------start Loading-------------------------- | //--------------------------start Loading-------------------------- | ||||
| private LoadingIosDialogFragment mDialogFragment; | private LoadingIosDialogFragment mDialogFragment; | ||||
| * 显示加载 | * 显示加载 | ||||
| */ | */ | ||||
| private void showLoading() { | private void showLoading() { | ||||
| if (mDialogFragment == null) | |||||
| if (mDialogFragment == null) { | |||||
| mDialogFragment = new LoadingIosDialogFragment(); | mDialogFragment = new LoadingIosDialogFragment(); | ||||
| } | |||||
| mDialogFragment.show(getSupportFragmentManager()); | mDialogFragment.show(getSupportFragmentManager()); | ||||
| } | } | ||||
| * 关闭加载 | * 关闭加载 | ||||
| */ | */ | ||||
| private void dismissLoading() { | private void dismissLoading() { | ||||
| if (mDialogFragment != null) | |||||
| if (mDialogFragment != null) { | |||||
| mDialogFragment.dismiss(); | mDialogFragment.dismiss(); | ||||
| } | |||||
| } | } | ||||
| //--------------------------end Loading-------------------------- | //--------------------------end Loading-------------------------- | ||||
| if (mBluetoothService != null) { | if (mBluetoothService != null) { | ||||
| mBluetoothService.stopScan(); | mBluetoothService.stopScan(); | ||||
| } | } | ||||
| unbindService(); | |||||
| } | } | ||||
| requestBluetooth(); | requestBluetooth(); | ||||
| return; | return; | ||||
| } | } | ||||
| // 没有定位权限就请求定位权限 | |||||
| if (!hasLocationPermission()) { | |||||
| requestLocationPermission(this); | |||||
| return; | |||||
| } | |||||
| // 没有定位服务就请求定位服务 | |||||
| if (!hasLocationService()) { | |||||
| requestLocationService(); | |||||
| return; | |||||
| } | |||||
| // 都有了,OK | |||||
| Toast.makeText(mContext, "权限都有,可以开始搜索", Toast.LENGTH_SHORT).show(); | |||||
| } | |||||
| new CheckPermissionUtils(this).checkPermissions(() -> { | |||||
| // 都有了,OK | |||||
| Toast.makeText(mContext, "权限都有,可以开始搜索", Toast.LENGTH_SHORT).show(); | |||||
| /** | |||||
| * 是否有定位权限 | |||||
| * | |||||
| * @return boolean | |||||
| */ | |||||
| private boolean hasLocationPermission() { | |||||
| return ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED; | |||||
| }); | |||||
| } | } | ||||
| /** | /** | ||||
| * 蓝牙是否打开 | * 蓝牙是否打开 | ||||
| * | * | ||||
| return BluetoothAdapter.getDefaultAdapter().isEnabled(); | return BluetoothAdapter.getDefaultAdapter().isEnabled(); | ||||
| } | } | ||||
| /** | |||||
| * 定位服务是否打开 | |||||
| * | |||||
| * @return boolean | |||||
| */ | |||||
| private boolean hasLocationService() { | |||||
| LocationManager locationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE); | |||||
| if (locationManager == null) { | |||||
| return false; | |||||
| } | |||||
| return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); | |||||
| } | |||||
| /** | |||||
| * 申请定位权限 | |||||
| */ | |||||
| private void requestLocationPermission(Activity activity) { | |||||
| ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_PERMISSION_CODE); | |||||
| } | |||||
| /** | /** | ||||
| * 申请打开蓝牙 | * 申请打开蓝牙 | ||||
| */ | */ | ||||
| @SuppressLint("MissingPermission") | |||||
| private void requestBluetooth() { | private void requestBluetooth() { | ||||
| Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); | Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); | ||||
| startActivityForResult(intent, REQUEST_PERMISSION_CODE); | |||||
| startActivity(intent); | |||||
| } | } | ||||
| /** | |||||
| * 申请打开定位服务 | |||||
| */ | |||||
| private void requestLocationService() { | |||||
| Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); | |||||
| startActivityForResult(intent, REQUEST_PERMISSION_CODE); | |||||
| } | |||||
| } | } | 
| private void setIp(byte[] ips) { | private void setIp(byte[] ips) { | ||||
| if (ips.length <= 14) | |||||
| if (ips.length <= 14) { | |||||
| bodyFatBleUtilsData.sendData(BodyFatDataUtil.getInstance().environmentIp(0, ips)); | bodyFatBleUtilsData.sendData(BodyFatDataUtil.getInstance().environmentIp(0, ips)); | ||||
| else { | |||||
| } else { | |||||
| boolean isend = false; | boolean isend = false; | ||||
| int i = 0; | int i = 0; | ||||
| byte[] byte1 = ips; | byte[] byte1 = ips; | ||||
| } | } | ||||
| private void setIpUrl(byte[] setIpUrl) { | private void setIpUrl(byte[] setIpUrl) { | ||||
| if (setIpUrl.length <= 14) | |||||
| if (setIpUrl.length <= 14) { | |||||
| bodyFatBleUtilsData.sendData(BodyFatDataUtil.getInstance().environmentUrl(0, setIpUrl)); | bodyFatBleUtilsData.sendData(BodyFatDataUtil.getInstance().environmentUrl(0, setIpUrl)); | ||||
| else { | |||||
| } else { | |||||
| boolean isend = false; | boolean isend = false; | ||||
| int i = 0; | int i = 0; | ||||
| byte[] byte1 = setIpUrl; | byte[] byte1 = setIpUrl; | ||||
| } else { | } else { | ||||
| byte[] password = BleStrUtils.stringToBytes(paw); | byte[] password = BleStrUtils.stringToBytes(paw); | ||||
| if (password != null) { | if (password != null) { | ||||
| if (password.length < 14) | |||||
| if (password.length < 14) { | |||||
| bodyFatBleUtilsData.sendData(BodyFatDataUtil.getInstance().setWifiPwd(0, password)); | bodyFatBleUtilsData.sendData(BodyFatDataUtil.getInstance().setWifiPwd(0, password)); | ||||
| else { | |||||
| } else { | |||||
| boolean isend = false; | boolean isend = false; | ||||
| int i = 0; | int i = 0; | ||||
| byte[] byte1 = password; | byte[] byte1 = password; | 
| package aicare.net.cn.sdk.ailinksdkdemoandroid.base; | package aicare.net.cn.sdk.ailinksdkdemoandroid.base; | ||||
| import android.Manifest; | |||||
| import android.content.Context; | import android.content.Context; | ||||
| import android.content.Intent; | |||||
| import android.content.pm.ActivityInfo; | import android.content.pm.ActivityInfo; | ||||
| import android.content.pm.PackageManager; | |||||
| import android.os.Build; | import android.os.Build; | ||||
| import android.os.Bundle; | import android.os.Bundle; | ||||
| import android.os.Handler; | import android.os.Handler; | ||||
| import java.lang.ref.WeakReference; | import java.lang.ref.WeakReference; | ||||
| import aicare.net.cn.sdk.ailinksdkdemoandroid.dialog.HintDataDialogFragment; | |||||
| import aicare.net.cn.sdk.ailinksdkdemoandroid.utils.AppStart; | |||||
| import androidx.annotation.NonNull; | |||||
| import aicare.net.cn.sdk.ailinksdkdemoandroid.utils.CheckPermissionUtils; | |||||
| import androidx.annotation.Nullable; | import androidx.annotation.Nullable; | ||||
| import androidx.appcompat.widget.Toolbar; | import androidx.appcompat.widget.Toolbar; | ||||
| import androidx.core.app.ActivityCompat; | |||||
| import androidx.core.content.ContextCompat; | |||||
| import butterknife.ButterKnife; | import butterknife.ButterKnife; | ||||
| import butterknife.Unbinder; | import butterknife.Unbinder; | ||||
| @Nullable | @Nullable | ||||
| protected Toolbar mToolbar; | protected Toolbar mToolbar; | ||||
| private Unbinder bind; | private Unbinder bind; | ||||
| //--------------ble--------------- | |||||
| /** | |||||
| * 需要申请的权限 | |||||
| */ | |||||
| private String[] LOCATION_PERMISSION = new String[]{Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.ACCESS_COARSE_LOCATION,Manifest.permission.WRITE_EXTERNAL_STORAGE}; | |||||
| /** | |||||
| * 权限请求返回 | |||||
| */ | |||||
| private final int PERMISSION = 101; | |||||
| /** | |||||
| * 定位服务返回 | |||||
| */ | |||||
| protected final int LOCATION_SERVER = 102; | |||||
| private HintDataDialogFragment mHintDataDialog = null; | |||||
| @Override | @Override | ||||
| protected void initPermissions() { | protected void initPermissions() { | ||||
| if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { | |||||
| onPermissionsOk(); | |||||
| return; | |||||
| } | |||||
| if (ContextCompat.checkSelfPermission(this, LOCATION_PERMISSION[0]) != PackageManager.PERMISSION_GRANTED) { | |||||
| ActivityCompat.requestPermissions(this, LOCATION_PERMISSION, PERMISSION); | |||||
| } else { | |||||
| boolean bleStatus = AppStart.isLocServiceEnable(mContext); | |||||
| if (!bleStatus) { | |||||
| //没有开启定位服务 | |||||
| mHintDataDialog = HintDataDialogFragment.newInstance() | |||||
| .setTitle("提示", 0) | |||||
| .setCancel("取消",0) | |||||
| .setOk("确定",0) | |||||
| .setContent("请求开启定位服务", true) | |||||
| .setDialogListener(new HintDataDialogFragment.DialogListener() { | |||||
| @Override | |||||
| public void tvSucceedListener(View v) { | |||||
| startLocationActivity(); | |||||
| } | |||||
| }); | |||||
| mHintDataDialog.show(getSupportFragmentManager()); | |||||
| } else { | |||||
| onPermissionsOk(); | |||||
| new CheckPermissionUtils(this).checkPermissions(new CheckPermissionUtils.OnPermissionListener() { | |||||
| @Override | |||||
| public void onPermissionsOk() { | |||||
| BleAppBaseActivity.this.onPermissionsOk(); | |||||
| } | } | ||||
| } | |||||
| } | |||||
| @Override | |||||
| public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, | |||||
| @NonNull int[] grantResults) { | |||||
| super.onRequestPermissionsResult(requestCode, permissions, grantResults); | |||||
| //请求权限被拒绝 | |||||
| if (requestCode != PERMISSION) | |||||
| return; | |||||
| if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { | |||||
| initPermissions(); | |||||
| } else { | |||||
| if (ActivityCompat.shouldShowRequestPermissionRationale(BleAppBaseActivity.this, | |||||
| LOCATION_PERMISSION[0])) { | |||||
| //权限请求失败,但未选中“不再提示”选项,再次请求 | |||||
| ActivityCompat.requestPermissions(this, LOCATION_PERMISSION, PERMISSION); | |||||
| } else { | |||||
| //权限请求失败,选中“不再提示”选项 | |||||
| mHintDataDialog = HintDataDialogFragment.newInstance() | |||||
| .setTitle("提示", 0) | |||||
| .setCancel("取消",0) | |||||
| .setOk("确定",0) | |||||
| .setContent("请求开启定位权限", true) | |||||
| .setDialogListener(new HintDataDialogFragment.DialogListener() { | |||||
| @Override | |||||
| public void tvSucceedListener(View v) { | |||||
| AppStart.startUseSetActivity(mContext); | |||||
| } | |||||
| }); | |||||
| mHintDataDialog.show(getSupportFragmentManager()); | |||||
| } | |||||
| } | |||||
| } | |||||
| /** | |||||
| * 启动去设置定位服务 | |||||
| */ | |||||
| protected void startLocationActivity() { | |||||
| AppStart.startLocationActivity(BleAppBaseActivity.this, LOCATION_SERVER); | |||||
| }); | |||||
| } | } | ||||
| } | } | ||||
| @Override | |||||
| protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { | |||||
| super.onActivityResult(requestCode, resultCode, data); | |||||
| if (requestCode == LOCATION_SERVER) { | |||||
| //定位服务页面返回 | |||||
| initPermissions(); | |||||
| } | |||||
| } | |||||
| /** | /** | ||||
| * 初始化事件 | * 初始化事件 | ||||
| if (mHandler != null) { | if (mHandler != null) { | ||||
| mHandler.removeCallbacksAndMessages(null); | mHandler.removeCallbacksAndMessages(null); | ||||
| } | } | ||||
| if (bind != null) | |||||
| if (bind != null) { | |||||
| bind.unbind(); | bind.unbind(); | ||||
| } | |||||
| } | } | ||||
| } | } | 
| import aicare.net.cn.sdk.ailinksdkdemoandroid.R; | import aicare.net.cn.sdk.ailinksdkdemoandroid.R; | ||||
| import aicare.net.cn.sdk.ailinksdkdemoandroid.utils.L; | import aicare.net.cn.sdk.ailinksdkdemoandroid.utils.L; | ||||
| import androidx.annotation.ColorInt; | import androidx.annotation.ColorInt; | ||||
| import androidx.annotation.NonNull; | import androidx.annotation.NonNull; | ||||
| import androidx.annotation.Nullable; | import androidx.annotation.Nullable; | ||||
| public class HintDataDialogFragment extends DialogFragment { | public class HintDataDialogFragment extends DialogFragment { | ||||
| private static String TAG = HintDataDialogFragment.class.getName(); | private static String TAG = HintDataDialogFragment.class.getName(); | ||||
| private Context mContext; | private Context mContext; | ||||
| private DialogListener mDialogListener; | |||||
| private onDialogListener mDialogListener; | |||||
| private TextView mTvTitle; | private TextView mTvTitle; | ||||
| private TextView mTvCancel, mTvSucceed, mTvContent; | private TextView mTvCancel, mTvSucceed, mTvContent; | ||||
| private View view_cancel_line; | private View view_cancel_line; | ||||
| * 是否居中 | * 是否居中 | ||||
| */ | */ | ||||
| private boolean isCenter = false; | private boolean isCenter = false; | ||||
| private CharSequence mCancel; | |||||
| private CharSequence mCancel=""; | |||||
| @ColorInt | @ColorInt | ||||
| private int mCancelColor = 0; | private int mCancelColor = 0; | ||||
| private CharSequence mOkStr; | |||||
| private CharSequence mOkStr=""; | |||||
| @ColorInt | @ColorInt | ||||
| private int mOkColor = 0; | private int mOkColor = 0; | ||||
| @ColorInt | @ColorInt | ||||
| /** | /** | ||||
| * 是否显示灰色背景 | * 是否显示灰色背景 | ||||
| */ | */ | ||||
| private boolean mBackground=true; | |||||
| private boolean mBackground = true; | |||||
| /** | /** | ||||
| * 点击空白区域是否关闭 | * 点击空白区域是否关闭 | ||||
| @Nullable | @Nullable | ||||
| @Override | @Override | ||||
| public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, | |||||
| @Nullable Bundle savedInstanceState) { | |||||
| public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { | |||||
| L.i(TAG, "onCreateView"); | L.i(TAG, "onCreateView"); | ||||
| return inflater.inflate(R.layout.dialog_hint_data, container);// 得到加载view | return inflater.inflate(R.layout.dialog_hint_data, container);// 得到加载view | ||||
| mTvContent = mDialogView.findViewById(R.id.tv_hint_data_context); | mTvContent = mDialogView.findViewById(R.id.tv_hint_data_context); | ||||
| mTvCancel.setOnClickListener(v -> { | mTvCancel.setOnClickListener(v -> { | ||||
| if (mDialogListener != null) { | if (mDialogListener != null) { | ||||
| mDialogListener.tvCancelListener(v); | |||||
| mDialogListener.onCancelListener(v); | |||||
| } | } | ||||
| this.dismiss(); | this.dismiss(); | ||||
| }); | }); | ||||
| mTvSucceed.setOnClickListener(v -> { | mTvSucceed.setOnClickListener(v -> { | ||||
| if (mDialogListener != null) { | if (mDialogListener != null) { | ||||
| mDialogListener.tvSucceedListener(v); | |||||
| mDialogListener.onSucceedListener(v); | |||||
| } | } | ||||
| this.dismiss(); | this.dismiss(); | ||||
| }); | }); | ||||
| public HintDataDialogFragment initColor(@ColorInt int cancelColor, @ColorInt int okColor) { | public HintDataDialogFragment initColor(@ColorInt int cancelColor, @ColorInt int okColor) { | ||||
| this.mCancelColor = cancelColor; | this.mCancelColor = cancelColor; | ||||
| this.mOkColor = okColor; | this.mOkColor = okColor; | ||||
| if (mTvCancel != null && mCancelColor != 0) | |||||
| if (mTvCancel != null && mCancelColor != 0) { | |||||
| mTvCancel.setTextColor(mCancelColor); | mTvCancel.setTextColor(mCancelColor); | ||||
| if (mTvSucceed != null && mOkColor != 0) | |||||
| } | |||||
| if (mTvSucceed != null && mOkColor != 0) { | |||||
| mTvSucceed.setTextColor(mOkColor); | mTvSucceed.setTextColor(mOkColor); | ||||
| } | |||||
| return this; | return this; | ||||
| } | } | ||||
| } else if (mContent == null) { | } else if (mContent == null) { | ||||
| mTvContent.setVisibility(View.GONE); | mTvContent.setVisibility(View.GONE); | ||||
| } | } | ||||
| if (isCenter) | |||||
| if (isCenter) { | |||||
| mTvContent.setGravity(Gravity.CENTER); | mTvContent.setGravity(Gravity.CENTER); | ||||
| else | |||||
| } else { | |||||
| mTvContent.setGravity(Gravity.CENTER_VERTICAL); | mTvContent.setGravity(Gravity.CENTER_VERTICAL); | ||||
| } | |||||
| } | } | ||||
| return this; | return this; | ||||
| } | } | ||||
| } else if (mOkStr == null) { | } else if (mOkStr == null) { | ||||
| mTvSucceed.setVisibility(View.GONE); | mTvSucceed.setVisibility(View.GONE); | ||||
| } | } | ||||
| if (mOkColor != 0) | |||||
| if (mOkColor != 0) { | |||||
| mTvSucceed.setTextColor(mOkColor); | mTvSucceed.setTextColor(mOkColor); | ||||
| } | |||||
| } | } | ||||
| return this; | return this; | ||||
| } | } | ||||
| * | * | ||||
| * @param isCenter 显示的内容是否居中 | * @param isCenter 显示的内容是否居中 | ||||
| */ | */ | ||||
| public HintDataDialogFragment initData(CharSequence title, CharSequence content, | |||||
| boolean isCenter, CharSequence cancel, CharSequence ok) { | |||||
| public HintDataDialogFragment initData(CharSequence title, CharSequence content, boolean isCenter, CharSequence cancel, CharSequence ok) { | |||||
| setTitle(title, mTitleColor); | setTitle(title, mTitleColor); | ||||
| setContent(content, isCenter); | setContent(content, isCenter); | ||||
| setCancel(cancel, mCancelColor); | setCancel(cancel, mCancelColor); | ||||
| /** | /** | ||||
| * 初始化数据 | * 初始化数据 | ||||
| */ | */ | ||||
| public HintDataDialogFragment initData(CharSequence title, CharSequence content, | |||||
| CharSequence cancel, CharSequence ok) { | |||||
| public HintDataDialogFragment initData(CharSequence title, CharSequence content, CharSequence cancel, CharSequence ok) { | |||||
| return this.initData(title, content, false, cancel, ok); | return this.initData(title, content, false, cancel, ok); | ||||
| } | } | ||||
| DisplayMetrics dm = new DisplayMetrics(); | DisplayMetrics dm = new DisplayMetrics(); | ||||
| if (getActivity() != null) { | if (getActivity() != null) { | ||||
| getActivity().getWindowManager().getDefaultDisplay().getMetrics(dm); | getActivity().getWindowManager().getDefaultDisplay().getMetrics(dm); | ||||
| if (dialog.getWindow() != null) | |||||
| if (dialog.getWindow() != null) { | |||||
| //设置宽度为80% | //设置宽度为80% | ||||
| dialog.getWindow() | |||||
| .setLayout((int) (dm.widthPixels * 0.9), | |||||
| ViewGroup.LayoutParams.WRAP_CONTENT); | |||||
| dialog.getWindow().setLayout((int) (dm.widthPixels * 0.9), ViewGroup.LayoutParams.WRAP_CONTENT); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| public interface DialogListener { | |||||
| public interface onDialogListener { | |||||
| /** | /** | ||||
| * 取消的点击事件 | * 取消的点击事件 | ||||
| * | * | ||||
| * @param v | * @param v | ||||
| */ | */ | ||||
| default void tvCancelListener(View v) { | |||||
| default void onCancelListener(View v) { | |||||
| } | } | ||||
| /** | /** | ||||
| * | * | ||||
| * @param v | * @param v | ||||
| */ | */ | ||||
| default void tvSucceedListener(View v) { | |||||
| default void onSucceedListener(View v) { | |||||
| } | } | ||||
| } | } | ||||
| public HintDataDialogFragment setDialogListener(DialogListener dialogListener) { | |||||
| public HintDataDialogFragment setOnDialogListener(onDialogListener dialogListener) { | |||||
| mDialogListener = dialogListener; | mDialogListener = dialogListener; | ||||
| return this; | return this; | ||||
| } | } | 
| package aicare.net.cn.sdk.ailinksdkdemoandroid.utils; | |||||
| import android.Manifest; | |||||
| import android.app.Activity; | |||||
| import android.content.Context; | |||||
| import android.content.Intent; | |||||
| import android.content.pm.PackageManager; | |||||
| import android.location.LocationManager; | |||||
| import android.net.Uri; | |||||
| import android.os.Build; | |||||
| import android.os.Bundle; | |||||
| import android.provider.Settings; | |||||
| import android.view.View; | |||||
| import java.lang.ref.WeakReference; | |||||
| import java.util.Map; | |||||
| import aicare.net.cn.sdk.ailinksdkdemoandroid.dialog.HintDataDialogFragment; | |||||
| import androidx.activity.result.ActivityResult; | |||||
| import androidx.activity.result.ActivityResultCallback; | |||||
| import androidx.activity.result.ActivityResultLauncher; | |||||
| import androidx.activity.result.contract.ActivityResultContracts; | |||||
| import androidx.annotation.Nullable; | |||||
| import androidx.appcompat.app.AppCompatActivity; | |||||
| import androidx.core.content.ContextCompat; | |||||
| import androidx.fragment.app.Fragment; | |||||
| import androidx.fragment.app.FragmentManager; | |||||
| /** | |||||
| * @author xing<br> | |||||
| * @date 2022/11/24<br> | |||||
| * 权限工具,用于动态权限检测 | |||||
| */ | |||||
| public class CheckPermissionUtils { | |||||
| private PermissionRequestFragment mPermissionRequestFragment; | |||||
| public CheckPermissionUtils(AppCompatActivity activity) { | |||||
| mPermissionRequestFragment = new PermissionRequestFragment(); | |||||
| WeakReference<AppCompatActivity> mActivity = new WeakReference<>(activity);; | |||||
| mPermissionRequestFragment.setActivity(mActivity.get()); | |||||
| } | |||||
| public void checkPermissions(OnPermissionListener listener) { | |||||
| try { | |||||
| if (mPermissionRequestFragment != null) { | |||||
| mPermissionRequestFragment.setOnPermissionListener(listener); | |||||
| mPermissionRequestFragment.initPermissions(); | |||||
| } | |||||
| } catch (Exception e) { | |||||
| e.printStackTrace(); | |||||
| } | |||||
| } | |||||
| public interface OnPermissionListener { | |||||
| void onPermissionsOk(); | |||||
| } | |||||
| public static class PermissionRequestFragment extends Fragment { | |||||
| private OnPermissionListener mOnPermissionListener; | |||||
| private AppCompatActivity mActivity; | |||||
| private Context mContext; | |||||
| /** | |||||
| * 需要申请的权限 | |||||
| */ | |||||
| private String[] LOCATION_PERMISSION = new String[]{Manifest.permission.ACCESS_FINE_LOCATION}; | |||||
| private String[] BLUETOOTH_PERMISSION = new String[]{Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_ADVERTISE, Manifest.permission.BLUETOOTH_CONNECT}; | |||||
| private ActivityResultLauncher<String[]> mActivityResultLauncher; | |||||
| private int mErrNumber; | |||||
| private FragmentManager mFragmentManager; | |||||
| public void setOnPermissionListener(OnPermissionListener onPermissionListener) { | |||||
| mOnPermissionListener = onPermissionListener; | |||||
| } | |||||
| private void setActivity(AppCompatActivity activity) { | |||||
| mActivity = activity; | |||||
| mContext = activity; | |||||
| } | |||||
| @Override | |||||
| public void onCreate(@Nullable Bundle savedInstanceState) { | |||||
| super.onCreate(savedInstanceState); | |||||
| initPermissions(); | |||||
| } | |||||
| protected void initPermissions() { | |||||
| // 创建Fragment | |||||
| if (!isAdded()) { | |||||
| if (mActivity != null) { | |||||
| mFragmentManager = mActivity.getSupportFragmentManager(); | |||||
| mFragmentManager.beginTransaction().add(0, this).commitAllowingStateLoss(); | |||||
| mFragmentManager.executePendingTransactions(); | |||||
| } | |||||
| return; | |||||
| } | |||||
| if (mContext==null||mActivity==null) { | |||||
| return; | |||||
| } | |||||
| if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { | |||||
| if (!checkBluetoothPermission()) { | |||||
| //没有权限,请求开启 | |||||
| requestBluetoothPermission(); | |||||
| } else { | |||||
| onPermissionsOk(); | |||||
| } | |||||
| } else { | |||||
| if (!checkBluetoothPermission()) { | |||||
| //没有权限,请求开启 | |||||
| requestLocationPermission(); | |||||
| } else { | |||||
| boolean bleStatus = isLocServiceEnable(mContext); | |||||
| if (!bleStatus) { | |||||
| //没有开启定位服务 | |||||
| HintDataDialogFragment.newInstance().setTitle("提示",0) | |||||
| .setContent("请求打开定位权限", true) | |||||
| .setOnDialogListener(new HintDataDialogFragment.onDialogListener() { | |||||
| @Override | |||||
| public void onCancelListener(View v) { | |||||
| } | |||||
| @Override | |||||
| public void onSucceedListener(View v) { | |||||
| startLocationActivity(); | |||||
| } | |||||
| }).show(mActivity.getSupportFragmentManager()); | |||||
| } else { | |||||
| onPermissionsOk(); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| private boolean checkBluetoothPermission() { | |||||
| if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { | |||||
| return true; | |||||
| } | |||||
| String[] perms; | |||||
| if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { | |||||
| perms = BLUETOOTH_PERMISSION; | |||||
| } else { | |||||
| perms = LOCATION_PERMISSION; | |||||
| } | |||||
| for (String perm : perms) { | |||||
| if (ContextCompat.checkSelfPermission(mContext, perm) != PackageManager.PERMISSION_GRANTED) { | |||||
| return false; | |||||
| } | |||||
| } | |||||
| return true; | |||||
| } | |||||
| /** | |||||
| * 申请蓝牙权限 | |||||
| */ | |||||
| private void requestBluetoothPermission() { | |||||
| mActivityResultLauncher = registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), new ActivityResultCallback<Map<String, Boolean>>() { | |||||
| @Override | |||||
| public void onActivityResult(Map<String, Boolean> result) { | |||||
| //权限状态 | |||||
| boolean permissionState = true; | |||||
| for (String s : BLUETOOTH_PERMISSION) { | |||||
| if (Boolean.FALSE.equals(result.get(s))) { | |||||
| permissionState = false; | |||||
| break; | |||||
| } | |||||
| } | |||||
| if (permissionState) { | |||||
| //请求的权限都有了 | |||||
| onPermissionsOk(); | |||||
| } else { | |||||
| //请求的权限有一个或者多个被拒绝 | |||||
| HintDataDialogFragment.newInstance().setTitle("提示",0).setContent("请求蓝牙权限", true) | |||||
| .setOnDialogListener(new HintDataDialogFragment.onDialogListener() { | |||||
| @Override | |||||
| public void onCancelListener(View v) { | |||||
| } | |||||
| @Override | |||||
| public void onSucceedListener(View v) { | |||||
| mErrNumber++; | |||||
| if (mErrNumber >= 3) { | |||||
| startUseSetActivity(mContext); | |||||
| } else { | |||||
| mActivityResultLauncher.launch(BLUETOOTH_PERMISSION); | |||||
| } | |||||
| } | |||||
| }).show(mActivity.getSupportFragmentManager()); | |||||
| } | |||||
| } | |||||
| }); | |||||
| mActivityResultLauncher.launch(BLUETOOTH_PERMISSION); | |||||
| } | |||||
| /** | |||||
| * 申请定位权限 | |||||
| */ | |||||
| private void requestLocationPermission() { | |||||
| mActivityResultLauncher = registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), result -> { | |||||
| //权限状态 | |||||
| boolean permissionState = true; | |||||
| for (String s : LOCATION_PERMISSION) { | |||||
| if (Boolean.FALSE.equals(result.get(s))) { | |||||
| permissionState = false; | |||||
| break; | |||||
| } | |||||
| } | |||||
| if (permissionState) { | |||||
| //请求的权限都有了 | |||||
| boolean bleStatus = isLocServiceEnable(mContext); | |||||
| if (!bleStatus) { | |||||
| //没有开启定位服务 | |||||
| HintDataDialogFragment.newInstance().setTitle("提示",0).setContent("请求位置权限", true) | |||||
| .setOnDialogListener(new HintDataDialogFragment.onDialogListener() { | |||||
| @Override | |||||
| public void onCancelListener(View v) { | |||||
| } | |||||
| @Override | |||||
| public void onSucceedListener(View v) { | |||||
| startLocationActivity(); | |||||
| } | |||||
| }).show(mActivity.getSupportFragmentManager()); | |||||
| } else { | |||||
| onPermissionsOk(); | |||||
| } | |||||
| } else { | |||||
| //请求的权限有一个或者多个被拒绝 | |||||
| HintDataDialogFragment.newInstance().setTitle("提示",0).setContent("请求定位权限", true) | |||||
| .setOnDialogListener(new HintDataDialogFragment.onDialogListener() { | |||||
| @Override | |||||
| public void onCancelListener(View v) { | |||||
| } | |||||
| @Override | |||||
| public void onSucceedListener(View v) { | |||||
| mErrNumber++; | |||||
| if (mErrNumber >= 3) { | |||||
| startUseSetActivity(mContext); | |||||
| } else { | |||||
| mActivityResultLauncher.launch(LOCATION_PERMISSION); | |||||
| } | |||||
| } | |||||
| }).show(mActivity.getSupportFragmentManager()); | |||||
| } | |||||
| }); | |||||
| mActivityResultLauncher.launch(LOCATION_PERMISSION); | |||||
| } | |||||
| /** | |||||
| * 启动去设置定位服务 | |||||
| */ | |||||
| protected void startLocationActivity() { | |||||
| Intent localIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); | |||||
| if (mActivity.getPackageManager().resolveActivity(localIntent, PackageManager.MATCH_DEFAULT_ONLY) != null) { | |||||
| registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() { | |||||
| @Override | |||||
| public void onActivityResult(ActivityResult result) { | |||||
| if (result.getResultCode() == Activity.RESULT_OK) { | |||||
| //定位服务页面返回 | |||||
| boolean bleStatus = isLocServiceEnable(mContext); | |||||
| if (!bleStatus) { | |||||
| //没有开启定位服务 | |||||
| HintDataDialogFragment.newInstance().setTitle("提示",0).setContent("请求位置权限", true) | |||||
| .setOnDialogListener(new HintDataDialogFragment.onDialogListener() { | |||||
| @Override | |||||
| public void onCancelListener(View v) { | |||||
| } | |||||
| @Override | |||||
| public void onSucceedListener(View v) { | |||||
| startLocationActivity(); | |||||
| } | |||||
| }).show(mActivity.getSupportFragmentManager()); | |||||
| } else { | |||||
| onPermissionsOk(); | |||||
| } | |||||
| } | |||||
| } | |||||
| }).launch(localIntent); | |||||
| } | |||||
| } | |||||
| /** | |||||
| * 权限ok | |||||
| */ | |||||
| private void onPermissionsOk() { | |||||
| if (!isDetached()&&!isRemoving()) { | |||||
| mFragmentManager.beginTransaction().detach(this).commit(); | |||||
| } | |||||
| if (mOnPermissionListener != null) { | |||||
| mOnPermissionListener.onPermissionsOk(); | |||||
| } | |||||
| } | |||||
| } | |||||
| /** | |||||
| * 进入应用设置界面 | |||||
| */ | |||||
| public static void startUseSetActivity(Context context) { | |||||
| Intent localIntent = new Intent(); | |||||
| localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); | |||||
| localIntent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS"); | |||||
| localIntent.setData(Uri.fromParts("package", context.getPackageName(), null)); | |||||
| context.startActivity(localIntent); | |||||
| } | |||||
| /** | |||||
| * 手机是否开启位置服务 | |||||
| */ | |||||
| public static boolean isLocServiceEnable(Context context) { | |||||
| LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); | |||||
| boolean gps = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); | |||||
| boolean network = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); | |||||
| return gps || network; | |||||
| } | |||||
| } | 
| android:layout_width="match_parent" | android:layout_width="match_parent" | ||||
| android:layout_height="wrap_content" | android:layout_height="wrap_content" | ||||
| android:layout_margin="10dp" | android:layout_margin="10dp" | ||||
| android:text="确定移除家人?" | |||||
| android:text="提示" | |||||
| android:padding="10dp" | android:padding="10dp" | ||||
| android:gravity="center" | android:gravity="center" | ||||
| android:textColor="@android:color/black" | android:textColor="@android:color/black" | ||||
| android:layout_width="match_parent" | android:layout_width="match_parent" | ||||
| android:layout_height="wrap_content" | android:layout_height="wrap_content" | ||||
| android:layout_margin="15dp" | android:layout_margin="15dp" | ||||
| android:text="移除后所有数据清空" | |||||
| android:text="" | |||||
| android:padding="8dp" | android:padding="8dp" | ||||
| android:gravity="center_vertical" | android:gravity="center_vertical" | ||||
| android:textSize="18dp" | android:textSize="18dp" | 
| } | } | ||||
| dependencies { | dependencies { | ||||
| classpath 'com.android.tools.build:gradle:3.4.0' | |||||
| classpath 'com.android.tools.build:gradle:4.1.3' | |||||
| classpath 'com.jakewharton:butterknife-gradle-plugin:10.2.0' | classpath 'com.jakewharton:butterknife-gradle-plugin:10.2.0' | ||||
| // NOTE: Do not place your application dependencies here; they belong | // NOTE: Do not place your application dependencies here; they belong | ||||
| // in the individual module build.gradle files | // in the individual module build.gradle files | 
| distributionPath=wrapper/dists | distributionPath=wrapper/dists | ||||
| zipStoreBase=GRADLE_USER_HOME | zipStoreBase=GRADLE_USER_HOME | ||||
| zipStorePath=wrapper/dists | zipStorePath=wrapper/dists | ||||
| distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip | |||||
| distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip |