package proj.Position;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import ntu.com.google.zxing.client.android.R;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
public class PositionActivity extends Activity {
private MyWebView mapView;
private ImageButton btnScan;
private TextView pointTitleText;
private TextView mapTitleText;
private String contentJsonUrl;
private String contentMapId;
private String contentMapVer;
private String contentPointId;
private String contentPotintTitle;
private String lastPointId;
private SharedPreferences settings;
private Thread thread;
private ProgressDialog waitDownDialog;
// Use for download handler message code
private interface messageCode {
public static final int DOWNLOAD_OK = 0;
public static final int DOWNLOAD_FAILED = 1;
public static final int RE_DOWNLOAD_OK = 2;
public static final int RE_DOWNLOAD_FAILED = 3;
}
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
findViews();
pointTitleText.setTextColor(Color.RED);
btnScan.setBackgroundResource(R.drawable.scanicon);
settings = getPreferences(MODE_PRIVATE);
if (checkSdCard()) {
// Check SD card exist
setListeners();
makeRootDir();
showEmptyMap();
startScan();
} else {
Builder noSdCardDialog = new AlertDialog.Builder(this);
noSdCardDialog.setTitle("�д��J�O�Хd!");
noSdCardDialog.setMessage("�{���Y�N����...");
noSdCardDialog.setPositiveButton("�T�w", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
});
noSdCardDialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
@Override
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_SEARCH) || (keyCode == KeyEvent.KEYCODE_BACK)) {
finish();
return true;
} else {
return false;
}
}
});
noSdCardDialog.show();
}
}
private Boolean checkSdCard() {
if (Environment.getExternalStorageState().equals(Environment.MEDIA_REMOVED)) {
return false;
} else {
return true;
}
}
private void findViews() {
pointTitleText = (TextView) findViewById(R.id.pointTitleText);
mapTitleText = (TextView) findViewById(R.id.mapTitleText);
mapView = (MyWebView) findViewById(R.id.mainMapView);
// Enable to zoom in/out
mapView.getSettings().setBuiltInZoomControls(true);
// Enable to zoom in/out by double tap
mapView.getSettings().setUseWideViewPort(true);
btnScan = (ImageButton) findViewById(R.id.scanBtn);
}
private void setListeners() {
btnScan.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
startScan();
}
});
}
private void startScan() {
Intent intent = new Intent("ntu.com.google.zxing.client.android.SCAN");
intent.setPackage("ntu.com.google.zxing.client.android");
intent.putExtra("SCAN_MODE", "QR_CODE_MODE");
startActivityForResult(intent, 0);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
// Here are three requestCodes now (0,1,2), scan, point list, map list
if (requestCode == 0) {
if (resultCode == RESULT_OK) {
String contents = intent.getStringExtra("SCAN_RESULT");
// String format = intent.getStringExtra("SCAN_RESULT_FORMAT");
Boolean isNeedUpdate;
try {
String[] contentArray = contents.split("\\?");
String[] contentPart = contentArray[1].split("&");
// Parse QR code content and assign value
contentJsonUrl = contents + "&from=client";
String[] tmp = contentPart[0].split("=");
contentMapId = tmp[1];
tmp = contentPart[1].split("=");
contentMapVer = tmp[1];
tmp = contentPart[2].split("=");
contentPointId = tmp[1];
tmp = contentPart[3].split("=");
contentPotintTitle = tmp[1];
// Assign map id to global variable
Global.MapId = contentMapId;
// Assign point id to global variable
Global.PointId = contentPointId;
// Assign title id to global variable
Global.PointTitle = contentPotintTitle;
// Assign point id preferences
settings.edit().putString(Global.MapId, Global.PointId).commit();
// Check whether it need to download JSON file
isNeedUpdate = !checkMapVerUpdate(Global.MapId, contentMapVer);
// Need to Update
if (isNeedUpdate) {
waitDownDialog = new ProgressDialog(PositionActivity.this);
waitDownDialog.setTitle("�U����!");
waitDownDialog.setMessage("�еy��...");
waitDownDialog.setCancelable(false);
waitDownDialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
@Override
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_SEARCH)) {
return true;
} else {
return false;
}
}
});
waitDownDialog.show();
// Start to download updated file
thread = new Thread(new Runnable() {
public void run() {
try {
downloadMapJson(Global.MapId, contentJsonUrl);
JSONObject jsonObj = new JSONObject(JsonParser.getJsonRespon(Global.SDPathRoot + "/" + Global.MapDirName + "/last.json"));
JSONArray jsonObjArray;
String map = jsonObj.getString("map");
DownloadHelper downloader = new DownloadHelper();
LookHelper look = new LookHelper();
if (!look.look(Global.SDPathRoot + "/" + Global.MapDirName + "/" + Global.MapId + "/", "map")) {
// Check does it need to download map
// image
downloader.downFile(map, Global.SDPathRoot + "/" + Global.MapDirName + "/" + Global.MapId + "/", "map");
}
jsonObjArray = jsonObj.getJSONArray("points");
try {
// Download point's images
for (int i = 0; i < jsonObjArray.length(); i++) {
if (!jsonObjArray.getJSONObject(i).getString("photo").equals("")) {
downloader.downFile(jsonObjArray.getJSONObject(i).getString("photo"), Global.SDPathRoot + "/" + Global.MapDirName + "/" + Global.MapId + "/", jsonObjArray.getJSONObject(i).getString("pointID"));
}
}
} catch (Exception e) {
// Still show map information even the
// point's images download failed
}
handler.sendEmptyMessage(messageCode.DOWNLOAD_OK);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
handler.sendEmptyMessage(messageCode.DOWNLOAD_FAILED);
} catch (JSONException e) {
e.printStackTrace();
}
}
});
thread.start();
} else {
// Not need to Update
JSONObject jsonObj = new JSONObject(JsonParser.getJsonRespon(Global.SDPathRoot + "/" + Global.MapDirName + "/" + Global.MapId + "/" + Global.MapId + ".json"));
// Assign MapTitle
Global.MapTitle = jsonObj.getString("title");
showMapData(Global.MapId);
showPointInfo(jsonObj, Global.PointId);
}
} catch (Exception e) {
// Handle when scan QR code which is not our form
// Assign point id to global variable
Global.PointId = null;
// Assign point title to global variable
Global.PointTitle = null;
showLastMapData();
Builder QRerrorDialog = new AlertDialog.Builder(PositionActivity.this);
QRerrorDialog.setTitle("���X�榡���~!").setMessage("�Ы��T�{�~��...").setPositiveButton("�T�{", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
QRerrorDialog.show();
}
// Handle successful scan
} else if (resultCode == RESULT_CANCELED) {
// Handle cancel
// Assign point id to global variable
Global.PointId = null;
// Assign point title to global variable
Global.PointTitle = null;
// Show last map data
showLastMapData();
}
}
// After click point list's item
if (requestCode == 1) {
if (resultCode == RESULT_OK) {
showMapData(Global.MapId);
try {
JSONObject jsonObj = new JSONObject(JsonParser.getJsonRespon(Global.SDPathRoot + "/" + Global.MapDirName + "/" + Global.MapId + "/" + Global.MapId + ".json"));
showPointInfo(jsonObj, Global.PointId);
} catch (Exception e) {
// TODO: handle exception
}
}
}
// After click map list's item
if (requestCode == 2) {
if (resultCode == RESULT_OK) {
showMapData(Global.MapId);
}
}
}
private void makeRootDir() {
// Make root dir if not in SD card yet
Boolean isExistent;
LookHelper looker = new LookHelper();
isExistent = looker.look(Global.SDPathRoot + "/", Global.MapDirName);
if (!isExistent) {
MakeDirHelper maker = new MakeDirHelper();
maker.make(Global.SDPathRoot + "/", Global.MapDirName);
}
}
private void downloadMapJson(String mapId, String downHttpUrl) throws IOException {
// Download the JSON file
DownloadHelper downloader = new DownloadHelper();
MakeDirHelper maker = new MakeDirHelper();
maker.make(Global.SDPathRoot + "/" + Global.MapDirName + "/", mapId);
downloader.downFile(downHttpUrl, Global.SDPathRoot + "/" + Global.MapDirName + "/" + mapId + "/", mapId + ".json");
// Copy last downloaded JSON file in to map dir root
File srcFile = new File(Global.SDPathRoot + "/" + Global.MapDirName + "/" + mapId + "/" + mapId + ".json");
File dstFile = new File(Global.SDPathRoot + "/" + Global.MapDirName + "/" + "last.json");
BufferedInputStream in = new BufferedInputStream(new FileInputStream(srcFile));
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(dstFile));
byte[] tmp = new byte[1024];
while (in.read(tmp) != -1) {
out.write(tmp);
}
in.close();
out.close();
}
private Boolean checkMapVerUpdate(String mapId, String mapVer) {
// Return false when it need to be updated
Boolean result = false;
try {
JSONObject jsonObj = new JSONObject(JsonParser.getJsonRespon(Global.SDPathRoot + "/" + Global.MapDirName + "/" + Global.MapId + "/" + Global.MapId + ".json"));
int verNow = jsonObj.getInt("mapVer");
if (verNow >= Integer.valueOf(mapVer)) {
result = true;
}
} catch (JSONException e) {
e.printStackTrace();
result = false;
}
return result;
}
private Boolean checkOldMapData(String MapId) {
// Return true if there is old map data
LookHelper look = new LookHelper();
return look.look(Global.SDPathRoot + "/" + Global.MapDirName + "/" + MapId + "/", MapId + ".json");
}
private void showEmptyMap() {
// In order to Focus when fist scan
String data = "<body style=\"margin:0;\"><img src = \"file:///android_res/drawable/emptymap.png\"/></body>";
final String mimeType = "text/html";
final String encoding = "utf-8";
mapView.loadDataWithBaseURL("about:blank", data, mimeType, encoding, "");
}
private void showChooseMap() {
mapTitleText.setText("�L��ܦa��");
pointTitleText.setText(null);
String data = "<body style=\"margin:0;\"><img src = \"file:///android_res/drawable/choosemap.png\"/></body>";
final String mimeType = "text/html";
final String encoding = "utf-8";
mapView.loadDataWithBaseURL("about:blank", data, mimeType, encoding, "");
}
private void showMapData(String mapId) {
// Show map title
if (Global.MapTitle == null || Global.MapTitle.equals("")) {
mapTitleText.setText("�L�a�ϦW��");
} else {
mapTitleText.setText(Global.MapTitle);
}
// Show point title
pointTitleText.setText(Global.PointTitle);
// Copy last downloaded JSON file into map dir root
File srcFile = new File(Global.SDPathRoot + "/" + Global.MapDirName + "/" + mapId + "/" + mapId + ".json");
File dstFile = new File(Global.SDPathRoot + "/" + Global.MapDirName + "/" + "last.json");
try {
BufferedInputStream in = new BufferedInputStream(new FileInputStream(srcFile));
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(dstFile));
byte[] tmp = new byte[1024];
while (in.read(tmp) != -1) {
out.write(tmp);
}
in.close();
out.close();
} catch (Exception e) {
// TODO: handle exception
}
// Enable to zoom in/out
mapView.getSettings().setBuiltInZoomControls(true);
// Enable to zoom in/out by double tap
mapView.getSettings().setUseWideViewPort(true);
// Bind the image path
String data = "<body style=\"margin:0;\"><img src = \"file:///sdcard/" + Global.MapDirName + "/" + mapId + "/" + "map" + "\"/></body>";
final String mimeType = "text/html";
final String encoding = "utf-8";
// Set map id
Global.MapId = mapId;
// Show map IMG
mapView.loadDataWithBaseURL("about:blank", data, mimeType, encoding, "");
// Update the touch points data (touchevent and onDraw method)
mapView.invalidate();
}
private void showLastMapData() {
// Show last Map data if it exists
try {
JSONObject jsonObj = new JSONObject(JsonParser.getJsonRespon(Global.SDPathRoot + "/" + Global.MapDirName + "/" + "last.json"));
// Assign MapTitle
Global.MapTitle = jsonObj.getString("title");
String mapId = jsonObj.getString("mapID");
showMapData(mapId);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Builder noMapDialog = new AlertDialog.Builder(PositionActivity.this);
noMapDialog.setTitle("�L����a��!").setMessage("���T�{�~��...").setPositiveButton("�T�{", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
noMapDialog.show();
}
}
private void showPointInfo(JSONObject jsonObj, String pointId) {
JSONArray jsonObjArray;
JSONObject jsonObjCoordObject;
try {
jsonObjArray = jsonObj.getJSONArray("points");
JSONObject jsonObjCoordJsonObject;
// Focus
int x = 0, y = 0;
for (int i = 0; i < jsonObjArray.length(); i++) {
if (jsonObjArray.getJSONObject(i).getString("pointID").equals(pointId)) {
jsonObjCoordJsonObject = jsonObjArray.getJSONObject(i).getJSONObject("coord");
x = jsonObjCoordJsonObject.getInt("x");
y = jsonObjCoordJsonObject.getInt("y");
break;
}
}
if (pointId != null) {
mapView.focusPoint(x, y);
mapView.invalidate();
}
// Show point's information
String title = "";
String desc = "";
// For check deleted point(non found)
Boolean tag = false;
for (int i = 0; i < jsonObjArray.length(); i++) {
jsonObjCoordObject = jsonObjArray.getJSONObject(i);
if (jsonObjCoordObject.getString("pointID").equals(pointId)) {
title = jsonObjCoordObject.getString("title");
desc = jsonObjCoordObject.getString("description");
if (desc.equals("null") || desc.equals("")) {
desc = "���a�I�|�L�y�z!";
}
tag = true;
break;
}
}
LayoutInflater factory = LayoutInflater.from(PositionActivity.this);
final View v = factory.inflate(R.layout.contentview, null);
Builder showPointDesc = new AlertDialog.Builder(PositionActivity.this);
showPointDesc.setPositiveButton("�T�{", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
TextView contentDesc = (TextView) v.findViewById(R.id.textDesc);
ImageView contentImg = (ImageView) v.findViewById(R.id.pointImg);
if (tag) {
showPointDesc.setTitle(title);
contentDesc.setText(desc);
} else {
showPointDesc.setTitle("��p");
contentDesc.setText("����m�w�Q�R��!");
}
// For show point image
LookHelper look = new LookHelper();
if (look.look(Global.SDPathRoot + "/" + Global.MapDirName + "/" + Global.MapId + "/", pointId)) {
Bitmap b = BitmapFactory.decodeFile(Global.SDPathRoot + "/" + Global.MapDirName + "/" + Global.MapId + "/" + pointId);
contentImg.setImageBitmap(b);
}
contentDesc.setTextSize(20);
showPointDesc.setView(v);
showPointDesc.show();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void showLastPosition() {
lastPointId = settings.getString(Global.MapId, "");
if (!lastPointId.equals("")) {
JSONObject jsonObj;
JSONArray jsonObjArray;
try {
jsonObj = new JSONObject(JsonParser.getJsonRespon(Global.SDPathRoot + "/" + Global.MapDirName + "/" + Global.MapId + "/" + Global.MapId + ".json"));
jsonObjArray = jsonObj.getJSONArray("points");
for (int i = 0; i < jsonObjArray.length(); i++) {
if (jsonObjArray.getJSONObject(i).getString("pointID").equals(lastPointId)) {
Global.PointTitle = jsonObjArray.getJSONObject(i).getString("title");
break;
}
}
Global.PointId = lastPointId;
// Show point title
pointTitleText.setText(Global.PointTitle);
showPointInfo(jsonObj, lastPointId);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
Builder noLastPointDialog = new AlertDialog.Builder(PositionActivity.this);
noLastPointDialog.setPositiveButton("�T�{", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
noLastPointDialog.setTitle("�L�W�����y�O��");
noLastPointDialog.setMessage("���T�{�~��...");
noLastPointDialog.show();
}
}
private void scanResultOk() {
try {
JSONObject jsonObj = new JSONObject(JsonParser.getJsonRespon(Global.SDPathRoot + "/" + Global.MapDirName + "/" + Global.MapId + "/" + Global.MapId + ".json"));
// Assign MapTitle
Global.MapTitle = jsonObj.getString("title");
// Show map data when download finished
showMapData(Global.MapId);
waitDownDialog.dismiss();
showPointInfo(jsonObj, Global.PointId);
} catch (Exception e) {
// TODO: handle exception
}
}
private void scanResultfailed() {
Boolean isOldMapData;
// Show old map data if it exist otherwise show last map
isOldMapData = checkOldMapData(Global.MapId);
if (isOldMapData) {
JSONObject jsonObj;
try {
jsonObj = new JSONObject(JsonParser.getJsonRespon(Global.SDPathRoot + "/" + Global.MapDirName + "/" + Global.MapId + "/" + Global.MapId + ".json"));
// Assign MapTitle
Global.MapTitle = jsonObj.getString("title");
// Assign point title to global variable
Global.PointTitle = null;
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
showMapData(Global.MapId);
} else {
showChooseMap();
}
// Show failed dialog when download failed
waitDownDialog.dismiss();
Builder showFailInfo = new AlertDialog.Builder(PositionActivity.this);
showFailInfo.setMessage("�нT�{�����s�u�A�ΰO�Хd���A\n\n�Ы��T�{�~��...");
showFailInfo.setTitle("�U������!").setPositiveButton("�T�{", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
showFailInfo.show();
}
private void reDownloadData() {
waitDownDialog = new ProgressDialog(PositionActivity.this);
waitDownDialog.setTitle("��s��!");
waitDownDialog.setMessage("�еy��...");
waitDownDialog.setCancelable(false);
waitDownDialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
@Override
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_SEARCH)) {
return true;
} else {
return false;
}
}
});
waitDownDialog.show();
// Start to download file
thread = new Thread(new Runnable() {
public void run() {
try {
// Not to update JSON file
// downloadMapJson(Global.MapId, contentJsonUrl);
JSONObject jsonObj = new JSONObject(JsonParser.getJsonRespon(Global.SDPathRoot + "/" + Global.MapDirName + "/last.json"));
JSONArray jsonObjArray;
String map = jsonObj.getString("map");
DownloadHelper downloader = new DownloadHelper();
downloader.downFile(map, Global.SDPathRoot + "/" + Global.MapDirName + "/" + Global.MapId + "/", "map");
jsonObjArray = jsonObj.getJSONArray("points");
try {
// Download point's images
for (int i = 0; i < jsonObjArray.length(); i++) {
if (!jsonObjArray.getJSONObject(i).getString("photo").equals("")) {
downloader.downFile(jsonObjArray.getJSONObject(i).getString("photo"), Global.SDPathRoot + "/" + Global.MapDirName + "/" + Global.MapId + "/", jsonObjArray.getJSONObject(i).getString("pointID"));
}
}
} catch (Exception e) {
// Still show map information even the
// point's images download failed
}
handler.sendEmptyMessage(messageCode.RE_DOWNLOAD_OK);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
handler.sendEmptyMessage(messageCode.RE_DOWNLOAD_FAILED);
} catch (JSONException e) {
e.printStackTrace();
}
}
});
thread.start();
}
private void reDownloadOk() {
showMapData(Global.MapId);
waitDownDialog.dismiss();
}
private void reDownloadFailed() {
// Show failed dialog when download failed
showMapData(Global.MapId);
waitDownDialog.dismiss();
Builder showFailInfo = new AlertDialog.Builder(PositionActivity.this);
showFailInfo.setMessage("�нT�{�����s�u�A�ΰO�Хd���A\n\n�Ы��T�{�~��...");
showFailInfo.setTitle("��s����!").setPositiveButton("�T�{", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
showFailInfo.show();
}
private Handler handler = new Handler() {
// Boolean isOldMapData;
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case messageCode.DOWNLOAD_OK:
scanResultOk();
break;
case messageCode.DOWNLOAD_FAILED:
scanResultfailed();
break;
case messageCode.RE_DOWNLOAD_OK:
reDownloadOk();
break;
case messageCode.RE_DOWNLOAD_FAILED:
reDownloadFailed();
break;
}
super.handleMessage(msg);
}
};
protected static final int MENU_ShowPoints = Menu.FIRST;
protected static final int MENU_ChooseMap = Menu.FIRST + 1;
protected static final int MENU_LastPosition = Menu.FIRST + 2;
protected static final int MENU_RefreshData = Menu.FIRST + 3;
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add(0, MENU_ShowPoints, 0, "�s���w���I");
menu.add(0, MENU_ChooseMap, 0, "��ܦa��");
menu.add(0, MENU_LastPosition, 0, "�W����m");
menu.add(0, MENU_RefreshData, 0, "����Ϥ�");
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
super.onOptionsItemSelected(item);
switch (item.getItemId()) {
case MENU_ShowPoints:
Intent intent1 = new Intent();
intent1.setClass(PositionActivity.this, ShowPointList.class);
startActivityForResult(intent1, 1);
break;
case MENU_ChooseMap:
Intent intent2 = new Intent();
intent2.setClass(PositionActivity.this, ShowMapList.class);
startActivityForResult(intent2, 2);
break;
case MENU_LastPosition:
showLastPosition();
break;
case MENU_RefreshData:
reDownloadData();
break;
}
return true;
}
}