目录

写在开头

正文

一、界面布局

二、功能实现

1.显示在线地图和定位

2.基站信息的获取和显示

3.地理信息的获取和解析

4.显示栅格离线地图(.tpk)

5.显示矢量离线地图(.vtpk)

三、主要问题及解决方案


写在开头

这个APP的开发是我们这学期的一门课的期末大作业,要求主要有三点:显示栅格离线地图切片(.tpk)显示矢量离线地图切片(.vtpk)基于基站实现手机定位

作为第一次接触安卓开发的小白,从Android Studio的安装到最终实现功能,这中间的每一步我都走得很艰难。做APP的这一周我遇到大大小小很多问题,也重写了很多次代码。无数次想要放弃,但每次都告诉自己再坚持一下看能不能解决,最终成功做出了这个APP,可喜可贺。其实这个APP并不完善,但是第一次零基础做到这样,我已经很满意了。这里主要记录一下APP的实现过程以及自己遇到的各种问题和解决办法,希望对有需要的小伙伴有帮助。

正文

以实现功能为主,本文主要展示核心代码,关于代码细节和一些原理并未详细描述。

一、界面布局

根据功能设计,首先我的界面需要一个ArcGIS中的MapView,用来显示地图;还需要三个按钮,分别用来切换显示本地栅格、本地矢量、在线地图;另外需要两个TextView,分别用来显示基站信息和地理信息。

我的界面大概就长下面这样:

整个界面的结构是MapView在最外层,如下:

上述界面是直接用代码实现的。如果不用代码而是要手动调整的话,我也不知道怎么实现。下面说说实现具体步骤:

1.在如下图的位置中找到“res”文件夹下的“layout”文件夹里的一个叫做“activity_main.xml”的文件:

2.打开上述xml文件,第一次应该首先看的是设计界面,在右上角点击Code切换到代码界面:

3.在“RelativeLayout”标签里写上我们整个界面的设计代码,如下:

<com.esri.arcgisruntime.mapping.view.MapViewandroid:id="@+id/mapView"android:layout_width="match_parent"android:layout_height="match_parent" ><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_weight="1"android:orientation="vertical"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="40dp"android:orientation="horizontal"android:paddingLeft="20dp"android:paddingRight="20dp"><Buttonandroid:id="@+id/button1"android:layout_width="20dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="栅格" /><Buttonandroid:id="@+id/button2"android:layout_width="20dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="矢量" /><Buttonandroid:id="@+id/button3"android:layout_width="20dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="在线" /></LinearLayout><TextViewandroid:id="@+id/textView"android:layout_width="match_parent"android:layout_height="wrap_content"android:textColor="#FFFFFF"android:text="基站信息" /><TextViewandroid:id="@+id/lacationText"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textColor="#FFFFFF"android:text="地理位置" /></LinearLayout>
</com.esri.arcgisruntime.mapping.view.MapView>

4.返回到设计界面,可以查看界面是否是上述的布局。

5.在MainActivity.java的“onCreate”里添加对上述三个按钮的点击事件,主要实现按钮上文本的变化,代码如下:

btngrid.setOnClickListener(new View.OnClickListener() {//栅格按钮@Overridepublic void onClick(View view) {btngrid.setText("栅格(now)");btnvector.setText("矢量");btnonline.setText("在线");}});btnvector.setOnClickListener(new View.OnClickListener() {//矢量按钮@Overridepublic void onClick(View view) {btnvector.setText("矢量(now)");btngrid.setText("栅格");btnonline.setText("在线");}});btnonline.setOnClickListener(new View.OnClickListener() {//在线按钮@Overridepublic void onClick(View view) {btnonline.setText("在线(now)");btnvector.setText("矢量");btngrid.setText("栅格");}});

二、功能实现

1.显示在线地图和定位

在线地图和定位的显示直接参考ArcGIS的安卓开发教程。

在线地图显示:https://developers.arcgis.com/labs/android/create-a-starter-app/

定位显示:https://developers.arcgis.com/labs/android/display-and-track-your-location/

下面贴一下自己程序中的代码。

首先是在线地图显示函数。其中Basemap的Type可以改的,我这里是栅格地图,你也可以设置成矢量图、街景图等等。代码如下:

//显示在线地图private void setupMap() {if (mMapView != null) {Basemap.Type basemapType = Basemap.Type.IMAGERY_WITH_LABELS;double latitude = 34.09042;double longitude = -118.71511;int levelOfDetail = 6;map = new ArcGISMap(basemapType, latitude, longitude, levelOfDetail);mMapView.setMap(map);}}

重写三个函数,以正确显示在线地图,直接写在“MainActivity”类中。代码如下:

 @Overrideprotected void onPause() {if (mMapView != null) {mMapView.pause();}super.onPause();}@Overrideprotected void onResume() {super.onResume();if (mMapView != null) {mMapView.resume();}}@Overrideprotected void onDestroy() {if (mMapView != null) {mMapView.dispose();}super.onDestroy();}

定位显示(功能实现函数+导航权限开启许可函数):

//位置导航private void setupLocationDisplay() {mLocationDisplay = mMapView.getLocationDisplay();mLocationDisplay.addDataSourceStatusChangedListener(dataSourceStatusChangedEvent -> {// If LocationDisplay started OK or no error is reported, then continue.if (dataSourceStatusChangedEvent.isStarted() || dataSourceStatusChangedEvent.getError() == null) {return;}int requestPermissionsCode = 2;String[] requestPermissions = new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION};// If an error is found, handle the failure to start.// Check permissions to see if failure may be due to lack of permissions.if (!(ContextCompat.checkSelfPermission(MainActivity.this, requestPermissions[0]) == PackageManager.PERMISSION_GRANTED&& ContextCompat.checkSelfPermission(MainActivity.this, requestPermissions[1]) == PackageManager.PERMISSION_GRANTED)) {// If permissions are not already granted, request permission from the user.ActivityCompat.requestPermissions(MainActivity.this, requestPermissions, requestPermissionsCode);} else {// Report other unknown failure types to the user - for example, location services may not// be enabled on the device.String message = String.format("Error in DataSourceStatusChangedListener: %s", dataSourceStatusChangedEvent.getSource().getLocationDataSource().getError().getMessage());Toast.makeText(MainActivity.this, message, Toast.LENGTH_LONG).show();}});mLocationDisplay.setAutoPanMode(LocationDisplay.AutoPanMode.COMPASS_NAVIGATION);mLocationDisplay.startAsync();}@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {// If request is cancelled, the result arrays are empty.if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {// Location permission was granted. This would have been triggered in response to failing to start the// LocationDisplay, so try starting this again.mLocationDisplay.startAsync();} else {// If permission was denied, show toast to inform user what was chosen. If LocationDisplay is started again,// request permission UX will be shown again, option should be shown to allow never showing the UX again.// Alternative would be to disable functionality so request is not shown again.Toast.makeText(MainActivity.this, getResources().getString(R.string.location_permission_denied), Toast.LENGTH_SHORT).show();}}

调用方法:“在线地图显示”和“定位显示”在MainActivity.java的“onCreate”里调用,保证界面打开就能展示;另外“在线地图显示”在“在线按钮”中再调用一次,用于切换地图。OnCreate里调用代码:

mMapView = findViewById(R.id.mapView);
setupMap();
setupLocationDisplay();

最后,需要在app > manifests > AndroidManifest.xml里开启权限。

在线地图显示权限(网络访问+OpenGL渲染):

<uses-permission android:name="android.permission.INTERNET" />
<uses-feature android:glEsVersion="0x00020000" android:required="true" />

导航显示权限(GPS位置):

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

注意:导航权限开启许可函数(onRequestPermissionsResult)和三个Override的函数不需要调用,直接执行上述操作就行了。

效果图(在线地图+导航)展示如下。这是最终成果图,所以有基站信息和位置信息,我先马赛克掉了。

2.基站信息的获取和显示

先来了解一下什么是基站信息。基站信息主要指以下四个参数:

mcc:国家代码(中国为460)

mnc:网络类型(移动为0,联通为1,电信为sid)

lac:位置区域码

cid: 基站编号

上述基站信息是存储在数据库中的,我们只需要调用函数,它便能根据手机地址在数据库中查询所需信息。网上有很多现成的相关代码,我的代码参考了Android实现基站定位一文。

首先用一个结构体来存储基站信息,结构体构建如下:

 /** 基站信息结构体 */public class SCell {public int MCC;public int MNC;public int LAC;public int CID;}

下面是获取基站信息的代码:

//获取基站信息private String getBaseStationInformation(){StringBuffer sbtv = new StringBuffer();cell = new SCell();//基站信息List<CellInfo> all_cell_info;//所有基站信息sbtv.append("基站信息"+"\r\n");if (mTelephonyManager == null) {mTelephonyManager = (TelephonyManager) getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE);}// 返回值MCC + MNCString operator = mTelephonyManager.getNetworkOperator();if (operator != null && operator.length() > 3) {cell.MCC = Integer.parseInt(operator.substring(0, 3));cell.MNC = Integer.parseInt(operator.substring(3));sbtv.append("mcc:" + cell.MCC + ";mnc:" + cell.MNC + ";\r\n");}// 获取邻区基站信息if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED&& ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {all_cell_info = mTelephonyManager.getAllCellInfo();sbtv.append("基站数量:" + all_cell_info.size() + "\r\n");CellInfo cellInfo = all_cell_info.get(0);GsmCellLocation location = (GsmCellLocation) mTelephonyManager.getCellLocation();if (location == null)Toast.makeText(getApplicationContext(), "获取基站信息失败", Toast.LENGTH_SHORT).show();cell.CID = location.getCid();cell.LAC = location.getLac();sbtv.append("最近基站:"+"cid:" + cell.CID + ";lac:" + cell.LAC + ";\r\n");} else {Toast.makeText(getApplicationContext(), "请检查定位是否开启", Toast.LENGTH_SHORT).show();}return sbtv.toString();}

上述函数将返回一个字符串文本,包含四个基站信息,在OnCreate方法里调用该函数,将结果显示在TextView里。调用代码如下:

text1 = findViewById(R.id.textView);
text1.setText(getBaseStationInformation());

效果图展示:

3.地理信息的获取和解析

这一步对我来说应该最难实现、耗时最多的一个环节了,因为里面用到一些HTTP的接口,还用到了子线程。另外,这一步遇到一个具大的问题就是:获取地理信息和在线地图显示两者居然不能同时实现!具体原因及解决思路在第三个部分-“问题及解决方案”中再详细探讨。这里主要说说如何实现地理信息的获取。

获取到的地理信息包括:经纬度和地址。

获取地理信息的思路:通过GET请求,利用四个基站信息在接口地址查询,返回数据的格式为CSV/JSON/XML。具体的接口说明和参数说明可以访问这个网址:接口说明文档

这里给一个访问接口的例子:http://api.cellocation.com:81/cell/?mcc=460&mnc=1&lac=4301&ci=20986&output=csv。返回的数据如下:

0,40.008899,116.483642,903,"北京市朝阳区望京开发街道屏翠东路;利泽东街与屏翠东路路口东189米"

这是一串字符串,我们最终只需要显示经纬度和地理位置,其余的信息就不用管了。

知道了思路,下面说一下如何用代码来获取信息。代码主要包括两个函数:函数getStringInfo用来访问接口,返回上述的字符串;函数getLocaionInfo用来解析上述字符串,从中剔出经纬度和地址存储在结构体中。

地理信息存储结构体构建如下:

/** 经纬度和地理位置信息结构体 */public class SLocationInfo {public String latitude;public String longitude;public String address;}

函数getStringInfo:

/** get网站经纬度和地理位置信息 */private String getStringInfo(String domain) throws Exception {String resultString = "";/** 采用Android默认的HttpClient */HttpClient client = new DefaultHttpClient();/** 采用GET方法 */HttpGet get = new HttpGet(domain);try {/** 发起GET请求并获得返回数据 */HttpResponse response = client.execute(get);HttpEntity entity = response.getEntity();BufferedReader buffReader = new BufferedReader(new InputStreamReader(entity.getContent()));StringBuffer strBuff = new StringBuffer();String result = null;while ((result = buffReader.readLine()) != null) {strBuff.append(result);}resultString = strBuff.toString();} catch (Exception e) {Log.e(e.getMessage(), e.toString());throw new Exception("获取经纬度和地理位置出现错误:"+e.getMessage());} finally{get.abort();client = null;}return resultString;}

函数getLocaionInfo(在这里面调用上面的函数getStringInfo):

//解析获取的经纬度和地理位置信息
private String getLocaionInfo(String url) throws Exception {locationinfo = new SLocationInfo();StringBuffer sblocationinfo = new StringBuffer();String resultString = "";resultString = getStringInfo(url);sblocationinfo.append("位置信息"+"\r\n");/** 解析基站位置 */try{String errcode = "";String[] arr = resultString.split(",");errcode = arr[0];if (errcode.equals("0")){locationinfo.latitude = arr[1];locationinfo.longitude = arr[2];locationinfo.address = arr[4];sblocationinfo.append("经度:"+locationinfo.longitude+";纬度:"+locationinfo.latitude+";地理位置:"+locationinfo.address+"\r\n");}} catch (Exception e) {Log.e(e.getMessage(), e.toString());throw new Exception("获解析地理位置出现错误:"+e.getMessage());}return sblocationinfo.toString();
}

函数getLocaionInfo需要单独开设一个子线程来调用,因为访问网站是很耗时间的,子线程可以大大减少主线程的负担。但是在这个处理网站访问的子线程里不能处理UI,也就是在TextView里显示地理信息这一操作不能在子线程中实现,因此还需要使用一个UI子线程。前面说得可能有点绕,简单来说就是:网站访问子线程用于处理网站访问操作,当成功获得返回数据后,给UI子线程发送一个成功信号,然后UI子线程用于刷新界面,显示获取的数据。下面直接上代码:

定义用于通知UI子线程的成功信号和失败信号:

private static final int MSG_SUCCESS = 0;// 获取成功的标识
private static final int MSG_FAILURE = 1;// 获取失败的标识

网站访问子线程runnable:

private Runnable runnable = new Runnable() {// 重写run()方法,此方法在新的线程中运行,用于访问网站获取经纬度和地理位置@Overridepublic void run() {try {locationText = getLocaionInfo(url);} catch (Exception e) {e.printStackTrace();handler.obtainMessage(MSG_FAILURE).sendToTarget();//给UI子线程发送失败信息} finally {handler.obtainMessage(MSG_SUCCESS).sendToTarget();//给UI子线程发送成功信息}}};

UI子线程handler:

private Handler handler = new Handler() {//UI子线程,用于显示经纬度和地理位置信息@Overridepublic void handleMessage(Message msg) {try{switch (msg.what){case MSG_SUCCESS:text2.setText(locationText);Log.e("Success", "解析基站位置成功");break;case MSG_FAILURE:Log.e("Failure", "解析基站位置失败");break;}}catch (Exception e) {e.printStackTrace();}}};

在OnCreate中运行子线程:

url = "http://api.cellocation.com:81/cell/?mcc=" + cell.MCC + "&mnc=" + cell.MNC + "&lac=" + cell.LAC + "&ci=" + cell.CID + "&output=csv";
text2 = findViewById(R.id.lacationText);
try {mThread = new Thread(runnable);mThread.start();} catch (Exception e) {Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
}

效果图展示:

4.显示栅格离线地图(.tpk)

tpk数据来源:由影像图通过ArcGIS制作而成,具体教程网上很多,大家可以自行搜索。

本地栅格图的显示有两个注意点:一是数据存储位置,二是数据范围。首先是数据存储位置,我使用的绝对位置,所以只有真机测试才能打开数据,如果用模拟器的话就要用其他方式读取数据存储位置了。数据范围一定要包含自己测试所用手机的GPS位置,如果没有,那么就无法显示地图。具体代码比较简单,如下:

定义绝对路径和栅格地图:

private String dirpath = Environment.getExternalStorageDirectory().getAbsolutePath();//本地数据路径
private ArcGISTiledLayer localTiledLayer;//本地栅格地图

本地栅格显示函数:

//打开本地栅格private void openMyTPK(){Toast.makeText(getApplicationContext(), dirpath + "/ArcGIS" + "/santai.tpk", Toast.LENGTH_SHORT).show();String fileLayer = dirpath+"/ArcGIS"+"/santai.tpk";localTiledLayer = new ArcGISTiledLayer(fileLayer);baseMap = new Basemap(localTiledLayer);map = new ArcGISMap(baseMap);mMapView.setMap(map);}

在“栅格”按钮里调用上述函数,效果图展示如下:

5.显示矢量离线地图(.vtpk)

vtpk数据来源:网上下载。

矢量离线地图显示的代码和前面的栅格地图几乎一样,唯一不一样的地方就是定义图层的格式不同。栅格是ArcGISTiledLayer,矢量是ArcGISVectorTiledLayer。下面是代码:

//打开本地矢量地图private void openMyVTPK() {try {Toast.makeText(getApplicationContext(), dirpath+"/ArcGIS"+"/china.vtpk", Toast.LENGTH_SHORT).show();String fileLayer = dirpath+"/ArcGIS"+"/china.vtpk";vTiledLayer = new ArcGISVectorTiledLayer(fileLayer);baseMap = new Basemap(vTiledLayer);map = new ArcGISMap(baseMap);mMapView.setMap(map);} catch (Exception e){String eResult = e.getMessage();Toast.makeText(MainActivity.this, eResult, Toast.LENGTH_SHORT).show();}}

效果图展示:

三、主要问题及解决方案

1.用安卓模拟器运行app时出现找不到device的错误

这是因为电脑BIOS中的虚拟技术没有打开,重启电脑按F2(因电脑而异,我的是联想)进入BIOS打开就行了。教程网上搜索一下就有,需要注意的是进入BIOS界面的时间是电脑开机后刚刚亮的那个瞬间,早了晚了都进不去,我重启了四次才进去。。。

2.本地地图显示不出来

按照我的代码,要想正确显示本地地图一定要在真机上测试,因为是绝对路径。路径是:本记SD卡->ArcGIS(自己建的文件夹)->xxx.tpk/xxx.vtpk。还要注意两点:1.保证离线地图上有自己手机目前的位置;2.开启读写权限,在AndroidManifest.xml的manifest标签写入代码如下:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

3.Get请求中的代码找不到对应的方法,例如:DefaultHttpClient

这和Android的SDK版本有关,我的编译版本是28,最小版本是19。在我使用的版本中安卓弃用了上述的一些方法,网上有说更换版本的,但是很麻烦不说还会造成其他代码的冲突。其实在build.gradle(app)中加入所需的包就行了,在android块中写入:

useLibrary'org.apache.http.legacy'

然后点击右上角的“Sync Now”,这样就可以正常使用Get方法了。

4.点击按钮,app就闪退

原因不太清楚,但解决办法是:在AndroidManifest.xml的application标签下添加如下代码:

<uses-library android:name="org.apache.http.legacy" android:required="false"/>

5.Get获取地理信息与在线地图显示不能同时实现

原因:获取地理信息的网址是Http协议,即明文协议,而在线地图是Https协议,Android Studio默认Https协议。不做任何设置的话,能显示在线地图,但是不能获取到地理信息。

解决方法:添加一个xml文件,作为安全协议设置,保证Http和Https都能访问。

具体步骤:在res文件夹下新建xml文件夹,然后在xml文件夹下新建一个名为“network_security_config.xml”的文件,在里面写入以下代码:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config><base-config cleartextTrafficPermitted="true"><trust-anchors><certificates src="system" /><certificates src="user" /></trust-anchors></base-config>
</network-security-config>

6.运行app时出现闪退现象

这个可能的原因有很多。我自己是在运行app前没有提前打开GPS,解决办法就是要记得提前打开GPS。

移动GIS开发:手机基站定位+离线切片地图(矢量vtpk+栅格tpk)导航安卓APP相关推荐

  1. 【2017年第1期】手机基站定位数据可视分析

    李海生1,2,黄媛洁1,2,宋璇1,2,杜军平3,陈国润4,丁富强4 1 北京工商大学计算机与信息工程学院,北京 1000482 食品安全大数据技术北京市重点实验室,北京 1000483 北京邮电大学 ...

  2. 手机基站定位(安卓手机定位源码)

    下面是手机基站定位代码: public class CellIDInfo {public int cellId;public String mobileCountryCode;public Strin ...

  3. 手机基站定位数据可视分析

    1 引言 随着手机等移动终端的普及,在城市中2G/3G/4G网络已经基本实现全区域覆盖.根据国家工业和信息化部统计,截至2015年,移动电话用户已达到13亿户,移动电话用户普及率达95.5部/百人,人 ...

  4. Android手机智能定位并在地图上显示地址

    最近做的项目用到了GPS.Wifi.基站三种不同方式进行定位,研究一下发现高德地图提供的智能选择定位方式进行定位较好,就写了下面相关代码进行定位并在地图上显示.有些写的不详细,大家可以去参考官方文档. ...

  5. 高德sdk定位当前位置_单次定位-获取位置-开发指南-iOS 定位SDK | 高德地图API

    iOS定位SDK提供的单次定位方法基于苹果定位核心,苹果定位核心会在设备移动时连续返回定位结果,高德在此基础上封装了单次定位.当设备可以正常联网时,还可以返回该定位点的对应的中国境内位置信息(包括:省 ...

  6. 设置电子围栏 高德地图_地理围栏-辅助功能-开发指南-Android 定位SDK | 高德地图API...

    以下内容自定位 SDK V3.2.0 版本后支持. 第一步,创建地理围栏 地理围栏没有最大个数限制,您可以无限制的创建围栏.但请您根据业务需求合理的创建围栏,控制围栏个数可以有效的保证程序执行效率.定 ...

  7. ios 高德获取定位_单次定位-获取位置-开发指南-iOS 定位SDK | 高德地图API

    iOS定位SDK提供的单次定位方法基于苹果定位核心,苹果定位核心会在设备移动时连续返回定位结果,高德在此基础上封装了单次定位.当设备可以正常联网时,还可以返回该定位点的对应的中国境内位置信息(包括:省 ...

  8. php 开发高德地图地理围栏,地理围栏-辅助功能-开发指南-Android 定位SDK | 高德地图API...

    以下内容自定位 SDK V3.2.0 版本后支持. 第一步,创建地理围栏 地理围栏没有最大个数限制,您可以无限制的创建围栏.但请您根据业务需求合理的创建围栏,控制围栏个数可以有效的保证程序执行效率.定 ...

  9. vue使用高德地图画电子围栏_地理围栏-辅助功能-开发指南-iOS 定位SDK | 高德地图API...

    以下内容自 iOS 定位SDK V2.3.0 后支持. 第 1 步,引入头文件 在调用地理围栏功能的类中引入AMapFoundationKit.h和AMapLocationKit.h这两个头文件,注意 ...

  10. 设置电子围栏 高德地图_地理围栏-辅助功能-开发指南-iOS 定位SDK | 高德地图API...

    以下内容自 iOS 定位SDK V2.3.0 后支持. 第 1 步,引入头文件 在调用地理围栏功能的类中引入AMapFoundationKit.h和AMapLocationKit.h这两个头文件,注意 ...

最新文章

  1. Hinton口中破解宇宙终极秘密的GPT-3厉害在哪?这有篇涂鸦详解
  2. 数据中心胶体电池的使用寿命
  3. 深度学习框架TensorFlow(1.安装和简介)
  4. Mysql数据库函数(数字,字符串,日期时间)
  5. 不能将紧实的字段 绑定到_代码整洁之道【笔记】
  6. C语言多文件编程基本格式
  7. C++ Socket编程步骤
  8. 征服ASP.NET Ajax典型应用 (试读)
  9. java文件删除失败
  10. c语言里除法符号,c语言整除符号(c语言switch用法举例)
  11. git commit --amend 的使用记录
  12. n次独立重复试验暨伯努利试验
  13. 【转载】Android 第三方ROM定制之适配谷歌Play Store
  14. 一元四次方程求解C++实现
  15. 梦想从来不是手里的钻石,而是放到天上的风筝!
  16. 32位plsql连接64位Oracle数据库
  17. 安卓手机查看已经连接的WIFI密码
  18. 一个博士毕业之际写的一些发文章的心得
  19. Scrapy 浅入浅出
  20. 全球主流云桌面传输协议

热门文章

  1. 【国产单片机】华大HC32L13系列使用printf进行调试(多种方法)
  2. 新手怎么创建域名?创建域名后怎么样建站?
  3. 哈哈,用FlexGrid做开发,轻松处理百万级表格数据
  4. 程序员在体制内的工作与生活是怎样的?
  5. 高频数据库分库分表面试题解析
  6. 邮件系统安全篇:GCMAil邮件系统怎样利用DNS黑名单高效实现反垃圾邮件过滤
  7. Windows***与提权技巧汇总
  8. 爬虫实战(三)----使用百度API获取经纬度/地址
  9. 什么样的公司需要IT外包?
  10. ELK之Kibana入门及使用