【Android App】获取照片里的位置信息及使用全球卫星导航系统(GNSS)获取位置实战(附源码和演示 超详细)

news/2024/4/25 16:50:20/文章来源:https://blog.csdn.net/jiebaoshayebuhui/article/details/128104122

需要全部代码请点赞关注收藏后评论区留言私信~~~

一、获取照片里的位置信息

手机拍摄的相片还保存着时间、地点、镜头参数等信息,这些信息由相片接口工具ExifInterface管理,它的常用方法说明如下:

getLatLong:获取相片拍摄时候的经纬度。

getAltitude:获取相片拍摄时候的海拔高度。

getAttribute:获取指定名称的属性值。

不过Android从9.0开始才支持获取照片的位置信息,并且增加了新的媒体位置权限,并且如果想访问存储卡的图片文件,还得给App赋予存储卡读写权限。

即照片在拍摄时会默认存储经纬度和时间等信息 可以通过对应方法来调用

代码如下

Java类

package com.example.location;import android.app.ProgressDialog;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.provider.MediaStore;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.GridLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;import androidx.appcompat.app.AppCompatActivity;import com.example.location.bean.ImageInfo;
import com.example.location.util.BitmapUtil;
import com.example.location.util.ExifUtil;
import com.example.location.util.FileUtil;
import com.example.location.util.Utils;import java.util.ArrayList;
import java.util.List;public class ImageLocationActivity extends AppCompatActivity {private final static String TAG = "ImageLocationActivity";private GridLayout gl_appendix; // 声明一个网格布局对象private ProgressDialog mDialog; // 声明一个进度对话框对象private List<ImageInfo> mImageList = new ArrayList<>(); // 图片列表private Uri mImageUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; // 相册的Uriprivate String[] mImageColumn = new String[]{ // 媒体库的字段名称数组MediaStore.Images.Media._ID, // 编号MediaStore.Images.Media.TITLE, // 标题MediaStore.Images.Media.SIZE, // 文件大小MediaStore.Images.Media.DATA}; // 文件路径@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_image_location);gl_appendix = findViewById(R.id.gl_appendix);new Handler().post(() -> showImageLocation()); // // 显示图像的位置信息}// 显示图像的位置信息private void showImageLocation() {// 显示进度对话框mDialog = ProgressDialog.show(this, "请稍候", "正在加载图片的位置信息");new Thread(() -> loadImageList()).start(); // 启动线程加载图片列表}// 加载图片列表private void loadImageList() {Log.d(TAG, "loadImageList");mImageList.clear(); // 清空图片列表// 查询相册媒体库,并返回结果集的游标。“_size asc”表示按照文件大小升序排列Cursor cursor = getContentResolver().query(mImageUri, mImageColumn, null, null, "_size desc");if (cursor != null) {// 下面遍历结果集,并逐个添加到图片列表。简单起见只挑选前六张图片for (int i=0; i<6 && cursor.moveToNext(); i++) {ImageInfo image = new ImageInfo(); // 创建一个图片信息对象image.setId(cursor.getLong(0)); // 设置图片编号image.setName(cursor.getString(1)); // 设置图片名称image.setSize(cursor.getLong(2)); // 设置图片的文件大小image.setPath(cursor.getString(3)); // 设置图片的文件路径Log.d(TAG, image.getName() + " " + image.getSize() + " " + image.getPath());// 检查该路径是否合法if (!FileUtil.checkFileUri(this, image.getPath())) {i--;continue; // 路径非法则再来一次}// 从指定路径解码得到位图对象Bitmap bitmap = BitmapFactory.decodeFile(image.getPath());// 给图像视图设置自动缩放的位图对象image.setBitmap(BitmapUtil.getAutoZoomImage(bitmap));mImageList.add(image); // 添加至图片列表}cursor.close(); // 关闭数据库游标}Log.d(TAG, "mImageList.size="+mImageList.size());runOnUiThread(() -> showImageGrid()); // 显示图像网格}// 显示图像网格private void showImageGrid() {Log.d(TAG, "showImageGrid");for (int i=0; i<mImageList.size(); i++) {final ImageInfo image = mImageList.get(i);LinearLayout ll_grid = new LinearLayout(this); // 创建一个线性布局视图ll_grid.setLayoutParams(new LinearLayout.LayoutParams(Utils.getScreenWidth(this)/3,ViewGroup.LayoutParams.WRAP_CONTENT)); // 设置线性布局的布局参数View view = LayoutInflater.from(this).inflate(R.layout.item_location, null);ImageView iv_photo = view.findViewById(R.id.iv_photo);iv_photo.setImageBitmap(image.getBitmap()); // 设置图像视图的位图对象TextView tv_latlng = view.findViewById(R.id.tv_latlng);// 获取指定图片的位置信息String location = ExifUtil.getLocationFromImage(this, image.getId()+"");tv_latlng.setText(location); // 设置文本视图的文字内容ll_grid.addView(view); // 把视图对象添加至线性布局gl_appendix.addView(ll_grid); // 把线性布局添加至网格布局}mDialog.dismiss(); // 关闭进度对话框}}

 二、全球卫星导航系统(GNSS)

联合国认可的全球卫星导航系统有下列4个:

(1)美国的GPS

(2)俄罗斯的格洛纳斯

(3)中国的北斗

(4)欧洲的伽利略

通过GnssStatus对象的下列方法可获取卫星详情。

getSatelliteCount:获取卫星的数量。

getCn0DbHz:获取卫星的信号。

getAzimuthDegrees:获取卫星的方位角。

getElevationDegrees:获取卫星的仰角。

getConstellationType:获取卫星的星座类型。

实际效果如下 有中间的浑天仪显示定位信息 更加美观与精准

如果一部手机只支持GPS  那么定位响应就会很慢,定位精度一般在十米左右,而且定位高度很不准确,误差相当大,一旦有了北大与格洛纳斯参与定位,那么在室内也能很快响应,精度一般能提升至五米,并且高度数值准确了许多

 代码如下

Java类

package com.example.location;import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.pm.PackageManager;
import android.location.Criteria;
import android.location.GnssStatus;
import android.location.GpsSatellite;
import android.location.GpsStatus;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;import com.example.location.bean.Satellite;
import com.example.location.util.DateUtil;
import com.example.location.util.SwitchUtil;
import com.example.location.widget.CompassView;import java.util.HashMap;
import java.util.Map;@SuppressLint("DefaultLocale")
public class SatelliteSphereActivity extends AppCompatActivity {private final static String TAG = "SatelliteSphereActivity";private Map<String, String> providerMap = new HashMap<>(); // 定位提供者映射private TextView tv_satellite; // 声明一个文本视图对象private CompassView cv_satellite; // 声明一个罗盘视图对象private Map<Integer, Satellite> mapSatellite = new HashMap<>(); // 导航卫星映射private LocationManager mLocationMgr; // 声明一个定位管理器对象private Criteria mCriteria = new Criteria(); // 声明一个定位准则对象private Handler mHandler = new Handler(Looper.myLooper()); // 声明一个处理器对象private boolean isLocationEnable = false; // 定位服务是否可用private String mLocationType = ""; // 定位类型。是卫星定位还是网络定位@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_satellite_sphere);providerMap.put("gps", "卫星");providerMap.put("network", "网络");tv_satellite = findViewById(R.id.tv_satellite);cv_satellite = findViewById(R.id.cv_satellite);SwitchUtil.checkLocationIsOpen(this, "需要打开定位功能才能查看卫星导航信息");}@Overrideprotected void onResume() {super.onResume();mHandler.removeCallbacks(mRefresh); // 移除定位刷新任务initLocation(); // 初始化定位服务mHandler.postDelayed(mRefresh, 100); // 延迟100毫秒启动定位刷新任务}// 初始化定位服务private void initLocation() {// 从系统服务中获取定位管理器mLocationMgr = (LocationManager) getSystemService(Context.LOCATION_SERVICE);// 设置定位精确度。Criteria.ACCURACY_COARSE表示粗略,Criteria.ACCURACY_FIN表示精细mCriteria.setAccuracy(Criteria.ACCURACY_FINE);mCriteria.setAltitudeRequired(true); // 设置是否需要海拔信息mCriteria.setBearingRequired(true); // 设置是否需要方位信息mCriteria.setCostAllowed(true); // 设置是否允许运营商收费mCriteria.setPowerRequirement(Criteria.POWER_LOW); // 设置对电源的需求// 获取定位管理器的最佳定位提供者String bestProvider = mLocationMgr.getBestProvider(mCriteria, true);if (mLocationMgr.isProviderEnabled(bestProvider)) {  // 定位提供者当前可用mLocationType = providerMap.get(bestProvider)+"定位";beginLocation(bestProvider); // 开始定位isLocationEnable = true;} else { // 定位提供者暂不可用isLocationEnable = false;}}// 设置定位结果文本private void showLocation(Location location) {if (location != null) {String desc = String.format("当前定位类型:%s,定位时间:%s" +"\n经度:%f,纬度:%f\n高度:%d米,精度:%d米",mLocationType, DateUtil.formatDate(location.getTime()),location.getLongitude(), location.getLatitude(),Math.round(location.getAltitude()), Math.round(location.getAccuracy()));tv_satellite.setText(desc);} else {Log.d(TAG, "暂未获取到定位对象");}}// 开始定位private void beginLocation(String method) {// 检查当前设备是否已经开启了定位功能if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {Toast.makeText(this, "请授予定位权限并开启定位功能", Toast.LENGTH_SHORT).show();return;}// 设置定位管理器的位置变更监听器mLocationMgr.requestLocationUpdates(method, 300, 0, mLocationListener);// 获取最后一次成功定位的位置信息Location location = mLocationMgr.getLastKnownLocation(method);showLocation(location); // 显示定位结果文本if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {// 注册全球导航卫星系统的状态监听器mLocationMgr.registerGnssStatusCallback(mGnssStatusListener, null);} else {// 给定位管理器添加导航状态监听器mLocationMgr.addGpsStatusListener(mStatusListener);}}private String[] mSystemArray = new String[] {"UNKNOWN", "GPS", "SBAS","GLONASS", "QZSS", "BEIDOU", "GALILEO", "IRNSS"};@RequiresApi(api = Build.VERSION_CODES.N)// 定义一个GNSS状态监听器private GnssStatus.Callback mGnssStatusListener = new GnssStatus.Callback() {@Overridepublic void onStarted() {}@Overridepublic void onStopped() {}@Overridepublic void onFirstFix(int ttffMillis) {}// 在卫星导航系统的状态变更时触发@Overridepublic void onSatelliteStatusChanged(GnssStatus status) {mapSatellite.clear();for (int i=0; i<status.getSatelliteCount(); i++) {Log.d(TAG, "i="+i+",getSvid="+status.getSvid(i)+",getConstellationType="+status.getConstellationType(i));Satellite item = new Satellite(); // 创建一个卫星信息对象item.signal = status.getCn0DbHz(i); // 获取卫星的信号item.elevation = status.getElevationDegrees(i); // 获取卫星的仰角item.azimuth = status.getAzimuthDegrees(i); // 获取卫星的方位角item.time = DateUtil.getNowDateTime(); // 获取当前时间int systemType = status.getConstellationType(i); // 获取卫星的类型item.name = mSystemArray[systemType];mapSatellite.put(i, item);}cv_satellite.setSatelliteMap(mapSatellite); // 设置卫星浑天仪}};// 定义一个位置变更监听器private LocationListener mLocationListener = new LocationListener() {@Overridepublic void onLocationChanged(Location location) {showLocation(location); // 显示定位结果文本}@Overridepublic void onProviderDisabled(String arg0) {}@Overridepublic void onProviderEnabled(String arg0) {}@Overridepublic void onStatusChanged(String arg0, int arg1, Bundle arg2) {}};// 定义一个刷新任务,若无法定位则每隔一秒就尝试定位private Runnable mRefresh = new Runnable() {@Overridepublic void run() {if (!isLocationEnable) {initLocation(); // 初始化定位服务mHandler.postDelayed(this, 1000);}}};@Overrideprotected void onDestroy() {super.onDestroy();if (mLocationMgr != null) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {// 注销全球导航卫星系统的状态监听器mLocationMgr.unregisterGnssStatusCallback(mGnssStatusListener);} else {// 移除定位管理器的导航状态监听器mLocationMgr.removeGpsStatusListener(mStatusListener);}// 移除定位管理器的位置变更监听器mLocationMgr.removeUpdates(mLocationListener);}}// 定义一个导航状态监听器private GpsStatus.Listener mStatusListener = new GpsStatus.Listener() {// 在卫星导航系统的状态变更时触发@Overridepublic void onGpsStatusChanged(int event) {if (ActivityCompat.checkSelfPermission(SatelliteSphereActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {// 获取卫星定位的状态信息GpsStatus gpsStatus = mLocationMgr.getGpsStatus(null);switch (event) {case GpsStatus.GPS_EVENT_SATELLITE_STATUS: // 周期性报告卫星状态// 得到所有收到的卫星的信息,包括 卫星的高度角、方位角、信噪比、和伪随机号(及卫星编号)Iterable<GpsSatellite> satellites = gpsStatus.getSatellites();for (GpsSatellite satellite : satellites) {/** satellite.getElevation(); //卫星的仰角 (卫星的高度)* satellite.getAzimuth(); //卫星的方位角* satellite.getSnr(); //卫星的信噪比* satellite.getPrn(); //卫星的伪随机码,可以认为就是卫星的编号* satellite.hasAlmanac(); //卫星是否有年历表* satellite.hasEphemeris(); //卫星是否有星历表* satellite.usedInFix(); //卫星是否被用于近期的GPS修正计算*/Satellite item = new Satellite(); // 创建一个卫星信息对象int prn_id = satellite.getPrn(); // 获取卫星的编号item.signal = Math.round(satellite.getSnr()); // 获取卫星的信号item.elevation = Math.round(satellite.getElevation()); // 获取卫星的仰角item.azimuth = Math.round(satellite.getAzimuth()); // 获取卫星的方位角item.time = DateUtil.getNowDateTime(); // 获取当前时间if (prn_id <= 51) { // 美国的GPSitem.name = "GPS";} else if (prn_id >= 201 && prn_id <= 235) { // 中国的北斗item.name = "BEIDOU";} else if (prn_id >= 65 && prn_id <= 96) { // 俄罗斯的格洛纳斯item.name = "GLONASS";} else if (prn_id >= 301 && prn_id <= 336) { // 欧洲的伽利略item.name = "GALILEO";} else {item.name = "未知";}Log.d(TAG, "id="+prn_id+", signal="+item.signal+", elevation="+item.elevation+", azimuth="+item.azimuth);mapSatellite.put(prn_id, item);}cv_satellite.setSatelliteMap(mapSatellite); // 设置卫星浑天仪case GpsStatus.GPS_EVENT_FIRST_FIX: // 首次卫星定位case GpsStatus.GPS_EVENT_STARTED: // 卫星导航服务开始case GpsStatus.GPS_EVENT_STOPPED: // 卫星导航服务停止default:break;}}}};}

创作不易 觉得有帮助请点赞关注收藏~~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_38777.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【人工智能 机器学习 深度学习】基础选择题1~30题 练习

目录 一、1~10题1.1 题目1.2 答案二、11~20题2.1 题目2.2 答案三、21~30题3.1 题目3.2 答案写在前面:适用于对 人工智能&机器学习&深度学习 进行复习的同学,同时,也可以通过基础题目的练习,加深理解。 一、1~10题 均是先给出10道题目,而后给出 10道题目的答案。 …

Python用广义加性模型GAM进行时间序列分析

每当你发现一个与时间对应的趋势时&#xff0c;你就会看到一个时间序列。我们围绕广义加性模型GAM技术进行一些咨询&#xff0c;帮助客户解决独特的业务问题。研究金融市场表现和天气预报的事实上的选择&#xff0c;时间序列是最普遍的分析技术之一&#xff0c;因为它与时间有着…

关于TreeView的简单使用(Qt6.4.1)

前言 TreeView是在Qt6.3中加入的&#xff0c;弥补了Qt中无官方树图。笔者上手尝试了下&#xff0c;虽然有点麻烦&#xff0c;但官方也做了不少简化。 本次教程&#xff0c;笔者创建一个简单的示例&#xff0c;以帮助读者使用TreeView。 一、创建模型类 当前模型需要使用C定义…

婚纱预订小程序开发,商家线上展示平台

婚纱代表着纯洁与忠贞&#xff0c;也是爱情永恒的见证者&#xff0c;穿上洁白的婚纱嫁给自己心爱的人是每个女生的梦想&#xff0c;婚纱对于每一个女生来说都有着重要的意义&#xff0c;所以选择一件美丽且适合的婚纱非常重要&#xff0c;因此人们在选择婚纱时会花费很多的时间…

Web3中文|区块链游戏的成长之痛

来源 | cointelegraph 编译 | DaliiNFTnews.com 在过去十年中&#xff0c;手机游戏已成为互动娱乐产业的重要支柱&#xff0c;得益于智能手机的普及&#xff0c;来自世界各地的用户都成为了硬核游戏玩家。 现在&#xff0c;区块链技术的出现正在推动一种范式的转变&#xff…

KNN最近邻算法分析及实现(Python实现)

KNN最近邻算法分析及实现&#xff08;代码附录后文&#xff09;1 KNN算法简介2 KNN基本原理3 简单实现KNN分析代码附录(Python)&#xff1a;呆&#xff0c;站住别跑&#xff0c;留个赞&#xff0c;给个关注嘛都看到这了Author&#xff1a; Nirvana Of Phoenixl Proverbs for yo…

计算机组成原理习题课第三章-1(唐朔飞)

计算机组成原理习题课第三章-1&#xff08;唐朔飞&#xff09; ✨欢迎关注&#x1f5b1;点赞&#x1f380;收藏⭐留言✒ &#x1f52e;本文由京与旧铺原创&#xff0c;csdn首发&#xff01; &#x1f618;系列专栏&#xff1a;java学习 &#x1f4bb;首发时间&#xff1a;&…

[附源码]SSM计算机毕业设计校园疫情防控管理系统JAVA

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

网络结点中心性 Centrality

结点中心性 node centrality 被认为是度量网络结点重要性的重要指标 常见的结点中心性有以下7种&#xff1a; &#xff08;以下各中心的概念在不同地方的定义可能不同&#xff0c;实际计算应查看使用工具的具体实现&#xff09; 1、度中心性 degree centrality 常被直接称为…

Spring Security权限管理原理

1.简介 授权是更具系统提前设置好的规则&#xff0c;给用户分配可以访问某一资源的权限&#xff0c;用户根据自己所具有的权限&#xff0c;去执行相应的操作&#xff0c;spring security提供的权限管理功能主要有两种&#xff1a; 基于过滤器的权限管理功能&#xff08;Filte…

Python学习笔记-数字类型

目录 1. 数字类型 1.1 整型 1.2 浮点数 1.3 复数 1.4 布尔类型 2. 常用内置数值计算函数库 3. 随机数函数 本文记录python中的基本数字类型信息&#xff0c;以及一些其他的相关知识点。 1. 数字类型 python中用于标识数字或者数值的数据类型&#xff0c;主要有如下分类…

盘点程序员的花式赚外快的骚操作

2022世界杯比赛难得如期开幕了&#xff0c;卡塔尔王子的表情包想必大家已经看到眼晕。 我拿2200亿和你玩&#xff0c;你踢一个0&#xff1a;2过不过分啊~ 现实中的投资可不比卡塔尔王子的表情包失落更多&#xff0c;毕竟投资有风险入行需谨慎。 然而悲惨的事实是&#xff0c;…

量表如何分析?

一、什么是量表 量表是一种测量工具&#xff0c;通常用来测量人们的主观态度、意见或价值观念。我们经常会在问卷中使用量表对调查对象进行测量&#xff0c;最常见到的就是李克特量表。 ‍1、定义&#xff1a;李克特量表 李克特量表是最常用的量表&#xff0c;是由美国社会心…

大数据平台功能

一 前言 计算机设备和信息数据的相互融合&#xff0c;对各个行业来说都是一次非常大的进步&#xff0c;已经渗入到工业、农业、商业、军事等领域&#xff0c;同时其大数据平台软件也得到一定发展。就目前来看&#xff0c;各类编程语言的发展、人工智能相关算法的应用、大数据时…

求树的直径算法以及证明

以下为两次dfs&#xff08;bfs&#xff09;的做法以及正确性证明。 算法步骤 &#xff08;1&#xff09;任取树上一点S&#xff0c;以S为源点BFS得S到各个顶点的d值&#xff1b; &#xff08;2&#xff09;取d值最大者之一为P&#xff0c;再以P为源点BFS得P到各个顶点的d值&am…

【计算机】可信平台模块Trusted Platform Module - TPM

简述 Brief Introduction TPM内部功能模块示意图&#xff1a; 引述 Trusted Platform Module Technology Overview (Windows) | Microsoft Learn&#xff1a; Trusted Platform Module (TPM) technology is designed to provide hardware-based, security-related functions.…

「区块链+数字身份」:DID 身份认证的新战场

美国经济学家布莱恩 • 阿瑟在其著作《技术的本质》中&#xff0c;写过这么一句话&#xff1a;「技术总是进行着这样一种循环&#xff0c;为解决老问题去采用新技术&#xff0c;新技术又引发新问题&#xff0c;新问题的解决又要诉诸更新的技术」。 区块链技术之所以能流行&…

在MacOS上实现两个网络调试助手的UDP通信测试

文章目录一、背景二、网络调试助手软件三、UDP通信过程一、背景 因为有一个项目要中会使用本机中两个应用程序之间的UDP通信。 因此本文记录一下怎么在MacOS上实现两个网络调试助手的UDP通信测试。 二、网络调试助手软件 我使用的网络调试助手软件是&#xff1a;网络调试助…

Redis实战——优惠券秒杀(超卖问题)

1 实现优惠券秒杀功能 下单时需要判断两点&#xff1a;1.秒杀是否开始或者结束2.库存是否充足 所以&#xff0c;我们的业务逻辑如下 1. 通过优惠券id获取优惠券信息 2.判断秒杀是否开始&#xff0c;如果未返回错误信息 3.判断秒杀是否结束&#xff0c;如果已经结束返回错误…

传奇登录器打不开的四种原因

最近很多传奇玩家或者GM都遇到了传奇登陆器打不开&#xff0c;没反应&#xff0c;提示无法访问指定设备等问题&#xff0c;导致很多游戏没有办法玩&#xff0c;让玩家心情沮丧&#xff0c;作为GM&#xff0c;那么就更伤心了&#xff0c;很多玩家进不来游戏&#xff0c;开服数千…