poi任务数据库保存

This commit is contained in:
wds 2021-06-15 19:02:10 +08:00
parent 24ed256033
commit 51086db7dc
26 changed files with 695 additions and 802 deletions

View File

@ -1,13 +1,14 @@
apply plugin: 'com.android.application'
android {
compileSdkVersion 30
buildToolsVersion "30.0.3"
ndkVersion '23.0.7123448'
compileSdkVersion 29
buildToolsVersion "29.0.0"
// ndkVersion '23.0.7123448'
defaultConfig {
applicationId "com.navinfo.outdoor"
minSdkVersion 23
targetSdkVersion 22
minSdkVersion 22
targetSdkVersion 30
versionCode 1
versionName "1.0"
@ -25,12 +26,6 @@ android {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
lintOptions {
checkReleaseBuilds false
// Or, if you prefer, you can continue to check for errors in release builds,
// but continue the build even when errors are found:
abortOnError false
}
}
//efs {
// //使
@ -112,6 +107,10 @@ dependencies {
//
implementation 'com.tencent.map.geolocation:TencentLocationSdk-openplatform:7.2.6'
// https://github.com/getActivity/XXPermissions
implementation 'com.github.getActivity:XXPermissions:11.5'
//room
def room_version = "2.2.0-alpha01"

View File

@ -2,7 +2,9 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.navinfo.outdoor">
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.READ_CALENDAR"/>
<uses-permission android:name="android.permission.WRITE_CALENDAR"/>
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
@ -26,6 +28,8 @@
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" /> <!-- 用于 log 日志 -->
<uses-feature
android:name="android.hardware.camera"
android:required="true" />
@ -34,19 +38,12 @@
android:name=".api.UserApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:requestLegacyExternalStorage="true"
android:label="@string/app_name"
android:networkSecurityConfig="@xml/network_security_config"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme.NoActionBar">
<activity android:name=".activity.camer.MyCamerActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|navigation"
android:launchMode="singleTop"
android:screenOrientation="portrait"
>
</activity>
<activity android:name=".activity.PictureActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|navigation"
@ -80,6 +77,7 @@
android:windowSoftInputMode="adjustPan" />
<activity android:name=".activity.ImageShowActivity" />
<activity android:name=".activity.UserActivity" />
<activity android:name=".activity.FilterActivity" />
</application>
</manifest>

View File

@ -0,0 +1,76 @@
package com.navinfo.outdoor.activity;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.constraintlayout.widget.ConstraintLayout;
import com.kongzue.dialog.interfaces.OnMenuItemClickListener;
import com.kongzue.dialog.v3.BottomMenu;
import com.navinfo.outdoor.R;
import com.navinfo.outdoor.base.BaseActivity;
/**
* 筛选的activity
*/
public class FilterActivity extends BaseActivity implements View.OnClickListener {
private ImageView ivFilter;
private TextView tvType;
private TextView tvDist;
private Button btnFilter;
@Override
protected int getLayout() {
return R.layout.activity_filter;
}
@Override
protected void initView() {
super.initView();
ConstraintLayout clDist = findViewById(R.id.cl_dist);
clDist.setOnClickListener(this::onClick);
ConstraintLayout clType = findViewById(R.id.cl_type);
clType.setOnClickListener(this::onClick);
tvType = findViewById(R.id.tv_type);
tvDist = findViewById(R.id.tv_dist);
btnFilter = findViewById(R.id.btn_filter);
btnFilter.setOnClickListener(this::onClick);
ivFilter = findViewById(R.id.iv_filter);
ivFilter.setOnClickListener(this);
}
@Override
protected void initData() {
super.initData();
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_filter:
case R.id.iv_filter:
finish();
break;
case R.id.cl_dist:
BottomMenu.show(FilterActivity.this, new String[]{"100米", "200米", "500米", "1000米", "2000米", "2500米", "5000米"}, new OnMenuItemClickListener() {
@Override
public void onClick(String text, int index) {
tvDist.setText(text);
}
});
break;
case R.id.cl_type:
BottomMenu.show(FilterActivity.this, new String[]{"poi", "道路", "充电站", "其他"}, new OnMenuItemClickListener() {
@Override
public void onClick(String text, int index) {
tvType.setText(text);
}
});
}
}
}

View File

@ -1,19 +1,26 @@
package com.navinfo.outdoor.activity;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PermissionGroupInfo;
import android.os.CountDownTimer;
import android.view.View;
import com.hjq.permissions.OnPermissionCallback;
import com.hjq.permissions.Permission;
import com.hjq.permissions.XXPermissions;
import com.kongzue.dialog.interfaces.OnDialogButtonClickListener;
import com.kongzue.dialog.util.BaseDialog;
import com.kongzue.dialog.v3.MessageDialog;
import com.navinfo.outdoor.R;
import com.navinfo.outdoor.api.Constant;
import com.navinfo.outdoor.base.BaseActivity;
import com.kongzue.dialog.util.DialogSettings;
import com.navinfo.outdoor.util.BackHandlerHelper;
import com.navinfo.outdoor.util.PermissionUtil;
import java.util.List;
/**
* 启动页
@ -28,48 +35,71 @@ public class MainActivity extends BaseActivity {
@Override
protected void initData() {
super.initData();
new CountDownTimer(3000, 1000) {
@Override
public void onTick(long l) {
}
@Override
public void onFinish() {
Intent intent = new Intent(MainActivity.this, LoginActivity.class);
startActivity(intent);
finish();
}
}.start();
//必须全局才可以改变样式
DialogSettings.style = (DialogSettings.STYLE.STYLE_KONGZUE);
DialogSettings.init();//初始化清空 BaseDialog 队列
}
private void initPermission() {
String[] pers = {
Manifest.permission.RECORD_AUDIO,
Manifest.permission.CAMERA,
Manifest.permission.INTERNET,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.READ_PHONE_STATE,
Manifest.permission.ACCESS_COARSE_LOCATION
};
XXPermissions.with(this)
// 申请安装包权限
//.permission(Permission.REQUEST_INSTALL_PACKAGES)
// 申请悬浮窗权限
//.permission(Permission.SYSTEM_ALERT_WINDOW)
// 申请通知栏权限
//.permission(Permission.NOTIFICATION_SERVICE)
// 申请系统设置权限
//.permission(Permission.WRITE_SETTINGS)
// 申请单个权限
.permission(Permission.RECORD_AUDIO)
// 申请多个权限
.permission(Permission.Group.CALENDAR)
// 申请读写外部存储卡
.permission(Permission.MANAGE_EXTERNAL_STORAGE)
// 申请相机权限
.permission(Permission.CAMERA)
// 位置权限
.permission(Permission.ACCESS_FINE_LOCATION)
// .permission(Permission.ACCESS_BACKGROUND_LOCATION)
.permission(Permission.ACCESS_COARSE_LOCATION)
//读写权限
.permission(Permission.READ_PHONE_STATE)
.request(new OnPermissionCallback() {
PermissionUtil.getInstance().checkPermission(this, pers, new Runnable() {
@Override
public void run() {
}
});
@Override
public void onGranted(List<String> permissions, boolean all) {
if (all) {
new CountDownTimer(3000, 1000) {
@Override
public void onTick(long l) {
}
@Override
public void onFinish() {
Intent intent = new Intent(MainActivity.this, LoginActivity.class);
startActivity(intent);
finish();
}
}.start();
}
}
@Override
public void onDenied(List<String> permissions, boolean never) {
if (never) {
DialogSettings.style = DialogSettings.STYLE.STYLE_KONGZUE;
MessageDialog.show(MainActivity.this, "提示", permissions.toString()+" 被永久拒绝授权请手动授权,", "确定").setOkButton(new OnDialogButtonClickListener() {
@Override
public boolean onClick(BaseDialog baseDialog, View v) {
XXPermissions.startPermissionActivity(MainActivity.this, permissions);
finish();
return false;
}
});
}
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable @org.jetbrains.annotations.Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
}
@Override
protected void initView() {
super.initView();

View File

@ -6,16 +6,10 @@ import androidx.annotation.Nullable;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.location.Location;
import android.media.Image;
import android.os.Looper;
import android.os.Message;
import android.util.DisplayMetrics;
@ -27,6 +21,7 @@ import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.Toast;
import com.navinfo.outdoor.R;
import com.navinfo.outdoor.api.Constant;
import com.navinfo.outdoor.base.BaseActivity;
@ -43,6 +38,7 @@ import com.otaliastudios.cameraview.PictureResult;
import com.otaliastudios.cameraview.VideoResult;
import com.otaliastudios.cameraview.controls.Engine;
import com.otaliastudios.cameraview.controls.Mode;
import com.otaliastudios.cameraview.size.AspectRatio;
import com.otaliastudios.cameraview.size.SizeSelectors;
import com.tencent.map.geolocation.TencentLocation;
@ -77,7 +73,8 @@ public class PictureActivity extends BaseActivity implements View.OnClickListene
private ImageButton capturePicture;
private long captureTime = 0;
private android.widget.Button btnSwitch;
private boolean USE_FRAME_PROCESSOR = false;
private boolean DECODE_BITMAP = false;
private TencentMap tencentMap;
private TencentLocationManager locationManager;
private TencentLocationRequest locationRequest;

View File

@ -1,430 +0,0 @@
package com.navinfo.outdoor.activity.camer
import android.animation.ValueAnimator
import android.content.Intent
import android.content.pm.ActivityInfo
import android.content.pm.PackageManager
import android.graphics.*
import android.os.Bundle
import android.view.View
import android.view.ViewGroup
import android.widget.ImageButton
import android.widget.ImageView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.navinfo.outdoor.R
import com.otaliastudios.cameraview.*
import com.otaliastudios.cameraview.controls.Facing
import com.otaliastudios.cameraview.controls.Mode
import com.otaliastudios.cameraview.controls.Preview
import com.otaliastudios.cameraview.filter.Filters
import com.otaliastudios.cameraview.frame.Frame
import com.otaliastudios.cameraview.frame.FrameProcessor
import com.tencent.map.geolocation.TencentLocationManager
import com.tencent.map.geolocation.TencentLocationRequest
import com.tencent.tencentmap.mapsdk.maps.TencentMap
import com.tencent.tencentmap.mapsdk.maps.model.MyLocationStyle
import kotlinx.android.synthetic.main.activity_camera.*
import kotlinx.android.synthetic.main.activity_my_camer.*
import kotlinx.android.synthetic.main.activity_my_camer.capturePicture
import kotlinx.android.synthetic.main.activity_my_camer.capturePictureSnapshot
import java.io.ByteArrayOutputStream
import java.io.File
class MyCamerActivity : AppCompatActivity(), View.OnClickListener, OptionView.Callback {
companion object {
private val LOG = CameraLogger.create("DemoApp")
private const val USE_FRAME_PROCESSOR = false
private const val DECODE_BITMAP = false
}
private var locationManager: TencentLocationManager? = null
private var locationRequest: TencentLocationRequest? = null
private val tencentMap: TencentMap? = null
private var locationStyle: MyLocationStyle? = null
private val camera: CameraView by lazy { findViewById(R.id.camera) }
private val edit : ImageButton by lazy { findViewById(R.id.edit) }
private val ivmap: ImageView by lazy { findViewById(R.id.iv_map) }
// private val ivmap: MapView by lazy { findViewById(R.id.iv_map) }
private val controlPanel: ViewGroup by lazy { findViewById(R.id.controls) }
private var captureTime: Long = 0
private var currentFilter = 0
private val allFilters = Filters.values()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_camera)
CameraLogger.setLogLevel(CameraLogger.LEVEL_VERBOSE)
camera.setLifecycleOwner(this)
camera.addCameraListener(Listener())
if (USE_FRAME_PROCESSOR) {
camera.addFrameProcessor(object : FrameProcessor {
private var lastTime = System.currentTimeMillis()
override fun process(frame: Frame) {
val newTime = frame.time
val delay = newTime - lastTime
lastTime = newTime
LOG.v("Frame delayMillis:", delay, "FPS:", 1000 / delay)
if (DECODE_BITMAP) {
if (frame.format == ImageFormat.NV21
&& frame.dataClass == ByteArray::class.java) {
val data = frame.getData<ByteArray>()
val yuvImage = YuvImage(data,
frame.format,
frame.size.width,
frame.size.height,
null)
val jpegStream = ByteArrayOutputStream()
yuvImage.compressToJpeg(Rect(0, 0,
frame.size.width,
frame.size.height), 100, jpegStream)
val jpegByteArray = jpegStream.toByteArray()
val bitmap = BitmapFactory.decodeByteArray(jpegByteArray,
0, jpegByteArray.size)
bitmap.toString()
}
}
}
})
}
edit.setOnClickListener(this)
capturePicture.setOnClickListener(this)
capturePictureSnapshot.setOnClickListener(this)
btn_switch.setOnClickListener(this)
// captureVideo.setOnClickListener(this)
// captureVideoSnapshot.setOnClickListener(this)
// toggleCamera.setOnClickListener(this)
val group = controlPanel.getChildAt(0) as ViewGroup
// val watermark = findViewById<View>( R.id.watermark)
val options: List<Option<*>> = listOf(
// Layout
Option.Width(), Option.Height(),
// Engine and preview
Option.Mode(), Option.Engine(), Option.Preview(),
// Some controls
Option.Flash(), Option.WhiteBalance(), Option.Hdr(),
Option.PictureMetering(), Option.PictureSnapshotMetering(),
Option.PictureFormat(),
// Video recording
Option.PreviewFrameRate(), Option.VideoCodec(), Option.Audio(), Option.AudioCodec(),
// Gestures
Option.Pinch(), Option.HorizontalScroll(), Option.VerticalScroll(),
Option.Tap(), Option.LongTap(),
// Watermarks
// Option.OverlayInPreview(watermark),
// Option.OverlayInPictureSnapshot(watermark),
// Option.OverlayInVideoSnapshot(watermark),
// Frame Processing
Option.FrameProcessingFormat(),
// Other
Option.Grid(), Option.GridColor(), Option.UseDeviceOrientation()
)
val dividers = listOf(
// Layout
false, true,
// Engine and preview
false, false, true,
// Some controls
false, false, false, false, false, true,
// Video recording
false, false, false, true,
// Gestures
false, false, false, false, true,
// Watermarks
// false, false, true,
// Frame Processing
true,
// Other
false, false, true
)
for (i in options.indices) {
val view = OptionView<Any>(this)
view.setOption(options[i] as Option<Any>, this)
view.setHasDivider(dividers[i])
group.addView(view, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
}
controlPanel.viewTreeObserver.addOnGlobalLayoutListener {
BottomSheetBehavior.from(controlPanel).state = BottomSheetBehavior.STATE_HIDDEN
}
// Animate the watermark just to show we record the animation in video snapshots
val animator = ValueAnimator.ofFloat(1f, 0.8f)
animator.duration = 300
animator.repeatCount = ValueAnimator.INFINITE
animator.repeatMode = ValueAnimator.REVERSE
// animator.addUpdateListener { animation ->
// val scale = animation.animatedValue as Float
// watermark.scaleX = scale
// watermark.scaleY = scale
// watermark.rotation = watermark.rotation + 2
// }
animator.start()
}
private fun message(content: String, important: Boolean) {
if (important) {
LOG.w(content)
Toast.makeText(this, content, Toast.LENGTH_LONG).show()
} else {
LOG.i(content)
Toast.makeText(this, content, Toast.LENGTH_SHORT).show()
}
}
private inner class Listener : CameraListener() {
override fun onCameraOpened(options: CameraOptions) {
val group = controlPanel.getChildAt(0) as ViewGroup
for (i in 0 until group.childCount) {
val view = group.getChildAt(i) as OptionView<*>
view.onCameraOpened(camera, options)
}
}
override fun onCameraError(exception: CameraException) {
super.onCameraError(exception)
message("Got CameraException #" + exception.reason, true)
}
override fun onPictureTaken(result: PictureResult) {
super.onPictureTaken(result)
if (camera.isTakingVideo) {
message("Captured while taking video. Size=" + result.size, false)
return
}
// This can happen if picture was taken with a gesture.
val callbackTime = System.currentTimeMillis()
if (captureTime == 0L) captureTime = callbackTime - 300
LOG.w("onPictureTaken called! Launching activity. Delay:", callbackTime - captureTime)
PicturePreviewActivity.pictureResult = result
val intent = Intent(this@MyCamerActivity, PicturePreviewActivity::class.java)
intent.putExtra("delay", callbackTime - captureTime)
startActivity(intent)
captureTime = 0
LOG.w("onPictureTaken called! Launched activity.")
}
override fun onVideoTaken(result: VideoResult) {
super.onVideoTaken(result)
LOG.w("onVideoTaken called! Launching activity.")
VideoPreviewActivity.videoResult = result
val intent = Intent(this@MyCamerActivity, VideoPreviewActivity::class.java)
startActivity(intent)
LOG.w("onVideoTaken called! Launched activity.")
}
override fun onVideoRecordingStart() {
super.onVideoRecordingStart()
LOG.w("onVideoRecordingStart!")
}
override fun onVideoRecordingEnd() {
super.onVideoRecordingEnd()
message("Video taken. Processing...", false)
LOG.w("onVideoRecordingEnd!")
}
override fun onExposureCorrectionChanged(newValue: Float, bounds: FloatArray, fingers: Array<PointF>?) {
super.onExposureCorrectionChanged(newValue, bounds, fingers)
message("Exposure correction:$newValue", false)
}
override fun onZoomChanged(newValue: Float, bounds: FloatArray, fingers: Array<PointF>?) {
super.onZoomChanged(newValue, bounds, fingers)
message("Zoom:$newValue", false)
}
}
override fun onClick(view: View) {
when (view.id) {
R.id.edit -> edit()
R.id.capturePicture -> capturePicture()
R.id.capturePictureSnapshot -> capturePictureSnapshot()
R.id.btn_switch -> btnSwitch()
// R.id.captureVideo -> captureVideo()
// R.id.captureVideoSnapshot -> captureVideoSnapshot()
// R.id.toggleCamera -> toggleCamera()
// R.id.changeFilter -> changeCurrentFilter()
}
}
override fun onBackPressed() {
val b = BottomSheetBehavior.from(controlPanel)
if (b.state != BottomSheetBehavior.STATE_HIDDEN) {
b.state = BottomSheetBehavior.STATE_HIDDEN
return
}
super.onBackPressed()
}
private fun edit() {
BottomSheetBehavior.from(controlPanel).state = BottomSheetBehavior.STATE_COLLAPSED
}
private fun capturePicture() {
if (camera.mode == Mode.VIDEO) return run {
message("Can't take HQ pictures while in VIDEO mode.", false)
}
if (camera.isTakingPicture) return
captureTime = System.currentTimeMillis()
message("Capturing picture...", false)
camera.takePicture()
}
private fun capturePictureSnapshot() {
if (camera.isTakingPicture) return
if (camera.preview != Preview.GL_SURFACE) return run {
message("Picture snapshots are only allowed with the GL_SURFACE preview.", true)
}
captureTime = System.currentTimeMillis()
message("Capturing picture snapshot...", false)
camera.takePictureSnapshot()
}
private fun captureVideo() {
if (camera.mode == Mode.PICTURE) return run {
message("Can't record HQ videos while in PICTURE mode.", false)
}
if (camera.isTakingPicture || camera.isTakingVideo) return
message("Recording for 5 seconds...", true)
camera.takeVideo(File(filesDir, "video.mp4"), 5000)
}
private fun captureVideoSnapshot() {
if (camera.isTakingVideo) return run {
message("Already taking video.", false)
}
if (camera.preview != Preview.GL_SURFACE) return run {
message("Video snapshots are only allowed with the GL_SURFACE preview.", true)
}
message("Recording snapshot for 5 seconds...", true)
camera.takeVideoSnapshot(File(filesDir, "video.mp4"), 5000)
}
private fun toggleCamera() {
if (camera.isTakingPicture || camera.isTakingVideo) return
when (camera.toggleFacing()) {
Facing.BACK -> message("Switched to back camera!", false)
Facing.FRONT -> message("Switched to front camera!", false)
}
}
//动态设置地图 相机切换的宽高
private fun btnSwitch() {
val layoutParams = ivmap.getLayoutParams()
val height = layoutParams.height
val width = layoutParams.width
val layoutParams1 = camera.getLayoutParams()
val height1 = layoutParams1.height
val width1 = layoutParams1.width
if (width > width1) {
layoutParams1.height = height
layoutParams1.width = width
camera.setLayoutParams(layoutParams1)
} else {
layoutParams.height = height1
layoutParams.width = width1
ivmap.setLayoutParams(layoutParams1)
}
}
private fun changeCurrentFilter() {
if (camera.preview != Preview.GL_SURFACE) return run {
message("Filters are supported only when preview is Preview.GL_SURFACE.", true)
}
if (currentFilter < allFilters.size - 1) {
currentFilter++
} else {
currentFilter = 0
}
val filter = allFilters[currentFilter]
message(filter.toString(), false)
// Normal behavior:
camera.filter = filter.newInstance()
// To test MultiFilter:
// DuotoneFilter duotone = new DuotoneFilter();
// duotone.setFirstColor(Color.RED);
// duotone.setSecondColor(Color.GREEN);
// camera.setFilter(new MultiFilter(duotone, filter.newInstance()));
}
override fun <T : Any> onValueChanged(option: Option<T>, value: T, name: String): Boolean {
if (option is Option.Width || option is Option.Height) {
val preview = camera.preview
val wrapContent = value as Int == ViewGroup.LayoutParams.WRAP_CONTENT
if (preview == Preview.SURFACE && !wrapContent) {
message("The SurfaceView preview does not support width or height changes. " +
"The view will act as WRAP_CONTENT by default.", true)
return false
}
}
option.set(camera, value)
BottomSheetBehavior.from(controlPanel).state = BottomSheetBehavior.STATE_HIDDEN
message("Changed " + option.name + " to " + name, false)
return true
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String?>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
val valid = grantResults.all { it == PackageManager.PERMISSION_GRANTED }
if (valid && !camera.isOpened) {
camera.open()
}
}
/**
* 定位的一些初始化设置
*/
// private fun initLocation() {
////用于访问腾讯定位服务的类, 周期性向客户端提供位置更新
// locationManager = TencentLocationManager.getInstance(getContext())
// //设置坐标系
// locationManager.setCoordinateType(TencentLocationManager.COORDINATE_TYPE_GCJ02)
// //创建定位请求
// locationRequest = TencentLocationRequest.create()
// //设置定位周期位置监听器回调周期为3s
// // locationRequest.setInterval(3000);
// //地图上设置定位数据源
// tencentMap.setLocationSource(this)
// //设置当前位置可见
// tencentMap.setMyLocationEnabled(true)
// //设置定位图标样式
// setLocMarkerStyle()
// // locationStyle = locationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE);
// tencentMap.setMyLocationStyle(locationStyle)
// }
/**
* 设置定位图标样式
*/
// private fun setLocMarkerStyle() {
// locationStyle = MyLocationStyle()
// //创建图标
// val bitmapDescriptor = BitmapDescriptorFactory.fromBitmap(getBitMap(R.drawable.location))
// locationStyle.icon(bitmapDescriptor)
// //设置定位圆形区域的边框宽度;
// locationStyle.strokeWidth(1)
// //设置圆区域的颜色
// // locationStyle.fillColor(R.color.colormap);
// // locationStyle.anchor(1000,2000);
// tencentMap!!.setMyLocationStyle(locationStyle)
// }
override fun onResume() {
/**
* 设置为横屏
*/
if (getRequestedOrientation() != ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
super.onResume()
}
}

View File

@ -16,6 +16,7 @@ public class Constant {
* 位置权限
*/
public static final String SET_LOCATION_PERMISSION = "请在“设置”中给予“TengXunMap”位置权限,否则当前功能将不可使用";
public static final String SET_LOCATION= "请在“设置”中给予权限否则当前功能将不可使用";
public static final String GET_ERR_MESSAGE1 = "设备缺少使用腾讯定位服务需要的基本条件";
@ -24,13 +25,13 @@ public class Constant {
public static final String BASE_FOLDER = SdkFolderCreate.getSDPath()+"/navinfoOutDoor";
// 保存图片的目录
public static final String PICTURE_FOLDER = BASE_FOLDER+"/picture";
public static final String PoiDao = BASE_FOLDER+"/poi";
public static final String POI_DAO = BASE_FOLDER+"/BaseDao/";
// 申请权限的RequestCode
public static final int PERMISSION_REQUEST_CODE = 0x100;
public static final int ROAD_PICTURE = 101;
//筛选
public static final int FILTER_CODE = 0x200;
@ -41,7 +42,6 @@ public class Constant {
public static final int POI_WORD_2 = 2;
public static final int POI_WORD_3 = 3;
/**
* 用户当前位置
*/

View File

@ -53,6 +53,8 @@ public abstract class BaseFragment extends Fragment implements FragmentBackHandl
protected <T extends View> T findViewById(@IdRes int id){
return getView().findViewById(id);
}
protected abstract int getLayout();
public void showLoadingDialog() {
alertDialog = new AlertDialog.Builder(getActivity()).create();

View File

@ -44,4 +44,14 @@ public class Info {
public void setT(String t) {
this.t = t;
}
@Override
public String toString() {
return "Info{" +
"photo='" + photo + '\'' +
", x='" + x + '\'' +
", y='" + y + '\'' +
", t='" + t + '\'' +
'}';
}
}

View File

@ -1,9 +1,13 @@
package com.navinfo.outdoor.fragment;
import android.Manifest;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.os.Build;
import android.os.Bundle;
import android.os.Message;
import android.util.Log;
@ -19,34 +23,45 @@ import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.hjq.permissions.OnPermissionCallback;
import com.hjq.permissions.Permission;
import com.hjq.permissions.XXPermissions;
import com.kongzue.dialog.interfaces.OnDialogButtonClickListener;
import com.kongzue.dialog.util.BaseDialog;
import com.kongzue.dialog.util.DialogSettings;
import com.kongzue.dialog.v3.MessageDialog;
import com.navinfo.outdoor.R;
import com.navinfo.outdoor.activity.FragmentManagement;
import com.navinfo.outdoor.activity.MainActivity;
import com.navinfo.outdoor.adapter.PoiRecycleAdapter;
import com.navinfo.outdoor.api.Constant;
import com.navinfo.outdoor.base.BaseDialogFragment;
import com.navinfo.outdoor.bean.Info;
import com.navinfo.outdoor.bean.PoiBean;
import com.navinfo.outdoor.room.PoiDao;
import com.navinfo.outdoor.room.PoiDatabase;
import com.navinfo.outdoor.room.PoiEntity;
import com.navinfo.outdoor.util.BackHandlerHelper;
import com.navinfo.outdoor.util.PhotoPathUtil;
import com.navinfo.outdoor.util.ToastUtil;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import static android.app.Activity.RESULT_OK;
/**
* 记录的Fragment
* 2021-5-25
@ -56,9 +71,9 @@ public class PoiFragment extends BaseDialogFragment implements View.OnClickListe
private EditText editDescribe;
private RelativeLayout rlPanorama, rlName, rlInternalPhotos, rlCard, rlElse;
private TextView tvExplain;
private ImageView ivPanorama,ivName,ivInternal,ivCard,ivElse;
private ImageView ivPanorama, ivName, ivInternal, ivCard, ivElse;
private TextView tvExamine;
private EditText editNameContent;
private EditText editNameContent, editSiteContent;
private RecyclerView recyclerPhone;
private PoiRecycleAdapter poiRecycleAdapter;
private ArrayList<String> phoneData;
@ -68,6 +83,10 @@ public class PoiFragment extends BaseDialogFragment implements View.OnClickListe
private Button btnUploading;
private PoiDatabase poiDatabase;
private PoiDao poiDao;
private String inode;
private List<Info> photoBean;
private boolean aBoolean = false;
private boolean bBoolean = false;
@Override
protected int getLayout() {
@ -77,11 +96,12 @@ public class PoiFragment extends BaseDialogFragment implements View.OnClickListe
@Override
public void onStart() {
super.onStart();
if(!EventBus.getDefault().isRegistered(this)){//加上判断
if (!EventBus.getDefault().isRegistered(this)) {//加上判断
EventBus.getDefault().register(this);
}
}
@Override
protected void initView() {
super.initView();
@ -92,10 +112,10 @@ public class PoiFragment extends BaseDialogFragment implements View.OnClickListe
checkBoxLife.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Message obtain = Message.obtain();
obtain.what= Constant.TREASURE_WORD_0;
obtain.obj=isChecked;
EventBus.getDefault().post(obtain);
Message obtain = Message.obtain();
obtain.what = Constant.TREASURE_WORD_0;
obtain.obj = isChecked;
EventBus.getDefault().post(obtain);
}
});
checkBoxRight.setVisibility(View.GONE);
@ -104,6 +124,7 @@ public class PoiFragment extends BaseDialogFragment implements View.OnClickListe
btnUploading = findViewById(R.id.btn_uploading);
btnUploading.setOnClickListener(this::onClick);
editNameContent = findViewById(R.id.tv_name_content);
editSiteContent = findViewById(R.id.tv_site_content);
tvExamine = findViewById(R.id.tv_examine);
tvExamine.setOnClickListener(this::onClick);
editDescribe = findViewById(R.id.edit_describe);
@ -126,10 +147,8 @@ public class PoiFragment extends BaseDialogFragment implements View.OnClickListe
rlElse.setOnClickListener(this::onClick);
recyclerPhone = findViewById(R.id.recycler_phone);
recyclerPhone.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerPhone.addItemDecoration(new DividerItemDecoration(getContext(),DividerItemDecoration.VERTICAL));
poiBeans = new ArrayList<>();//存储对象
phoneData = new ArrayList<>();//存储手机号
poiBeans.add(new PoiBean("电话*","1000000",R.drawable.icon_add_bg));
recyclerPhone.addItemDecoration(new DividerItemDecoration(getContext(), DividerItemDecoration.VERTICAL));
poiBeans.add(new PoiBean("电话*", "1000000", R.drawable.icon_add_bg));
poiRecycleAdapter = new PoiRecycleAdapter(getContext(), poiBeans);
recyclerPhone.setAdapter(poiRecycleAdapter);
poiRecycleAdapter.setInitPoiClick(new PoiRecycleAdapter.initPoiClick() {
@ -139,9 +158,9 @@ public class PoiFragment extends BaseDialogFragment implements View.OnClickListe
poiRecycleAdapter.addData(new PoiBean("", "100000", R.drawable.icon_del_bg));
} else {
poiRecycleAdapter.removeData(aInt);
if (phoneData.size()>0){
if (phoneData.size() > 0) {
phoneData.remove(aInt);
Log.d("TAG", "initView: "+phoneData.toString());
Log.d("TAG", "initView: " + phoneData.toString());
}
@ -150,22 +169,29 @@ public class PoiFragment extends BaseDialogFragment implements View.OnClickListe
});
poiRecycleAdapter.setInitPoiEditClick(new PoiRecycleAdapter.initPoiEditClick() {
@Override
public void item(String a,String data, int aInt) {
if (data.length()==11){
if (a!=null){
phoneData.add(aInt,a+","+data);
}else {
phoneData.add(aInt,data);
public void item(String a, String data, int aInt) {
if (data.length() == 11) {
if (a != null) {
phoneData.add(aInt, a + "," + data);
} else {
phoneData.add(aInt, data);
}
Log.d("TAG", "initView: "+phoneData.toString());
Log.d("TAG", "initView: " + phoneData.toString());
}
}
});
}
@Override
protected void initData() {
super.initData();
//存储对象
poiBeans = new ArrayList<>();
//存储手机号
phoneData = new ArrayList<>();
//存储图片地址
photoBean = new ArrayList<>();
}
@Override
@ -173,20 +199,6 @@ public class PoiFragment extends BaseDialogFragment implements View.OnClickListe
super.onResume();
}
// //主界面获取焦点
// private void getFocus() {
// getView().setFocusableInTouchMode(true);
// getView().requestFocus();
// getView().setOnKeyListener(new View.OnKeyListener() {
// @Override
// public boolean onKey(View v, int keyCode, KeyEvent event) {
// if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK) {
//
// }
// return true;
// }
// });
// }
@Override
public void onPause() {
@ -202,30 +214,117 @@ public class PoiFragment extends BaseDialogFragment implements View.OnClickListe
@Subscribe
public void onEvent(Message data) {
if (data.what==Constant.POI_WORD_2){
String s = data.obj.toString();
Toast.makeText(getContext(), s, Toast.LENGTH_SHORT).show();
if (data.what == Constant.POI_WORD_2) {
inode = data.obj.toString();
Toast.makeText(getContext(), inode, Toast.LENGTH_SHORT).show();
}
}
@Override
public void onClick(View v) {
switch (v.getId()){
switch (v.getId()) {
case R.id.btn_save_local:
XXPermissions.with(this)
//读写权限
.permission(Permission.READ_EXTERNAL_STORAGE)
.request(new OnPermissionCallback() {
@Override
public void onGranted(List<String> permissions, boolean all) {
if (all) {
//保存数据库
PoiEntity poiEntity = new PoiEntity();
String name = editNameContent.getText().toString().trim();//名称
if (name == null || name.equals("")) {
Toast.makeText(getActivity(), "请输入poi 名称", Toast.LENGTH_SHORT).show();
return;
} else {
poiEntity.setName(name);
}
String site = editSiteContent.getText().toString().trim();
if (site == null || site.equals("")) {
Toast.makeText(getActivity(), "请输入poi 地址", Toast.LENGTH_SHORT).show();
return;
} else {
poiEntity.setAddress(site);
}
if (inode == null || inode.equals("")) {
Toast.makeText(getActivity(), "请确定点位", Toast.LENGTH_SHORT).show();
return;
} else {
String[] split = inode.split(",");
poiEntity.setX(split[0]);
poiEntity.setY(split[1]);
}
String describe = editDescribe.getText().toString().trim();
if (describe == null || describe.equals("")) {
Toast.makeText(getActivity(), "请输入任务描述", Toast.LENGTH_SHORT).show();
return;
} else {
poiEntity.setDescribe(describe);
}
if (phoneData.size() <= 0) {
Toast.makeText(getActivity(), "请输入手机号", Toast.LENGTH_SHORT).show();
return;
} else {
poiEntity.setPhoto(phoneData.get(0));
}
if (photoBean.size() < 0) {
Toast.makeText(getActivity(), "请拍照", Toast.LENGTH_SHORT).show();
return;
} else {
poiEntity.setPhotoInfo(photoBean);
}
if (!aBoolean) {
Toast.makeText(getActivity(), "请拍照 全景图", Toast.LENGTH_SHORT).show();
return;
}
if (!bBoolean) {
Toast.makeText(getActivity(), "请拍照 名称", Toast.LENGTH_SHORT).show();
return;
}
new Thread(new Runnable() {
@Override
public void run() {
poiDao.insertPoiEntity(poiEntity);
}
}).start();
Message obtains = Message.obtain();
obtains.what = Constant.TREASURE_FRAGMENT;
obtains.obj = false;
} else {
Toast.makeText(getActivity(), "没有申请权限,请手动申请", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onDenied(List<String> permissions, boolean never) {
if (never) {
Toast.makeText(getActivity(), "被永久拒绝授权,请手动授予权限", Toast.LENGTH_SHORT).show();
// 如果是被永久拒绝就跳转到应用权限系统设置页面
XXPermissions.startPermissionActivity(getActivity(), permissions);
}
}
});
break;
case R.id.btn_uploading:
new Thread(new Runnable() {
@Override
public void run() {
List<PoiEntity> allPoi = poiDao.getAllPoi();
Log.d("TAG", "run: "+allPoi.toString());
}
}).start();
Message obtain = Message.obtain();
obtain.what= Constant.TREASURE_FRAGMENT;
obtain.obj=false;
obtain.what = Constant.TREASURE_FRAGMENT;
obtain.obj = false;
EventBus.getDefault().post(obtain);
PoiEntity poiEntity = new PoiEntity();
poiDao.insertPoiEntity(poiEntity);
break;
case R.id.tv_examine:
Toast.makeText(getContext(), editNameContent.getText().toString(), Toast.LENGTH_SHORT).show();
break;
case R.id.tv_explain:
Intent intentExplain = new Intent(getActivity(), FragmentManagement.class);
intentExplain.putExtra("tag",7);
intentExplain.putExtra("tag", 7);
startActivity(intentExplain);
break;
case R.id.rl_panorama:
@ -250,15 +349,17 @@ public class PoiFragment extends BaseDialogFragment implements View.OnClickListe
break;
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 101 && resultCode == RESULT_OK) {
Bundle extras = data.getExtras();//从Intent中获取附加值
Bitmap bitmap = (Bitmap) extras.get("data");//从附加值中获取返回的图像
int height= bitmap.getHeight();
int width= bitmap.getWidth();
if (height>width){
int height = bitmap.getHeight();
int width = bitmap.getWidth();
if (height > width) {
DialogSettings.style = DialogSettings.STYLE.STYLE_KONGZUE;
MessageDialog.show((AppCompatActivity) getContext(), "提示", "请重新拍照,要求横屏拍照", "确定").setOkButton(new OnDialogButtonClickListener() {
@Override
@ -268,16 +369,21 @@ public class PoiFragment extends BaseDialogFragment implements View.OnClickListe
return false;
}
});
}else {
} else {
String takePhotoPath = PhotoPathUtil.getTakePhotoPath(data);
Info info = new Info();
info.setPhoto(takePhotoPath);
photoBean.add(info);
ivPanorama.setImageBitmap(bitmap);//显示图像
aBoolean = true;
}
} else if (requestCode == 102 && resultCode == RESULT_OK) {
Bundle extras = data.getExtras();//从Intent中获取附加值
Bitmap bitmap = (Bitmap) extras.get("data");//从附加值中获取返回的图像
int height= bitmap.getHeight();
int width= bitmap.getWidth();
if (height>width){
int height = bitmap.getHeight();
int width = bitmap.getWidth();
if (height > width) {
DialogSettings.style = DialogSettings.STYLE.STYLE_KONGZUE;
MessageDialog.show((AppCompatActivity) getContext(), "提示", "请重新拍照,要求横屏拍照", "确定").setOkButton(new OnDialogButtonClickListener() {
@Override
@ -287,16 +393,21 @@ public class PoiFragment extends BaseDialogFragment implements View.OnClickListe
return false;
}
});
}else {
} else {
String takePhotoPath = PhotoPathUtil.getTakePhotoPath(data);
Info info = new Info();
info.setPhoto(takePhotoPath);
photoBean.add(info);
ivName.setImageBitmap(bitmap);//显示图像
bBoolean = true;
}
}else if (requestCode == 103 && resultCode == RESULT_OK) {
} else if (requestCode == 103 && resultCode == RESULT_OK) {
Bundle extras = data.getExtras();//从Intent中获取附加值
Bitmap bitmap = (Bitmap) extras.get("data");//从附加值中获取返回的图像
int height= bitmap.getHeight();
int width= bitmap.getWidth();
if (height>width){
int height = bitmap.getHeight();
int width = bitmap.getWidth();
if (height > width) {
DialogSettings.style = DialogSettings.STYLE.STYLE_KONGZUE;
MessageDialog.show((AppCompatActivity) getContext(), "提示", "请重新拍照,要求横屏拍照", "确定").setOkButton(new OnDialogButtonClickListener() {
@Override
@ -306,15 +417,19 @@ public class PoiFragment extends BaseDialogFragment implements View.OnClickListe
return false;
}
});
}else {
} else {
String takePhotoPath = PhotoPathUtil.getTakePhotoPath(data);
Info info = new Info();
info.setPhoto(takePhotoPath);
photoBean.add(info);
ivInternal.setImageBitmap(bitmap);//显示图像
}
}else if (requestCode == 104 && resultCode == RESULT_OK) {
} else if (requestCode == 104 && resultCode == RESULT_OK) {
Bundle extras = data.getExtras();//从Intent中获取附加值
Bitmap bitmap = (Bitmap) extras.get("data");//从附加值中获取返回的图像
int height= bitmap.getHeight();
int width= bitmap.getWidth();
if (height>width){
int height = bitmap.getHeight();
int width = bitmap.getWidth();
if (height > width) {
DialogSettings.style = DialogSettings.STYLE.STYLE_KONGZUE;
MessageDialog.show((AppCompatActivity) getContext(), "提示", "请重新拍照,要求横屏拍照", "确定").setOkButton(new OnDialogButtonClickListener() {
@Override
@ -324,15 +439,19 @@ public class PoiFragment extends BaseDialogFragment implements View.OnClickListe
return false;
}
});
}else {
} else {
String takePhotoPath = PhotoPathUtil.getTakePhotoPath(data);
Info info = new Info();
info.setPhoto(takePhotoPath);
photoBean.add(info);
ivCard.setImageBitmap(bitmap);//显示图像
}
}else if (requestCode == 105 && resultCode == RESULT_OK) {
} else if (requestCode == 105 && resultCode == RESULT_OK) {
Bundle extras = data.getExtras();//从Intent中获取附加值
Bitmap bitmap = (Bitmap) extras.get("data");//从附加值中获取返回的图像
int height= bitmap.getHeight();
int width= bitmap.getWidth();
if (height>width){
int height = bitmap.getHeight();
int width = bitmap.getWidth();
if (height > width) {
DialogSettings.style = DialogSettings.STYLE.STYLE_KONGZUE;
MessageDialog.show((AppCompatActivity) getContext(), "提示", "请重新拍照,要求横屏拍照", "确定").setOkButton(new OnDialogButtonClickListener() {
@Override
@ -342,12 +461,17 @@ public class PoiFragment extends BaseDialogFragment implements View.OnClickListe
return false;
}
});
}else {
} else {
String takePhotoPath = PhotoPathUtil.getTakePhotoPath(data);
Info info = new Info();
info.setPhoto(takePhotoPath);
photoBean.add(info);
ivElse.setImageBitmap(bitmap);//显示图像
}
}
}
public static int readPictureDegree(String path) {
int degree = 0;
try {

View File

@ -30,18 +30,22 @@ import androidx.core.content.ContextCompat;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import com.hjq.permissions.OnPermissionCallback;
import com.hjq.permissions.Permission;
import com.hjq.permissions.XXPermissions;
import com.kongzue.dialog.interfaces.OnBackClickListener;
import com.kongzue.dialog.interfaces.OnShowListener;
import com.kongzue.dialog.util.BaseDialog;
import com.kongzue.dialog.util.DialogSettings;
import com.kongzue.dialog.v3.ShareDialog;
import com.navinfo.outdoor.R;
import com.navinfo.outdoor.activity.FilterActivity;
import com.navinfo.outdoor.activity.FragmentManagement;
import com.navinfo.outdoor.activity.MainActivity;
import com.navinfo.outdoor.api.Constant;
import com.navinfo.outdoor.base.BaseFragment;
import com.navinfo.outdoor.util.BackHandlerHelper;
import com.navinfo.outdoor.util.NetWorkUtils;
import com.navinfo.outdoor.util.PermissionUtil;
import com.navinfo.outdoor.util.ToastUtil;
import com.sothree.slidinguppanel.SlidingUpPanelLayout;
import com.tencent.map.geolocation.TencentLocation;
@ -113,6 +117,7 @@ public class TreasureFragment extends BaseFragment implements View.OnClickListen
ivRefish = findViewById(R.id.iv_refrish);
ivRefish.setOnClickListener(this::onClick);
ivFilter = findViewById(R.id.iv_filter);
ivFilter.setOnClickListener(this::onClick);
ivSubmit = findViewById(R.id.iv_submit);
ivSubmit.setOnClickListener(this::onClick);
treasureMap = (MapView) findViewById(R.id.treasure_map);
@ -229,7 +234,7 @@ public class TreasureFragment extends BaseFragment implements View.OnClickListen
Constant.markerLongitude = latLng.longitude;
Message obtain = Message.obtain();
obtain.what=Constant.POI_WORD_2;
obtain.obj=Constant.markerLatitude + " " + Constant.markerLongitude;
obtain.obj=Constant.markerLatitude +","+ Constant.markerLongitude;
EventBus.getDefault().post(obtain);
}
@ -237,7 +242,6 @@ public class TreasureFragment extends BaseFragment implements View.OnClickListen
}
}
/**
* 设置定位图标样式
*/
@ -391,7 +395,9 @@ public class TreasureFragment extends BaseFragment implements View.OnClickListen
}
}).setTitle(title);
break;
case R.id.iv_refrish:
case R.id.iv_filter:
Intent intent = new Intent(getActivity(), FilterActivity.class);
startActivityForResult(intent,Constant.FILTER_CODE);
break;
}
}
@ -411,6 +417,7 @@ public class TreasureFragment extends BaseFragment implements View.OnClickListen
* 检查所需权限
*/
private void checkMyLocation() {
// 1.判断是否拥有定位的权限
// 1.1 拥有权限进行相应操作
// 1.2 没有权限申请权限
@ -418,21 +425,30 @@ public class TreasureFragment extends BaseFragment implements View.OnClickListen
// 1.2.1.1 用户给予权限进行相应操作
// 1.2.1.2 用户没有给予权限 作出相应提示
// 1.2.2 某些5.0权限的手机执行相应操作
String[] permission = {
Manifest.permission.ACCESS_COARSE_LOCATION
};
PermissionUtil.getInstance().checkPermission((AppCompatActivity) getActivity(), permission, new Runnable() {
@Override
public void run() {
if (ContextCompat.checkSelfPermission(getContext(), permission[0]) == PackageManager.PERMISSION_GRANTED){
//建立定位
initLocation();
}else {
PermissionUtil.getInstance().showPermissionSettingDialog((AppCompatActivity) getActivity());
}
}
});
XXPermissions.with(this)
.permission(Permission.ACCESS_COARSE_LOCATION)
.request(new OnPermissionCallback() {
@Override
public void onGranted(List<String> permissions, boolean all) {
if (all) {
//建立定位
initLocation();
} else {
Toast.makeText(getActivity(), "申请权限失败", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onDenied(List<String> permissions, boolean never) {
if (never) {
Toast.makeText(getActivity(), "被永久拒绝授权,请手动授予定位权限", Toast.LENGTH_SHORT).show();
// 如果是被永久拒绝就跳转到应用权限系统设置页面
XXPermissions.startPermissionActivity(getActivity(), permissions);
}
}
});
}

View File

@ -1,7 +1,6 @@
package com.navinfo.outdoor.http;
/**
* Created by yzb_android on 2019/12/30.
* 作用
*/

View File

@ -4,7 +4,6 @@ import com.lzy.okgo.model.Response;
import com.lzy.okgo.request.base.Request;
/**
* Created by yzb_android on 2021 5 25
* 作用网络请求前显示一个dialog,请求结束后取消loading
*/

View File

@ -11,7 +11,6 @@ import okhttp3.ResponseBody;
/**
* Created by yzb_android on 2019/12/30.
* 作用将返回过来的json字符串转换为实体类
*/

View File

@ -15,7 +15,6 @@ import java.io.File;
import java.util.ArrayList;
/**
* Created by yzb_android on 2019/12/30.
* 作用OKGO帮助类-建造者模式
*/

View File

@ -9,6 +9,8 @@ import androidx.room.RoomDatabase;
import androidx.room.migration.Migration;
import androidx.sqlite.db.SupportSQLiteDatabase;
import com.navinfo.outdoor.api.Constant;
@Database(entities = {PoiEntity.class}, version = 1, exportSchema = false)
public abstract class PoiDatabase extends RoomDatabase {
private static final String DB_NAME = "navinfo.db";
@ -20,9 +22,8 @@ public abstract class PoiDatabase extends RoomDatabase {
}
return instance;
}
private static PoiDatabase create(final Context context) {
return Room.databaseBuilder(context, PoiDatabase.class, DB_NAME)
return Room.databaseBuilder(context, PoiDatabase.class, Constant.POI_DAO+DB_NAME)
.addMigrations(migration_1_2)
.addMigrations(migration_2_3)
.addMigrations(migration_3_4)

View File

@ -169,4 +169,27 @@ public class PoiEntity {
public void setDetail(String detail) {
this.detail = detail;
}
@Override
public String toString() {
return "PoiEntity{" +
"id=" + id +
", pid=" + pid +
", taskId=" + taskId +
", userId=" + userId +
", createTime='" + createTime + '\'' +
", name='" + name + '\'' +
", describe='" + describe + '\'' +
", address='" + address + '\'' +
", telPhone='" + telPhone + '\'' +
", memo='" + memo + '\'' +
", precision=" + precision +
", photo='" + photo + '\'' +
", photoInfo=" + photoInfo +
", existence=" + existence +
", x='" + x + '\'' +
", y='" + y + '\'' +
", detail='" + detail + '\'' +
'}';
}
}

View File

@ -9,9 +9,6 @@ import java.io.InputStreamReader;
/**
* <读取Json文件的工具类>
*
* @author: 小嵩
* @date: 2017/3/16 16:22
*/

View File

@ -6,8 +6,6 @@ import android.net.NetworkInfo;
/**
* 项目名称网络工具类
* 创建人 mwb
* 创建时间2018/9/3 8:57
*/
public class NetWorkUtils {
/**

View File

@ -1,176 +0,0 @@
package com.navinfo.outdoor.util;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.provider.Settings;
import android.util.Log;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
/**
* 动态申请权限工具类
*/
public class PermissionUtil {
private final int PERMISSION_REQUEST_CODE = 100;
private final int PERMISSION_SETTING_CODE = 101;
private AlertDialog permissionExplainDialog = null;
private AlertDialog permissionSettingDialog = null;
private PermissionUtil() {
}
public static PermissionUtil getInstance() {
return PermissionUtilHolder.instance;
}
private static class PermissionUtilHolder {
private static final PermissionUtil instance = new PermissionUtil();
}
/**
* 第一步检查权限
*
* @param activity 上下文
* @param permissions 权限数组
* @param callBack 线程
*/
public void checkPermission(AppCompatActivity activity, String[] permissions, Runnable callBack) {
boolean allGranted = true;
for (String permission : permissions) {
int result = ContextCompat.checkSelfPermission(activity, permission);
Log.d("检查权限:" + permission, "结果:" + result);
// 有权限: PackageManager.PERMISSION_GRANTED
// 无权限: PackageManager.PERMISSION_DENIED
if (result != PackageManager.PERMISSION_GRANTED) {// 有权限
allGranted = false;
// Toast.makeText(activity, "拥有" + permission + "权限", Toast.LENGTH_SHORT).show();
}
}
if (allGranted) {// 拥有全部权限
callBack.run();
} else {// 申请权限
startRequestPermission(activity, permissions);
}
}
/**
* 第二步如果用户之前拒绝过展示需要权限的提示框否则的话直接请求相关权限
*
* @param activity 上下文
* @param permissions 权限数组
*/
private void startRequestPermission(AppCompatActivity activity, String[] permissions) {
for (String permission : permissions) {
/**
* shouldShowRequestPermissionRationale
* 如果应用之前请求过该权限但用户拒绝了该方法就会返回true
*
* 如果用户之前拒绝了权限请求并且勾选了权限请求对话框的不再询问该方法会返回false
* 如果设备策略禁止该应用获得该权限也会返回false
*/
if (ActivityCompat.shouldShowRequestPermissionRationale(activity, permission)) {
// 向用户显示一个解释要以异步非阻塞的方式
// 该线程将等待用户响应等用户看完解释后再继续尝试请求权限
Log.v("tag", "showPermissionExplainDialog()");
showPermissionExplainDialog(activity, permissions);
} else {
/**
* 当你的应用调用requestPermissions()方法时系统会向用户展示一个标准对话框
* 你的应用不能修改也不能自定义这个对话框如果你需要给用户一些额外的信息和解释你就需要在
* 调用requestPermissions()之前像上面一样" 解释为什么应用需要这些权限"
*/
Log.v("tag", "requestPermission");
requestPermission(activity, permissions);
}
}
}
/**
* 不需要向用户解释了我们可以直接请求该权限
* 第三步. 请求权限
*
* @param activity 上下文
* @param permissions 权限数组
*/
private void requestPermission(AppCompatActivity activity, String[] permissions) {
ActivityCompat.requestPermissions(activity, permissions, PERMISSION_REQUEST_CODE);
}
/**
* 当用户之前拒绝过展示一个对话框解释为什么需要此权限
*
* @param activity 上下文
* @param permissions 权限数组
*/
private void showPermissionExplainDialog(final AppCompatActivity activity, final String[] permissions) {
if (permissionExplainDialog == null) {
permissionExplainDialog = new AlertDialog.Builder(activity).setTitle("权限申请").setMessage("您刚才拒绝了相关权限,但是现在应用需要这个权限," +
"点击确定申请权限,点击取消将无法使用该功能")
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
requestPermission(activity, permissions);
dialog.cancel();
}
})
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
}).create();
permissionExplainDialog.show();
}
}
/**
* 最后一步当用户拒绝并且勾选了不在提示那么只能引导用户去设置页面打开权限
*
* @param activity 上下文
*/
public void showPermissionSettingDialog(final AppCompatActivity activity) {
if (permissionSettingDialog == null) {
permissionSettingDialog = new AlertDialog.Builder(activity)
.setTitle("权限设置")
.setMessage("您刚才拒绝了相关的权限,请到应用设置页面更改应用的权限")
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", activity.getPackageName(), null);
intent.setData(uri);
activity.startActivityForResult(intent, PERMISSION_SETTING_CODE);
dialog.cancel();
}
})
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
}).create();
permissionSettingDialog.show();
}
}
}

View File

@ -0,0 +1,73 @@
package com.navinfo.outdoor.util;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import com.navinfo.outdoor.api.Constant;
import java.io.File;
import java.io.FileOutputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
/**
* 获取图片的真实路径
*/
public class PhotoPathUtil {
public static String getTakePhotoPath(Intent data) {
Bitmap photo = null;
Uri uri = data.getData();
if (uri != null) {
photo = BitmapFactory.decodeFile(uri.getPath());
}
if (photo == null) {
Bundle bundle = data.getExtras();
if (bundle != null) {
photo = (Bitmap) bundle.get("data");
} else {
return "";
}
}
FileOutputStream fileOutputStream = null;
try {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
String format = formatter.format(calendar.getTime());
//文件
File file = new File(Constant.PICTURE_FOLDER, format + ".jpg");
/***打开文件输出流*/
fileOutputStream = new FileOutputStream(file);
// 生成图片文件
/**
* 对应Bitmap的compress(Bitmap.CompressFormat format, int quality, OutputStream stream)方法中第一个参数
* CompressFormat类是个枚举有三个取值JPEGPNG和WEBP其中
* PNG是无损格式忽略质量设置会导致方法中的第二个参数压缩质量失效
* JPEG不解释
* 而WEBP格式是Google新推出的据官方资料称在质量相同的情况下WEBP格式图像的体积要比JPEG格式图像小40%
*/
photo.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream);
/***相片的完整路径*/
return file.getPath();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fileOutputStream != null) {
try {
fileOutputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
return "";
}
}

View File

@ -1,7 +0,0 @@
package model;
import com.navinfo.outdoor.base.BaseModel;
public class CapacityEvaluationModel extends BaseModel {
}

View File

@ -1,10 +0,0 @@
package presenter;
import com.navinfo.outdoor.base.BasePresenter;
public class CapacityEvaluationPresenter extends BasePresenter {
@Override
protected void initModel() {
}
}

View File

@ -0,0 +1,169 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/rl_filter"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#1BA5F1"
android:orientation="horizontal"
android:paddingTop="@dimen/top_pind_sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="@+id/iv_filter"
android:layout_width="wrap_content"
android:layout_height="45dp"
android:layout_alignParentLeft="true"
android:layout_marginLeft="15dp"
android:src="@drawable/icon_arrow" />
<TextView
android:id="@+id/tv_filter"
style="@style/text_style_toolbar_title"
android:layout_width="wrap_content"
android:layout_toRightOf="@id/iv_find_task"
android:text="任务筛选" />
</LinearLayout>
<LinearLayout
android:id="@+id/ll_filter"
android:layout_width="match_parent"
android:layout_height="100dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/rl_filter">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_type"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@drawable/road_shape">
<TextView
style="@style/text_style"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:text="类型"
app:layout_constraintBottom_toTopOf="@+id/tv_type"
app:layout_constraintStart_toStartOf="@+id/tv_type" />
<TextView
android:id="@+id/tv_type"
style="@style/main_about_text_style"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:text="全部"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.65" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="20dp"
android:background="@drawable/ic_baseline_arrow_forward"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_dist"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@drawable/road_shape">
<TextView
style="@style/text_style"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:text="距离"
app:layout_constraintBottom_toTopOf="@+id/tv_dist"
app:layout_constraintStart_toStartOf="@+id/tv_dist" />
<TextView
android:id="@+id/tv_dist"
style="@style/main_about_text_style"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:text="50000米"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.65" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="20dp"
android:background="@drawable/ic_baseline_arrow_forward"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
<RelativeLayout
android:id="@+id/rl_filters"
android:layout_width="match_parent"
android:layout_height="80dp"
android:background="@drawable/road_shape"
android:layout_marginTop="80dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/ll_filter">
<TextView
android:id="@+id/tv_result"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_margin="20dp"
android:text="筛选结果"
android:textSize="20sp" />
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/tv_result"
android:layout_centerVertical="true"
android:textStyle="italic"
android:text="共101条"/>
<Button
android:id="@+id/btn_filter"
android:layout_width="80dp"
android:layout_height="40dp"
android:layout_marginRight="20dp"
style="@style/user_style"
android:text="地图显示"
android:gravity="center"
android:textColor="@color/white"
android:layout_centerVertical="true"
android:layout_alignParentRight="true"
android:textSize="15sp"
/>
</RelativeLayout>
<com.jcodecraeer.xrecyclerview.XRecyclerView
android:id="@+id/recycler_filter"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/rl_filters" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -9,26 +9,26 @@
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="35dp"
android:layout_marginTop="70dp"
android:text="Welcome"
android:textColor="@color/colorWhite"
android:textSize="30sp"
app:layout_constraintBottom_toTopOf="@+id/tv_login_deck"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_login_deck"
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="35dp"
android:text="欢迎来到地图寻宝"
android:textColor="@color/colorWhite"
android:textSize="35sp"
app:layout_constraintBottom_toTopOf="@+id/login_name"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_title" />
@ -38,23 +38,24 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="25dp"
android:layout_marginBottom="9dp"
android:text="用户名"
app:layout_constraintBottom_toTopOf="@+id/et_login_name"
app:layout_constraintLeft_toLeftOf="@id/tv_login_deck"
app:layout_constraintTop_toBottomOf="@id/tv_login_deck" />
<EditText
android:id="@+id/et_login_name"
android:layout_width="300dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:hint=" ID/手机号"
android:paddingBottom="20dp"
android:layout_marginRight="35dp"
android:layout_marginLeft="35dp"
android:textColorHint="@color/colorTransparent"
android:textCursorDrawable="@drawable/text_color"
android:theme="@style/MyEditText"
app:layout_constraintLeft_toLeftOf="@id/login_name"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@+id/login_name"
app:layout_constraintTop_toBottomOf="@id/login_name" />
@ -70,15 +71,19 @@
<EditText
android:id="@+id/et_login_paw"
android:layout_width="300dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginRight="35dp"
android:layout_marginLeft="35dp"
android:layout_marginTop="8dp"
android:hint=" 请输入密码"
android:paddingBottom="15dp"
android:textColorHint="@color/colorTransparent"
android:textCursorDrawable="@drawable/text_color"
android:theme="@style/MyEditText"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintLeft_toLeftOf="@id/login_paw"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/login_paw" />
<ImageView
@ -91,6 +96,7 @@
app:layout_constraintTop_toBottomOf="@id/et_login_paw" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="2dp"
@ -126,11 +132,10 @@
style="@style/login_style"
android:layout_width="300dp"
android:layout_height="50dp"
android:layout_marginTop="20dp"
android:layout_marginBottom="266dp"
android:gravity="center"
android:text="登录"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="@id/iv_login_check"
app:layout_constraintTop_toBottomOf="@id/tv_forget_paw" />
android:layout_marginTop="30dp"
app:layout_constraintEnd_toEndOf="@+id/et_login_paw"
app:layout_constraintStart_toStartOf="@+id/et_login_paw"
app:layout_constraintTop_toBottomOf="@+id/textView" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -57,7 +57,9 @@
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/road_bg">