修改兼容性,解决sdk版本无法使用相机和权限校验问题

This commit is contained in:
qiji4215 2023-04-25 14:54:25 +08:00
parent 2a6dad3ac0
commit 9fb85862db
15 changed files with 277 additions and 27 deletions

View File

@ -12,12 +12,16 @@ android {
defaultConfig { defaultConfig {
applicationId "com.navinfo.omqs" applicationId "com.navinfo.omqs"
minSdk 26 minSdk 21
targetSdk 33 targetSdk 21
versionCode 1 versionCode 1
versionName "1.0" versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
multiDexEnabled true
ndk {
abiFilters "armeabi-v7a", "armeabi", "mips"
}
} }
buildTypes { buildTypes {
@ -37,7 +41,18 @@ android {
viewBinding true viewBinding true
dataBinding true dataBinding true
} }
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
debug.setRoot('build-types/debug')
release.setRoot('build-types/release')
}
//ok了
lintOptions {
checkReleaseBuilds false
abortOnError false
}
} }
@ -46,7 +61,6 @@ dependencies {
implementation project(':collect-library') implementation project(':collect-library')
testImplementation 'junit:junit:4.13.2' testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5' androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
@ -72,8 +86,8 @@ dependencies {
kapt "androidx.room:room-ktx:2.5.1" kapt "androidx.room:room-ktx:2.5.1"
//excel word等文件 //excel word等文件
implementation 'org.apache.poi:poi:5.2.3' implementation 'org.apache.poi:poi:4.0.0'
implementation 'org.apache.poi:poi-ooxml:5.2.3' implementation 'org.apache.poi:poi-ooxml:4.0.0'
// spatialite文件 // spatialite文件
implementation 'com.github.sevar83:android-spatialite:2.0.1' implementation 'com.github.sevar83:android-spatialite:2.0.1'

View File

@ -0,0 +1,204 @@
/**
*
*/
package com.navinfo.omqs.ui.activity;
import android.Manifest;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.view.KeyEvent;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
/**
* 继承了Activity实现Android6.0的运行时权限检测
* 需要进行运行时权限检测的Activity可以继承这个类
*/
public class CheckPermissionsActivity extends BaseActivity {
//是否需要检测后台定位权限设置为true时如果用户没有给予后台定位权限会弹窗提示
private boolean needCheckBackLocation = false;
//如果设置了target > 28需要增加这个权限否则不会弹出"始终允许"这个选择框
private static String BACKGROUND_LOCATION_PERMISSION = "android.permission.ACCESS_BACKGROUND_LOCATION";
/**
* 需要进行检测的权限数组
*/
protected String[] needPermissions = {
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE,
};
private static final int PERMISSON_REQUESTCODE = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(Build.VERSION.SDK_INT > 28
&& getApplicationContext().getApplicationInfo().targetSdkVersion > 28) {
needPermissions = new String[] {
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE,
BACKGROUND_LOCATION_PERMISSION
};
}
}
/**
* 判断是否需要检测防止不停的弹框
*/
private boolean isNeedCheck = true;
@Override
protected void onResume() {
super.onResume();
if (Build.VERSION.SDK_INT >= 23
&& getApplicationInfo().targetSdkVersion >= 23) {
if (isNeedCheck) {
checkPermissions(needPermissions);
}
}
}
/**
*
* @param permissions
*
*/
private void checkPermissions(String... permissions) {
try {
if (Build.VERSION.SDK_INT >= 23
&& getApplicationInfo().targetSdkVersion >= 23) {
List<String> needRequestPermissonList = findDeniedPermissions(permissions);
if (null != needRequestPermissonList
&& needRequestPermissonList.size() > 0) {
String[] array = needRequestPermissonList.toArray(new String[needRequestPermissonList.size()]);
Method method = getClass().getMethod("requestPermissions", new Class[]{String[].class,
int.class});
method.invoke(this, array, PERMISSON_REQUESTCODE);
}
}
} catch (Throwable e) {
}
}
/**
* 获取权限集中需要申请权限的列表
*
* @param permissions
*
*/
private List<String> findDeniedPermissions(String[] permissions) {
List<String> needRequestPermissonList = new ArrayList<String>();
if (Build.VERSION.SDK_INT >= 23
&& getApplicationInfo().targetSdkVersion >= 23){
try {
for (String perm : permissions) {
Method checkSelfMethod = getClass().getMethod("checkSelfPermission", String.class);
Method shouldShowRequestPermissionRationaleMethod = getClass().getMethod("shouldShowRequestPermissionRationale",
String.class);
if ((Integer)checkSelfMethod.invoke(this, perm) != PackageManager.PERMISSION_GRANTED
|| (Boolean)shouldShowRequestPermissionRationaleMethod.invoke(this, perm)) {
if(!needCheckBackLocation
&& BACKGROUND_LOCATION_PERMISSION.equals(perm)) {
continue;
}
needRequestPermissonList.add(perm);
}
}
} catch (Throwable e) {
}
}
return needRequestPermissonList;
}
/**
* 检测是否所有的权限都已经授权
*
*/
private boolean verifyPermissions(int[] grantResults) {
for (int result : grantResults) {
if (result != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
return true;
}
@TargetApi(23)
public void onRequestPermissionsResult(int requestCode,
String[] permissions, int[] paramArrayOfInt) {
if (requestCode == PERMISSON_REQUESTCODE) {
if (!verifyPermissions(paramArrayOfInt)) {
showMissingPermissionDialog();
isNeedCheck = false;
}
}
}
/**
* 显示提示信息
*
*/
private void showMissingPermissionDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("提示");
builder.setMessage("当前应用缺少必要权限。\\n\\n请点击\\\"设置\\\"-\\\"权限\\\"-打开所需权限。");
// 拒绝, 退出应用
builder.setNegativeButton("取消",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
});
builder.setPositiveButton("设置",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
startAppSettings();
}
});
builder.setCancelable(false);
builder.show();
}
/**
* 启动应用的设置
*
*/
private void startAppSettings() {
Intent intent = new Intent(
Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setData(Uri.parse("package:" + getPackageName()));
startActivity(intent);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_BACK){
this.finish();
return true;
}
return super.onKeyDown(keyCode, event);
}
}

View File

@ -33,7 +33,7 @@ open abstract class PermissionsActivity : BaseActivity() {
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.Q) { if (Build.VERSION.SDK_INT == Build.VERSION_CODES.Q) {
// permissionList.add(Permission.ACCESS_BACKGROUND_LOCATION) // permissionList.add(Permission.ACCESS_BACKGROUND_LOCATION)
} }
XXPermissions.with(this) /* XXPermissions.with(this)
// 申请单个权限 // 申请单个权限
.permission(permissionList) .permission(permissionList)
// 设置权限请求拦截器(局部设置) // 设置权限请求拦截器(局部设置)
@ -73,7 +73,7 @@ open abstract class PermissionsActivity : BaseActivity() {
onPermissionsDenied() onPermissionsDenied()
} }
} }
}) })*/
} }
/** /**

View File

@ -11,6 +11,7 @@ import androidx.lifecycle.Observer
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.navinfo.omqs.R import com.navinfo.omqs.R
import com.navinfo.omqs.databinding.ActivityLoginBinding import com.navinfo.omqs.databinding.ActivityLoginBinding
import com.navinfo.omqs.ui.activity.CheckPermissionsActivity
import com.navinfo.omqs.ui.activity.PermissionsActivity import com.navinfo.omqs.ui.activity.PermissionsActivity
import com.navinfo.omqs.ui.activity.map.MainActivity import com.navinfo.omqs.ui.activity.map.MainActivity
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
@ -20,7 +21,7 @@ import dagger.hilt.android.AndroidEntryPoint
*/ */
@AndroidEntryPoint @AndroidEntryPoint
class LoginActivity : PermissionsActivity() { class LoginActivity : CheckPermissionsActivity() {
private lateinit var binding: ActivityLoginBinding private lateinit var binding: ActivityLoginBinding
private val viewModel by viewModels<LoginViewModel>() private val viewModel by viewModels<LoginViewModel>()
@ -97,15 +98,6 @@ class LoginActivity : PermissionsActivity() {
} }
} }
//进应用根本不调用,待查
override fun onPermissionsGranted() {
Log.e("jingo", "调用了吗")
}
override fun onPermissionsDenied() {
}
override fun onDestroy() { override fun onDestroy() {
super.onDestroy() super.onDestroy()
} }

View File

@ -28,6 +28,7 @@ class QsRecordListAdapter(
private val context: Context private val context: Context
) : BaseRecyclerViewAdapter<QsRecordBean>() { ) : BaseRecyclerViewAdapter<QsRecordBean>() {
private var itemClickListener: IKotlinItemClickListener? = null
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder {
val viewBinding = val viewBinding =
@ -46,6 +47,10 @@ class QsRecordListAdapter(
val qsRecordBean = data[position] val qsRecordBean = data[position]
//tag 方便onclick里拿到数据 //tag 方便onclick里拿到数据
holder.tag = qsRecordBean.id.toString() holder.tag = qsRecordBean.id.toString()
// 点击事件
holder.itemView.setOnClickListener {
itemClickListener!!.onItemClickListener(position)
}
changeViews(binding, qsRecordBean) changeViews(binding, qsRecordBean)
} }
@ -59,6 +64,16 @@ class QsRecordListAdapter(
override fun getItemViewRes(position: Int): Int { override fun getItemViewRes(position: Int): Int {
return R.layout.adapter_qs_record_list return R.layout.adapter_qs_record_list
} }
// 提供set方法
fun setOnKotlinItemClickListener(itemClickListener: IKotlinItemClickListener) {
this.itemClickListener = itemClickListener
}
//自定义接口
interface IKotlinItemClickListener {
fun onItemClickListener(position: Int)
}
} }

View File

@ -5,13 +5,17 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.viewModels import androidx.fragment.app.viewModels
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView.VERTICAL import androidx.recyclerview.widget.RecyclerView.VERTICAL
import com.blankj.utilcode.util.ToastUtils
import com.navinfo.omqs.R import com.navinfo.omqs.R
import com.navinfo.omqs.databinding.FragmentQsRecordListBinding import com.navinfo.omqs.databinding.FragmentQsRecordListBinding
import com.navinfo.omqs.ui.activity.map.MainActivity
import com.navinfo.omqs.ui.fragment.BaseFragment import com.navinfo.omqs.ui.fragment.BaseFragment
import com.navinfo.omqs.ui.fragment.tasklist.QsRecordListAdapter import com.navinfo.omqs.ui.fragment.tasklist.QsRecordListAdapter
import com.navinfo.omqs.ui.other.BaseToast.makeText
import com.navinfo.omqs.ui.widget.RecycleViewDivider import com.navinfo.omqs.ui.widget.RecycleViewDivider
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import org.apache.poi.xwpf.usermodel.VerticalAlign import org.apache.poi.xwpf.usermodel.VerticalAlign
@ -51,6 +55,18 @@ class QsRecordListFragment : BaseFragment(){
itemDecoration.setDrawable(resources.getDrawable(R.drawable.separator)) itemDecoration.setDrawable(resources.getDrawable(R.drawable.separator))
binding.qsRecyclerview.addItemDecoration(itemDecoration) binding.qsRecyclerview.addItemDecoration(itemDecoration)
viewModel.getList(requireContext()) viewModel.getList(requireContext())
// itemClick
adapter!!.setOnKotlinItemClickListener(object : QsRecordListAdapter.IKotlinItemClickListener {
override fun onItemClickListener(position: Int) {
viewModel.onItemClickListener(activity as MainActivity,position)
findNavController().popBackStack()
}
})
}
override fun onResume() {
super.onResume()
viewModel.getList(requireContext())
} }
override fun onDestroyView() { override fun onDestroyView() {

View File

@ -1,11 +1,16 @@
package com.navinfo.omqs.ui.fragment.qsrecordlist package com.navinfo.omqs.ui.fragment.qsrecordlist
import android.content.Context import android.content.Context
import android.os.Bundle
import android.util.Log import android.util.Log
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import androidx.navigation.findNavController
import com.blankj.utilcode.util.ToastUtils
import com.navinfo.collect.library.data.entity.QsRecordBean import com.navinfo.collect.library.data.entity.QsRecordBean
import com.navinfo.omqs.R
import com.navinfo.omqs.ui.activity.map.MainActivity
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
import io.realm.Realm import io.realm.Realm
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@ -27,4 +32,11 @@ class QsRecordListViewModel @Inject constructor(
} }
} }
fun onItemClickListener(activity: MainActivity, position :Int){
val naviController = activity.findNavController(R.id.main_activity_right_fragment)
val bundle = Bundle()
bundle.putString("QsId", liveDataQSList.value?.get(position)?.id)
naviController.navigate(R.id.EvaluationResultFragment, bundle)
ToastUtils.showLong(liveDataQSList.value?.get(position)?.classType)
}
} }

View File

@ -28,9 +28,7 @@ android {
arguments = ["room.schemaLocation": "$projectDir/schemas".toString()] arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
} }
} }
ndk {
abiFilters "armeabi", "armeabi-v7a", "arm64-v8a"
}
} }
buildTypes { buildTypes {
@ -60,7 +58,6 @@ dependencies {
api fileTree(dir: 'libs', include: ['*.jar', '*.aar']) api fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
api files('libs/BaiduLBS_Android.jar') api files('libs/BaiduLBS_Android.jar')
//
api 'androidx.core:core-ktx:1.9.0' api 'androidx.core:core-ktx:1.9.0'
api 'androidx.appcompat:appcompat:1.6.1' api 'androidx.appcompat:appcompat:1.6.1'
api 'com.google.android.material:material:1.8.0' api 'com.google.android.material:material:1.8.0'

View File

@ -75,7 +75,7 @@ class LocationLayerHandler(context: AppCompatActivity, mapView: NIMapView) : Bas
//可选默认gcj02设置返回的定位结果坐标系如果配合百度地图使用建议设置为bd09ll; //可选默认gcj02设置返回的定位结果坐标系如果配合百度地图使用建议设置为bd09ll;
locationOption.setCoorType("gcj02") locationOption.setCoorType("gcj02")
//可选默认0即仅定位一次设置发起连续定位请求的间隔需要大于等于1000ms才是有效的 //可选默认0即仅定位一次设置发起连续定位请求的间隔需要大于等于1000ms才是有效的
locationOption.setScanSpan(1000) locationOption.setScanSpan(1200)
//可选,设置是否需要地址信息,默认不需要 //可选,设置是否需要地址信息,默认不需要
locationOption.setIsNeedAddress(false) locationOption.setIsNeedAddress(false)
//可选,设置是否需要地址描述 //可选,设置是否需要地址描述
@ -97,11 +97,11 @@ class LocationLayerHandler(context: AppCompatActivity, mapView: NIMapView) : Bas
//可选默认false设置定位时是否需要海拔信息默认不需要除基础定位版本都可用 //可选默认false设置定位时是否需要海拔信息默认不需要除基础定位版本都可用
locationOption.setIsNeedAltitude(true) locationOption.setIsNeedAltitude(true)
//设置打开自动回调位置模式该开关打开后期间只要定位SDK检测到位置变化就会主动回调给开发者该模式下开发者无需再关心定位间隔是多少定位SDK本身发现位置变化就会及时回调给开发者 //设置打开自动回调位置模式该开关打开后期间只要定位SDK检测到位置变化就会主动回调给开发者该模式下开发者无需再关心定位间隔是多少定位SDK本身发现位置变化就会及时回调给开发者
// locationOption.setOpenAutoNotifyMode() locationOption.setOpenAutoNotifyMode()
//设置打开自动回调位置模式该开关打开后期间只要定位SDK检测到位置变化就会主动回调给开发者 //设置打开自动回调位置模式该开关打开后期间只要定位SDK检测到位置变化就会主动回调给开发者
locationOption.setOpenAutoNotifyMode( /* locationOption.setOpenAutoNotifyMode(
5, 1, LocationClientOption.LOC_SENSITIVITY_HIGHT 5, 1, LocationClientOption.LOC_SENSITIVITY_HIGHT
) )*/
//需将配置好的LocationClientOption对象通过setLocOption方法传递给LocationClient对象使用 //需将配置好的LocationClientOption对象通过setLocOption方法传递给LocationClient对象使用
locationClient.locOption = locationOption locationClient.locOption = locationOption
} catch (e: Throwable) { } catch (e: Throwable) {