添加手动输入定位信息,并且显示位置功能。
This commit is contained in:
parent
1113503a23
commit
5e66647495
@ -1,8 +1,8 @@
|
||||
#Created by .winboll/winboll_app_build.gradle
|
||||
#Fri Mar 21 03:15:13 GMT 2025
|
||||
#Fri Mar 21 09:01:41 GMT 2025
|
||||
stageCount=0
|
||||
libraryProject=
|
||||
baseVersion=1.0
|
||||
publishVersion=1.0.0
|
||||
buildCount=281
|
||||
buildCount=355
|
||||
baseBetaVersion=1.0.1
|
||||
|
@ -41,6 +41,7 @@ import java.util.List;
|
||||
import cc.winboll.studio.positions.activities.AbsActivity;
|
||||
import android.widget.Toolbar;
|
||||
import cc.winboll.studio.libappbase.utils.ToastUtils;
|
||||
import androidx.fragment.app.FragmentStatePagerAdapter;
|
||||
|
||||
final public class MainActivity extends AbsActivity implements IWinBollActivity, ViewPager.OnPageChangeListener, View.OnClickListener {
|
||||
|
||||
@ -50,8 +51,15 @@ final public class MainActivity extends AbsActivity implements IWinBollActivity,
|
||||
public static final int REQUEST_ABOUT_ACTIVITY = 1;
|
||||
|
||||
public static final String ACTION_SOS = "cc.winboll.studio.libappbase.WinBoll.ACTION_SOS";
|
||||
|
||||
|
||||
// 创建Fragment列表和标题列表
|
||||
List<Fragment> fragmentList = new ArrayList<>();
|
||||
List<String> tabTitleList = new ArrayList<>();
|
||||
|
||||
TXMSFragment mTXMSFragment;
|
||||
PositionsFragment mPositionsFragment;
|
||||
TasksFragment mTasksFragment;
|
||||
LogFragment mLogFragment;
|
||||
LogView mLogView;
|
||||
Toolbar mToolbar;
|
||||
CheckBox cbMainService;
|
||||
@ -97,13 +105,13 @@ final public class MainActivity extends AbsActivity implements IWinBollActivity,
|
||||
setContentView(R.layout.activity_main);
|
||||
|
||||
// 初始化工具栏
|
||||
mToolbar = findViewById(R.id.toolbar);
|
||||
setActionBar(mToolbar);
|
||||
// if (isEnableDisplayHomeAsUp()) {
|
||||
// // 显示后退按钮
|
||||
// getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
// }
|
||||
getActionBar().setTitle("");
|
||||
// mToolbar = findViewById(R.id.toolbar);
|
||||
// setActionBar(mToolbar);
|
||||
//// if (isEnableDisplayHomeAsUp()) {
|
||||
//// // 显示后退按钮
|
||||
//// getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
//// }
|
||||
// getActionBar().setTitle("");
|
||||
|
||||
// 初始化地图视图
|
||||
// 创建Fragment实例
|
||||
@ -117,18 +125,23 @@ final public class MainActivity extends AbsActivity implements IWinBollActivity,
|
||||
tabLayout = findViewById(R.id.tabLayout);
|
||||
viewPager = findViewById(R.id.viewPager);
|
||||
|
||||
// 创建Fragment列表和标题列表
|
||||
List<Fragment> fragmentList = new ArrayList<>();
|
||||
List<String> tabTitleList = new ArrayList<>();
|
||||
fragmentList.add(new PositionsFragment());
|
||||
fragmentList.add(new TasksFragment());
|
||||
fragmentList.add(new LogFragment());
|
||||
mPositionsFragment = new PositionsFragment();
|
||||
fragmentList.add(mPositionsFragment);
|
||||
tabTitleList.add("位置");
|
||||
|
||||
mTasksFragment = new TasksFragment();
|
||||
fragmentList.add(mTasksFragment);
|
||||
tabTitleList.add("任务");
|
||||
|
||||
|
||||
mLogFragment = new LogFragment();
|
||||
fragmentList.add(mLogFragment);
|
||||
tabTitleList.add("日志");
|
||||
|
||||
|
||||
|
||||
// 设置ViewPager的适配器
|
||||
MyPagerAdapter adapter = new MyPagerAdapter(getSupportFragmentManager(), fragmentList, tabTitleList);
|
||||
MyPagerAdapter adapter = new MyPagerAdapter(getSupportFragmentManager());
|
||||
viewPager.setAdapter(adapter);
|
||||
|
||||
// 关联TabLayout和ViewPager
|
||||
@ -137,25 +150,23 @@ final public class MainActivity extends AbsActivity implements IWinBollActivity,
|
||||
|
||||
|
||||
// ViewPager的适配器
|
||||
private class MyPagerAdapter extends FragmentPagerAdapter {
|
||||
public class MyPagerAdapter extends FragmentStatePagerAdapter {
|
||||
private static final int PAGE_COUNT = 3;
|
||||
|
||||
private List<Fragment> fragmentList;
|
||||
private List<String> tabTitleList;
|
||||
|
||||
public MyPagerAdapter(FragmentManager fm, List<Fragment> fragmentList, List<String> tabTitleList) {
|
||||
super(fm);
|
||||
this.fragmentList = fragmentList;
|
||||
this.tabTitleList = tabTitleList;
|
||||
public MyPagerAdapter(FragmentManager fm) {
|
||||
super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fragment getItem(int position) {
|
||||
// 根据position返回不同的Fragment
|
||||
return fragmentList.get(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return fragmentList.size();
|
||||
// 返回页面总数
|
||||
return PAGE_COUNT;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -163,6 +174,7 @@ final public class MainActivity extends AbsActivity implements IWinBollActivity,
|
||||
return tabTitleList.get(position);
|
||||
}
|
||||
}
|
||||
|
||||
//初始化view,即显示的图片
|
||||
// void initViewPager() {
|
||||
// pagerAdapter = new MyPagerAdapter(getSupportFragmentManager());
|
||||
@ -261,7 +273,8 @@ final public class MainActivity extends AbsActivity implements IWinBollActivity,
|
||||
|
||||
@Override
|
||||
public Toolbar initToolBar() {
|
||||
return findViewById(R.id.toolbar);
|
||||
return null;
|
||||
//return findViewById(R.id.toolbar);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -43,8 +43,8 @@ public class LogFragment extends Fragment {
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_log, container, false);
|
||||
LogView logView = view.findViewById(R.id.logview);
|
||||
logView.start();
|
||||
// LogView logView = view.findViewById(R.id.logview);
|
||||
// logView.start();
|
||||
return view;
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,9 @@ import android.location.Location;
|
||||
import android.location.LocationListener;
|
||||
import android.location.LocationManager;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.os.SystemClock;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
@ -23,21 +26,32 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import cc.winboll.studio.libappbase.LogUtils;
|
||||
import cc.winboll.studio.libappbase.utils.ToastUtils;
|
||||
import cc.winboll.studio.positions.R;
|
||||
import cc.winboll.studio.positions.models.PostionFixModel;
|
||||
import cc.winboll.studio.positions.utils.LocationFusion;
|
||||
import cc.winboll.studio.positions.utils.TimeUtils;
|
||||
import android.widget.EditText;
|
||||
|
||||
public class PositionsFragment extends Fragment {
|
||||
|
||||
public static final String TAG = "ContactsFragment";
|
||||
public static final String TAG = "PositionsFragment";
|
||||
|
||||
private static final String ARG_PAGE = "ARG_PAGE";
|
||||
private int mPage;
|
||||
|
||||
private LocationManager locationManager;
|
||||
|
||||
private TextView tvWifiLocation;
|
||||
private TextView tvGPSLocation;
|
||||
private TextView tvFuseLocation;
|
||||
static MyHandler _MyHandler;
|
||||
|
||||
TextView mtvTXMyLocationInfo;
|
||||
TextView mtvPhoneMyLocationInfo;
|
||||
TextView mtvPostionFixModelInfo;
|
||||
TextView mtvLockPostionInfo;
|
||||
|
||||
EditText metLockLatitude;
|
||||
EditText metLockLongitude;
|
||||
|
||||
double latitudeWifiLock;
|
||||
double longitudeWifiLock;
|
||||
@ -46,6 +60,14 @@ public class PositionsFragment extends Fragment {
|
||||
double latitudeFuseLock;
|
||||
double longitudeFuseLock;
|
||||
|
||||
PostionFixModel mPostionFixModel;
|
||||
static Location _LocationTX;
|
||||
static Location _LocationPhoneGPS;
|
||||
static Location _LocationPhoneGPSLock;
|
||||
|
||||
LocationManager locationManagerPhoneGPS;
|
||||
volatile static int nFixActivationCountValue = 20;
|
||||
volatile static int nCurrentFixActivationCountValue = 0;
|
||||
|
||||
// public static PositionsFragment newInstance(int page) {
|
||||
// Bundle args = new Bundle();
|
||||
@ -69,31 +91,112 @@ public class PositionsFragment extends Fragment {
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View viewMain = inflater.inflate(R.layout.fragment_positions, container, false);
|
||||
|
||||
nCurrentFixActivationCountValue = 0;
|
||||
|
||||
// Toolbar toolbar = viewMain.findViewById(R.id.toolbar);
|
||||
// getActivity().getMenuInflater().inflate(R.menu.toolbar_positions, toolbar.getMenu());
|
||||
//
|
||||
tvWifiLocation = viewMain.findViewById(R.id.wifi_position_tv);
|
||||
tvGPSLocation = viewMain.findViewById(R.id.gps_position_tv);
|
||||
tvFuseLocation = viewMain.findViewById(R.id.fuse_position_tv);
|
||||
mtvTXMyLocationInfo = viewMain.findViewById(R.id.txmylocationinfo_tv);
|
||||
mtvPhoneMyLocationInfo = viewMain.findViewById(R.id.phonemylocationinfo_tv);
|
||||
mtvPostionFixModelInfo = viewMain.findViewById(R.id.postionfixmodelinfo_tv);
|
||||
mtvLockPostionInfo = viewMain.findViewById(R.id.lockpostioninfo_tv);
|
||||
|
||||
metLockLatitude = viewMain.findViewById(R.id.locklatitude_et);
|
||||
metLockLongitude = viewMain.findViewById(R.id.locklongitude_et);
|
||||
|
||||
// tvWifiLocation = viewMain.findViewById(R.id.wifi_position_tv);
|
||||
// tvGPSLocation = viewMain.findViewById(R.id.gps_position_tv);
|
||||
// tvFuseLocation = viewMain.findViewById(R.id.fuse_position_tv);
|
||||
locationManager = (LocationManager) getActivity().getSystemService(getActivity().LOCATION_SERVICE);
|
||||
|
||||
Button btnLockingPosition = viewMain.findViewById(R.id.locking_position_btn);
|
||||
btnLockingPosition.setOnClickListener(new View.OnClickListener(){
|
||||
@Override
|
||||
public void onClick(View p1) {
|
||||
TXMSFragment.moveToLocation(latitudeFuseLock, longitudeFuseLock);
|
||||
if (!metLockLatitude.getText().toString().trim().equals("")
|
||||
&& !metLockLongitude.getText().toString().trim().equals("")) {
|
||||
_LocationPhoneGPSLock = new Location("User_Defined_GPS");
|
||||
_LocationPhoneGPSLock.setLatitude(Double.parseDouble(metLockLatitude.getText().toString()));
|
||||
_LocationPhoneGPSLock.setLongitude(Double.parseDouble(metLockLongitude.getText().toString()));
|
||||
ToastUtils.show("定位手动设定位置");
|
||||
} else {
|
||||
// 用腾讯定位数据与GPS定位数据的数据差修复模型,来修复一下GPS定位数据。
|
||||
mPostionFixModel = PostionFixModel.loadPostionFixModel();
|
||||
Location locationFix = fixGPSLocationFromPostionFixModel(_LocationPhoneGPS);
|
||||
//_LocationPhoneGPSLock = _LocationTX;
|
||||
_LocationPhoneGPSLock = locationFix;
|
||||
ToastUtils.show("定位GPS设定位置");
|
||||
}
|
||||
showLockPostionInfo();
|
||||
//ToastUtils.show(String.format("%s", locationFix.toString()));
|
||||
|
||||
TXMSFragment.moveToLocation(_LocationPhoneGPSLock.getLatitude(), _LocationPhoneGPSLock.getLongitude());
|
||||
}
|
||||
});
|
||||
|
||||
// 请求GPS定位
|
||||
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, gpsLocationListener);
|
||||
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, phoneGPSLocationListener);
|
||||
|
||||
// 请求基站(网络)定位
|
||||
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, networkLocationListener);
|
||||
|
||||
_MyHandler = new MyHandler();
|
||||
|
||||
//ToastUtils.show("PositionsFragment onCreateView");
|
||||
|
||||
showLocationTX();
|
||||
showLocationPhoneGPS();
|
||||
showPostionFixModelInfo();
|
||||
|
||||
return viewMain;
|
||||
}
|
||||
|
||||
void showLocationPhoneGPS() {
|
||||
if (_LocationPhoneGPS != null) {
|
||||
String szTemp = String.format("\nPhoneGPS MyLocation Info\nLatitude %f\nLongitude %f\nAccuracy %f\n", _LocationPhoneGPS.getLatitude(), _LocationPhoneGPS.getLongitude(), _LocationPhoneGPS.getAccuracy());
|
||||
mtvPhoneMyLocationInfo.append(szTemp);
|
||||
LogUtils.d(TAG, szTemp);
|
||||
}
|
||||
}
|
||||
|
||||
void showPostionFixModelInfo() {
|
||||
if (mPostionFixModel != null && _LocationTX != null && _LocationPhoneGPS != null) {
|
||||
String szTemp = String.format("\nFixModel Info\nLatitude TX %f\nLatitude GPS %f\nLatitude Fix %f\nLongitude TX %f\nLongitude GPS %f\nLongitude Fix %f\n\n",
|
||||
_LocationTX.getLatitude(),
|
||||
_LocationPhoneGPS.getLatitude(),
|
||||
mPostionFixModel.getLatitudeFixModel(),
|
||||
_LocationTX.getLongitude(),
|
||||
_LocationPhoneGPS.getLongitude(),
|
||||
mPostionFixModel.getLongitudeFixModel());
|
||||
mtvPostionFixModelInfo.append(szTemp);
|
||||
LogUtils.d(TAG, szTemp);
|
||||
}
|
||||
}
|
||||
|
||||
void showLockPostionInfo() {
|
||||
if (mPostionFixModel != null && _LocationTX != null && _LocationPhoneGPSLock != null) {
|
||||
String szTemp = String.format("\n%s\nFixModel Info\nLatitude TX %f\nLatitude GPS %f\nLatitude Fix %f\nLongitude TX %f\nLongitude GPS %f\nLongitude Fix %f\n\n",
|
||||
TimeUtils.getCurrentTimeString(),
|
||||
_LocationTX.getLatitude(),
|
||||
_LocationPhoneGPS.getLatitude(),
|
||||
mPostionFixModel.getLatitudeFixModel(),
|
||||
_LocationTX.getLongitude(),
|
||||
_LocationPhoneGPS.getLongitude(),
|
||||
mPostionFixModel.getLongitudeFixModel());
|
||||
mtvLockPostionInfo.append(szTemp);
|
||||
LogUtils.d(TAG, szTemp);
|
||||
}
|
||||
}
|
||||
|
||||
void showLocationTX() {
|
||||
if (_LocationTX != null) {
|
||||
String szTemp = String.format("TX MyLocation Init Info\nLatitude %f, Longitude %f, Accuracy %f", _LocationTX.getLatitude(), _LocationTX.getLongitude(), _LocationTX.getAccuracy());
|
||||
mtvTXMyLocationInfo.setText(szTemp);
|
||||
LogUtils.d(TAG, szTemp);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
|
||||
inflater.inflate(R.menu.toolbar_positions, menu);
|
||||
@ -108,7 +211,7 @@ public class PositionsFragment extends Fragment {
|
||||
ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
|
||||
return;
|
||||
}
|
||||
locationManager.removeUpdates(gpsLocationListener);
|
||||
locationManager.removeUpdates(phoneGPSLocationListener);
|
||||
locationManager.removeUpdates(networkLocationListener);
|
||||
}
|
||||
}
|
||||
@ -128,7 +231,56 @@ public class PositionsFragment extends Fragment {
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
private LocationListener gpsLocationListener = new LocationListener() {
|
||||
void updatePostionFixModel() {
|
||||
if (_LocationPhoneGPS == null
|
||||
|| _LocationTX == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
nCurrentFixActivationCountValue++;
|
||||
if (nCurrentFixActivationCountValue < nFixActivationCountValue) {
|
||||
mPostionFixModel = PostionFixModel.loadPostionFixModel();
|
||||
mPostionFixModel.setLatitudeFixModel(_LocationPhoneGPS.getLatitude() - _LocationTX.getLatitude());
|
||||
mPostionFixModel.setLongitudeFixModel(_LocationPhoneGPS.getLongitude() - _LocationTX.getLongitude());
|
||||
|
||||
// String szTemp = String.format("PostionFixModel Info\nLatitude Fix %f, Longitude Fix %f", mPostionFixModel.getLatitudeFixModel(), mPostionFixModel.getLongitudeFixModel());
|
||||
// mtvPostionFixModelInfo.setText(szTemp);
|
||||
// LogUtils.d(TAG, szTemp);
|
||||
PostionFixModel.savePostionFixModel(mPostionFixModel);
|
||||
//ToastUtils.show(szTemp);
|
||||
LogUtils.d(TAG, String.format("updatePostionFixModel() run %d", nCurrentFixActivationCountValue));
|
||||
|
||||
showPostionFixModelInfo();
|
||||
} else {
|
||||
// 定位修复模型数据定型, GPS定位监听停止
|
||||
// 在需要停止监听的地方(如onPause/onDestroy)添加:
|
||||
if (locationManagerPhoneGPS != null) {
|
||||
// 取消位置更新监听
|
||||
locationManagerPhoneGPS.removeUpdates(phoneGPSLocationListener);
|
||||
// 可选:停止后释放资源
|
||||
phoneGPSLocationListener = null;
|
||||
}
|
||||
LogUtils.d(TAG, String.format("updatePostionFixModel() stop %d", nCurrentFixActivationCountValue));
|
||||
}
|
||||
}
|
||||
|
||||
private Location fixGPSLocationFromPostionFixModel(Location location) {
|
||||
//Location location = locationTX;
|
||||
Location locationFix = new Location("GPS_Fix_Map_Manual");
|
||||
|
||||
// 设置基础坐标
|
||||
locationFix.setLatitude(location.getLatitude() - mPostionFixModel.getLatitudeFixModel());
|
||||
locationFix.setLongitude(location.getLongitude() - mPostionFixModel.getLongitudeFixModel());
|
||||
|
||||
// 设置必要元数据
|
||||
location.setTime(System.currentTimeMillis());
|
||||
location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
|
||||
location.setAccuracy(5.0f); // 手动点击精度设为5米
|
||||
|
||||
return location;
|
||||
}
|
||||
|
||||
private LocationListener phoneGPSLocationListener = new LocationListener() {
|
||||
@Override
|
||||
public void onLocationChanged(Location location) {
|
||||
// 处理GPS定位结果
|
||||
@ -171,22 +323,32 @@ public class PositionsFragment extends Fragment {
|
||||
longitudeWifiLock = longitude;
|
||||
|
||||
// 简单的融合示例:这里只是显示最后获取到的位置,实际应用中需要更复杂的融合算法
|
||||
tvWifiLocation.setText(String.format("Wifi [ Latitude: %f \nLongitude: %f ]", latitudeWifiLock, longitudeWifiLock));
|
||||
//tvWifiLocation.setText(String.format("Wifi [ Latitude: %f \nLongitude: %f ]", latitudeWifiLock, longitudeWifiLock));
|
||||
fuseLocationData();
|
||||
}
|
||||
}
|
||||
|
||||
void updateGPSLocation(Location location) {
|
||||
if (location != null) {
|
||||
double latitude = location.getLatitude();
|
||||
double longitude = location.getLongitude();
|
||||
// double latitude = location.getLatitude();
|
||||
// double longitude = location.getLongitude();
|
||||
//
|
||||
// latitudeGPSLock = latitude;
|
||||
// longitudeGPSLock = longitude;
|
||||
//
|
||||
// // 简单的融合示例:这里只是显示最后获取到的位置,实际应用中需要更复杂的融合算法
|
||||
// tvGPSLocation.setText(String.format("GPS [ Latitude: %f \nLongitude: %f ]", latitudeGPSLock, longitudeGPSLock));
|
||||
// fuseLocationData();
|
||||
|
||||
latitudeGPSLock = latitude;
|
||||
longitudeGPSLock = longitude;
|
||||
|
||||
// 简单的融合示例:这里只是显示最后获取到的位置,实际应用中需要更复杂的融合算法
|
||||
tvGPSLocation.setText(String.format("GPS [ Latitude: %f \nLongitude: %f ]", latitudeGPSLock, longitudeGPSLock));
|
||||
fuseLocationData();
|
||||
_LocationPhoneGPS = location;
|
||||
// 位置变化时的处理逻辑
|
||||
// double latitude = location.getLatitude();
|
||||
// double longitude = location.getLongitude();
|
||||
// String szTemp = String.format("Phone GPS MyLocation Init Info\nLatitude %f, Longitude %f, Accuracy %f", _LocationPhoneGPS.getLatitude(), _LocationPhoneGPS.getLongitude(), _LocationPhoneGPS.getAccuracy());
|
||||
// mtvPhoneMyLocationInfo.setText(szTemp);
|
||||
// LogUtils.d(TAG, szTemp);
|
||||
showLocationPhoneGPS();
|
||||
updatePostionFixModel();
|
||||
}
|
||||
}
|
||||
|
||||
@ -205,6 +367,32 @@ public class PositionsFragment extends Fragment {
|
||||
latitudeFuseLock = result[0];
|
||||
longitudeFuseLock = result[1];
|
||||
|
||||
tvFuseLocation.setText(String.format("Fuse [ Latitude: %f \nLongitude: %f ]", latitudeFuseLock, longitudeFuseLock));
|
||||
//tvFuseLocation.setText(String.format("Fuse [ Latitude: %f \nLongitude: %f ]", latitudeFuseLock, longitudeFuseLock));
|
||||
}
|
||||
|
||||
public static final int INIT_POSITION = 1;
|
||||
class MyHandler extends Handler {
|
||||
@Override
|
||||
public void handleMessage(@NonNull Message msg) {
|
||||
switch (msg.what) {
|
||||
case INIT_POSITION:
|
||||
// 在这里处理接收到消息后的逻辑,比如更新 UI
|
||||
_LocationTX = (Location)msg.obj;
|
||||
showLocationTX();
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static void sendInitPositioningMessage(Location location) {
|
||||
if (_MyHandler != null) {
|
||||
Message message = Message.obtain();
|
||||
message.what = INIT_POSITION;
|
||||
message.obj = location;
|
||||
_MyHandler.sendMessage(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -68,21 +68,16 @@ public class TXMSFragment extends Fragment implements /*EasyPermissions.Permissi
|
||||
private int mPage;
|
||||
private TextureMapView mapView;
|
||||
protected TencentMap tencentMap;
|
||||
TextView mtvTXMyLocationInfo;
|
||||
TextView mtvPhoneMyLocationInfo;
|
||||
TextView mtvPostionFixModelInfo;
|
||||
|
||||
private LocationSource.OnLocationChangedListener locationChangedListener;
|
||||
|
||||
private TencentLocationManager mTencentLocationManager;
|
||||
private TencentLocationRequest mTencentLocationRequest;
|
||||
private MyLocationStyle mMyLocationStyle;
|
||||
ArrayList<PostionModel> locationPostionModelList;
|
||||
Location lastLocation;
|
||||
//Location lastLocation;
|
||||
static TXMSFragment _TXMSFragment;
|
||||
PostionFixModel mPostionFixModel;
|
||||
Location locationTX;
|
||||
Location locationPhoneGPS;
|
||||
LocationManager locationManagerPhoneGPS;
|
||||
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
@ -101,9 +96,6 @@ public class TXMSFragment extends Fragment implements /*EasyPermissions.Permissi
|
||||
//创建tencentMap地图对象,可以完成对地图的几乎所有操作
|
||||
tencentMap = mapView.getMap();
|
||||
|
||||
mtvTXMyLocationInfo = viewRoot.findViewById(R.id.txmylocationinfo_tv);
|
||||
mtvPhoneMyLocationInfo = viewRoot.findViewById(R.id.phonemylocationinfo_tv);
|
||||
mtvPostionFixModelInfo = viewRoot.findViewById(R.id.postionfixmodelinfo_tv);
|
||||
|
||||
checkLocationPermission();
|
||||
|
||||
@ -189,48 +181,30 @@ public class TXMSFragment extends Fragment implements /*EasyPermissions.Permissi
|
||||
// }
|
||||
|
||||
// 手机 GPS 定位信息
|
||||
LocationListener phoneGPSLocationListener = new LocationListener() {
|
||||
@Override
|
||||
public void onLocationChanged(Location location) {
|
||||
locationPhoneGPS = location;
|
||||
// 位置变化时的处理逻辑
|
||||
// double latitude = location.getLatitude();
|
||||
// double longitude = location.getLongitude();
|
||||
String szTemp = String.format("Phone GPS MyLocation Init Info\nLatitude %f, Longitude %f, Accuracy %f", locationPhoneGPS.getLatitude(), locationPhoneGPS.getLongitude(), locationPhoneGPS.getAccuracy());
|
||||
mtvPhoneMyLocationInfo.setText(szTemp);
|
||||
LogUtils.d(TAG, szTemp);
|
||||
updatePostionFixModel();
|
||||
|
||||
}
|
||||
// LocationListener phoneGPSLocationListener = new LocationListener() {
|
||||
// @Override
|
||||
// public void onLocationChanged(Location location) {
|
||||
// locationPhoneGPS = location;
|
||||
// // 位置变化时的处理逻辑
|
||||
//// double latitude = location.getLatitude();
|
||||
//// double longitude = location.getLongitude();
|
||||
// String szTemp = String.format("Phone GPS MyLocation Init Info\nLatitude %f, Longitude %f, Accuracy %f", locationPhoneGPS.getLatitude(), locationPhoneGPS.getLongitude(), locationPhoneGPS.getAccuracy());
|
||||
// mtvPhoneMyLocationInfo.setText(szTemp);
|
||||
// LogUtils.d(TAG, szTemp);
|
||||
// updatePostionFixModel();
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onProviderDisabled(String provider) {}
|
||||
//
|
||||
// @Override
|
||||
// public void onProviderEnabled(String provider) {}
|
||||
//
|
||||
// @Override
|
||||
// public void onStatusChanged(String provider, int status, Bundle extras) {}
|
||||
// };
|
||||
|
||||
@Override
|
||||
public void onProviderDisabled(String provider) {}
|
||||
|
||||
@Override
|
||||
public void onProviderEnabled(String provider) {}
|
||||
|
||||
@Override
|
||||
public void onStatusChanged(String provider, int status, Bundle extras) {}
|
||||
};
|
||||
|
||||
void updatePostionFixModel() {
|
||||
mPostionFixModel = PostionFixModel.loadPostionFixModel();
|
||||
mPostionFixModel.setLatitudeFixModel(locationPhoneGPS.getLatitude() - locationTX.getLatitude());
|
||||
mPostionFixModel.setLongitudeFixModel(locationPhoneGPS.getLongitude() - locationTX.getLongitude());
|
||||
PostionFixModel.savePostionFixModel(mPostionFixModel);
|
||||
String szTemp = String.format("PostionFixModel Info\nLatitude Fix %f, Longitude Fix %f", mPostionFixModel.getLatitudeFixModel(), mPostionFixModel.getLongitudeFixModel());
|
||||
mtvPostionFixModelInfo.setText(szTemp);
|
||||
LogUtils.d(TAG, szTemp);
|
||||
|
||||
// 在需要停止监听的地方(如onPause/onDestroy)添加:
|
||||
if (locationManagerPhoneGPS != null) {
|
||||
// 取消位置更新监听
|
||||
locationManagerPhoneGPS.removeUpdates(phoneGPSLocationListener);
|
||||
// 可选:停止后释放资源
|
||||
phoneGPSLocationListener = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// 创建Location对象方法
|
||||
@ -374,33 +348,15 @@ public class TXMSFragment extends Fragment implements /*EasyPermissions.Permissi
|
||||
_TXMSFragment.moveToGPSLocation(location);
|
||||
}
|
||||
}
|
||||
|
||||
private Location fixGPSLocationFromPostionFixModel(Location location) {
|
||||
Location locationFix = new Location("GPS_Fix_Map_Manual");
|
||||
|
||||
// 设置基础坐标
|
||||
locationFix.setLatitude(location.getLatitude() - mPostionFixModel.getLatitudeFixModel());
|
||||
locationFix.setLongitude(location.getLongitude() - mPostionFixModel.getLongitudeFixModel());
|
||||
|
||||
// 设置必要元数据
|
||||
location.setTime(System.currentTimeMillis());
|
||||
location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
|
||||
location.setAccuracy(5.0f); // 手动点击精度设为5米
|
||||
|
||||
return location;
|
||||
}
|
||||
|
||||
private void moveToGPSLocation(Location location) {
|
||||
// 用腾讯定位数据与GPS定位数据的数据差修复模型,来修复一下GPS定位数据。
|
||||
mPostionFixModel = PostionFixModel.loadPostionFixModel();
|
||||
Location locationFix = fixGPSLocationFromPostionFixModel(location);
|
||||
//ToastUtils.show(String.format("%s", locationFix.toString()));
|
||||
|
||||
//对地图操作类进行操作
|
||||
CameraUpdate cameraSigma =
|
||||
CameraUpdateFactory.newCameraPosition(new CameraPosition(
|
||||
convertLocationToLatLng(locationFix),
|
||||
15,
|
||||
convertLocationToLatLng(location),
|
||||
19f,
|
||||
0f,
|
||||
0f));
|
||||
//移动地图
|
||||
@ -427,7 +383,7 @@ public class TXMSFragment extends Fragment implements /*EasyPermissions.Permissi
|
||||
public void onLocationChanged(TencentLocation tencentLocation, int i, String s) {
|
||||
|
||||
if (i == TencentLocation.ERROR_OK && locationChangedListener != null) {
|
||||
locationTX = new Location(tencentLocation.getProvider());
|
||||
final Location locationTX = new Location(tencentLocation.getProvider());
|
||||
//设置经纬度以及精度
|
||||
locationTX.setLatitude(tencentLocation.getLatitude());
|
||||
locationTX.setLongitude(tencentLocation.getLongitude());
|
||||
@ -436,48 +392,50 @@ public class TXMSFragment extends Fragment implements /*EasyPermissions.Permissi
|
||||
locationChangedListener.onLocationChanged(locationTX);
|
||||
|
||||
//显示回调的实时位置信息
|
||||
getActivity().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
//对地图操作类进行操作
|
||||
// CameraUpdate cameraSigma =
|
||||
// CameraUpdateFactory.newCameraPosition(new CameraPosition(
|
||||
// convertToLatLng(location),
|
||||
// 15,
|
||||
// 0f,
|
||||
// 0f));
|
||||
// //移动地图
|
||||
// tencentMap.moveCamera(cameraSigma);
|
||||
// Rules.getEffectInfo(location);
|
||||
// double distance = DistanceUtils.getDistance(
|
||||
// locationA.getLatitude(),
|
||||
// locationA.getLongitude(),
|
||||
// locationB.getLatitude(),
|
||||
// locationB.getLongitude()
|
||||
// );
|
||||
String szTemp = String.format("TX MyLocation Init Info\nLatitude %f, Longitude %f, Accuracy %f", locationTX.getLatitude(), locationTX.getLongitude(), locationTX.getAccuracy());
|
||||
mtvTXMyLocationInfo.setText(szTemp);
|
||||
LogUtils.d(TAG, szTemp);
|
||||
//打印tencentLocation的json字符串
|
||||
// Toast.makeText(getApplicationContext(), new Gson().toJson(location), Toast.LENGTH_LONG).show();
|
||||
|
||||
|
||||
//
|
||||
// 本机 GPS 定位服务调用服务
|
||||
//
|
||||
locationManagerPhoneGPS = (LocationManager) getActivity().getSystemService(getActivity().LOCATION_SERVICE);
|
||||
String provider = LocationManager.GPS_PROVIDER;
|
||||
//Location location = locationManager.getLastKnownLocation(provider);
|
||||
locationManagerPhoneGPS.requestLocationUpdates(provider, 2000, 10, phoneGPSLocationListener);
|
||||
}
|
||||
});
|
||||
// getActivity().runOnUiThread(new Runnable() {
|
||||
// @Override
|
||||
// public void run() {
|
||||
//
|
||||
// //对地图操作类进行操作
|
||||
//// CameraUpdate cameraSigma =
|
||||
//// CameraUpdateFactory.newCameraPosition(new CameraPosition(
|
||||
//// convertToLatLng(location),
|
||||
//// 15,
|
||||
//// 0f,
|
||||
//// 0f));
|
||||
//// //移动地图
|
||||
//// tencentMap.moveCamera(cameraSigma);
|
||||
//// Rules.getEffectInfo(location);
|
||||
//// double distance = DistanceUtils.getDistance(
|
||||
//// locationA.getLatitude(),
|
||||
//// locationA.getLongitude(),
|
||||
//// locationB.getLatitude(),
|
||||
//// locationB.getLongitude()
|
||||
//// );
|
||||
// String szTemp = String.format("TX MyLocation Init Info\nLatitude %f, Longitude %f, Accuracy %f", locationTX.getLatitude(), locationTX.getLongitude(), locationTX.getAccuracy());
|
||||
// mtvTXMyLocationInfo.setText(szTemp);
|
||||
// LogUtils.d(TAG, szTemp);
|
||||
// //打印tencentLocation的json字符串
|
||||
//// Toast.makeText(getApplicationContext(), new Gson().toJson(location), Toast.LENGTH_LONG).show();
|
||||
//
|
||||
//
|
||||
// //
|
||||
// // 本机 GPS 定位服务调用服务
|
||||
// //
|
||||
// locationManagerPhoneGPS = (LocationManager) getActivity().getSystemService(getActivity().LOCATION_SERVICE);
|
||||
// String provider = LocationManager.GPS_PROVIDER;
|
||||
// //Location location = locationManager.getLastKnownLocation(provider);
|
||||
// locationManagerPhoneGPS.requestLocationUpdates(provider, 2000, 10, phoneGPSLocationListener);
|
||||
// }
|
||||
// });
|
||||
|
||||
// 保存最后定位信息
|
||||
lastLocation = new Location(tencentLocation.getProvider());
|
||||
lastLocation.setLatitude(tencentLocation.getLatitude());
|
||||
lastLocation.setLongitude(tencentLocation.getLongitude());
|
||||
lastLocation.setAccuracy(tencentLocation.getAccuracy());
|
||||
// lastLocation = new Location(tencentLocation.getProvider());
|
||||
// lastLocation.setLatitude(tencentLocation.getLatitude());
|
||||
// lastLocation.setLongitude(tencentLocation.getLongitude());
|
||||
// lastLocation.setAccuracy(tencentLocation.getAccuracy());
|
||||
|
||||
PositionsFragment.sendInitPositioningMessage(locationTX);
|
||||
|
||||
// 当不再需要定位时
|
||||
// 取消定位监听
|
||||
@ -488,6 +446,8 @@ public class TXMSFragment extends Fragment implements /*EasyPermissions.Permissi
|
||||
if (tencentMap != null) {
|
||||
tencentMap.setMyLocationEnabled(false);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@ import cc.winboll.studio.libappbase.utils.ToastUtils;
|
||||
|
||||
public class TasksFragment extends Fragment {
|
||||
|
||||
public static final String TAG = "GmsFragment";
|
||||
public static final String TAG = "TasksFragment";
|
||||
|
||||
private static final String ARG_PAGE = "ARG_PAGE";
|
||||
private int mPage;
|
||||
|
@ -0,0 +1,26 @@
|
||||
package cc.winboll.studio.positions.utils;
|
||||
|
||||
/**
|
||||
* @Author ZhanGSKen@AliYun.Com
|
||||
* @Date 2025/03/21 16:02:56
|
||||
* @Describe 时间工具集
|
||||
*/
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
public class TimeUtils {
|
||||
|
||||
public static final String TAG = "TimeUtils";
|
||||
|
||||
public static String getCurrentTimeString() {
|
||||
// 获取当前日期时间
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
// 定义日期时间格式
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
// 格式化日期时间
|
||||
String formattedDateTime = now.format(formatter);
|
||||
//System.out.println(formattedDateTime);
|
||||
return formattedDateTime;
|
||||
}
|
||||
|
||||
}
|
@ -9,13 +9,8 @@
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="400dp"
|
||||
android:layout_height="300dp"
|
||||
android:id="@+id/frameLayout"/>
|
||||
|
||||
<android.widget.Toolbar
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/toolbar"/>
|
||||
|
||||
<androidx.viewpager.widget.ViewPager
|
||||
android:layout_width="match_parent"
|
||||
|
@ -7,40 +7,158 @@
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1.0">
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="0dp"
|
||||
<TextView
|
||||
android:id="@+id/txmylocationinfo_tv"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1.0">
|
||||
android:textColor="@color/colorPrimary"
|
||||
android:textStyle="bold"
|
||||
android:textSize="10sp"
|
||||
android:background="#C0FFFFFF">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/wifi_position_tv"/>
|
||||
</TextView>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/gps_position_tv"/>
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/fuse_position_tv"/>
|
||||
android:layout_weight="1.0">
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#FFC4EF9E">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/phonemylocationinfo_tv"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/colorPrimary"
|
||||
android:textStyle="bold"
|
||||
android:textSize="10sp">
|
||||
|
||||
</TextView>
|
||||
|
||||
</ScrollView>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1.0">
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#FFABE2F7">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/postionfixmodelinfo_tv"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/colorPrimary"
|
||||
android:textStyle="bold"
|
||||
android:textSize="10sp">
|
||||
|
||||
</TextView>
|
||||
|
||||
</ScrollView>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<Button
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="定位"
|
||||
android:id="@+id/locking_position_btn"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="150dp">
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1.0"
|
||||
android:background="#FFADA4FD">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/lockpostioninfo_tv"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/colorPrimary"
|
||||
android:textStyle="bold"
|
||||
android:textSize="10sp">
|
||||
|
||||
</TextView>
|
||||
|
||||
</ScrollView>
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="150dp"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Latitude:"/>
|
||||
|
||||
<EditText
|
||||
android:layout_width="0dp"
|
||||
android:ems="10"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1.0"
|
||||
android:id="@+id/locklatitude_et"
|
||||
android:singleLine="true"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Longitude:"/>
|
||||
|
||||
<EditText
|
||||
android:layout_width="0dp"
|
||||
android:ems="10"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1.0"
|
||||
android:id="@+id/locklongitude_et"
|
||||
android:singleLine="true"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<Button
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="定位"
|
||||
android:id="@+id/locking_position_btn"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
@ -5,62 +5,13 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
android:layout_height="match_parent"
|
||||
android:background="#FFF4E3FF">
|
||||
|
||||
<RelativeLayout
|
||||
<com.tencent.tencentmap.mapsdk.maps.TextureMapView
|
||||
android:id="@+id/mapview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.tencent.tencentmap.mapsdk.maps.TextureMapView
|
||||
android:id="@+id/mapview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txmylocationinfo_tv"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/colorPrimary"
|
||||
android:textStyle="bold"
|
||||
android:textSize="10sp"
|
||||
android:background="#C0FFFFFF">
|
||||
|
||||
</TextView>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/phonemylocationinfo_tv"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/colorPrimary"
|
||||
android:textStyle="bold"
|
||||
android:textSize="10sp"
|
||||
android:background="#C0FFFFFF"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentRight="true">
|
||||
|
||||
</TextView>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/postionfixmodelinfo_tv"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/colorPrimary"
|
||||
android:textStyle="bold"
|
||||
android:textSize="10sp"
|
||||
android:background="#C0FFFFFF"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentRight="true">
|
||||
|
||||
</TextView>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
android:layout_height="match_parent"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user