接着《ArcGIS for Android 例子Offline Editor (BETA)(一)》要实现刷新,下载Geodatabase和同步Geodatabase的事件,在实现这些事件方法之前,先在GDBUtil这个工具类中加入一个变量GeodatabaseTask类型的变量 geoTask,和两个静态的方法:showMessage、showProgress用来显示Toast信息和控制OfflineEditorActivity中Progress的显示和隐藏的,两方法代码如下:
//显示toast信息
public static void showMessage(final Activity activity ,final String msg){
activity.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(activity, msg, Toast.LENGTH_SHORT).show();
}
});
}
//显示和隐藏OfflineEditorActivity的progress
public static void showProgress(final OfflineEditorActivity activity , final boolean isshow){
activity.runOnUiThread(new Runnable() {
public void run() {
activity.setProgressBarIndeterminateVisibility(isshow);
}
});
}
一、刷新方法的实现
在OfflineEditorActivity中刷新按钮的代码还是比较容易的,只要移除MapView中所有的FeatureLayer,只要在重新加载配置文件,在重新加载FeatureLayer,代码如下:
/**
* 刷新
*/
public void loadLayers(View v) {
Layer[] layers= mMapView.getLayers();
//移除所有的ArcGISFeatureLayer
for(Layer layer : layers){
if(layer instanceof ArcGISFeatureLayer){
mMapView.removeLayer(layer);
}
}
//重新加载ArcGISFeatureLayer
GDBUtil.loadPreferences(this);
for( int layerid: GDBUtil.getLayerIds()){
mMapView.addLayer(new ArcGISFeatureLayer(GDBUtil.getFsUrl()+"/"+layerid, ArcGISFeatureLayer.MODE.ONDEMAND));
}
GDBUtil.showMessage(this, "刷新成功");
}
二、下载GDB方法的实现
从服务器下载GDB可以使用GeodatabaseTask的submitGenerateGeodatabaseJobAndDownload,可以给这个方法传入GenerateGeodatabaseParameters的参数,保存GDB的路径,GeodatabaseStatusCallback类型的状态变化的回调和CallbackListener<Geodatabase>类型的下载完成的回调。在GenerateGeodatabaseParameters类中可以设置,同步类型,下载的图层等参数。当GDB下载完成之后,就可以移除掉MapView中的ArcGISFeatureLayer了,用GDB中的featurelayer来代替
可以在GDBUtil加入如下静态方法,来实现下载:
//下载Geodatabase
public static void downGeodatabase(final OfflineEditorActivity activity,final MapView mapView){
//显示Progress
showProgress(activity, true);
geoTask=new GeodatabaseTask(getFsUrl(),null,new CallbackListener<FeatureServiceInfo>() {
public void onCallback(FeatureServiceInfo objs) {
//判断返回的是否可以同步
if(objs.isSyncEnabled()){
//设置下载参数
GenerateGeodatabaseParameters paras=new GenerateGeodatabaseParameters(getLayerIds(), mapView.getExtent(), mapView.getSpatialReference(), returnAttachments, getSyncModel(), mapView.getSpatialReference());
//下载状态的回调方法
GeodatabaseStatusCallback statusCallback=new GeodatabaseStatusCallback() {
public void statusUpdated(GeodatabaseStatusInfo status) {
showMessage(activity, status.getStatus().getValue());
}
};
//下载完成之后的回调
CallbackListener<Geodatabase> callback=new CallbackListener<Geodatabase>() {
public void onError(Throwable e) {
showMessage(activity, e.getMessage());
showProgress(activity, false);
}
public void onCallback(Geodatabase objs) {
showMessage(activity , "geodatabase下载完成");
//移除MapView中的FeatureLayer
Layer[] layers=mapView.getLayers();
for(Layer layer:layers){
if(layer instanceof ArcGISFeatureLayer){
mapView.removeLayer(layer);
}
}
//添加Geodatabase中的图层
List<GdbFeatureTable> gdbtablses=objs.getGdbTables();
for(GdbFeatureTable gdbtable :gdbtablses){
mapView.addLayer(new FeatureLayer(gdbtable));
}
showProgress(activity, false);
}
};
//下载
geoTask.submitGenerateGeodatabaseJobAndDownload(paras, getGdbFileName(), statusCallback, callback);
}
}
public void onError(Throwable e) {
showMessage(activity, e.getMessage());
showProgress(activity, false);
}
});
}
三、同步GDB方法的实现
把本地的GDB同步到服务器,可以使用GeodatabaseTask中的submitSyncJobAndApplyResults,给该方法传入SyncGeodatabaseParameters类型的参数(可以从Geodatabse中的getSyncParameters()方法得到)、Geodatabase、状态变化的回调函数GeodatabaseStatusCallback和同步完成的回调函数CallbackListener<Geodatabase>。
可以在GDBUtil加入如下静态方法,来实现GDB的同步:
//同步Geodatabase
public static void sycnGeodatabase(final OfflineEditorActivity activity){
showProgress(activity, true);
geoTask=new GeodatabaseTask(getFsUrl(),null, new CallbackListener<FeatureServiceInfo>() {
public void onCallback(FeatureServiceInfo objs) {
try {
if(objs.isSyncEnabled()){
//得到Geodabase
Geodatabase databse=new Geodatabase(getGdbFileName());
//得到同步参数
SyncGeodatabaseParameters paras=databse.getSyncParameters();
//同步状态的回调
GeodatabaseStatusCallback statusCallback=new GeodatabaseStatusCallback() {
public void statusUpdated(GeodatabaseStatusInfo status) {
showMessage(activity, status.getStatus().getValue());
}
};
//同步结束之后的回调
CallbackListener<Geodatabase> callback=new CallbackListener<Geodatabase>() {
public void onError(Throwable e) {
showMessage(activity, e.getMessage());
showProgress(activity, false);
}
public void onCallback(Geodatabase objs) {
showMessage(activity, "同步成功");
showProgress(activity, false);
}
};
geoTask.submitSyncJobAndApplyResults(paras, databse, statusCallback, callback);
}
} catch (Exception e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
public void onError(Throwable e) {
showMessage(activity, e.getMessage());
showProgress(activity, false);
}
});
}
四 、完成了下载和同步方法,就可以回到OfflineEditorActivity中,建个内部异步类MyAsyncTask继承AsyncTask<String, Void, Void>,在这个异步类中进行GDB的下载与同步,代码如下:
//下载和同步Geodatabase的异步类
class MyAsyncTask extends AsyncTask<String, Void, Void>{
private OfflineEditorActivity activity;
private MapView map;
public MyAsyncTask(OfflineEditorActivity activity, MapView map) {
super();
this.activity = activity;
this.map = map;
}
//判断params参数,来执行下载或者同步
protected Void doInBackground(String... params) {
String param=params[0];
if(param.equalsIgnoreCase("downLoad")){//下载
GDBUtil.downGeodatabase(activity, map);
}else if(param.equalsIgnoreCase("sync")){//同步
GDBUtil.sycnGeodatabase(activity);
}
return null;
}
}
接下只要在下载和同步按钮的事件方法中,写两行代码:
/**
* 下载GBD
*/
public void downloadGdb(View v) {
new MyAsyncTask(this, mMapView).execute("downLoad");
}
/**
* 同步Gdb
*/
public void syncGdb(View v) {
new MyAsyncTask(this, mMapView).execute("sync");
}
五、经过二、三、四实现了GBD的下载同步,接下来实现底图离线和在线的切换。
底图的切换比较容易,当从在线切换到离线的时候,要先判断下离线的tpk文件是否存在,如果存在,就把MapView中的第0层,也就是ArcGISTiledMapServiceLayer类型的在线切片底图移除,把离线的tpk底图加载到MapView的第0层。如果是有离线切换到在线,就相反就可以啦,代码如下:
/**
* 切换底图
*/
public void switchLocalBasemap(View v) {
if( tbtn_switch.isChecked()){//离线底图
File file=new File(GDBUtil.getBasemapFileName());
if(file.exists()){
ArcGISLocalTiledLayer tms=new ArcGISLocalTiledLayer(GDBUtil.getBasemapFileName());
mMapView.removeLayer(0);//移除在线底图
mMapView.addLayer(tms,0);//增加离线底图
GDBUtil.showMessage(this, "切换到离线底图");
}else{
GDBUtil.showMessage(this, "tpk底图不存在!");
}
}else{//在线底图
mMapView.removeLayer(0);//移除离线底图
mMapView.addLayer(new ArcGISTiledMapServiceLayer("http://services.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer"),0);//增加在线底图
GDBUtil.showMessage(this, "切换到在线底图");
}
}