Location Based Services - LBS

Slides:



Advertisements
Similar presentations
第 4 章 PHP 基本語法.
Advertisements

第13章 繪圖與多媒體 13-1 顯示圖檔-行動相簿 13-2 音樂播放-音樂播放器 13-3 影片播放-視訊播放器
第5章 HTML 標籤介紹.
MVC Servlet与MVC设计模式.
第8章 CSS基础知识 【学习目标】 对于一个网页设计者来说,对HTML语言一定不感到陌生,因为它是网页制作的基础,但是如果希望网页能够美观、大方,并且升级维护方便,那么仅仅知道HTML还是不够的,还需要了解CSS。了解CSS基础知识,可以为后面的学习打下基础。 本章主要内容包括: 为什么在网页中加入CSS。
實驗五:多媒體播放器選單介面.
Part 2 開發Android應用程式的流程
位置與地圖應用 此投影片為講解Android如何取得定位經緯度和使用Google Map地圖.
第二章 JAVA语言基础.
Android + Web Service 建國科技大學 資管系 饒瑞佶 2017/3 V1.
ArrayAdapter & Spinner
Location Based Services - LBS
Chaper 12 網路服務.
Location Based Services - LBS
Android App 系統開發教學 Luna 陳雯琳 2014/12/18
厦门大学数据库实验室 报告人:谢荣东 导师:林子雨 2014年8月30日
Chapter 4 手機控制項應用.
實驗四:單位轉換程式.
Chapter 13 Android 實戰演練.
Android + JUnit 單元測試 建國科技大學資管系 饒瑞佶 2012/8/19V4.
Introduction to PHP part3
實驗十三:顯示目前經緯度位置.
数据库操作示例 import java.sql.*; //导入java.sql包 public class JDBCDemo {
Ch06 再談選單元件 物件導向系統實務.
专题4:JSP脚本和指令.
使用Android控制Arduino 史先强
第10章 App微信分享的实现 倚动实验室.
Android資料庫處理 Android智慧型手機程式設計 程式設計與應用班 建國科技大學 資管系 饒瑞佶 2012/4 V1
第9章 位置服务与地图应用.
JSP自定义标签技术的分析与应用 ----Custom Tag 的分析与应用
第一个Android程序 本讲大纲: 1、创建Android应用程序 2、Android项目结构说明 3、运行Android应用程序
第8章 Android内容提供者(ContentProvider)应用
Chapter 6 Advanced UI Design.
Android智慧型手機程式設計實務應用班
Chapter 7 Android應用元件 Android應用元件可以幫助我們獲得系統資源訊息(ActivityManager)、提供系統服務(Service)、搜尋系統服務(SearchManager)、監聽Intent訊息(Broadcast Receiver)以及資料共享(ContentProvider和ContentResolver)。
Android介面設計 Android智慧型手機程式設計 建國科技大學 資管系 饒瑞佶 2012/4 V1 2012/8 V2
Chapter 6 進階UI設計.
第4章 Android生命周期.
ContentProvider與資料共享
第9章 使用意圖啟動活動與內建應用程式 9-1 意圖的基礎 9-2 使用意圖啟動活動
ANDROID PROGRAMMING2.
CH7 佈局、按鈕與文字編輯元件.
Android + Service 建國科技大學 資管系 饒瑞佶.
Android 基礎.
實驗十四:顯示與控制地圖.
第2讲 移动应用开发基础知识(二) 宋婕
第6章 建立Android使用介面 6-1 介面元件的基礎 6-2 Android的事件處理 6-3 按鈕元件 6-4 文字元件
Java程序设计 第2章 基本数据类型及操作.
第11章 Android客户端与服务器交互.
生活智慧王 樹德科技大學 資訊工程系 指導教授 : 陳毓璋 教授 小組成員: 劉上緯 翁維廷 洪文財.
第10章 GPS位置服务与地图编程.
實驗十一:待辦事項程式 (儲存在手機上).
主编:钟元生 赵圣鲁.
透過YouTuBe API取得資料 建國科技大學 資管系 饒瑞佶 2018/1 V1.
ArrayAdapter & Spinner
Chapter 5 Basic UI Design.
Android視窗介面 建國科技大學 資管系 饒瑞佶 2010/10.
實驗九:延續實驗八, 製作一個完整音樂播放器
Location Based Services - LBS
進階UI元件:Spinner與接合器 靜宜大學資管系 楊子青
第二章 Java语法基础.
Android視窗介面 建國科技大學 資管系 饒瑞佶 2010/10.
第二章 Java基本语法 讲师:复凡.
RecyclerView and CardView
Android Speech To Text(STT)
用Intent啟動程式中的其他Activity、運用WebView顯示網頁 靜宜大學資管系 楊子青
第2章 Java语言基础.
讀取網路資料及JSON開放資料 靜宜大學資管系 楊子青
Part 8 Broadcast Receiver、Service和App Widget
進階UI元件:Spinner與接合器 靜宜大學資管系 楊子青
Presentation transcript:

Location Based Services - LBS 系統實例 – 天災救援

Outline 系統簡介 系統規劃 系統環境建置 天災救援建置

Chapter1. 系統簡介

系統簡介 1. 創作動機 近年台灣地區各種天災所帶來的災害不容小覷,以八八水災重創南台灣為例,因災區無法向外界即時求援,而造成災情持續擴大。

系統簡介 1. 創作動機 附近有間全家 在有隻小貓 旁邊 有更明確 的目標嗎? 報案地點在哪邊?

系統簡介 1. 創作動機 天災救援因應而生

系統簡介 Mobile Device 2. 系統功能 災情定位 災情回報 物資需求 災情監控 物資管理 災情管理 Web

系統簡介 2. 系統架構 Client Web Server Web Service Database Internet

系統簡介 3. 系統操作流程 天災資訊網 (開放一般民眾查詢) 發送求救 災情回報 天災管理 資訊系統 救援管理系統 (救難人員使用)

系統簡介 3. 系統操作流程 一般民眾

系統簡介 3. 系統操作流程 救援人員

系統簡介 3. 系統操作流程 緊急登入

系統簡介 3. 系統操作流程 一般民眾天災管理系統 提供一般民眾透過網頁方式來查詢目前發佈災害的位置,並可掌握即時最新消息,亦可以在平台上發佈尋人啟事。

系統簡介 3. 系統操作流程 救難人員天災救援管理系統 救難人員可以掌握目前災害的詳細資訊(詳細地點與照片),並可以即時作物資的配送與救難人員的調度。

Chapter2. 系統規劃

系統規劃 1. 系統功能介面規劃 Android Web 天災管理系統 ID Picture Type Require Position Simid Check # 災害照片 災害類型 需求或描述 位置座標 傳送人 確認按鈕

系統規劃 2.ER-Model alarmType ad_id simID Name Notify check User Alarm_Detail simid lat lng location alarmDetail

帳號登入(若沒帳號則會註冊,若有帳號則會更新姓名) 系統規劃 3. Web Service 規劃 Service Http 功能描述 需求參數 返回格式 返回參數 備註 login.php get 帳號登入(若沒帳號則會註冊,若有帳號則會更新姓名) simid json response name alarmDetail.php post 新增災難相關資訊 (文字&照片) alarmType alarmDetail location photo alarmStatus.php 查詢發佈災難的狀態 (0:未確認,1:已確認) String 0 or 1 ad_id

系統規劃 4.天災救援 Use Case Diagram 天災救援系統(Android) 使用者 天災救援系統(Web) 救災人員 地圖打點 <<include>> 地圖打點 災情通報 <<include>> 通報 等待回覆 使用者 會員登入 天災救援系統(Web) <<include>> 災情確認 通報災情管理 救災人員

系統規劃 5.天災救援 Class Diagram <<persistent>> User - simid : String - name : String - lat : Double - lng : Double + getName(simid): String + addUser(simid,name) <<persistent>> Alarm_Detail - ad_id : Int - simid : String - alarmType : String - alarmDetail : String - location : Double - check : Int + addAlarm (simid,alarmType,alarmDetail,location) + getAlarmList(aid): List + getStatus(simid,ad_id): String 1 0…*

系統規劃 6.天災救援 Sequence Diagram :會員 :報警 Web Android Service login(simid,name):boolean checkUser(simid,name):json return return addAlarm (alarmType,alarmDetail,location,simid,photo) addAlarm (alarmType,alarmDetail,location,simid,photo): json return return getStatus(simid,ad_id) getStatus(simid,ad_id): json return return getAlarmList(): List getAlarmList(): json return return

Chapter3. 系統環境建置

系統環境建置 1.建置資料庫 點擊Admin,啟動MySQL管理介面

系統環境建置 2.建置資料庫 alarm utf8_general_ci 1 2 3 4

系統環境建置 3.建置資料庫欄位 user 2 3 user 2 1 2

系統環境建置 3.建置資料庫欄位 建立user相關欄位

系統環境建置 3.建置資料庫欄位 alarm_detail 6 3 alarm_detail 6 1 2

系統環境建置 3.建置資料庫欄位 建立alarm_detail相關欄位

Chapter4. 天災救援建置

天災救援建置 3. 權限說明 Uses Permission INTERNET 網路存取權限 ACCESS_FINE_LOCATION GPS定位權限 ACCESS_COARSE_LOCATION 無線網路定位 ACCESS_NETWORK_STATE 允許應用程序訪問有關GSM網絡信息 WRITE_EXTERNAL_STORAGE 允許應用程序寫入外部存儲器

天災救援建置 3. 權限說明 Uses Permission Permission MAPS_RECEIVE 允許下載圖資 READ_PHONE_STATE 允許存取 SIM Card 資訊 READ_GSERVICES 允許 API 訪問 Google Web 的服務 Permission MAPS_RECEIVE 允許下載圖資

在其他user-permission底下貼上READ_GSERVICES權限 天災救援建置 在其他user-permission底下貼上READ_GSERVICES權限 只有READ_GSERVICES的權限需要透過手動的方式加入到AndroidManifest.xml程式碼當中 2 1 <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>

天災救援建置 4. 物件參數設定 value.java 1 2 3 4 5 6 7 8 9 而 service 參數要設定成自己的位置 /* package com.stu.alarm; 2 public final class value { 3 public static String simid = ""; 4 public static String name = ""; 5 public static String service = 6 "http://localhost/service/alarm/"; 7 /* 每個頁面可能會用到的參數, 8 都會先宣告在 value 物件當中 9 而 service 參數要設定成自己的位置 /* 10 11 } 打開 value.java

天災救援建置 5. 登入功能描述 Android Web Service 1 MainActivity.java Require 將 SIMID 與 NAME 傳送給 Service 後,便可直接登入到功能頁面 Require response simid Web Service name JSON login.php GET 第一次登入會透過SIM CARD ID 當作帳號與輸入姓名來新增一筆帳號,再次登入僅會更新姓名資料 Response

天災救援建置 5-1. 登入功能 Service login.php 1 2 3 4 5 6 7 8 9 10 11 if (isset($_GET['simid']) && isset($_GET['name'])) 2 { 3 $simid = mysql_real_escape_string($_GET['simid']); 4 $name = mysql_real_escape_string($_GET['name']); 5 //透過 GET 代入 simid (SIM Card ID) 與 name (名稱) 參數 6 include("../connect.php"); 7 $sql = "SELECT * FROM user WHERE simid = '$simid'"; 8 $result = mysql_query($sql, $link) or die("oops"); 9 //指定查詢 $simid 是否有註冊紀錄,若回傳資料筆數為 0 則表示未註冊 1 則已註冊 10 if(mysql_num_rows($result) != 0) { 11 $sql = "Update user SET name = '$name' WHERE simid = '$simid'";

天災救援建置 12 // 若已註冊則更新這個 $simid 的 name 欄位,更改名稱 13 $result = mysql_query($sql, $link) or die("oops"); 14 }else{ 15 $sql = "INSERT INTO user(simid,name,lat,lng) VALUES('$simid','$name','0','0')"; 16 //若未註冊則新增一筆使用者紀錄,預設 lat 與 lng 經緯度位置為 0 17 18 } 19 if($result) { 20 $data['responese'] = 'success'; 21 echo json_encode($data); 22 23 24

天災救援建置 5-2. 登入功能 Layout activity_main.xml 1 2 3 4 5 6 7 8 9 10 11 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:paddingBottom="@dimen/activity_vertical_margin" 6 android:paddingLeft="@dimen/activity_horizontal_margin" 7 android:paddingRight="@dimen/activity_horizontal_margin" 8 android:paddingTop="@dimen/activity_vertical_margin" 9 tools:context=".MainActivity" > 10 <Button 11 android:id="@+id/button1"

天災救援建置 12 android:layout_width="wrap_content" 13 android:layout_height="wrap_content" 14 android:layout_alignParentBottom="true" 15 android:layout_centerHorizontal="true" 16 android:layout_marginBottom="78dp" 17 android:text="登入" /> 18 <EditText 19 android:id="@+id/editText1" 20 21 22 android:layout_alignParentTop="true" 23 24 android:layout_marginTop="95dp"

天災救援建置 25 android:ems="10" 26 android:inputType="textMultiLine" > 27 <requestFocus /> 28 </EditText> 29 <TextView 30 android:id="@+id/textView1" 31 android:layout_width="wrap_content" 32 android:layout_height="wrap_content" 33 android:layout_alignBottom="@+id/editText1" 34 android:layout_centerHorizontal="true" 35 android:layout_marginBottom="51dp" 36 android:text="名稱" 37 android:textAppearance="?android:attr/textAppearanceLarge" /> 38 </RelativeLayout>

天災救援建置 5-3. 登入功能 MainActivity.java 1 2 3 4 5 6 7 8 9 import org.apache.http.HttpEntity; 3 import org.apache.http.HttpResponse; 4 import org.apache.http.client.HttpClient; 5 import org.apache.http.client.methods.HttpGet; 6 import org.apache.http.impl.client.DefaultHttpClient; 7 import org.apache.http.util.EntityUtils; 8 import android.app.Activity; 9 import android.content.Context; 10 import android.content.Intent; 11 import android.os.Bundle; Android:MainActivity.java 打開 MainActivity.java

天災救援建置 12 import android.telephony.TelephonyManager; 13 import android.util.Log; 14 import android.view.View; 15 import android.view.View.OnClickListener; 16 import android.widget.Button; 17 import android.widget.EditText; 18 19 public class MainActivity extends Activity { 20 EditText name; 21 Button login; 22 23 protected void onCreate(Bundle savedInstanceState) { 24 super.onCreate(savedInstanceState);

天災救援建置 25 setContentView(R.layout.activity_main); 26 findViwe(); 27 //前置先與 Layout 元件作連結 28 simid(); 29 //取得 SIM Card ID 30 initListener(); 31 32 } 33 public void findViwe() { 34 name = (EditText) findViewById(R.id.editText1); 35 login = (Button) findViewById(R.id.button1); 36 //連結 EditText 與 Button 元件,並給定到參數中 37

天災救援建置 38 39 40 41 42 43 44 45 46 47 48 49 50 public void simid() { TelephonyManager manager = 40 (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); 41 value.simid = manager.getDeviceId(); 42 //透過 TelephonyManager 取得 SimCard ID,存放到 value.simid 43 } 44 45 public void initListener() { 46 login.setOnClickListener(new OnClickListener() { 47 public void onClick(View v) { 48 value.name = name.getText().toString(); 49 login Login = new login(); 50 Login.start();

天災救援建置 51 52 53 54 55 並在執行 Login 執行緒後,轉跳功能選擇頁 /* 56 } 57 }); 58 59 60 Intent intent = new Intent(); 52 intent.setClass(MainActivity.this, Map.class); 53 startActivity(intent); 54 /* 將 name 當中輸入的字串設定給 value 物件, 55 並在執行 Login 執行緒後,轉跳功能選擇頁 /* 56 } 57 }); 58 59 60 61 62 63

天災救援建置 64 class login extends Thread { 65 66 public void run() { 67 super.run(); 68 try { 69 HttpClient client = new DefaultHttpClient(); 70 String url = value.service + "login.php?simid=" + value.simid 71 + "&name=" + value.name; 72 //將 value 物件中的 service 與 simid 與 name 透過 GET 呼叫 login.php 73 HttpGet get = new HttpGet(url); 74 HttpResponse response = client.execute(get); 75 //執行 url 設定的 Login Service 76

天災救援建置 77 HttpEntity resEntity = response.getEntity(); 78 String result = EntityUtils.toString(resEntity); 79 //回傳執行的結果並存放在 result 當中 80 } catch (Exception e) { 81 e.printStackTrace(); 82 } 83 84 85 86 87 88 89

天災救援建置 6. 災害通報功能描述 Android Web Service 2 Map.java DetailActivity.java 3 Bundle(lat,lng) Map.java DetailActivity.java Require 在地圖上打點(災害位置)後 Bundle座標位置到災情回報頁面,並填寫災害類型與需求與拍攝現場照片 alarmType alarmDetail response location Web Service JSON simid alarmDetail.php photo 處理上傳相片並建立一筆新的災難紀錄 POST Response

天災救援建置 6-1. 災害通報功能 Service alarmDetail.php 1 @header("Content-Type:text/html; charset=utf-8"); 2   3 if (isset($_POST['alarmType']) && isset($_POST['alarmDetail']) && 4   isset($_POST['location']) && isset($_POST['simid']) && isset($_FILES['photo'])) { 5 6     $alarmType = mysql_real_escape_string($_POST['alarmType']); 7     $alarmDetail = mysql_real_escape_string($_POST['alarmDetail']); 8     $location = mysql_real_escape_string($_POST['location']); 9     $simid = mysql_real_escape_string($_POST['simid']); 10     /* 11      * 透過 Http Post 方式傳入

天災救援建置 12 * alarmDetail: 災害敘述或需求 13 * location: 災害位置(經緯度) 14      * simid: 使用者ID 15      * photo: 上傳檔案(照片) 16     */ 17  include("connect.php"); 18     $sql = "INSERT INTO alarm_detail(alarmDetail,alarmType,location,simid) 19             VALUES('$alarmDetail','$alarmType','$location','$simid')"; 20     $result = mysql_query($sql, $link) or die("oops"); 21     $last_id = mysql_insert_id(); 22     //加入一筆新的災害通報,並把自動產生的ID記錄到$last_id當中 23     if($result) 24     {

天災救援建置 25 if ($_FILES["photo"]["error"] > 0){ 26         echo "Error: " . $_FILES["photo"]["error"]; 27         //判斷上傳檔案是否有錯誤 28         }else{ 29             move_uploaded_file($_FILES["photo"]["tmp_name"],"upload/".$last_id.".jpg"); 30             echo 'OK:'.$last_id; 31             //若檔案上傳正常則將檔案從暫存位置移動到指定的目錄位置 32         } 33     }else 34     { 35 echo "Error"; 36 } 37

天災救援建置 6-2. 災害通報地圖打點功能 Layout map.xml 1 2 3 4 5 6 7 8 9 10 11 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 android:layout_width="fill_parent" 3 android:layout_height="fill_parent"> 4 5 <Button 6 android:id="@+id/button01" 7 android:layout_width="wrap_content" 8 android:layout_height="wrap_content" 9 android:layout_centerHorizontal="true" 10 android:layout_alignParentBottom="true" 11 android:text="下一步"/>

天災救援建置 12 <fragment 13 android:id="@+id/map" 14 android:layout_width="match_parent" 15 android:layout_height="wrap_content" 16 android:layout_alignParentTop="true" 17 android:layout_above="@id/button01" 18 class="com.google.android.gms.maps.MapFragment"/> 19 </RelativeLayout> 20 21 22 23 24

天災救援建置 6-3. 災害通報功能 Layout activity_detail.xml 1 2 3 4 5 6 7 8 9 10 11 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:paddingBottom="@dimen/activity_vertical_margin" 6 android:paddingLeft="@dimen/activity_horizontal_margin" 7 android:paddingRight="@dimen/activity_horizontal_margin" 8 android:paddingTop="@dimen/activity_vertical_margin" 9 tools:context=".MainActivity" > 10 <TextView 11 android:id="@+id/textView1"

天災救援建置 12 android:layout_width="wrap_content" 13 android:layout_height="wrap_content" 14 android:layout_marginTop="10dp" 15 android:text="災害類型:"/> 16 <Spinner 17 android:id="@+id/spinner1" 18 19 20 android:layout_below="@id/textView1" 21 /> 22 <EditText 23 android:id="@+id/editText1" 24 android:layout_width="match_parent"

天災救援建置 25 android:layout_height="wrap_content" 26 android:layout_below="@id/spinner1" 27 android:layout_marginTop="10dp" 28 android:hint="災害需求" 29 /> 30 <ImageButton 31 android:id="@+id/imageButton1" 32 android:layout_width="100dp" 33 android:layout_height="100dp" 34 android:layout_below="@id/editText1" 35 android:layout_centerHorizontal="true" 36 android:layout_marginTop="10dp"/> 37

天災救援建置 38 <Button 39 android:id="@+id/button1" 40 android:layout_width="wrap_content" 41 android:layout_height="wrap_content" 42 android:layout_below="@id/imageButton1" 43 android:layout_centerHorizontal="true" 44 android:layout_marginTop="10dp" 45 android:text="Send" 46 /> 47 </RelativeLayout> 48 49 50

天災救援建置 6-4. 災害通報地圖打點功能 Map.java 打開 Map.java 1 import android.app.Activity; 2 import android.content.Intent; 3 import android.os.Bundle; 4 import android.view.View; 5 import android.widget.Button; 6 import android.view.View.OnClickListener; 7 import com.google.android.gms.maps.GoogleMap; 8 import com.google.android.gms.maps.MapFragment; 9 import com.google.android.gms.maps.model.LatLng; 10 import com.google.android.gms.maps.model.Marker; 11 import com.google.android.gms.maps.CameraUpdateFactory; 打開 Map.java

天災救援建置 12 import com.google.android.gms.maps.model.MarkerOptions; 13 import com.google.android.gms.maps.GoogleMap.OnMapClickListener; 14 import com.google.android.gms.maps.GoogleMap.OnMarkerClickListener; 15   16 public class Map extends Activity implements OnMarkerClickListener,OnMapClickListener 17 { 18     //實作 OnMarkerClickListener 與 OnMapClickListener 19     static LatLng AlarmLocation = null; 20     GoogleMap mMap; 21     Button button01; 22     LatLng latlng = new LatLng(22.764702, 120.371935); 23     Marker myMarker; 24

天災救援建置 25     @Override 26     protected void onCreate(Bundle savedInstanceState) { 27         super.onCreate(savedInstanceState); 28         setContentView(R.layout.map); 29         findViwe(); 30         //前置先與 Layout 元件作連結 31         initListener(); 32         //初始化相關監聽物件 33         setMap(); 34         //地圖初始設定 35     } 36      37     public void findViwe() {

天災救援建置 38 button01=(Button)findViewById(R.id.button01); 39         mMap = ((MapFragment) getFragmentManager() 40                 .findFragmentById(R.id.map)) 41                 .getMap(); 42     } 43      44     public void initListener() { 45         button01.setOnClickListener(new OnClickListener() { 46             @Override 47             public void onClick(View v) { 48                 // TODO Auto-generated method stub 49               if(AlarmLocation != null) 50               {

天災救援建置 51 Intent intent = new Intent(); 52                 intent.setClass(Map.this, DetailActivity.class); 53                 intent.putExtra("location", 54                                     AlarmLocation.latitude + "," + 55                                     AlarmLocation.longitude); 56                 startActivity(intent); 57                 /* 58                  * 按下按鈕後先判斷 AlarmLocation 是否有值 59                  * 再傳值 Location 至下一個 Activity 60                  */ 61               } 62             } 63         });

天災救援建置 64 } 65 66 public void setMap(){ 67     } 65      66     public void setMap(){ 67         mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL); 68         mMap.moveCamera(CameraUpdateFactory. 69                 newLatLngZoom(latlng, 15.0f)); 70         mMap.setOnMapClickListener(this); 71         //設置地圖 72 73 74     @Override 75     public boolean onMarkerClick(Marker marker) { 76         // TODO Auto-generated method stub

天災救援建置 77 if (marker.equals(myMarker)) { 78 // handle click here 79 }         } 80         return false; 81     } 82   83     @Override 84     public void onMapClick(LatLng point) { 85          86         if(myMarker == null) 87         { 88             MarkerOptions markerOptions = new MarkerOptions(); 89             markerOptions.position(point);

天災救援建置 90 markerOptions.title("災害地點"); 91             myMarker = mMap.addMarker(markerOptions); 92             //點擊地圖後,即會在地圖上新增災害標記位置 93         }else 94         { 95             myMarker.setPosition(point); 96             //如果已經新增過標記,即作災害標記位置的移動 97         } 98         AlarmLocation = point; 99         //觸發點擊地圖即紀錄座標位置於 AlarmLocation 100     } 101   102 }

打開 DetailActivity.java 天災救援建置 6-5. 災害通報功能 DetailActivity.java 1 import java.io.ByteArrayOutputStream; 2 import java.io.FileNotFoundException; 3 import java.nio.charset.Charset; 4 import org.apache.http.HttpResponse; 5 import org.apache.http.client.HttpClient; 6 import org.apache.http.client.methods.HttpPost; 7 import org.apache.http.entity.ContentType; 8 import org.apache.http.entity.mime.HttpMultipartMode; 9 import org.apache.http.entity.mime.MultipartEntityBuilder; 10 import org.apache.http.entity.mime.content.ByteArrayBody; 11 import org.apache.http.impl.client.DefaultHttpClient; 打開 DetailActivity.java

天災救援建置 12 import org.apache.http.protocol.BasicHttpContext; 13 14 import org.apache.http.protocol.HttpContext; 15 import org.apache.http.util.EntityUtils; 16 import android.app.Activity; 17 import android.content.ContentResolver; 18 import android.content.Intent; 19 import android.graphics.Bitmap; 20 import android.graphics.BitmapFactory; 21 import android.net.Uri; 22 import android.os.Bundle; 23 import android.os.Handler; 24 import android.os.Message;

天災救援建置 25 import android.util.Log; 26 import android.view.View; 27 import android.view.View.OnClickListener; 28 import android.widget.AdapterView; 29 import android.widget.AdapterView.OnItemSelectedListener; 30 import android.widget.ArrayAdapter; 31 import android.widget.Button; 32 import android.widget.EditText; 33 import android.widget.ImageButton; 34 import android.widget.Spinner; 35   36 public class DetailActivity extends Activity { 37     

天災救援建置 38 Spinner spinner1; 39 EditText editText1; 40     ImageButton imageButton1; 41     Button button1; 42     String[] SpinnerList = new 43             String[]{"火災","水災","地震", 44                         "土石流","報案","物資","其他"}; 45     String location = ""; 46     String alarmType = ""; 47     String alarmDetail = ""; 48     String ad_id = ""; 49     Bitmap photo = null; 50     

天災救援建置 51     @Override 52     protected void onCreate(Bundle savedInstanceState) { 53         super.onCreate(savedInstanceState); 54         setContentView(R.layout.activity_detail); 55         findViwe(); 56         //前置先與 Layout 元件作連結 57         getValue(); 58         //取得前一個Activity傳遞資料 59         init(); 60         //初始化物件 61         initListener(); 62         //初始化相關監聽物件 63     }

天災救援建置 64 65 public void findViwe() { 66   65     public void findViwe() { 66         spinner1=(Spinner)findViewById(R.id.spinner1); 67         editText1=(EditText)findViewById(R.id.editText1); 68         imageButton1=(ImageButton)findViewById(R.id.imageButton1); 69         button1=(Button)findViewById(R.id.button1); 70     } 71      72     public void getValue() 73     { 74         Intent intent1=getIntent(); 75         location = intent1.getStringExtra("location"); 76         //取得Map Activity 傳遞的 location 值

天災救援建置 77 } 78 79 public void init() 80 { 81     } 78      79     public void init() 80     { 81         ArrayAdapter ListAD = new ArrayAdapter 82                (this,android.R.layout.simple_spinner_item,SpinnerList); 83         spinner1.setAdapter(ListAD); 84         //初始化下拉式選單 85 86   87     public void initListener() { 88          89         spinner1.setOnItemSelectedListener(new OnItemSelectedListener(){

天災救援建置 90   91             @Override 92             public void onItemSelected(AdapterView arg0, View arg1, 93                     int position, long arg3) { 94                 // TODO Auto-generated method stub 95                 alarmType = SpinnerList[position]; 96                 //將所選擇的 position 對應給 Spinner String Array 並存放在 alarmType 97             } 98 99 100             public void onNothingSelected(AdapterView arg0) { 101 102                 

天災救援建置 103             } 104              105         }); 106          107         imageButton1.setOnClickListener(new OnClickListener() { 108             @Override 109             public void onClick(View arg0) { 110                 // TODO Auto-generated method stub 111                 Intent intent = new Intent( 112                         android.provider.MediaStore.ACTION_IMAGE_CAPTURE); 113                 startActivityForResult(intent, 1); 114                 /* 透過 startActivityForResult 啟動拍照功能 115                  * 並透過 intent 轉跳到攝影畫面再返回相關照片路徑資料

天災救援建置 116                  */ 117             } 118              119         }); 120         button1.setOnClickListener(new OnClickListener() { 121             @Override 122             public void onClick(View v) { 123                 AlarmUpload alarmUpload = new AlarmUpload(); 124                 alarmUpload.start(); 125                 //當按下按鈕後便啟動 AlarmUpload 執行序 126 127 128     }

天災救援建置 129 130 class AlarmUpload extends Thread { 131 @Override 132   130     class AlarmUpload extends Thread { 131         @Override 132         public void run() { 133             // TODO Auto-generated method stub 134             super.run(); 135             alarmDetail = editText1.getText().toString(); 136             //取得 textview 輸入之內容 137             if(location.isEmpty()||alarmType.isEmpty()|| 138                     alarmDetail.isEmpty()||photo==null) 139             { 140                 return; 141                 //判斷是否有資料不齊全,若不齊全則跳出

天災救援建置 142             } 143              144             try { 145                 HttpClient httpClient = new DefaultHttpClient(); 146                 HttpContext localContext = new BasicHttpContext(); 147                 HttpPost httpPost = new HttpPost( 148                         value.service + "alarmDetail.php" ); 149                 //透過 HttpPost 將 Service URL 位置設定好 150                 MultipartEntityBuilder meBuilder = MultipartEntityBuilder.create(); 151                 meBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE); 152                 meBuilder.setCharset(Charset.forName(HTTP.UTF_8)); 153                 photo = Bitmap.createScaledBitmap(photo, photo.getWidth()/2, 154                                                       photo.getHeight()/2, true);

天災救援建置 155                 ByteArrayOutputStream baoStream = new ByteArrayOutputStream(); 156                 byte [] data = baoStream.toByteArray(); 157                 //將photo調整長寬比例後並將其轉置存放在 ByteArray 158                  159                 meBuilder.addPart("photo",new ByteArrayBody(data, "test.jpg")); 160                 meBuilder.addTextBody("alarmType", alarmType, ContentType 161                         .create( "text/plain" , Charset.forName( HTTP.UTF_8))); 162                 meBuilder.addTextBody("alarmDetail", alarmDetail,ContentType 163 164                 meBuilder.addTextBody("location", location); 165                 meBuilder.addTextBody("simid", value.simid); 166                 //透過 MultipartEntityBuilder來建立 Post 傳遞相關資訊 167                 httpPost.setEntity(meBuilder.build()); 168                 HttpResponse response = httpClient.execute(httpPost, localContext);

天災救援建置 169                 String Response = EntityUtils.toString(response.getEntity()); 170                  171                 if(Response.startsWith("OK")) 172                 { 173                     ad_id = Response.split(":")[1]; 174                     //取出 Web Service 新建立災情自動編號的回傳 ID 值 175                     Message msg = new Message(); 176                     msg.what=1; 177                     mHandler.sendMessage(msg); 178                     //此 Web Service 回傳資訊是以":"作間隔,例: OK;2,故透過 split 來作分割 179                 } 180             } catch (Exception e) { 181                 e.printStackTrace();

天災救援建置 182             } 183         } 184     } 185      186     protected void onActivityResult(int requestCode, int resultCode, Intent data) 187     { 188         if (requestCode==1&&resultCode == RESULT_OK) 189         { 190             Uri uri=data.getData(); 191             ContentResolver CR=getContentResolver(); 192             try { 193                 //由抽象資料接口轉換圖檔路徑為 Bitmap 194                 photo= BitmapFactory.decodeStream(CR.openInputStream(uri));

天災救援建置 195 imageButton1.setImageBitmap(photo); 196             } catch (FileNotFoundException e) { 197                  Log.e("Exception", e.getMessage(),e); 198             } 199         } 200         super.onActivityResult(requestCode, resultCode, data); 201     } 202      203     private Handler mHandler = new Handler() { 204         public void handleMessage(Message msg) { 205             super.handleMessage(msg); 206              207             if(msg.what==1)

天災救援建置 208 { 209 Intent intent = new Intent(); 210             { 209                 Intent intent = new Intent(); 210                 intent.setClass(DetailActivity.this, StatusActivity.class); 211                 intent.putExtra("ad_id", ad_id); 212                 startActivity(intent); 213             } 214             /* 215                      透過 handler 來請 main thread 處理 setList 216                 sub thread 不能值接對 UI 作控制,必須透過 handler 來請主程序作 217             */ 218         } 219     }; 220 }

天災救援建置 7. 災害通報遠端回覆功能描述 Android Web Service 4 StatusActivity.java Require 在將災害資料上傳後,便等待遠端救難人員的確認訊息 simid 0 or 1 ad_id String Web Service GET alarmStatus.php 查詢災害狀態是否已被確認

天災救援建置 7-1. 災害通報功能 Service alarmStatus.php 1 @header("Content-Type:text/html; charset=utf-8"); 2 if (isset($_GET['simid'])&&isset($_GET['ad_id'])) { 3     $simid = mysql_real_escape_string($_GET['simid']); 4     $ad_id = mysql_real_escape_string($_GET['ad_id']); 5      6     include("connect.php"); 7   8     $sql = "SELECT `check` FROM alarm_detail 9              WHERE simid = '$simid' AND ad_id = '$ad_id'"; 10     $result = mysql_query($sql, $link) or die("oops"); 11     //指定查詢 $simid 與$ad_id 條件,察看災情處理人員是否確認收到這筆資訊

天災救援建置 12 if(mysql_num_rows($result) != 0) 13 { 14     { 14         while($row = mysql_fetch_array($result)) { 15           echo $row['check']; 16           //show 出災難通報是否已確認(check -> 已確認:1, 未確認:0 ) 17             break; 18         } 19     } 20 } 21 22 23 24

天災救援建置 7-2.災害通報功能 Layout activity_status.xml 1 2 3 4 5 6 7 8 9 10 11 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:paddingBottom="@dimen/activity_vertical_margin" 6 android:paddingLeft="@dimen/activity_horizontal_margin" 7 android:paddingRight="@dimen/activity_horizontal_margin" 8 android:paddingTop="@dimen/activity_vertical_margin" 9 tools:context=".MainActivity" > 10 <TextView 11 android:id="@+id/textView1"

天災救援建置 12 android:layout_width="wrap_content" 13 android:layout_height="wrap_content" 14 android:layout_centerHorizontal="true" 15 android:layout_marginBottom="51dp" 16 android:text="災情處理中心未確認" 17 android:textAppearance="?android:attr/textAppearanceLarge" /> 18 19 </RelativeLayout> 20 21 22 23 24

打開 StatusActivity.java 天災救援建置 7-3.災害通報功能 StatusActivity.java 1 import org.apache.http.HttpEntity; 2 import org.apache.http.HttpResponse; 3 import org.apache.http.client.HttpClient; 4 import org.apache.http.client.methods.HttpGet; 5 import org.apache.http.impl.client.DefaultHttpClient; 6 import org.apache.http.util.EntityUtils; 7 import android.app.Activity; 8 import android.content.Intent; 9 import android.os.Bundle; 10 import android.os.Handler; 11 import android.os.Message; 打開 StatusActivity.java

天災救援建置 12 import android.widget.TextView; 13 14   14 public class StatusActivity extends Activity { 15     TextView textView; 16     String ad_id = ""; 17 18     protected void onCreate(Bundle savedInstanceState) { 19         super.onCreate(savedInstanceState); 20         setContentView(R.layout.activity_status); 21         getValue(); 22         //取出前一個 Activity 傳遞的值 23         findViwe(); 24

天災救援建置 25 //前置先與 Layout 元件作連結 26 AlarmStatus AS = new AlarmStatus(); 27         AS.start(); 28         //執行 AlarmStatus 執行序 29     } 30      31     public void getValue() 32     { 33         Intent intent1 = getIntent(); 34         ad_id = intent1.getStringExtra("ad_id"); 35 36 37     public void findViwe() {

天災救援建置 38 textView = (TextView) findViewById(R.id.textView1); 39         //連結 EditText 與 Button 元件,並給定到參數中 40     } 41   42     // 登入的執行序 43     class AlarmStatus extends Thread { 44         @Override 45         public void run() { 46             // TODO Auto-generated method stub 47             super.run(); 48             try { 49                 HttpClient client = new DefaultHttpClient(); 50                 String url = value.service + "alarmStatus.php?simid="

天災救援建置 51 + value.simid+"&ad_id=" + ad_id; 52                 //將 value 物件中的 service 與 simid 與 name 透過 GET 呼叫 login.php 53                 HttpGet get = new HttpGet(url); 54                 HttpResponse response = client.execute(get); 55                 //執行 url 設定的 Login Service 56                 HttpEntity resEntity = response.getEntity(); 57                 String result = EntityUtils.toString(resEntity); 58                 if(result.equals("1")) 59                 { 60                     Message msg = new Message(); 61                     msg.what=1; 62                     mHandler.sendMessage(msg); 63                     //若回傳訊息值為 1,則執行畫面更新為已確認

天災救援建置 64 }else 65 { 66 Thread.sleep(5000); 67                 { 66                     Thread.sleep(5000); 67                     AlarmStatus AS = new AlarmStatus(); 68                     AS.start(); 69                     //若回傳訊息為 0,則休眠 5s 在重複執行確認動作 70                 } 71             } catch (Exception e) { 72                 e.printStackTrace(); 73             } 74         } 75     } 76     

天災救援建置 } 77 private Handler mHandler = new Handler() { 78         public void handleMessage(Message msg) { 79             super.handleMessage(msg); 80             if(msg.what == 1) 81             { 82                 textView.setText("災情處理中心已確認"); 83             } 84             /* 透過 handler 來請 main thread 處理 setList 85              * sub thread 不能值接對 UI 作控制,必須透過 handler 來請主程序作 86              */  87         } 88     }; 89 }

天災救援建置 8. 天災後端確認功能描述 Web alarm.php 天災管理系統 Require 顯示全部天災通報相關資訊,並且在即時確認後更新通報狀態,讓手機端可以接收確認訊息 response ad_id POST 天災管理系統 ID Picture Type Require Position Simid Check # 災害照片 災害類型 需求或描述 位置座標 傳送人 確認按鈕

天災救援建置 8-1. 天災後端確認 Web alarm.php 1 <!-- Latest compiled and minified CSS Bootstrap --> 2 <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css"> 3 <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css"> 4 <style type="text/css"> 5 td{ 6 vertical-align: middle !important; 7 text-align: center !important; 8 } 9 </style> 10 <body> 11 <div class="container">

天災救援建置 12 <table frame="box" rules="all" class="center-block table table-striped table-hover"> 13 <th colspan="7" class="text-center">天災管理系統</th> 14 <tr class="text-center"> 15 <td>ID</td> 16 <td>Picture</td> 17 <td>Type</td> 18 <td>Require</td> 19 <td>Position</td> 20 <td>Simid</td> 21 <td>Check</td> 22 <tr> 23 <?php 24 @header("Content-Type:text/html; charset=utf-8");

天災救援建置 25 include("connect.php"); 26 if(isset($_POST['ad_id'])) 27 { 28 $ad_id = mysql_real_escape_string($_POST['ad_id']); 29 $sql = "Update alarm_detail SET `check` = '1' WHERE ad_id = '$ad_id'"; 30 $result = mysql_query($sql, $link) or die("oops"); 31 //如果$_POST['ad_id']有取得值,則進行更新該 ad_id 的 check 狀態為1 32 } 33 $sql = "SELECT * FROM alarm_detail"; 34 35 //查詢所有天災通報的資訊 36 if(mysql_num_rows($result) != 0) 37

天災救援建置 38 while($row = mysql_fetch_array($result)) { 39 echo '<tr><td>'.$row['ad_id'].'</td><td>' 40 .'<img src="upload/'.$row['ad_id'] 41 .'.jpg" alt="photo" width="100" class' 42 .'="img-thumbnail center-block"></td><td>' 43 .$row['alarmType'].'</td><td>' 44 .$row['alarmDetail'].'</td><td>' 45 .$row['location'].'</td><td>' 46 .$row['simid'].'</td><td>'; 47 //使用迴圈將資料逐筆取出,並且寫至html的表格當中 48     if($row['check']=='0') 49 { 50 echo '<form name="form1" method="post" action="">'

天災救援建置 51 .'<input type="submit" name="submit" value="確認"' 52 .' class="btn btn-primary center-block">'; 53 echo '<input type="hidden" name="ad_id" value="' 54 .$row['ad_id'].'" ></form>'; 55 //檢查check欄位目前狀態, 值為 0:則秀出按鈕 1:不顯示按鈕 56 } 57 echo '</td></tr>'; 58 59 60 ?> 61 </table> 62 </div> 63 </body>

天災救援建置 8-1. 天災後端確認 Web 天災後端頁面展示