Browse Source

适配android12

master
陈福行 2 years ago
parent
commit
2f47d8d370

+ 8
- 9
app/build.gradle View File

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'

+ 26
- 9
app/src/main/AndroidManifest.xml View File

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" />

+ 55
- 156
app/src/main/java/aicare/net/cn/sdk/ailinksdkdemoandroid/ShowBleActivity.java View File

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);
}

} }

+ 6
- 6
app/src/main/java/aicare/net/cn/sdk/ailinksdkdemoandroid/WeightScaleWifiBleActivity.java View File





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;

+ 8
- 104
app/src/main/java/aicare/net/cn/sdk/ailinksdkdemoandroid/base/BleAppBaseActivity.java View File

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();
}
} }
} }

+ 25
- 26
app/src/main/java/aicare/net/cn/sdk/ailinksdkdemoandroid/dialog/HintDataDialogFragment.java View File



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;
} }

+ 340
- 0
app/src/main/java/aicare/net/cn/sdk/ailinksdkdemoandroid/utils/CheckPermissionUtils.java View File

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;
}

}

+ 2
- 2
app/src/main/res/layout/dialog_hint_data.xml View File

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"

+ 1
- 1
build.gradle View File

} }
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

+ 1
- 1
gradle/wrapper/gradle-wrapper.properties View File

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

Loading…
Cancel
Save