Android LBS相关

2024-08-21 22:48
文章标签 android 相关 lbs

本文主要是介绍Android LBS相关,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

##Android定位/LBS

刚刚写完一个定位的小需求,小记一下。

需求:

获取当前手机所在城市/国家

当看到这个需求的时候,我打算用百度、高德或者QQ的地图SDK的,但是考虑到国外定位的准确性,BOSS说用Google地图。可是国内Android手机基本都是太监(阉割了谷歌服务),所以只能放弃了。

原本已经打算用高德好了,但是发现了一个谷歌地图的API,即:

maps.google.cn/maps/api/geocode/json?language=zh-CN&sensor=true&latlng=-33.86984542,151.20689392

用浏览器访问这个地址,你会得到当前经纬度的定位信息,这里的-33.86984542,151.20689392对应的是悉尼。

那么就好办了,完成上面的需求只需要一下几个步骤了:

0.简略了解谷歌地图的api 1.获取手机的经纬度 2.根据经纬度访问谷歌地图的api 3.解析返回的数据


####0.谷歌地图的API 在开始之前,先解释一下上面的API地址,官方文档很详细,这里我简要记载一些基本的。

1.language=zh-CN 代表返回的是中文,当然language=en就是英文了。 2.用.cn而不是.com是因为伟大的GFW。 3.json 代表返回的是json数据,这里还可以是xml。 4.sensor 顾名思义,是否支持传感器。 5.latlng 就是经纬度了,用逗号隔开。

####1.获取手机当前位置的经纬度

....private long locationRefreshMinTime = 5000;
private long locationRefreshMinDistance = 0;....private void getLocalInformation() {//获取LocationManager实例LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {//如果GPS可用locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, locationRefreshMinTime, locationRefreshMinDistance, locationListener);} else {//如果GPS不可用locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, locationRefreshMinTime, locationRefreshMinDistance, locationListener);}
}

通过LocationManager的requestLocationUpdates()方法去请求当前的Location信息,requestLocationUpdates()接收四个参数:

1.provider,供应者,即Location的信息从谁那里获取,这里有两个供应者: LocationManager.GPS_PROVIDER ,LocationManager.NETWORK_PROVIDER。 2.minTime,最小时间,其实就是更新的间隔时间,单位是毫秒。 3.minDistance,最小距离,其实就是更新的最小偏移距离,即当手机的偏移位置超过了这个值,才进行更新。 4.listener,LocationListener,Location信息变化时调用的接口。

下面去实现LocationListener,代码如下:

private LocationListener locationListener = new LocationListener() {@Overridepublic void onStatusChanged(String provider, int status, Bundle extras) {// 当Location信息供应者发生变化的时候调用}@Overridepublic void onProviderEnabled(String provider) {// Provider被disable时调用,比如GPS被关闭   }@Overridepublic void onProviderDisabled(String provider) {//  Provider被enable时调用,比如GPS被打开   }@Overridepublic void onLocationChanged(Location location) {// 当坐标改变时调用if (location != null) {latitude = location.getLatitude() + "";longitude = location.getLongitude() + "";LogUtil.e(tag, "经度:" + latitude + "\n" + "纬度:" + longitude);editor.putString(SharedPreferencesConst.LOCATION_INFORMATION_LATITUDE, latitude);editor.putString(SharedPreferencesConst.LOCATION_INFORMATION_LONGITUDE, longitude);editor.commit();thisTime = location.getTime();LogUtil.e(tag, "thisTime = " + thisTime);LogUtil.e(tag, "lastTime = " + lastTime);LogUtil.e(tag, "thisTime - lastTime = " + (thisTime - lastTime));if (thisTime - lastTime > intervalTime || locality.equals(" ") || country.equals(" ")) {lastTime = thisTime;editor.putLong(SharedPreferencesConst.LOCATION_INFORMATION_UPDATE_LAST_TIME, thisTime);editor.commit();if (isAnalyzeJson) {} else {analyzeJson();}}}}
};

有些地方加了注释,是因为我实际开发需求才需要这些代码,与本文的探讨无关,所以先注释掉。

如上代码,我们分别实现了LocationListener的四个接口,在相应的状态下去处理事务,当位置信息发生变化时,调用了onLocationChanged(Location location),如果location不为空,即获取到了当前手机的地理位置信息。


####1.根据经纬度访问谷歌地图的api

在上面的代码中,我们获取了信息之后,我调用了我自己写的”analyzeJson()”方法去获取并解析数据,代码如下:

private void analyzeJson() {isAnalyzeJson = true;LogUtil.e(tag, "analyzeJson()");//格式化访问的地址String urlString = String.format(iNFOMATION_URL, Double.valueOf(latitude), Double.valueOf(longitude));parseJsonString(getJsonStringFromUrl(urlString));for (int i = 0; i < loactions.size(); i++) {ArrayList<String> typesList = loactions.get(i).typesList;int typesListSize = typesList.size();for (int j = 0; j < typesListSize; j++) {if (typesList.get(j).equals("country")) {hasCountry = true;country = loactions.get(i).formatted_address;editor.putString(SharedPreferencesConst.LOCATION_INFORMATION_COUNTRY, loactions.get(i).formatted_address);editor.commit();}}ArrayList<ADDRESS_COMPONENTS> address_components_list = loactions.get(i).address_components_list;int address_components_list_size = address_components_list.size();for (int k = 0; k < address_components_list_size; k++) {ADDRESS_COMPONENTS address_components = address_components_list.get(k);ArrayList<String> address_components_typesList = address_components.typesList;int address_components_typesListSize = address_components_typesList.size();for (int j = 0; j < address_components_typesListSize; j++) {if (address_components_typesList.get(j).equals("locality")) {hasLocality = true;locality = address_components.long_name;editor.putString(SharedPreferencesConst.LOCATION_INFORMATION_LOCALITY, address_components.long_name);editor.commit();}if (address_components_typesList.get(j).equals("country")) {hasCountry = true;country = address_components.long_name;editor.putString(SharedPreferencesConst.LOCATION_INFORMATION_COUNTRY, address_components.long_name);editor.commit();}}}}if (!hasCountry) {country = " ";editor.putString(SharedPreferencesConst.LOCATION_INFORMATION_COUNTRY, country);editor.commit();}if (!hasLocality) {locality = " ";editor.putString(SharedPreferencesConst.LOCATION_INFORMATION_LOCALITY, locality);editor.commit();}LogUtil.e(tag, "analyzeJson(),locality = " + locality);LogUtil.e(tag, "analyzeJson(),country = " + country);isAnalyzeJson = false;hasCountry = false;hasLocality = false;
}

首先根据location.getLatitude()location.getLongitude()获取到的经纬度去组织API访问地址:

private static final String iNFOMATION_URL = "http://maps.google.cn/maps/api/geocode/json?language=zh-CN&sensor=true&latlng=%1$s,%2$s";
...
String urlString = String.format(iNFOMATION_URL, Double.valueOf(latitude), Double.valueOf(longitude));//组织Url地址

接着调用getJsonStringFromUrl(String url)去访问API地址:

private String getJsonStringFromUrl(String url) {LogUtil.e(tag, "getJsonStringFromUrl(),url = " + url);//设置线程的策略,获取log信息StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectDiskReads().detectDiskWrites().detectNetwork().penaltyLog().build());StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectLeakedSqlLiteObjects().penaltyLog().penaltyDeath().build());URL cityInfoUrl;byte[] data = new byte[] {};try {cityInfoUrl = new URL(url);HttpURLConnection connection = (HttpURLConnection) cityInfoUrl.openConnection();connection.setReadTimeout(5 * 1000);connection.setRequestMethod("GET");InputStream inStream = connection.getInputStream();data = readInputStream(inStream);return (new String(data));} catch (Exception e) {e.printStackTrace();}return (new String(data));
}

####2.解析数据 上面调用getJsonStringFromUrl(String url)去访问API地址后,返回了当前手机经纬度的地理信息,接着就要解析这一大坨信息了。 调用parseJsonString()方法去解析获取到的joson数据:

private ArrayList<LOCATION> loactions = new ArrayList<LOCATION>();
....
private void parseJsonString(String jsonString) {try {JSONObject json = new JSONObject(jsonString);JSONArray results = json.getJSONArray("results");int resultsLength = results.length();for (int i = 0; i < resultsLength; i++) {JSONObject results_item = results.getJSONObject(i);loactions.add(LOCATION.fromJson(results_item));}} catch (JSONException e) {e.printStackTrace();}
}

下面是用于解析返回Json数据的实体类。 因为是实际开发的项目,这里我使用了开源的ActiveAndroid。

###LOCATION类: @Table(name = “LOCATION”) public class LOCATION extends Model implements Serializable { private static final long serialVersionUID = 1L;

	@Column(name = "formatted_address")public String formatted_address;@Column(name = "place_id")public String place_id;public ArrayList<ADDRESS_COMPONENTS> address_components_list = new ArrayList<ADDRESS_COMPONENTS>();public ArrayList<GEOMETRY> geometry_list = new ArrayList<GEOMETRY>();public ArrayList<String> typesList = new ArrayList<String>();public static LOCATION fromJson(JSONObject jsonObject) throws JSONException {if (null == jsonObject) {return null;}LOCATION localItem = new LOCATION();localItem.formatted_address = jsonObject.optString("formatted_address");localItem.place_id = jsonObject.optString("place_id");JSONArray address_components = jsonObject.optJSONArray("address_components");if (address_components != null) {for (int i = 0; i < address_components.length(); i++) {if (localItem.address_components_list != null) {localItem.address_components_list.add(ADDRESS_COMPONENTS.fromJson(address_components.getJSONObject(i)));}}}JSONArray geometry = jsonObject.optJSONArray("geometry");if (geometry != null) {for (int i = 0; i < geometry.length(); i++) {if (localItem.geometry_list != null) {localItem.geometry_list.add(GEOMETRY.fromJson(geometry.getJSONObject(i)));}}}JSONArray types = jsonObject.optJSONArray("types");if (types != null) {for (int i = 0; i < types.length(); i++) {if (localItem.typesList != null) {localItem.typesList.add(types.getString(i));}}}return localItem;}
}

###ADDRESS_COMPONENTS类:

public class ADDRESS_COMPONENTS extends Model implements Serializable {private static final String tag = "ADDRESS_COMPONENTS";private static final long serialVersionUID = 1L;@Column(name = "long_name")public String long_name;@Column(name = "short_name")public String short_name;public ArrayList<String> typesList = new ArrayList<String>();public static ADDRESS_COMPONENTS fromJson(JSONObject jsonObject) throws JSONException {if (null == jsonObject) {return null;}ADDRESS_COMPONENTS localItem = new ADDRESS_COMPONENTS();localItem.long_name = jsonObject.optString("long_name");localItem.short_name = jsonObject.optString("short_name");JSONArray types = jsonObject.optJSONArray("types");if (types != null) {for (int i = 0; i < types.length(); i++) {if (localItem.typesList != null) {localItem.typesList.add(types.getString(i));}}}return localItem;}
}

###GEOMETRY类:

public class GEOMETRY extends Model implements Serializable {private static final String tag = "GEOMETRY";private static final long serialVersionUID = 1L;@Column(name = "location_type")public String location_type;@Column(name = "lat")public String lat;@Column(name = "lng")public String lng;public ArrayList<String> location = new ArrayList<String>();public static GEOMETRY fromJson(JSONObject jsonObject) throws JSONException {if (null == jsonObject) {return null;}GEOMETRY localItem = new GEOMETRY();localItem.location_type = jsonObject.optString("location_type");JSONObject location = jsonObject.getJSONObject("location");localItem.lat = location.optString("lat");localItem.lng = location.optString("lng");return localItem;}
}

通过以上的方法,就完成了API返回数据的解析,接着对数据进行遍历,判断types来获取相应的数据。

例如 types 包含 country,那么当前层级下的 long_name 对应的就是国家。 下面给出一下 types 所拥有的类型值:

street_number:表示精确的街道编号。
airport:表示机场。
premise:表示已命名的位置,通常是具有常用名称的建筑物或建筑群。
neighborhood:表示已命名的邻近地区。
sublocality_level_1:表示仅次于地区级别的1级行政实体。
sublocality_level_2:表示仅次于地区级别的2级行政实体。
sublocality_level_3:表示仅次于地区级别的3级行政实体。
administrative_area_level_1:表示仅次于国家级别的1级行政实体,中国为“省”。
administrative_area_level_2:表示仅次于国家级别的2级行政实体,中国为“市”。
administrative_area_level_3:表示仅次于国家级别的3级行政实体,中国为“县”。
sublocality:
postal_code 表示邮政编码。
political:表示某个行政管理区的多边形。
route:表示一条已命名的路线。
street_address:一个精确的街道地址。
locality:表示合并的市镇级别政治实体。(城市)
country:国家政治实体

最后,因为获取并解析数据是一个耗时的操作,所以这些操作应该写在Service中。 因为是公司项目,所以就不能上Demo了。 下面附上我获取LocationInrmation的完整代码,其实主要的操作都在这里了:

public class LocationInformationService extends Service {public static final String tag = "LocationInformationService";public static final String LOCATIONSTATUS = "com.qzmobile.android.location";private static final String iNFOMATION_URL = "http://maps.google.cn/maps/api/geocode/json?language=zh-CN&sensor=true&latlng=%1$s,%2$s";// private long intervalTime = 1000 * 60 * 30;private long intervalTime = 5000;private long locationRefreshMinTime = 5000;private long locationRefreshMinDistance = 0;private SharedPreferences shared;private SharedPreferences.Editor editor;private String latitude;private String longitude;private long lastTime;private long thisTime;private ArrayList<LOCATION> loactions = new ArrayList<LOCATION>();private String locality;private String country;private boolean isAnalyzeJson = false;private boolean hasCountry = false;private boolean hasLocality = false;@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {return super.onStartCommand(intent, flags, startId);}@Overridepublic void onCreate() {LogUtil.e(tag, "onCreate()");super.onCreate();shared = getSharedPreferences(SharedPreferencesConst.LOCATION_INFORMATION, 0);editor = shared.edit();initData();getLocalInformation();}private void initData() {LogUtil.e(tag, "initData()");latitude = shared.getString(SharedPreferencesConst.LOCATION_INFORMATION_LATITUDE, "0.00");longitude = shared.getString(SharedPreferencesConst.LOCATION_INFORMATION_LONGITUDE, "0.00");lastTime = shared.getLong(SharedPreferencesConst.LOCATION_INFORMATION_UPDATE_LAST_TIME, 0);locality = shared.getString(SharedPreferencesConst.LOCATION_INFORMATION_LOCALITY, " ");country = shared.getString(SharedPreferencesConst.LOCATION_INFORMATION_COUNTRY, " ");}private void getLocalInformation() {LogUtil.e(tag, "getLocalInformation()");LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {LogUtil.e(tag, "GPS_PROVIDER");locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, locationRefreshMinTime, locationRefreshMinDistance, locationListener);} else {LogUtil.e(tag, "NETWORK_PROVIDER");locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, locationRefreshMinTime, locationRefreshMinDistance, locationListener);}}@Overridepublic IBinder onBind(Intent intent) {return null;}private LocationListener locationListener = new LocationListener() {@Overridepublic void onStatusChanged(String provider, int status, Bundle extras) {LogUtil.e(tag, "onStatusChanged");}@Overridepublic void onProviderEnabled(String provider) {LogUtil.e(tag, "onProviderEnabled");}@Overridepublic void onProviderDisabled(String provider) {LogUtil.e(tag, "onProviderDisabled");}@Overridepublic void onLocationChanged(Location location) {LogUtil.e(tag, "onLocationChanged");if (location != null) {latitude = location.getLatitude() + "";longitude = location.getLongitude() + "";LogUtil.e(tag, "经度:" + latitude + "\n" + "纬度:" + longitude);editor.putString(SharedPreferencesConst.LOCATION_INFORMATION_LATITUDE, latitude);editor.putString(SharedPreferencesConst.LOCATION_INFORMATION_LONGITUDE, longitude);editor.commit();thisTime = location.getTime();LogUtil.e(tag, "thisTime = " + thisTime);LogUtil.e(tag, "lastTime = " + lastTime);LogUtil.e(tag, "thisTime - lastTime = " + (thisTime - lastTime));if (thisTime - lastTime > intervalTime || locality.equals(" ") || country.equals(" ")) {lastTime = thisTime;editor.putLong(SharedPreferencesConst.LOCATION_INFORMATION_UPDATE_LAST_TIME, thisTime);editor.commit();if (isAnalyzeJson) {} else {analyzeJson();}}}}};private void analyzeJson() {isAnalyzeJson = true;LogUtil.e(tag, "analyzeJson()");String urlString = String.format(iNFOMATION_URL, Double.valueOf(latitude), Double.valueOf(longitude));parseJsonString(getJsonStringFromUrl(urlString));for (int i = 0; i < loactions.size(); i++) {ArrayList<String> typesList = loactions.get(i).typesList;int typesListSize = typesList.size();for (int j = 0; j < typesListSize; j++) {if (typesList.get(j).equals("country")) {hasCountry = true;country = loactions.get(i).formatted_address;editor.putString(SharedPreferencesConst.LOCATION_INFORMATION_COUNTRY, loactions.get(i).formatted_address);editor.commit();}}ArrayList<ADDRESS_COMPONENTS> address_components_list = loactions.get(i).address_components_list;int address_components_list_size = address_components_list.size();for (int k = 0; k < address_components_list_size; k++) {ADDRESS_COMPONENTS address_components = address_components_list.get(k);ArrayList<String> address_components_typesList = address_components.typesList;int address_components_typesListSize = address_components_typesList.size();for (int j = 0; j < address_components_typesListSize; j++) {if (address_components_typesList.get(j).equals("locality")) {hasLocality = true;locality = address_components.long_name;editor.putString(SharedPreferencesConst.LOCATION_INFORMATION_LOCALITY, address_components.long_name);editor.commit();}if (address_components_typesList.get(j).equals("country")) {hasCountry = true;country = address_components.long_name;editor.putString(SharedPreferencesConst.LOCATION_INFORMATION_COUNTRY, address_components.long_name);editor.commit();}}}}if (!hasCountry) {country = " ";editor.putString(SharedPreferencesConst.LOCATION_INFORMATION_COUNTRY, country);editor.commit();}if (!hasLocality) {locality = " ";editor.putString(SharedPreferencesConst.LOCATION_INFORMATION_LOCALITY, locality);editor.commit();}LogUtil.e(tag, "analyzeJson(),locality = " + locality);LogUtil.e(tag, "analyzeJson(),country = " + country);isAnalyzeJson = false;hasCountry = false;hasLocality = false;}private String getJsonStringFromUrl(String url) {LogUtil.e(tag, "getJsonStringFromUrl(),url = " + url);StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectDiskReads().detectDiskWrites().detectNetwork().penaltyLog().build());StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectLeakedSqlLiteObjects().penaltyLog().penaltyDeath().build());URL cityInfoUrl;byte[] data = new byte[] {};try {cityInfoUrl = new URL(url);HttpURLConnection connection = (HttpURLConnection) cityInfoUrl.openConnection();connection.setReadTimeout(5 * 1000);connection.setRequestMethod("GET");InputStream inStream = connection.getInputStream();data = readInputStream(inStream);return (new String(data));} catch (Exception e) {e.printStackTrace();}return (new String(data));}private byte[] readInputStream(InputStream inStream) throws Exception {ByteArrayOutputStream outStream = new ByteArrayOutputStream();byte[] buffer = new byte[1024];int len = 0;while ((len = inStream.read(buffer)) != -1) {outStream.write(buffer, 0, len);}inStream.close();return outStream.toByteArray();}private void parseJsonString(String jsonString) {try {JSONObject json = new JSONObject(jsonString);JSONArray results = json.getJSONArray("results");int resultsLength = results.length();for (int i = 0; i < resultsLength; i++) {JSONObject results_item = results.getJSONObject(i);loactions.add(LOCATION.fromJson(results_item));}} catch (JSONException e) {e.printStackTrace();}}
}

Whitelaning’s wiki It’s very easy to be different but very difficult to be better.

这篇关于Android LBS相关的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1094505

相关文章

sqlite3 相关知识

WAL 模式 VS 回滚模式 特性WAL 模式回滚模式(Rollback Journal)定义使用写前日志来记录变更。使用回滚日志来记录事务的所有修改。特点更高的并发性和性能;支持多读者和单写者。支持安全的事务回滚,但并发性较低。性能写入性能更好,尤其是读多写少的场景。写操作会造成较大的性能开销,尤其是在事务开始时。写入流程数据首先写入 WAL 文件,然后才从 WAL 刷新到主数据库。数据在开始

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

android-opencv-jni

//------------------start opencv--------------------@Override public void onResume(){ super.onResume(); //通过OpenCV引擎服务加载并初始化OpenCV类库,所谓OpenCV引擎服务即是 //OpenCV_2.4.3.2_Manager_2.4_*.apk程序包,存

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compose中的列表和滚动

两个月冲刺软考——访问位与修改位的题型(淘汰哪一页);内聚的类型;关于码制的知识点;地址映射的相关内容

1.访问位与修改位的题型(淘汰哪一页) 访问位:为1时表示在内存期间被访问过,为0时表示未被访问;修改位:为1时表示该页面自从被装入内存后被修改过,为0时表示未修改过。 置换页面时,最先置换访问位和修改位为00的,其次是01(没被访问但被修改过)的,之后是10(被访问了但没被修改过),最后是11。 2.内聚的类型 功能内聚:完成一个单一功能,各个部分协同工作,缺一不可。 顺序内聚:

log4j2相关配置说明以及${sys:catalina.home}应用

${sys:catalina.home} 等价于 System.getProperty("catalina.home") 就是Tomcat的根目录:  C:\apache-tomcat-7.0.77 <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5p %c{1}:%L - %msg%n" /> 2017-08-10

Node Linux相关安装

下载经编译好的文件cd /optwget https://nodejs.org/dist/v10.15.3/node-v10.15.3-linux-x64.tar.gztar -xvf node-v10.15.3-linux-x64.tar.gzln -s /opt/node-v10.15.3-linux-x64/bin/npm /usr/local/bin/ln -s /opt/nod

git ssh key相关

step1、进入.ssh文件夹   (windows下 下载git客户端)   cd ~/.ssh(windows mkdir ~/.ssh) step2、配置name和email git config --global user.name "你的名称"git config --global user.email "你的邮箱" step3、生成key ssh-keygen

Android 10.0 mtk平板camera2横屏预览旋转90度横屏拍照图片旋转90度功能实现

1.前言 在10.0的系统rom定制化开发中,在进行一些平板等默认横屏的设备开发的过程中,需要在进入camera2的 时候,默认预览图像也是需要横屏显示的,在上一篇已经实现了横屏预览功能,然后发现横屏预览后,拍照保存的图片 依然是竖屏的,所以说同样需要将图片也保存为横屏图标了,所以就需要看下mtk的camera2的相关横屏保存图片功能, 如何实现实现横屏保存图片功能 如图所示: 2.mtk