使用Android 原生定位 ,并使用GEO进行城市定位
在Android开发中经常涉及到定位用户位置,以及获得当前设备的城市信息,其实Google已经给出了一套较好的解决方案,我们可以使用Android中的原生定位来完成这项任务,不需要像高德或者百度SDK一样配置繁琐的key,只需要专注于业务逻辑就行
在进行定位处理前,我们要确定是否向用户申请了定位权限
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
//请求对应权限REQUEST_LOCATION_CODE为自定义
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_LOCATION_CODE);
} else {
//执行需要权限的操作
doGetLocation();
}
使用下方的工具类进行定位
package com.phcbest.smartcitydemo.utils;
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
import androidx.core.app.ActivityCompat;
import com.phcbest.smartcitydemo.base.MyApplication;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
/**
* 经纬度获取
*
* @author peng
* 创建日期:2020/9/27 14
* 描述:
*/
public class GLocationUtils {
private static String locationProvider;
public interface CallBackLocation {
/**
* coolback
*/
void callBack(Location location);
}
public static void getLatAndLog(final CallBackLocation callBackLocation) {
// 不支持网络定位,需要在空旷的地方定位
final LocationManager locationManager = (LocationManager) MyApplication.getContext()
.getSystemService(Context.LOCATION_SERVICE);
List<String> providers = locationManager.getProviders(true);
//判断位置类型是什么
if (providers.contains(LocationManager.GPS_PROVIDER)) {
locationProvider = LocationManager.GPS_PROVIDER;
} else if (providers.contains(LocationManager.NETWORK_PROVIDER)) {
locationProvider = LocationManager.NETWORK_PROVIDER;
} else {
Toast.makeText(MyApplication.getContext(), "没有可用的位置提供器",
Toast.LENGTH_SHORT).show();
}
//获取位置
if (ActivityCompat.checkSelfPermission(
MyApplication.getContext(), Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(MyApplication.getContext(),
Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(MyApplication.getContext(), "您缺少权限",
Toast.LENGTH_SHORT).show();
return;
}
locationManager.requestLocationUpdates(locationProvider,
3000,
0,
new LocationListener() {
@Override
public void onLocationChanged(Location location) {
//解析地理位置
//拿到了第一次位置后就直接关掉
locationManager.removeUpdates(this);
Log.i("location", "backLocation: " + location.toString());
//回调返回location对象
callBackLocation.callBack(location);
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
});
}
//获取地址信息:城市、街道等信息
public static List<Address> getAddress(Location location) {
try {
if (location != null) {
Geocoder gc = new Geocoder(MyApplication.getContext(), Locale.getDefault());
List<Address> result = gc.getFromLocation(location.getLatitude(),
location.getLongitude(), 5);
Toast.makeText(MyApplication.getContext(),
"获取地址信息:" + result.toString(), Toast.LENGTH_LONG).show();
Log.v("TAG", "获取地址信息:" + result.toString());
return result;
}
} catch (Exception e) {
e.printStackTrace();
}
return new ArrayList<>();
}
}
调用相册获取图片,并转换为位图对象或byte集合
请求权限
//申请文件权限
if (ContextCompat.checkSelfPermission(UpSetActivity.this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
//请求对应权限
ActivityCompat.requestPermissions(UpSetActivity.this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_WRITE_CODE);
} else {
//执行需要权限的操作
doSelectPhoto();
}
权限请求回调
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_WRITE_CODE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
doSelectPhoto();
}
}
}
跳转拍照的intent
private void doSelectPhoto() {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(intent, 1);
}
打开图片选择界面的回调
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 1) {
//对uri进行操作
Uri uri = data.getData();
//获得内容解析器
ContentResolver contentResolver = MyApplication.getContext().getContentResolver();
//获得fd文件描述符
try {
ParcelFileDescriptor pfd = contentResolver.openFileDescriptor(uri, "r");
FileDescriptor fileDescriptor = pfd.getFileDescriptor();
//使用位图工厂将fd变为位图
Bitmap bitmap = BitmapFactory.decodeFileDescriptor(fileDescriptor);
mIvImage.setImageBitmap(bitmap);
//将文件转换为byte数组
FileInputStream fileInputStream = new FileInputStream(fileDescriptor);
bytes = new byte[fileInputStream.available()];
int read = fileInputStream.read(bytes);
Log.i(TAG, "onActivityResult: " + read);
pfd.close();
fileInputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
将图片上传到服务器
-
retrofit接口
@Multipart @POST("/work/covererror/postFile/{euid}") Observable<Map<String, String>> putFile(@Path("euid") String euid, @Part MultipartBody.Part file);
-
使用接口
RequestBody requestBody = RequestBody.create(MediaType.parse("image/*"), imageByte); MultipartBody.Part part = MultipartBody.Part.createFormData("file", uri2file(fileUri), requestBody); Observable<Map<String, String>> mapObservable = apiCoverError.putFile(recordsBean.getUid(), part); mapObservable.observeOn(AndroidSchedulers.mainThread()) .subscribeOn(Schedulers.io()) .subscribe(new Observer<Map<String, String>>() { @Override public void onSubscribe(@NonNull Disposable d) { } @Override public void onNext(@NonNull Map<String, String> stringStringMap) { Toast.makeText(getContext(), "上传成功", Toast.LENGTH_SHORT).show(); } @Override public void onError(@NonNull Throwable e) { Toast.makeText(getContext(), "上传失败", Toast.LENGTH_SHORT).show(); } @Override public void onComplete() { } });
` uri2file`方法是用于使用uri获得文件的名字
private String uri2file(Uri uri) { String image_path; Cursor cursor = getContext().getContentResolver().query(uri, null, null, null, null); if (cursor == null) { image_path = uri.getPath(); } else { int columnIndexOrThrow = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME); cursor.moveToFirst(); image_path = cursor.getString(columnIndexOrThrow); } Log.i(TAG, "uri2file: " + image_path); return image_path; }
imageByte
是将获得的文件转换为的byte数组