Parcourir la source

集成Apex Mobile

Ray Zhang il y a 7 ans
Parent
commit
6fdda90a3e
100 fichiers modifiés avec 30286 ajouts et 0 suppressions
  1. 63 0
      ApexDrivers/apexmobile/build.gradle
  2. BIN
      ApexDrivers/apexmobile/libs/BaiduLBS_Android.jar
  3. BIN
      ApexDrivers/apexmobile/libs/bcprov-jdk15on-157.jar
  4. BIN
      ApexDrivers/apexmobile/libs/core-2.3.0.jar
  5. BIN
      ApexDrivers/apexmobile/libs/httpmime-4.1.1.jar
  6. 40 0
      ApexDrivers/apexmobile/proguard-project.txt
  7. 354 0
      ApexDrivers/apexmobile/src/main/AndroidManifest.xml
  8. BIN
      ApexDrivers/apexmobile/src/main/ic_launcher-web.png
  9. 167 0
      ApexDrivers/apexmobile/src/main/java/com/usai/Contacts/Contact.java
  10. 475 0
      ApexDrivers/apexmobile/src/main/java/com/usai/Contacts/ContactsManager.java
  11. 154 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/AboutActivity.java
  12. 362 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/Alarmreceiver.java
  13. 497 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/AnnouncementActivity.java
  14. 219 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/ApexActivity.java
  15. 51 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/ApexBackgroundService.java
  16. 88 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/ApexHistoryActivity.java
  17. 25 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/ApexPushService.java
  18. 501 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/ApexTrackingApplication.java
  19. 700 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/BaiduMapFragment.java
  20. 97 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/BootBroadcastReceiver.java
  21. 370 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/ChangePasswordActivity.java
  22. 166 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/ContainerSearchActivity.java
  23. 330 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/CustomizeFieldsActivity.java
  24. 607 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/DetailActivity.java
  25. 1726 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/DetailFragment.java
  26. 25 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/DocumentsActivity.java
  27. 86 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/DocumentsFragment.java
  28. 282 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/DragListView.java
  29. 411 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/FunctionSelectActivity.java
  30. 48 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/HelpActivity.java
  31. 312 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/InnerMapActivity.java
  32. 31 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/InnerToolsActivity.java
  33. 540 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/KPI/KPICell.java
  34. 67 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/KPI/KPIDot.java
  35. 47 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/KPI/KPIItemButton.java
  36. 47 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/KPI/KPIListView.java
  37. 53 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/KPI/KPISwipeRefresh.java
  38. 88 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/KPI/KPIViewPager.java
  39. 711 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/KPI/PieChartView.java
  40. 70 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/LicenseActivity.java
  41. 203 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/LocalDocumentActivity.java
  42. 29 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/LocationDetail.java
  43. 171 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/LocationDetailActivity.java
  44. 370 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/MessageActivity.java
  45. 424 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/MessageDetailActivity.java
  46. 646 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/Result/AMResultActivity.java
  47. 348 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/Result/PullRefreshListView.java
  48. 1361 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/Result/SearchResultActivity.java
  49. 871 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/ResultActivity.java
  50. 424 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/RetrievePasswordActivity.java
  51. 412 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/SearchActivity.java
  52. 161 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/SearchHistoryActivity.java
  53. 695 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/SearchListActivity.java
  54. 78 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/SearchResult.java
  55. 174 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/SegmentView.java
  56. 79 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/ServiceLocationFragment.java
  57. 371 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/SettingsActivity.java
  58. 735 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/ShipMap/ShipMap.java
  59. 71 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/TestActivity.java
  60. 57 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/TestAppComActivity.java
  61. 45 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/ViewPagerAdapter.java
  62. 87 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/WebActivity.java
  63. 94 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/mainframe/BottomNavigationViewHelper.java
  64. 355 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/mainframe/HistoryFragment.java
  65. 230 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/mainframe/HomeFragment.java
  66. 749 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/mainframe/KPIFragment.java
  67. 475 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/mainframe/LoginFragment.java
  68. 167 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/mainframe/MyFragment.java
  69. 934 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/mainframe/NewDetailActivity.java
  70. 30 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/mainframe/NoScrollViewPager.java
  71. 333 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/mainframe/RecentFragment.java
  72. 634 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/mainframe/RootActivity.java
  73. 131 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/mainframe/SearchFragment.java
  74. 237 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/mainframe/StaticModelistFragment.java
  75. 308 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/mainframe/ToolsFragment.java
  76. 83 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/mainframe/TrackingImageView.java
  77. 843 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/mainframe/TrackingListFragment.java
  78. 159 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/mainframe/TrackingListSearchResult.java
  79. 401 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/pdf/PDFPreviewActivity.java
  80. 98 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/saved/AMListFragment.java
  81. 185 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/saved/CheckSavedActivity.java
  82. 374 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/saved/SavedDetailFragment.java
  83. 490 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/saved/SavedDocumentsFragment.java
  84. 399 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/saved/SavedSearchFragment.java
  85. 41 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/swipemenulistview/BaseSwipListAdapter.java
  86. 53 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/swipemenulistview/SwipeMenu.java
  87. 149 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/swipemenulistview/SwipeMenuAdapter.java
  88. 13 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/swipemenulistview/SwipeMenuCreator.java
  89. 96 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/swipemenulistview/SwipeMenuItem.java
  90. 347 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/swipemenulistview/SwipeMenuLayout.java
  91. 339 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/swipemenulistview/SwipeMenuListView.java
  92. 104 0
      ApexDrivers/apexmobile/src/main/java/com/usai/apex/swipemenulistview/SwipeMenuView.java
  93. 242 0
      ApexDrivers/apexmobile/src/main/java/com/usai/util/AES.java
  94. 1904 0
      ApexDrivers/apexmobile/src/main/java/com/usai/util/Network.java
  95. 849 0
      ApexDrivers/apexmobile/src/main/java/com/usai/util/RAUtil.java
  96. 96 0
      ApexDrivers/apexmobile/src/main/java/com/usai/util/SqlOpenHelper.java
  97. 211 0
      ApexDrivers/apexmobile/src/main/java/com/usai/util/commonUtil.java
  98. 384 0
      ApexDrivers/apexmobile/src/main/java/com/usai/util/dbUtil.java
  99. 119 0
      ApexDrivers/apexmobile/src/main/java/com/usai/util/dbgUtil.java
  100. 8 0
      ApexDrivers/apexmobile/src/main/java/com/usai/util/package-info.java

+ 63 - 0
ApexDrivers/apexmobile/build.gradle

@@ -0,0 +1,63 @@
+apply plugin: 'com.android.application'
+
+android {
+    signingConfigs {
+    }
+    compileSdkVersion 26
+    defaultConfig {
+        applicationId "com.usai.apex"
+        minSdkVersion 23
+        targetSdkVersion 26
+//        multiDexEnabled true
+
+//        ndk {
+//            abiFilters  "armeabi-v7a"  // 指定要ndk需要兼容的架构(这样其他依赖包里mips,x86,armeabi,arm-v8之类的so会被过滤掉)
+//        }
+    }
+    buildTypes {
+        release {
+
+            ndk {
+                abiFilters "armeabi-v7a"
+                // 指定要ndk需要兼容的架构(这样其他依赖包里mips,x86,armeabi,arm-v8之类的so会被过滤掉)
+            }
+
+            minifyEnabled true
+            zipAlignEnabled true
+            shrinkResources true
+            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-project.txt'
+        }
+        debug {
+//            minifyEnabled true
+//            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-project.txt'
+        }
+    }
+    sourceSets {
+        main {
+            jniLibs.srcDir 'libs'
+            //说明so的路径为该libs路径,关联所有地图SDK的so文件
+        }
+    }
+}
+
+dependencies {
+    //    compile 'com.android.support:support-v4:19.1.0'
+    implementation files('libs/bcprov-jdk15on-157.jar')
+    api 'com.android.support:appcompat-v7:26.1.0'
+    api 'com.android.support:support-v4:26.1.0'
+    api 'com.android.support.constraint:constraint-layout:1.1.3'
+    api 'com.android.support:design:26.1.0'
+    //    compile 'com.android.support:recyclerview-v7:26.1.0'
+    //    compile 'com.google.android.gms:play-services:11.0.4'
+    api 'com.google.android.gms:play-services-maps:11.4.2'
+    api 'com.google.android.gms:play-services-location:11.4.2'
+    //    compile files('libs/baidumapapi_base_v3_7_1.jar')
+    //    compile files('libs/baidumapapi_map_v3_7_1.jar')
+    implementation files('libs/httpmime-4.1.1.jar')
+    implementation files('libs/core-2.3.0.jar')
+    api 'com.github.barteksc:android-pdf-viewer:3.0.0-beta.5'
+    implementation files('libs/BaiduLBS_Android.jar')
+}
+android {
+    useLibrary 'org.apache.http.legacy'
+}

BIN
ApexDrivers/apexmobile/libs/BaiduLBS_Android.jar


BIN
ApexDrivers/apexmobile/libs/bcprov-jdk15on-157.jar


BIN
ApexDrivers/apexmobile/libs/core-2.3.0.jar


BIN
ApexDrivers/apexmobile/libs/httpmime-4.1.1.jar


+ 40 - 0
ApexDrivers/apexmobile/proguard-project.txt

@@ -0,0 +1,40 @@
+# To enable ProGuard in your project, edit project.properties
+# to define the proguard.config property as described in that file.
+#
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in ${sdk.dir}/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the ProGuard
+# include property in project.properties.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}
+#-libraryjars   /libs/android-support-v4.jar
+#-libraryjars   /libs/httpmime-4.1.1.jar
+
+-dontwarn android.support.v4.** 
+-dontwarn com.google.android.gms.** 
+-dontwarn javax.naming.**
+
+# Remove all Verbose/Debug logging
+-optimizations code/removal/simple,code/removal/advanced
+-dontobfuscate
+-assumenosideeffects class android.util.Log {
+    public static *** d(...);
+    public static *** v(...);
+    public static *** i(...);
+}
+
+
+-keep class com.baidu.** {*;}
+#-keep class com.baidu.mapapi.** {*;}
+-keep class vi.com.gdi.bgl.** {*;}

+ 354 - 0
ApexDrivers/apexmobile/src/main/AndroidManifest.xml

@@ -0,0 +1,354 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.usai.apex"
+    android:versionCode="17"
+    android:versionName="A180723"> <!-- Copied from Google Maps Library/AndroidManifest.xml. -->
+    <!--<uses-sdk-->
+        <!--android:minSdkVersion="14"-->
+        <!--android:targetSdkVersion="18" />-->
+
+    <!-- 写联系人权限 -->
+    <uses-permission android:name="android.permission.WRITE_CONTACTS" />
+    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
+    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
+    <!--
+         <uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
+    <uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT" />
+    -->
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.READ_CONTACTS" />
+    <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
+    <!-- External storage for caching. -->
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <!-- My Location -->
+    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+    <!-- Maps API needs OpenGL ES 2.0. -->
+    <uses-feature
+        android:glEsVersion="0x00020000"
+        android:required="true" />
+    <!-- End of copy. -->
+
+
+    <!-- Baidu Map API -->
+
+    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
+    <!--<uses-permission android:name="android.permission.WRITE_SETTINGS" />-->
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+
+    <!--
+    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
+    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
+    <uses-permission android:name="android.permission.USE_CREDENTIALS" />
+    <uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
+    <uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
+
+    <permission android:name="android.permission.BAIDU_LOCATION_SERVICE" >
+    </permission>
+
+    <uses-permission android:name="android.permission.BAIDU_LOCATION_SERVICE" >
+    </uses-permission>
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" >
+    </uses-permission>
+    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" >
+    </uses-permission>
+    <uses-permission android:name="android.permission.INTERNET" >
+    </uses-permission>
+    <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" >
+    </uses-permission>
+    -->
+    <!-- <uses-permission android:name="android.permission.WRITE_APN_SETTINGS"></uses-permission> -->
+    <!--
+    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" >
+    </uses-permission>
+    <uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" />
+    <uses-permission android:name="android.permission.WAKE_LOCK" >
+    </uses-permission>
+    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
+   
+    <uses-permission android:name="android.permission.ACCESS_GPS" />
+    -->
+    <!--
+    <uses-permission android:name="android.permission.CALL_PHONE" />
+    <uses-permission android:name="android.permission.READ_SMS" />
+    <uses-permission android:name="android.permission.SEND_SMS" />
+    -->
+    <!-- SDK1.5需要android.permission.GET_TASKS权限判断本程序是否为当前运行的应用? -->
+    <!--
+        <uses-permission android:name="android.permission.GET_TASKS" />
+     <uses-permission android:name="android.permission.CAMERA" >
+    </uses-permission>
+    <uses-permission android:name="android.permission.RECORD_AUDIO" >
+    </uses-permission>
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" >
+    </uses-permission>
+    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
+    <uses-permission android:name="android.permission.BROADCAST_STICKY" />
+    -->
+    <!-- 来电消音 -->
+    <!--
+    <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" >
+    </uses-permission>
+    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
+    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
+    -->
+    <application
+        android:name=".ApexTrackingApplication"
+        android:allowBackup="true"
+        android:icon="@drawable/ic_launcher"
+        android:label="@string/app_name"
+        android:screenOrientation="portrait"
+        android:theme="@style/FixedActionbarTheme">
+        <provider
+            android:name="android.support.v4.content.FileProvider"
+            android:authorities="com.usai.apex.fileprovider"
+            android:exported="false"
+            android:grantUriPermissions="true">
+            <meta-data
+                android:name="android.support.FILE_PROVIDER_PATHS"
+                android:resource="@xml/download_dir" />
+        </provider>
+
+        <!-- release key -->
+        <meta-data
+            android:name="com.google.android.maps.v2.API_KEY"
+            android:value="AIzaSyDdbk58Lx6QzaXcB_hNpSHVp3l_CJeNpoo" />
+        <meta-data
+            android:name="com.baidu.lbsapi.API_KEY"
+            android:value="nqBQoSDbxrslhuzW91uViQX7" />
+        <meta-data
+            android:name="com.google.android.gms.version"
+            android:value="@integer/google_play_services_version" />
+
+        <!-- debug key -->
+
+
+         <!--<meta-data-->
+         <!--android:name="com.google.android.maps.v2.API_KEY"-->
+         <!--android:value="AIzaSyD6Snyg2SDUGtkC3sOAr979__IDCZnGGuU" />-->
+         <!--<meta-data-->
+         <!--android:name="com.baidu.lbsapi.API_KEY"-->
+         <!--android:value="tznWFxd3RvSoul1TGQp6GSzo" />-->
+         <!--<meta-data-->
+         <!--android:name="com.google.android.gms.version"-->
+         <!--android:value="@integer/google_play_services_version" />-->
+
+        <activity
+            android:name=".DetailActivity"
+            android:label="@string/title_activity_detail"
+            android:screenOrientation="portrait"
+            android:theme="@style/DetailActionbarTheme">
+
+            <!--
+                 <meta-data
+                android:name="android.support.PARENT_ACTIVITY"
+                android:value="android.support.v4.app.FragmentActivity" />
+
+           
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+            -->
+        </activity>
+        <activity
+            android:name=".ApexActivity"
+            android:label="@string/title_activity_apex"
+            android:logo="@drawable/apexlogo_2"
+            android:screenOrientation="portrait"
+            android:windowSoftInputMode="adjustPan" />
+        <!--
+             <activity
+            android:name="com.usai.apex.LoginFragment"
+            android:label="@string/title_activity_login"
+            android:windowSoftInputMode="adjustResize|stateVisible" >
+        </activity>
+        <activity
+            android:name="com.usai.apex.DirectTrackingFragment"
+            android:label="@string/title_activity_direct_tracking" >
+        </activity>
+        -->
+        <!-- android:launchMode="singleTask" -->
+        <activity
+            android:name=".mainframe.RootActivity"
+            android:configChanges="fontScale"
+            android:launchMode="singleTop"
+            android:screenOrientation="portrait"
+            android:theme="@style/ToolbarTheme">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity
+            android:name=".FunctionSelectActivity"
+            android:label="@string/title_activity_function_select"
+            android:launchMode="singleTop"
+            android:logo="@drawable/apexlogo_2"
+            android:screenOrientation="portrait">
+
+            <!-- <intent-filter> -->
+            <!-- <action android:name="android.intent.action.MAIN" /> -->
+
+
+            <!-- <category android:name="android.intent.category.LAUNCHER" /> -->
+            <!-- </intent-filter> -->
+        </activity>
+        <activity
+            android:name=".SearchActivity"
+            android:label="@string/title_activity_search"
+            android:screenOrientation="portrait" />
+        <activity
+            android:name=".AnnouncementActivity"
+            android:label="@string/title_activity_announcements"
+            android:screenOrientation="portrait" />
+        <activity
+            android:name=".CustomizeFieldsActivity"
+            android:label="@string/title_activity_customize_fields"
+            android:screenOrientation="portrait" />
+        <activity
+            android:name=".ResultActivity"
+            android:label="@string/title_activity_result"
+            android:screenOrientation="portrait" />
+        <activity
+            android:name=".LocationDetailActivity"
+            android:label="@string/title_activity_location_detail"
+            android:screenOrientation="portrait" />
+        <activity
+            android:name=".InnerMapActivity"
+            android:label="@string/title_activity_inner_map"
+            android:screenOrientation="portrait" />
+        <activity
+            android:name=".HelpActivity"
+            android:label="@string/title_activity_help"
+            android:screenOrientation="portrait"
+            android:theme="@android:style/Theme.Holo.NoActionBar" />
+        <activity
+            android:name=".SearchListActivity"
+            android:label="@string/title_activity_search_list"
+            android:screenOrientation="portrait"
+            android:theme="@style/SearchActionbarTheme"
+            android:windowSoftInputMode="adjustUnspecified|stateHidden" />
+        <activity
+            android:name=".RetrievePasswordActivity"
+            android:label="@string/title_activity_retrieve_password"
+            android:screenOrientation="portrait" />
+        <activity
+            android:name=".MessageActivity"
+            android:label="@string/title_activity_message"
+            android:screenOrientation="portrait" />
+        <activity
+            android:name=".SearchHistoryActivity"
+            android:label="@string/title_activity_search_history"
+            android:screenOrientation="portrait" />
+        <activity
+            android:name=".ChangePasswordActivity"
+            android:label="Change Password"
+            android:screenOrientation="portrait"
+            android:windowSoftInputMode="adjustResize|stateVisible" />
+        <activity
+            android:name=".AboutActivity"
+            android:label="@string/title_activity_about"
+            android:screenOrientation="portrait" />
+        <activity
+            android:name=".WebActivity"
+            android:label="@string/title_activity_web"
+            android:screenOrientation="portrait" />
+
+        <receiver
+            android:name=".BootBroadcastReceiver"
+            android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
+            <intent-filter>
+
+                <action android:name="android.intent.action.DOWNLOAD_COMPLETE" />
+                <action android:name="android.intent.action.BOOT_COMPLETED" />
+                <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
+            </intent-filter>
+        </receiver>
+        <receiver android:name=".Alarmreceiver">
+            <intent-filter>
+                <action android:name="com.usai.apex.push" />
+                <action android:name="com.usai.apex.push.cancel" />
+            </intent-filter>
+        </receiver>
+
+        <activity
+            android:name=".MessageDetailActivity"
+            android:label="@string/title_activity_message_detail"
+            android:screenOrientation="portrait" />
+        <activity
+            android:name=".InnerToolsActivity"
+            android:label="@string/title_activity_inner_tools"
+            android:screenOrientation="portrait" />
+        <activity
+            android:name=".DocumentsActivity"
+            android:label="@string/title_activity_documents"
+            android:screenOrientation="portrait" />
+        <activity
+            android:name=".LocalDocumentActivity"
+            android:label="@string/title_activity_localdocuments"
+            android:screenOrientation="portrait" />
+        <activity
+            android:name=".ApexHistoryActivity"
+            android:label="@string/title_activity_apexhistory"
+            android:screenOrientation="portrait" />
+        <activity
+            android:name=".SettingsActivity"
+            android:label="@string/title_activity_settings"
+            android:screenOrientation="portrait" />
+
+        <service
+            android:name=".ApexBackgroundService"
+            android:label="Apex Mobile Background Service" />
+
+        <service
+            android:name="com.baidu.location.f"
+            android:enabled="true"
+            android:process=":remote" >
+            <intent-filter>
+                <action android:name="com.baidu.location.service_v2.2" >
+                </action>
+            </intent-filter>
+        </service>
+
+        <activity
+            android:name=".saved.CheckSavedActivity"
+            android:screenOrientation="portrait"
+            android:theme="@style/FixedActionbarTheme" />
+        >
+        <activity
+            android:name=".TestAppComActivity"
+            android:screenOrientation="portrait"
+            android:theme="@style/FixedActionbarTheme">
+
+            <!-- <intent-filter> -->
+            <!-- <action android:name="android.intent.action.MAIN" /> -->
+
+
+            <!-- <category android:name="android.intent.category.LAUNCHER" /> -->
+            <!-- </intent-filter> -->
+        </activity>
+        <activity
+            android:name=".Result.AMResultActivity"
+            android:screenOrientation="portrait"
+            android:theme="@style/ResultActionbarTheme" />
+        <activity
+            android:name=".Result.SearchResultActivity"
+            android:screenOrientation="portrait" />
+        <activity android:name=".ContainerSearchActivity" />
+        <activity
+            android:name=".pdf.PDFPreviewActivity"
+            android:screenOrientation="portrait"
+            android:theme="@style/ResultActionbarTheme" />
+        <activity android:name=".LicenseActivity" />
+        <activity android:name=".TestActivity"></activity>
+        <activity android:name=".mainframe.NewDetailActivity"
+            android:theme="@style/DetailActionbarTheme"
+            android:screenOrientation="portrait"></activity>
+    </application>
+
+</manifest>

BIN
ApexDrivers/apexmobile/src/main/ic_launcher-web.png


+ 167 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/Contacts/Contact.java

@@ -0,0 +1,167 @@
+package com.usai.Contacts;
+
+import android.graphics.Bitmap;
+import android.provider.ContactsContract;
+
+import java.io.ByteArrayOutputStream;
+
+public class Contact {
+
+    public static final String NUMBER_TYPE_WORK = String.valueOf(ContactsContract.CommonDataKinds.Phone.TYPE_WORK);
+    public static final String NUMBER_TYPE_FAX_WORK = String.valueOf(ContactsContract.CommonDataKinds.Phone.TYPE_FAX_WORK);
+    public static final String EMAIL_TYPE_WORK = String.valueOf(ContactsContract.CommonDataKinds.Email.TYPE_WORK);
+    public static final String WEB_TYPE_HOMEPAGE = String.valueOf(ContactsContract.CommonDataKinds.Website.TYPE_HOMEPAGE);
+    public static final String POSTAL_TYPE_WORK = String.valueOf(ContactsContract.CommonDataKinds.StructuredPostal.TYPE_WORK);
+
+    private String id;
+    private String name;
+    private String number;
+    private String numberType;
+    private String fax;
+    private String faxType;
+    private String email;
+    private String emailType;
+    private String homePage;
+    private String homePageType;
+    private String address;
+    private String addressType;
+    private Bitmap photo;
+
+
+    public Contact(){
+    }
+
+    public Contact(Contact contact){
+        copyContact(contact);
+    }
+
+    public void copyContact(Contact contact) {
+        this.name = contact.getName();
+        this.number = contact.getNumber();
+        this.numberType = contact.getNumberType();
+        this.email = contact.getEmail();
+        this.emailType = contact.getEmailType();
+        this.fax = contact.getFax();
+        this.faxType = contact.getFaxType();
+        this.homePage = contact.getHomePage();
+        this.homePageType = contact.getHomePageType();
+        this.address = contact.getAddress();
+        this.addressType = contact.getAddressType();
+        this.photo = contact.getPhoto();
+    }
+
+    public String getEmail() {
+        return email;
+    }
+    public String getEmailType() {
+        if (emailType == null) {
+            return EMAIL_TYPE_WORK;
+        }
+        return emailType;
+    }
+    public String getId() {
+        return id;
+    }
+    public String getName() {
+        return name;
+    }
+    public String getNumber() {
+        return number;
+    }
+    public String getNumberType() {
+        if (numberType == null) {
+            return NUMBER_TYPE_WORK;
+        }
+        return numberType;
+    }
+    public String getFax() {
+        return fax;
+    }
+    public String getFaxType() {
+        if (faxType == null) {
+            return NUMBER_TYPE_FAX_WORK;
+        }
+        return faxType;
+    }
+    public String getAddress() {
+        return address;
+    }
+
+    public String getAddressType() {
+        if (addressType == null) {
+            return POSTAL_TYPE_WORK;
+        }
+        return addressType;
+    }
+
+    public String getHomePage() {
+        if (homePage == null) {
+            return WEB_TYPE_HOMEPAGE;
+        }
+        return homePage;
+    }
+
+    public String getHomePageType() {
+        return homePageType;
+    }
+
+    public Bitmap getPhoto() {
+        return photo;
+    }
+
+    public byte[] getPhotoData() {
+        if (photo == null) {
+            return null;
+        }
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        photo.compress(Bitmap.CompressFormat.PNG, 100, baos);
+        byte[] data = baos.toByteArray();
+        return data;
+    }
+
+    public void setEmail(String email) {
+        this.email = email;
+    }
+    public void setEmailType(String emailType) {
+        this.emailType = emailType;
+    }
+    public void setId(String id) {
+        this.id = id;
+    }
+    public void setName(String name) {
+        this.name = name;
+    }
+    public void setNumber(String number) {
+        this.number = number;
+    }
+    public void setNumberType(String numberType) {
+        this.numberType = numberType;
+    }
+
+    public void setFax(String fax) {
+        this.fax = fax;
+    }
+    public void setFaxType(String faxType) {
+        this.faxType = faxType;
+    }
+
+    public void setHomePage(String homePage) {
+        this.homePage = homePage;
+    }
+
+    public void setHomePageType(String homePageType) {
+        this.homePageType = homePageType;
+    }
+
+    public void setAddress(String address) {
+        this.address = address;
+    }
+
+    public void setAddressType(String addressType) {
+        this.addressType = addressType;
+    }
+
+    public void setPhoto(Bitmap photo) {
+        this.photo = photo;
+    }
+}

+ 475 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/Contacts/ContactsManager.java

@@ -0,0 +1,475 @@
+package com.usai.Contacts;
+
+import android.content.ContentProviderOperation;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
+import android.net.Uri;
+import android.provider.ContactsContract;
+import android.util.Log;
+
+import java.util.ArrayList;
+
+public class ContactsManager {
+
+    private ContentResolver contentResolver;
+    private static final String TAG = "ContactsManager";
+
+
+    private static final String COLUMN_CONTACT_ID =
+            ContactsContract.Data.CONTACT_ID;
+    private static final String COLUMN_RAW_CONTACT_ID =
+            ContactsContract.Data.RAW_CONTACT_ID;
+    private static final String COLUMN_MIMETYPE =
+            ContactsContract.Data.MIMETYPE;
+    private static final String COLUMN_NAME =
+            ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME;
+    private static final String COLUMN_NUMBER =
+            ContactsContract.CommonDataKinds.Phone.NUMBER;
+    private static final String COLUMN_NUMBER_TYPE =
+            ContactsContract.CommonDataKinds.Phone.TYPE;
+    private static final String COLUMN_EMAIL =
+            ContactsContract.CommonDataKinds.Email.DATA;
+    private static final String COLUMN_EMAIL_TYPE =
+            ContactsContract.CommonDataKinds.Email.TYPE;
+
+    private static final String COLUMN_WEB =
+            ContactsContract.CommonDataKinds.Website.DATA;
+    private static final String COLUMN_WEB_TYPE =
+            ContactsContract.CommonDataKinds.Website.TYPE;
+
+    private static final String COLUMN_POSTAL =
+            ContactsContract.CommonDataKinds.StructuredPostal.DATA;
+    private static final String COLUMN_POSTAL_TYPE =
+            ContactsContract.CommonDataKinds.StructuredPostal.TYPE;
+
+    private static final String COLUMN_PHOTO =
+            ContactsContract.CommonDataKinds.Photo.PHOTO;
+
+
+    private static final String MIMETYPE_STRING_NAME =
+            ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE;
+    private static final String MIMETYPE_STRING_PHONE =
+            ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE;
+    private static final String MIMETYPE_STRING_EMAIL =
+            ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE;
+    private static final String MIMETYPE_STRING_WEB =
+            ContactsContract.CommonDataKinds.Website.CONTENT_ITEM_TYPE;
+    private static final String MIMETYPE_STRING_ADDRESS =
+            ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE;
+    private static final String MIMETYPE_STRING_PHOTO =
+            ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE;
+
+    public ContactsManager(ContentResolver contentResolver) {
+        this.contentResolver = contentResolver;
+    }
+
+
+    public Contact searchContact(String name) {
+        Log.w(TAG, "**search start**");
+        Contact contact = new Contact();
+        contact.setName(name);
+        Log.d(TAG, "search name: " + contact.getName());
+        String id = getContactID(contact.getName());
+        contact.setId(id);
+
+        if(id.equals("0")) {
+            Log.d(TAG, contact.getName() + " not exist. exit.");
+        } else {
+            Log.d(TAG, "find id: " + id);
+            //Fetch Phone Number
+            Cursor cursor = contentResolver.query(
+                    ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
+                    new String[]{COLUMN_NUMBER, COLUMN_NUMBER_TYPE},
+                    COLUMN_CONTACT_ID + "='" + id + "'", null, null);
+            while(cursor.moveToNext()) {
+                contact.setNumber(cursor.getString(cursor.getColumnIndex(COLUMN_NUMBER)));
+                contact.setNumberType(cursor.getString(cursor.getColumnIndex(COLUMN_NUMBER_TYPE)));
+                Log.d(TAG, "find number: " + contact.getNumber());
+                Log.d(TAG, "find numberType: " + contact.getNumberType());
+            }
+            //cursor.close();
+
+            //Fetch email
+            cursor = contentResolver.query(
+                    ContactsContract.CommonDataKinds.Email.CONTENT_URI,
+                    new String[]{COLUMN_EMAIL, COLUMN_EMAIL_TYPE},
+                    COLUMN_CONTACT_ID + "='" + id + "'", null, null);
+            while(cursor.moveToNext()) {
+                contact.setEmail(cursor.getString(cursor.getColumnIndex(COLUMN_EMAIL)));
+                contact.setEmailType(cursor.getString(cursor.getColumnIndex(COLUMN_EMAIL_TYPE)));
+                Log.d(TAG, "find email: " + contact.getEmail());
+                Log.d(TAG, "find emailType: " + contact.getEmailType());
+            }
+            cursor.close();
+        }
+        Log.w(TAG, "**search end**");
+        return contact;
+    }
+
+
+    public String getContactID(String name) {
+        String id = "0";
+
+        String searchName = name;
+        Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_FILTER_URI, searchName);
+
+        //  Uri uri2 = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, phoneNumber); 根据电话号码查找联系人
+
+        String[] projection = new String[]{ContactsContract.Contacts._ID};
+        Cursor cursor = contentResolver.query(uri, projection, null, null, null);
+
+        if (cursor.moveToFirst()) {
+            id = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts._ID));
+        }
+        return id;
+    }
+//    public String getContactID(String name) {
+//        String id = "0";
+//
+//
+////        ContactsContract.Contacts.DISPLAY_NAME_ALTERNATIVE
+//
+//        Cursor cursor = contentResolver.query(
+//                ContactsContract.Contacts.CONTENT_URI,
+//                new String[]{ContactsContract.Contacts._ID},
+//                ContactsContract.Contacts.DISPLAY_NAME_ALTERNATIVE +
+//                        "='" + name + "'", null, null);
+//        if(cursor.moveToNext()) {
+//            id = cursor.getString(cursor.getColumnIndex(
+//                    ContactsContract.Contacts._ID));
+//        }
+//        return id;
+//    }
+
+    public boolean contactExist(String name) {
+        if (name == null) {
+            return false;
+        }
+        String id = getContactID(name);
+        if(!id.equals("0")) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+
+    public void addContact(Contact contact,boolean checkExist) {
+        Log.w(TAG, "**add start**");
+
+        if (checkExist) {
+            String id = getContactID(contact.getName());
+            if(!id.equals("0")) {
+                Log.d(TAG, "contact already exist. exit.");
+            } else if(contact.getName().trim().equals("")){
+                Log.d(TAG, "contact name is empty. exit.");
+            } else {
+                addContact(contact);
+            }
+        } else {
+            addContact(contact);
+        }
+
+        Log.w(TAG, "**add end**");
+
+    }
+
+    private void addContact(Contact contact) {
+
+        ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
+
+        ops.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
+                .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, null)
+                .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null)
+                .build());
+        ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
+                .withValueBackReference(COLUMN_RAW_CONTACT_ID, 0)
+                .withValue(COLUMN_MIMETYPE, MIMETYPE_STRING_NAME)
+                .withValue(COLUMN_NAME, contact.getName())
+                .build());
+        Log.d(TAG, "add name: " + contact.getName());
+
+        // photo
+        ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
+                .withValueBackReference(COLUMN_RAW_CONTACT_ID, 0)
+                .withValue(COLUMN_MIMETYPE, MIMETYPE_STRING_PHOTO)
+                .withValue(COLUMN_PHOTO, contact.getPhotoData())
+                .build());
+
+        // web
+        ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
+                .withValueBackReference(COLUMN_RAW_CONTACT_ID, 0)
+                .withValue(COLUMN_MIMETYPE, MIMETYPE_STRING_WEB)
+                .withValue(COLUMN_WEB,contact.getHomePage())
+                .withValue(COLUMN_WEB_TYPE, contact.getHomePage())
+                .build());
+
+        // postal
+        ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
+                .withValueBackReference(COLUMN_RAW_CONTACT_ID, 0)
+                .withValue(COLUMN_MIMETYPE, MIMETYPE_STRING_ADDRESS)
+                .withValue(COLUMN_POSTAL,contact.getAddress())
+                .withValue(COLUMN_POSTAL_TYPE, contact.getAddressType())
+                .build());
+
+        if(!contact.getNumber().trim().equals("")) {
+            ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
+                    .withValueBackReference(COLUMN_RAW_CONTACT_ID, 0)
+                    .withValue(COLUMN_MIMETYPE, MIMETYPE_STRING_PHONE)
+                    .withValue(COLUMN_NUMBER, contact.getNumber())
+                    .withValue(COLUMN_NUMBER_TYPE, contact.getNumberType())
+                    .build());
+            Log.d(TAG, "add number: " + contact.getNumber());
+        }
+
+        if(!contact.getFax().trim().equals("")) {
+            ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
+                    .withValueBackReference(COLUMN_RAW_CONTACT_ID, 0)
+                    .withValue(COLUMN_MIMETYPE, MIMETYPE_STRING_PHONE)
+                    .withValue(COLUMN_NUMBER, contact.getFax())
+                    .withValue(COLUMN_NUMBER_TYPE, contact.getFaxType())
+                    .build());
+            Log.d(TAG, "add fax: " + contact.getFax());
+        }
+
+        if(!contact.getEmail().trim().equals("")) {
+            ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
+                    .withValueBackReference(COLUMN_RAW_CONTACT_ID, 0)
+                    .withValue(COLUMN_MIMETYPE, MIMETYPE_STRING_EMAIL)
+                    .withValue(COLUMN_EMAIL, contact.getEmail())
+                    .withValue(COLUMN_EMAIL_TYPE, contact.getEmailType())
+                    .build());
+            Log.d(TAG, "add email: " + contact.getEmail());
+        }
+
+        try {
+            contentResolver.applyBatch(ContactsContract.AUTHORITY, ops);
+            Log.d(TAG, "add contact success.");
+        } catch (Exception e) {
+            Log.d(TAG, "add contact failed.");
+            Log.e(TAG, e.getMessage());
+        }
+    }
+
+
+    public void deleteContact(Contact contact) {
+        Log.w(TAG, "**delete start**");
+        ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
+
+        String id = getContactID(contact.getName());
+        //delete contact
+        ops.add(ContentProviderOperation.newDelete(ContactsContract.RawContacts.CONTENT_URI)
+                .withSelection(ContactsContract.RawContacts.CONTACT_ID+"="+id, null)
+                .build());
+        //delete contact information such as phone number,email
+        ops.add(ContentProviderOperation.newDelete(ContactsContract.Data.CONTENT_URI)
+                .withSelection(COLUMN_CONTACT_ID + "=" + id, null)
+                .build());
+        Log.d(TAG, "delete contact: " + contact.getName());
+
+        try {
+            contentResolver.applyBatch(ContactsContract.AUTHORITY, ops);
+            Log.d(TAG, "delete contact success");
+        } catch (Exception e) {
+            Log.d(TAG, "delete contact failed");
+            Log.e(TAG, e.getMessage());
+        }
+        Log.w(TAG, "**delete end**");
+    }
+
+
+    public void updateContact(Contact contactOld, Contact contactNew) {
+        Log.w(TAG, "**update start**");
+        String id = getContactID(contactOld.getName());
+        if(id.equals("0")) {
+            Log.d(TAG, contactOld.getName()+" not exist.");
+        }/* else if(contactNew.getName().trim().equals("")){
+            Log.d(TAG, "contact name is empty. exit.");
+        } else if(!getContactID(contactNew.getName()).equals("0")){
+            Log.d(TAG, "new contact name already exist. exit.");
+        }*/ else {
+
+            ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
+
+            //update name
+//            ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
+//                    .withSelection(COLUMN_CONTACT_ID + "=? AND " + COLUMN_MIMETYPE + "=?",
+//                            new String[]{id, MIMETYPE_STRING_NAME})
+//                    .withValue(COLUMN_NAME, contactNew.getName())
+//                    .build());
+            Log.d(TAG, "update name: " + contactNew.getName());
+
+            // photo
+            ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
+                    .withSelection(COLUMN_CONTACT_ID + "=? AND " + COLUMN_MIMETYPE + "=?",
+                            new String[]{id, MIMETYPE_STRING_PHOTO})
+                    .withValue(COLUMN_PHOTO, contactNew.getPhotoData())
+                    .build());
+
+            // web
+            ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
+                    .withSelection(COLUMN_CONTACT_ID + "=? AND " + COLUMN_MIMETYPE + "=?",
+                            new String[]{id, MIMETYPE_STRING_WEB})
+                    .withValue(COLUMN_WEB,contactNew.getHomePage())
+                    .withValue(COLUMN_WEB_TYPE, contactNew.getHomePage())
+                    .build());
+
+            // postal
+            ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
+                    .withSelection(COLUMN_CONTACT_ID + "=? AND " + COLUMN_MIMETYPE + "=?",
+                            new String[]{id, MIMETYPE_STRING_ADDRESS})
+                    .withValue(COLUMN_POSTAL,contactNew.getAddress())
+                    .withValue(COLUMN_POSTAL_TYPE, contactNew.getAddressType())
+                    .build());
+
+            //update number
+            if(!contactNew.getNumber().trim().equals("")) {
+                ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
+                        .withSelection(COLUMN_CONTACT_ID + "=? AND " + COLUMN_MIMETYPE + "=? AND " + COLUMN_NUMBER_TYPE + "=?",
+                                new String[]{id, MIMETYPE_STRING_PHONE,contactNew.getNumberType()})
+                        .withValue(COLUMN_NUMBER, contactNew.getNumber())
+                        .withValue(COLUMN_NUMBER_TYPE, contactNew.getNumberType())
+                        .build());
+                Log.d(TAG, "update number: " + contactNew.getNumber());
+            }
+
+            // fax
+            if(!contactNew.getNumber().trim().equals("")) {
+                ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
+                        .withSelection(COLUMN_CONTACT_ID + "=? AND " + COLUMN_MIMETYPE + "=? AND " + COLUMN_NUMBER_TYPE + "=?",
+                                new String[]{id, MIMETYPE_STRING_PHONE,contactNew.getFaxType()})
+                        .withValue(COLUMN_NUMBER, contactNew.getFax())
+                        .withValue(COLUMN_NUMBER_TYPE, contactNew.getFaxType())
+                        .build());
+                Log.d(TAG, "update fax: " + contactNew.getNumber());
+            }
+
+
+            //update email if mail
+            if(!contactNew.getEmail().trim().equals("")) {
+                ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
+                        .withSelection(COLUMN_CONTACT_ID + "=? AND " + COLUMN_MIMETYPE + "=?",
+                                new String[]{id, MIMETYPE_STRING_EMAIL})
+                        .withValue(COLUMN_EMAIL, contactNew.getEmail())
+                        .withValue(COLUMN_EMAIL_TYPE, contactNew.getEmailType())
+                        .build());
+                Log.d(TAG, "update email: " + contactNew.getEmail());
+            }
+
+            try {
+                contentResolver.applyBatch(ContactsContract.AUTHORITY, ops);
+                Log.d(TAG, "update success");
+            } catch (Exception e) {
+                Log.d(TAG, "update failed");
+                Log.e(TAG, e.getMessage());
+            }
+        }
+        Log.w(TAG, "**update end**");
+    }
+
+
+    public Uri getContactUri(String contactId, Context context)  {
+
+        if (context == null || contactId == null) {
+            return null;
+        }
+
+        //获取联系人信息的Uri
+        Uri uri = ContactsContract.Contacts.CONTENT_URI;
+        //获取ContentResolver
+        ContentResolver contentResolver = context.getContentResolver();
+        //查询数据,返回Cursor
+        Cursor cursor = contentResolver.query(uri, null, null, null, null);
+
+
+        while (cursor.moveToNext()) {
+
+            //获取联系人的ID
+            String id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
+            //获取联系人的姓名
+            String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
+
+            String lookupKey = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
+
+            if (id != null && id.equals(contactId)) {
+
+                return ContactsContract.Contacts.getLookupUri(Integer.valueOf(contactId), lookupKey);
+
+            }
+        }
+        return null;
+    }
+
+    /**
+     * @brief 显示联系人编辑界面
+     * */
+    public void editContact(String contactId,Context context) {
+
+        if (context == null || contactId == null) {
+            return ;
+        }
+
+        Uri uri = getContactUri(contactId,context);
+        if (uri != null) {
+
+            Intent editIntent = new Intent(Intent.ACTION_EDIT);
+            editIntent.setDataAndType(uri,ContactsContract.Contacts.CONTENT_ITEM_TYPE);
+//            editIntent.putExtra("finishActivityOnSaveCompleted", true);
+            context.startActivity(editIntent);
+
+        } else {
+
+        }
+    }
+
+    /**
+     * @brief 新建联系人显示编辑界面
+     * */
+    public void insertContact(Contact contact,Context context) {
+
+        if (context == null) {
+            return;
+        }
+
+        Intent intent = new Intent(ContactsContract.Intents.Insert.ACTION);
+        intent.setType(ContactsContract.RawContacts.CONTENT_TYPE);
+
+        intent.putExtra(ContactsContract.Intents.Insert.NAME, contact.getName());
+
+        intent.putExtra(ContactsContract.Intents.Insert.PHONE, contact.getNumber());
+        intent.putExtra(ContactsContract.Intents.Insert.PHONE_TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_WORK);
+
+        intent.putExtra(ContactsContract.Intents.Insert.SECONDARY_PHONE, contact.getFax());
+        intent.putExtra(ContactsContract.Intents.Insert.SECONDARY_PHONE_TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_FAX_WORK);
+
+        intent.putExtra(ContactsContract.Intents.Insert.EMAIL, contact.getEmail());
+        intent.putExtra(ContactsContract.Intents.Insert.EMAIL_TYPE, ContactsContract.CommonDataKinds.Email.TYPE_WORK);
+
+        intent.putExtra(ContactsContract.Intents.Insert.POSTAL, contact.getAddress());
+        intent.putExtra(ContactsContract.Intents.Insert.POSTAL_TYPE, ContactsContract.CommonDataKinds.StructuredPostal.TYPE_WORK);
+
+        // Insert中没有的类型,通过Data写入
+        ArrayList<ContentValues> data = new ArrayList<ContentValues>();
+
+        ContentValues row1 = new ContentValues();
+        row1.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Website.CONTENT_ITEM_TYPE);
+        row1.put(ContactsContract.CommonDataKinds.Website.DATA, contact.getHomePage());
+        data.add(row1);
+
+        ContentValues row2 = new ContentValues();
+        row2.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE);
+        row2.put(ContactsContract.CommonDataKinds.Photo.PHOTO, contact.getPhotoData());
+        data.add(row2);
+
+//		Intent intent = new Intent(Intent.ACTION_INSERT, ContactsContract.Contacts.CONTENT_URI);
+
+        intent.putParcelableArrayListExtra(ContactsContract.Intents.Insert.DATA, data);
+
+        context.startActivity(intent);
+
+    }
+}
+

+ 154 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/AboutActivity.java

@@ -0,0 +1,154 @@
+package com.usai.apex;
+
+import android.content.Intent;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.Bundle;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AppCompatActivity;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.TextView;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+public class AboutActivity extends AppCompatActivity
+{
+	@Override
+	public boolean onOptionsItemSelected(MenuItem item)
+	{
+		Intent intent = new Intent();
+		switch (item.getItemId())
+		{
+			case android.R.id.home:
+				finish();
+				break;
+
+			default:
+				break;
+		}
+		return super.onOptionsItemSelected(item);
+	}
+
+	private void setCustomActionBar() {
+		ActionBar.LayoutParams lp =new ActionBar.LayoutParams(ActionBar.LayoutParams.MATCH_PARENT, ActionBar.LayoutParams.MATCH_PARENT, Gravity.CENTER);
+		View mActionBarView = LayoutInflater.from(this).inflate(R.layout.actionbar_customtitle, null);
+
+		TextView titleview = mActionBarView.findViewById(R.id.title);
+		titleview.setText("About");
+		setTitle("About");
+
+		ActionBar actionBar = getSupportActionBar();
+		actionBar.setCustomView(mActionBarView, lp);
+//		actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
+//		actionBar.setDisplayShowCustomEnabled(true);
+		actionBar.setDisplayHomeAsUpEnabled(true);
+
+
+		actionBar.setDisplayShowTitleEnabled(true);
+	}
+	@Override
+	protected void onCreate(Bundle savedInstanceState)
+	{
+		Log.d("AboutActivity", "onCreate");
+
+		super.onCreate(savedInstanceState);
+		setContentView(R.layout.activity_about);
+
+		setCustomActionBar();
+		final TextView tv_ver = (TextView) findViewById(R.id.about_ver_value_tv);
+
+
+		TextView tv_pdfpreview = (TextView) findViewById(R.id.tv_androidpdfviewer);
+		tv_pdfpreview.setOnClickListener(new View.OnClickListener() {
+			@Override
+			public void onClick(View v) {
+
+				InputStream is = getResources().openRawResource(R.raw.license_androidpdfviewer);//把文件转换为输入流
+				StringBuffer response = new StringBuffer();                //创建StringBuffer实例
+				BufferedReader br = new BufferedReader(new InputStreamReader(is));  //根据is创建缓冲字符输入流
+				String s = null;                            //创建s变量
+				try {                            //try语句捕获异常
+					while ((s = br.readLine()) != null) {       //把这一行的值赋值给变量s,并判断是否有值
+						response.append(s);                        //把值添加进StringBuffer
+						response.append("\n");                 //再添加一个换行符
+					}
+				} catch (IOException e) {
+					// TODO Auto-generated catch block          //catch异常处理
+					e.printStackTrace();       //得到错误的实例, 调用方法在命令行打印程序出错的位置及原因
+				} finally {              //finally try语句大多数情况下都会执行的代码块
+					try {
+						if (is != null) {      //如果文件输入流不为空
+							is.close();            //调用close函数关掉输入流
+						}
+						if (br != null) {      //如果缓冲字符输入流不为空
+							br.close();            //调用close函数关掉缓冲字符输入流
+						}
+					} catch (IOException e) {
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+					}
+				}
+
+				Intent intent = new Intent();
+				intent.setClass(AboutActivity.this, LicenseActivity.class);
+
+				intent.putExtra("function_name", "barteksc/AndroidPdfViewer");
+
+				intent.putExtra("content", response.toString());
+
+
+				startActivity(intent);
+			}
+		});
+		// String str =
+		// "<a href='https://ra.apexshipping.com/main.php?action=handset_search&action_type=download_doc&sessionid=hjqvgilu0o64d22qfqgat1afk2&url=QVRwVUswa3ZFNlBFTzhLbFpYcC9rVEhSZ1h0MGd6ekpwZ2ZqTkhXNnN2SytGM0FhRkhyNG5QbkdtV2tPMXZrK2p3' target=_blank>A1303540085F.pdf</a>";
+
+//		WebView wv = (WebView) findViewById(R.id.webView1);
+//		String content = "";
+//		try
+//		{
+//			InputStream in = getResources().openRawResource(R.raw.about);
+//			// 获取文件的字节数
+//			int lenght = in.available();
+//			// 创建byte数组
+//			byte[] buffer = new byte[lenght];
+//			// 将文件中的数据读到byte数组中
+//			in.read(buffer);
+//			content = EncodingUtils.getString(buffer, "UTF-8");
+//		}
+//		catch (Exception e)
+//		{
+//			e.printStackTrace();
+//		}
+//		wv.getSettings().setDefaultTextEncodingName("UTF-8");
+//		wv.loadData(content, "text/html", null);
+//
+
+		try
+		{
+
+			tv_ver.setText(ApexTrackingApplication.get_instance()
+							.getPackageManager()
+							.getPackageInfo("com.usai.apex", 0).versionName);
+		}
+		catch (NameNotFoundException e1)
+		{
+			// TODO Auto-generated catch block
+			e1.printStackTrace();
+		}
+	}
+	//
+	// @Override
+	// public boolean onCreateOptionsMenu(Menu menu) {
+	// // Inflate the menu; this adds items to the action bar if it is present.
+	// getMenuInflater().inflate(R.menu.about, menu);
+	// return true;
+	// }
+
+}

+ 362 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/Alarmreceiver.java

@@ -0,0 +1,362 @@
+package com.usai.apex;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+//import com.usai.util.Crypto;
+import com.usai.util.Network;
+import com.usai.util.dbUtil;
+import com.usai.util.dbgUtil;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.database.sqlite.SQLiteDatabase;
+import android.os.AsyncTask;
+import android.os.Parcelable;
+import android.os.SystemClock;
+import android.util.Log;
+
+public class Alarmreceiver extends BroadcastReceiver
+{
+	private SearchTask	m_task	= null;
+
+	public void checkpush(Context context)
+	{
+
+		if (m_task != null)
+		{
+			return;
+		}
+		// mStatusMessageView.setText(R.string.str_Loading);
+		// showProgress(true);
+		m_task = new SearchTask(context);
+
+		// TextView text_page = (TextView) view_page_footer
+		// .findViewById(R.id.text_page);
+		// text_page.setText("Loading...");
+		// text_page.setEnabled(false);
+		m_task.execute();
+
+	}
+
+	class SearchTask extends AsyncTask<Void, Void, Boolean>
+	{
+		int		errorcode;
+		String	content	= null;
+		Context	mcontext;
+
+		public SearchTask(Context context)
+		{
+			mcontext = context;
+		}
+
+		@Override
+		protected Boolean doInBackground(Void... params)
+		{
+			Log.d("SearchTask", "doInBackground");
+			if (!Network.NetworkIsAvailable())
+
+			{
+				errorcode = Network.RESULT_NET_NOTAVAILABLE;
+				return false;
+			}
+			String jstr = "";
+			jstr = Network.check_push();
+			// if (module_name.equals("Announcements"))
+			// jstr = Network.get_announcements(lastid, limit);
+			// else
+			// jstr = Network.get_marketnews(lastid, limit);
+			if (jstr == null || jstr.length() <= 0)
+			{
+				// Log.d(TAG, "json is wrong");
+
+				errorcode = Network.RESULT_NET_ERROR;
+				return false;
+			}
+
+			content = jstr;
+			return true;
+		}
+
+		@Override
+		protected void onPostExecute(Boolean success)
+		{
+			String tag = "onPostExec@Alarmreceiver";
+			Log.i( tag, "entry");
+			m_task = null;
+			// showProgress(false);
+
+			// switch (errorcode)
+			// {
+			// // case Network.RESULT_NET_NOTAVAILABLE:
+			// // {
+			// // Toast toast = Toast.makeText(
+			// // ApexTrackingApplication.get_instance(),
+			// // getText(R.string.msg_connection_none),
+			// // Toast.LENGTH_LONG);
+			// // toast.setGravity(Gravity.CENTER, 0, 0);
+			// // toast.show();
+			// // break;
+			// // }
+			// // case Network.RESULT_NET_ERROR:
+			// // {
+			// // Toast toast = Toast.makeText(
+			// // ApexTrackingApplication.get_instance(),
+			// // getText(R.string.msg_net_error), Toast.LENGTH_LONG);
+			// // toast.setGravity(Gravity.CENTER, 0, 0);
+			// // toast.show();
+			// // break;
+			// // }
+			// // case Network.RESULT_ERROR:
+			// // // case Network.RESULT_RESPONSE_NULL:
+			// // {
+			// // Toast toast = Toast.makeText(
+			// // ApexTrackingApplication.get_instance(),
+			// // getText(R.string.msg_net_resulterror),
+			// // Toast.LENGTH_LONG);
+			// // toast.setGravity(Gravity.CENTER, 0, 0);
+			// // toast.show();
+			// // break;
+			// // }
+			//
+			// default:
+			// break;
+			// }
+
+			if (success)
+			{
+				JSONObject jsobj;
+				//
+				// array = new JSONArray(json);
+				try
+				{
+					jsobj = new JSONObject(content);
+
+					String message = jsobj.getString("message");
+					String date = jsobj.getString("date");
+					String s_id = jsobj.getString("s_id");
+					String e_id = jsobj.getString("e_id");
+					int count = jsobj.getInt("count");
+					SQLiteDatabase db = dbUtil.OpenDB(
+							ApexTrackingApplication.get_instance(), null, true);
+					db.execSQL("insert into push_message(s_id,e_id,msgcount,message,h_time,user,create_time,read) values('"
+							+ s_id
+							+ "','"
+							+ e_id
+							+ "',"
+							+ count
+							+ ",'"
+							+ message
+							+ "','"
+							+ date
+							+ "','"
+							+ ApexTrackingApplication.get_user()
+							+ "',"
+							+ System.currentTimeMillis() + ",0)");
+					dbUtil.CloseDB(db);
+
+					boolean bnotify = mcontext.getSharedPreferences("setting",
+							0).getBoolean("notifications_new_message", true);
+					if (bnotify)
+					{
+
+						boolean bsound = mcontext.getSharedPreferences(
+								"setting", 0).getBoolean(
+								"notifications_new_message_sound", true);
+						boolean bvibrate = mcontext.getSharedPreferences(
+								"setting", 0).getBoolean(
+								"notifications_new_message_vibrate", true);
+						NotificationManager nManager = (NotificationManager) mcontext
+								.getSystemService(Context.NOTIFICATION_SERVICE);
+
+//						Notification notification = new Notification(
+//								R.drawable.ic_launcher,
+//								mcontext.getString(R.string.str_notification_title),
+//								System.currentTimeMillis());
+						Intent intent = new Intent(mcontext,
+								FunctionSelectActivity.class);
+						intent.putExtra("launcher", "notification");
+
+						PendingIntent pintent = PendingIntent.getActivity(
+								mcontext, 0, intent,
+								PendingIntent.FLAG_UPDATE_CURRENT);
+
+
+						Notification.Builder builder = new Notification.Builder(mcontext);//新建Notification.Builder对象
+						String ntitle = "";
+						int number = ApexTrackingApplication.ncount++;
+						if (number > 1)
+							ntitle=number
+									+ " "
+									+ ApexTrackingApplication
+									.get_instance()
+									.getString(
+											R.string.str_mnotification_title);
+						else
+							ntitle = ApexTrackingApplication
+									.get_instance()
+									.getString(
+											R.string.str_notification_title);
+
+						builder.setContentTitle(ntitle);//设置标题
+						builder.setContentText(ApexTrackingApplication
+								.get_instance()
+								.getString(
+										R.string.str_notification_text)
+								+ date);//设置内容
+						builder.setSmallIcon(R.drawable.ic_launcher);//设置图片
+						builder.setContentIntent(pintent);//执行intent
+						Notification notification = builder.getNotification();//将builder对象转换为普通的notifications
+
+						if (bsound && bvibrate)
+							notification.defaults = Notification.DEFAULT_ALL;
+						else if (bsound)
+							notification.defaults = Notification.DEFAULT_SOUND
+									| Notification.DEFAULT_LIGHTS;
+						else if (bvibrate)
+							notification.defaults = Notification.DEFAULT_VIBRATE
+									| Notification.DEFAULT_LIGHTS;
+						notification.flags = Notification.FLAG_AUTO_CANCEL;
+						notification.number = number;
+//						if (notification.number > 1)
+//							notification
+//									.setLatestEventInfo(
+//											mcontext,
+//											notification.number
+//													+ " "
+//													+ ApexTrackingApplication
+//															.get_instance()
+//															.getString(
+//																	R.string.str_mnotification_title),
+//											ApexTrackingApplication
+//													.get_instance()
+//													.getString(
+//															R.string.str_notification_text)
+//													+ date, pintent);
+//						else
+//							notification
+//									.setLatestEventInfo(
+//											mcontext,
+//
+//											ApexTrackingApplication
+//													.get_instance()
+//													.getString(
+//															R.string.str_notification_text)
+//													+ date, pintent);
+						nManager.notify(R.layout.activity_apex, notification);
+					}
+
+					// Intent intenticon = new Intent();
+					// intenticon.setClass(ApexTrackingApplication
+					// .get_instance(), FunctionSelectActivity.class);
+					// Intent addShortcut = new
+					// Intent("com.android.launcher.action.INSTALL_SHORTCUT");
+					// Parcelable icon =
+					// Intent.ShortcutIconResource.fromContext(mcontext,
+					// R.drawable.ic_launcher_new);
+					// addShortcut.putExtra(Intent.EXTRA_SHORTCUT_NAME,
+					// ApexTrackingApplication
+					// .get_instance().getString(R.string.app_name));
+					// addShortcut.putExtra(Intent.EXTRA_SHORTCUT_INTENT,
+					// intent);
+					// addShortcut.putExtra("duplicate", 0);
+					// addShortcut.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE,
+					// icon);
+					// ApexTrackingApplication
+					// .get_instance().sendBroadcast(addShortcut);
+
+					// notification
+
+				}
+				catch (JSONException e)
+				{
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+				// if (bfinish)
+				// {
+				// // getListView().removeFooterView(view_page_footer);
+				// // Toast.makeText(AnnouncementActivity.this, "Load all!",
+				// // Toast.LENGTH_LONG).show();
+				//
+				// TextView tv = (TextView) view_page_footer
+				// .findViewById(R.id.text_page);
+				// tv.setText("No more items");
+				// tv.setEnabled(false);
+				// }
+				// else
+				// {
+				// TextView tv = (TextView) view_page_footer
+				// .findViewById(R.id.text_page);
+				// tv.setText("More...");
+				// tv.setEnabled(true);
+				// }
+				// adapter.notifyDataSetChanged();
+				// // getListAdapter().notifyDataSetChanged;
+				// // BaseAdapter mJson = null;
+				// // mJson.notifyDataSetChanged();
+			}
+
+			super.onPostExecute(success);
+		}
+
+		@Override
+		protected void onCancelled()
+		{
+			m_task = null;
+			// showProgress(false);
+		}
+	}
+
+	@Override
+	public void onReceive(Context context, Intent intent)
+	{
+		String tag = "onReceive@Alarmreceiver";
+		if (intent.getAction().equals("com.usai.apex.push"))
+		{
+
+			// Bundle b = intent.getExtras();
+			// Set<String> keySet = b.keySet();
+			// for(String key : keySet) {
+			// Log.e(tag, key);
+			// }
+			// String s =b.getString("caller");
+			Log.i( tag, "receive alarm broadcast caller =="
+					+ intent.getStringExtra("caller"));
+
+			if (SystemClock.elapsedRealtime()
+					- ApexTrackingApplication.getLastCheckMessageTime() > 120000)
+			{
+				Log.i(tag, "check messsage");
+				ApexTrackingApplication.UpdateLastCheckMessageTime();
+				checkpush(context);
+
+			}
+			// Intent i = new Intent();
+			// i.setClass(context, DaemonService.class);
+			// // 启动service
+			// // 多次调用startService并不会启动多个service 而是会多次调用onStart
+			// context.startService(i);
+		}
+		else if (intent.getAction().equals("com.usai.apex.push.cancel"))
+		{
+			if (m_task != null)
+				m_task.cancel(true);
+			NotificationManager nManager = (NotificationManager) context
+					.getSystemService(Context.NOTIFICATION_SERVICE);
+			nManager.cancel(R.layout.activity_apex);
+			ApexTrackingApplication.cancelalarm();
+			// ApexTrackingApplication.put_password("");
+			// ApexTrackingApplication.put_sessionid("");
+			// ApexTrackingApplication.put_user("");
+			ApexTrackingApplication.logout();
+
+		}
+	}
+
+}

+ 497 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/AnnouncementActivity.java

@@ -0,0 +1,497 @@
+package com.usai.apex;
+
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AppCompatActivity;
+import android.util.Base64;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.ListAdapter;
+import android.widget.ListView;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.usai.util.Network;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class AnnouncementActivity extends AppCompatActivity
+{
+	String				lastid			= "";
+	int					limit			= 10;
+	private SearchTask	m_task			= null;
+	SearchResult		searchresult	= new SearchResult();
+	BaseAdapter			adapter			= null;
+	View				view_page_footer;
+
+	String				module_name		= "";
+
+	ListView mList;
+	ListAdapter mAdapter;
+
+
+	public void setListAdapter(ListAdapter adapter) {
+		synchronized (this) {
+
+			mAdapter = adapter;
+			mList.setAdapter(adapter);
+		}
+	}
+	public ListView getListView() {
+
+		return mList;
+	}
+	public void requestdata()
+	{
+
+		if (m_task != null)
+		{
+			return;
+		}
+		// mStatusMessageView.setText(R.string.str_Loading);
+		// showProgress(true);
+		m_task = new SearchTask();
+
+		TextView text_page = (TextView) view_page_footer
+				.findViewById(R.id.text_page);
+		text_page.setText("Loading...");
+		text_page.setEnabled(false);
+		m_task.execute();
+
+	}
+
+
+	protected void onListItemClick(ListView l, View v, int position, long id)
+	{
+		// TODO Auto-generated method stub
+
+
+		// Log.i("FragmentList", "Item clicked: " + id);
+		Intent intent = new Intent();
+		intent.putExtra("url", searchresult.getData().get(position).get("url")
+				.toString());
+		intent.putExtra("title", searchresult.getData().get(position).get("title")
+				.toString());
+		intent.setClass(this, WebActivity.class);
+		startActivity(intent);
+	}
+
+	@Override
+	public void onDestroy()
+	{
+		if (m_task != null)
+			m_task.cancel(false);
+		super.onDestroy();
+	}
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item)
+    {
+        Intent intent = new Intent();
+        switch (item.getItemId())
+        {
+            case android.R.id.home:
+                finish();
+                break;
+
+            default:
+                break;
+        }
+        return super.onOptionsItemSelected(item);
+    }
+
+    private void setCustomActionBar() {
+		ActionBar.LayoutParams lp =new ActionBar.LayoutParams(ActionBar.LayoutParams.MATCH_PARENT, ActionBar.LayoutParams.MATCH_PARENT, Gravity.CENTER);
+		View mActionBarView = LayoutInflater.from(this).inflate(R.layout.actionbar_customtitle, null);
+
+		TextView titleview = mActionBarView.findViewById(R.id.title);
+		titleview.setText(getIntent().getStringExtra("module_name"));
+		setTitle(getIntent().getStringExtra("module_name"));
+		ActionBar actionBar = getSupportActionBar();
+		actionBar.setCustomView(mActionBarView, lp);
+//		actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
+//		actionBar.setDisplayShowCustomEnabled(true);
+		actionBar.setDisplayHomeAsUpEnabled(true);
+
+
+		actionBar.setDisplayShowTitleEnabled(true);
+	}
+	@Override
+	protected void onCreate(Bundle savedInstanceState)
+	{
+
+		// setTitle("Booking Result");
+
+		super.onCreate(savedInstanceState);
+		setContentView(R.layout.activity_announcements);
+
+		setCustomActionBar();
+
+		adapter = new AnnouncementAdapter(searchresult, this);
+
+		module_name = getIntent().getStringExtra("module_name");
+
+		setTitle(module_name);
+
+		mList = findViewById(android.R.id.list);
+		mList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+			@Override
+			public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+//				super.onListItemClick(parent, view, position, id);
+				AnnouncementActivity.this.onListItemClick((ListView) parent,view,position,id);
+			}
+		});
+		view_page_footer = LayoutInflater.from(this).inflate(
+				R.layout.view_page_footer, null);
+		getListView().addFooterView(view_page_footer);// 添加底部视图
+		TextView text_page = (TextView) view_page_footer
+				.findViewById(R.id.text_page);
+		text_page.setOnClickListener(new View.OnClickListener()
+		{
+			// 点击按钮 追加数据 并通知适配器
+			@Override
+			public void onClick(View v)
+			{
+				// TODO Auto-generated method stub
+				// TextView tv = (TextView) v;
+				// tv.setText("Loading...");
+				requestdata();
+				// tv.setText("下一页");
+				// adapter.notifyDataSetChanged();
+			}
+		});
+
+		setListAdapter(adapter);
+		// this.getListView().setBackgroundColor(Color.WHITE);
+		requestdata();
+
+	}
+
+	class SearchTask extends AsyncTask<Void, Void, Boolean>
+	{
+		int		errorcode;
+		boolean	bfinish	= false;
+
+		@Override
+		protected Boolean doInBackground(Void... params)
+		{
+			Log.d("SearchTask", "doInBackground");
+			if (!Network.NetworkIsAvailable())
+
+			{
+				errorcode = Network.RESULT_NET_NOTAVAILABLE;
+				return false;
+			}
+			String jstr;
+			if (module_name.equals("Announcements"))
+				jstr = Network.get_announcements(lastid, limit);
+			else
+				jstr = Network.get_marketnews(lastid, limit);
+			if (jstr == null || jstr.length() <= 0)
+			{
+				// Log.d(TAG, "json is wrong");
+
+				errorcode = Network.RESULT_NET_ERROR;
+				return false;
+			}
+
+			JSONObject jsobj;
+			//
+			// array = new JSONArray(json);
+			try
+			{
+				jsobj = new JSONObject(jstr);
+				// if (searchresult.get_fieldscount() == 0)
+				// {
+				// JSONObject objfields = jsobj.getJSONObject("fields");
+				// if (objfields != null)
+				// searchresult.init_fields(objfields.toString());
+				// }
+				int count = jsobj.getInt("total");
+				if (count < limit)
+					bfinish = true;
+				JSONObject objrecords = jsobj.getJSONObject("records");
+				if (objrecords != null)
+					searchresult.add_records(objrecords.toString(), count);
+				errorcode = Network.RESULT_TRUE;
+
+				return true;
+
+			}
+			catch (JSONException e)
+			{
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+			errorcode = Network.RESULT_NET_ERROR;
+			return false;
+		}
+
+		@Override
+		protected void onPostExecute(Boolean success)
+		{
+			String tag = "onPostExecute@AnnouncementActivity";
+			Log.d("onPostExecute", "entry");
+			m_task = null;
+			// showProgress(false);
+
+			switch (errorcode)
+			{
+				case Network.RESULT_NET_NOTAVAILABLE:
+				{
+					Toast toast = Toast.makeText(
+							ApexTrackingApplication.get_instance(),
+							getText(R.string.msg_connection_none),
+							Toast.LENGTH_LONG);
+					toast.setGravity(Gravity.CENTER, 0, 0);
+					toast.show();
+					break;
+				}
+				case Network.RESULT_NET_ERROR:
+				{
+					Toast toast = Toast.makeText(
+							ApexTrackingApplication.get_instance(),
+							getText(R.string.msg_net_error), Toast.LENGTH_LONG);
+					toast.setGravity(Gravity.CENTER, 0, 0);
+					toast.show();
+					break;
+				}
+				case Network.RESULT_ERROR:
+				// case Network.RESULT_RESPONSE_NULL:
+				{
+					Toast toast = Toast.makeText(
+							ApexTrackingApplication.get_instance(),
+							getText(R.string.msg_net_resulterror),
+							Toast.LENGTH_LONG);
+					toast.setGravity(Gravity.CENTER, 0, 0);
+					toast.show();
+					break;
+				}
+
+				default:
+					break;
+			}
+
+			if (success)
+			{
+
+				if (bfinish)
+				{
+					// getListView().removeFooterView(view_page_footer);
+					// Toast.makeText(AnnouncementActivity.this, "Load all!",
+					// Toast.LENGTH_LONG).show();
+
+					TextView tv = (TextView) view_page_footer
+							.findViewById(R.id.text_page);
+					tv.setText("No more items");
+					tv.setEnabled(false);
+				}
+				else
+				{
+					TextView tv = (TextView) view_page_footer
+							.findViewById(R.id.text_page);
+					tv.setText("More...");
+					tv.setEnabled(true);
+				}
+				adapter.notifyDataSetChanged();
+				// getListAdapter().notifyDataSetChanged;
+				// BaseAdapter mJson = null;
+				// mJson.notifyDataSetChanged();
+			}
+			else
+			{
+				TextView tv = (TextView) view_page_footer
+						.findViewById(R.id.text_page);
+				tv.setText("More...");
+				tv.setEnabled(true);
+			}
+			super.onPostExecute(success);
+		}
+
+		@Override
+		protected void onCancelled()
+		{
+			m_task = null;
+			// showProgress(false);
+		}
+	}
+
+	private class SearchResult
+	{
+		List<Map<String, Object>>	datalist	= new ArrayList<Map<String, Object>>();
+
+		public int get_count()
+		{
+			return datalist.size();
+		}
+
+		public void add_records(String source, int count)
+		{
+			JSONObject objrecords;
+			try
+			{
+				objrecords = new JSONObject(source);
+
+				for (int i = 0; i < count; i++)
+				{
+					// offset++;
+					JSONObject objrec = objrecords.getJSONObject("record" + i);
+					String title = objrec.getString("title");
+					String content = objrec.getString("content");
+					String image = objrec.getString("image");
+					String id = objrec.getString("id");
+					String url = objrec.getString("url");
+					lastid = id;
+					Map<String, Object> map = new HashMap<String, Object>();
+					map.put("title", title);
+					map.put("content", content);
+					map.put("image", image);
+					map.put("id", id);
+					map.put("url", url);
+					datalist.add(map);
+
+					// Iterator<?> it = rec.keys();
+					// HashMap<String, String> record = new HashMap<String,
+					// String>();
+					// while (it.hasNext()) // loop for each function
+					// {
+					// String field_name = (String) it.next();
+					// String val = rec.getString(field_name)
+					// .replace("\n", "");
+					// record.put(field_name, val);
+					// }
+					// records.add(record);
+
+				}
+			}
+			catch (JSONException e)
+			{
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+
+		}
+
+		public List<Map<String, Object>> getData()
+		{
+
+			return datalist;
+		}
+	}
+
+	private class AnnouncementAdapter extends BaseAdapter
+	{
+		private LayoutInflater	mInflater;	// 动态布局映射
+		private SearchResult	result;
+
+		// private Context context;
+		// private int i = 0;
+		public AnnouncementAdapter(SearchResult result, Context context)
+		{
+			this.result = result;
+			// this.context = context;
+			this.mInflater = LayoutInflater.from(context);
+		}
+
+		@Override
+		public int getCount()
+		{
+			// TODO Auto-generated method stub
+			return result.get_count();
+		}
+
+		@Override
+		public Object getItem(int position)
+		{
+			// TODO Auto-generated method stub
+			return null;
+		}
+
+		@Override
+		public long getItemId(int position)
+		{
+			// TODO Auto-generated method stub
+			return 0;
+		}
+
+		@Override
+		public View getView(int position, View convertView, ViewGroup parent)
+		{
+			// TODO Auto-generated method stub
+			convertView = mInflater.inflate(R.layout.announcement_cell, null);// 根据布局文件实例化view
+
+			TextView title = (TextView) convertView.findViewById(R.id.tv_title);// 找某个控件
+			title.setText(result.getData().get(position).get("title")
+					.toString());// 给该控件设置数据(数据从集合类中来)
+			TextView content = (TextView) convertView
+					.findViewById(R.id.tv_content);
+			content.setText(result.getData().get(position).get("content")
+					.toString());
+            ImageView iv_thumb = (ImageView) convertView
+                    .findViewById(R.id.iv_thumb);
+			if (result.getData().get(position).get("image").toString().length() > 0)
+			{
+				byte[] gzipBuff = Base64.decode(result.getData().get(position)
+						.get("image").toString(), 0);
+
+				ByteArrayInputStream memstream = new ByteArrayInputStream(
+						gzipBuff, 0, gzipBuff.length);
+
+				ByteArrayOutputStream baos = new ByteArrayOutputStream(
+						gzipBuff.length);
+
+				try
+				{
+					baos.write(gzipBuff);
+
+					Bitmap bmp = BitmapFactory.decodeStream(memstream);
+
+					// ImageView image = new ImageView(this);
+
+					iv_thumb.setImageBitmap(bmp);
+				}
+				catch (IOException e)
+				{
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+			}
+			else
+            {
+                if(module_name.equals("Market News"))
+                {
+                    iv_thumb.setImageResource(R.drawable.rect_market_news);
+                }
+                else
+                {
+                    iv_thumb.setImageResource(R.drawable.mode_announcement);
+
+                }
+            }
+			// img.setBackgroundResource((Integer)jObject.get("img"));
+
+			return convertView;
+		}
+	}
+}

+ 219 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/ApexActivity.java

@@ -0,0 +1,219 @@
+package com.usai.apex;
+
+//import com.google.android.gms.maps.SupportMapFragment;
+
+import android.app.ActionBar;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.Bundle;
+//import android.app.Fragment;
+//import android.app.FragmentTransaction;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentActivity;
+import android.support.v4.app.FragmentTransaction;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.widget.TabHost;
+
+import com.usai.apex.mainframe.LoginFragment;
+import com.usai.apex.mainframe.ToolsFragment;
+
+public class ApexActivity extends FragmentActivity /*
+													 * implements
+													 * OnTabChangeListener
+													 */
+{
+	boolean	m_bhasgoogleframework	= false;
+
+	@Override
+	public boolean onKeyDown(int keyCode, KeyEvent event)
+	{
+		if (keyCode == KeyEvent.KEYCODE_BACK)
+		{
+			// Intent myIntent = new Intent();
+			// myIntent = new Intent(EditActivity.this, tabActivity.class);
+			// startActivity(myIntent);
+			finish();
+			
+			return false;
+		}
+		return super.onKeyDown(keyCode, event);
+	}
+
+	TabHost	mTabHost;
+
+	@Override
+	protected void onCreate(Bundle savedInstanceState)
+	{
+		Log.d("ApexActivity", "onCreate");
+
+		// ApexTrackingApplication.get_instance()
+		// .getPackageManager().
+		PackageInfo packageInfo;
+		try
+		{
+			packageInfo = this.getPackageManager().getPackageInfo(
+					"com.google.android.gms", 0);
+
+		}
+		catch (NameNotFoundException e)
+		{
+			packageInfo = null;
+			e.printStackTrace();
+		}
+		if (packageInfo == null)
+		{
+			m_bhasgoogleframework = false;
+			System.out.println("没有安装");
+		}
+		else
+		{
+			m_bhasgoogleframework = true;
+			System.out.println("已经安装");
+		}
+
+		super.onCreate(savedInstanceState);
+		setContentView(R.layout.activity_apex);
+		ActionBar bar = getActionBar();
+		bar.setTitle("");
+		setupTabs();
+
+	}
+
+	// @Override
+	// public boolean onCreateOptionsMenu(Menu menu) {
+	// // Inflate the menu; this adds items to the action bar if it is present.
+	// getMenuInflater().inflate(R.menu.apex, menu);
+	// return true;
+	// }
+	//
+	// @Override
+	// public boolean onOptionsItemSelected(MenuItem item) {
+	// switch (item.getItemId()) {
+	// case R.id.forget_password:
+	// Intent intent = new Intent();
+	// intent.setClass(this, RetrievePasswordActivity.class);
+	// startActivity(intent);
+	//
+	// break;
+	// default:
+	// break;
+	//
+	// }
+	// return super.onOptionsItemSelected(item);
+	// }
+
+	private void setupTabs()
+	{
+		mTabHost = (TabHost) this.findViewById(R.id.tabhost);
+
+		mTabHost.setup();
+		// // ��ɵײ��Զ�����ʽ�İ�ť
+		// String[] title = new String[] { "Login", "Not login" };
+		// int[] tabIds = new int[] { R.id.tab1, R.id.tab2 };
+		mTabHost.addTab(mTabHost.newTabSpec(getString(R.string.action_sign_in_short)).setIndicator(getString(R.string.action_sign_in_short))
+				.setContent(R.id.tab1));
+		// mTabHost.addTab(mTabHost.newTabSpec("test").setIndicator("test").setContent(R.id.tabtest));
+
+		mTabHost.addTab(mTabHost.newTabSpec(getString(R.string.str_tool)).setIndicator(getString(R.string.str_tool))
+				.setContent(R.id.tab2));
+		mTabHost.addTab(mTabHost.newTabSpec(getString(R.string.str_location))
+				.setIndicator(getString(R.string.str_location)).setContent(R.id.tab3));
+
+		// Instantiate a new fragment.
+		Fragment loginFragment = new LoginFragment();
+		Fragment toolsFragment = new ToolsFragment();
+		Fragment slFragment;
+//		 m_bhasgoogleframework=false;
+		if (m_bhasgoogleframework)
+			slFragment = new ServiceLocationFragment();
+		else
+			slFragment = new BaiduMapFragment();
+		// Add the fragment to the activity, pushing this transaction
+		// on to the back stack.
+
+		FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
+		ft.replace(R.id.tab1, loginFragment);
+		ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
+		ft.addToBackStack("Login");
+
+		ft.replace(R.id.tab2, toolsFragment);
+		ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
+		ft.addToBackStack("Tools");		
+		
+		
+		// ft.replace(R.id.tab2, dtFragement);
+		// ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
+		// ft.addToBackStack("Tracking");
+		// Fragment test = new ServiceLocationFragment();
+		// ft.replace(R.id.tabtest, (Fragment) test);
+		// ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
+		// ft.addToBackStack("test");
+
+		ft.replace(R.id.tab3, (Fragment) slFragment);
+		ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
+		ft.addToBackStack("Location");
+
+		ft.commit();
+
+		// if (manager.findFragmentByTag(tabId) == null)
+		// {
+		// FragmentTransaction trans = manager.beginTransaction();
+		// trans.replace(contentViewID, frag, tabId);
+		// trans.commit();
+		// }
+		// for (int i = 0; i < title.length; i++) {
+		// Button button = new Button(this);
+		// button.setText(title[i]);
+		// button.setBackgroundDrawable(this.getResources().getDrawable(
+		// R.drawable.tab_lable)); //�Զ��尴ť��ʽ
+		// mTabHost.addTab(mTabHost.newTabSpec(title[i]).setIndicator(button)
+		// .setContent(tabIds[i]));
+		// }
+
+		// mTabHost.setOnTabChangedListener(this);
+	}
+
+	// @Override
+	// public void onTabChanged(String tabId)
+	// {
+	// TODO Auto-generated method stub
+	// Fragment frag = null;
+	// int contentViewID = 0;
+	// if (tabId.equals("Login")) {
+	// frag = new LoginFragment();
+	// //�Զ���̳�Fragment��UI������һ���򵥵���ʾ�ı�����Ŀؼ���
+	// contentViewID = R.id.tab1;
+	// } else if (tabId.equals("Not login")) {
+	// frag = new DirectTrackingFragment();
+	// contentViewID = R.id.tab2;
+	// }
+	// if (frag == null)
+	// return;
+	//
+	// FragmentManager manager = this.getFragmentManager();
+	//
+	// if (manager.findFragmentByTag(tabId) == null) {
+	// FragmentTransaction trans = manager.beginTransaction();
+	// trans.replace(contentViewID, frag, tabId);
+	// trans.commit();
+	// }
+	// }
+	// public class LoginFragment extends Fragment implements OnClickListener{
+	// @Override
+	// public View onCreateView(LayoutInflater inflater, ViewGroup container,
+	// Bundle savedInstanceState) {
+	// View view = inflater.inflate(R.layout.activity_login, null);
+	// Button btn = (Button)view.findViewById(R.id.sign_in_button);
+	// btn.setOnClickListener(this);
+	// return view;
+	// }
+	//
+	// @Override
+	// public void onClick(View v)
+	// {
+	// // TODO Auto-generated method stub
+	//
+	// }
+	// }
+}

+ 51 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/ApexBackgroundService.java

@@ -0,0 +1,51 @@
+package com.usai.apex;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+import android.util.Log;
+
+public class ApexBackgroundService extends Service
+{
+
+	ApexTrackingApplication app = null;
+	
+	
+	
+	@Override
+	public void onCreate()
+	{
+		app = ApexTrackingApplication.get_instance();
+
+		super.onCreate();
+	}
+
+
+
+	@Override
+	public void onStart(Intent intent, int startId)
+	{
+		if(app==null)
+			Log.e("service start","app is null");
+		super.onStart(intent, startId);
+	}
+
+
+
+	@Override
+	public int onStartCommand(Intent intent, int flags, int startId)
+	{
+
+		return super.onStartCommand(intent, flags, startId);
+	}
+
+
+
+	@Override
+	public IBinder onBind(Intent intent)
+	{
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+}

+ 88 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/ApexHistoryActivity.java

@@ -0,0 +1,88 @@
+package com.usai.apex;
+
+import android.content.Intent;
+import android.graphics.Color;
+import android.os.Bundle;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AppCompatActivity;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.webkit.WebView;
+import android.widget.TextView;
+
+import org.apache.http.util.EncodingUtils;
+
+import java.io.InputStream;
+
+public class ApexHistoryActivity extends AppCompatActivity
+{
+	@Override
+	public boolean onOptionsItemSelected(MenuItem item)
+	{
+		Intent intent = new Intent();
+		switch (item.getItemId())
+		{
+			case android.R.id.home:
+				finish();
+				break;
+
+			default:
+				break;
+		}
+		return super.onOptionsItemSelected(item);
+	}
+
+	private void setCustomActionBar() {
+		ActionBar.LayoutParams lp =new ActionBar.LayoutParams(ActionBar.LayoutParams.MATCH_PARENT, ActionBar.LayoutParams.MATCH_PARENT, Gravity.CENTER);
+		View mActionBarView = LayoutInflater.from(this).inflate(R.layout.actionbar_customtitle, null);
+
+		TextView titleview = mActionBarView.findViewById(R.id.title);
+		titleview.setText("Apex History");
+		setTitle("Apex History");
+		ActionBar actionBar = getSupportActionBar();
+		actionBar.setCustomView(mActionBarView, lp);
+//		actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
+//		actionBar.setDisplayShowCustomEnabled(true);
+		actionBar.setDisplayHomeAsUpEnabled(true);
+
+
+		actionBar.setDisplayShowTitleEnabled(true);
+	}
+	@Override
+	protected void onCreate(Bundle savedInstanceState)
+	{
+		Log.d("AboutActivity", "onCreate");
+
+		super.onCreate(savedInstanceState);
+		setContentView(R.layout.activity_history);
+
+		setCustomActionBar();
+		WebView wv = (WebView) findViewById(R.id.webView1);
+
+		wv.setBackgroundColor(Color.TRANSPARENT); // 设置背景色
+//		wv.getBackground().setAlpha(); // 设置填充透明度 范围:0-255
+
+		String content = "";
+		try
+		{
+			InputStream in = getResources().openRawResource(R.raw.about);
+			// 获取文件的字节数
+			int lenght = in.available();
+			// 创建byte数组
+			byte[] buffer = new byte[lenght];
+			// 将文件中的数据读到byte数组中
+			in.read(buffer);
+			content = EncodingUtils.getString(buffer, "UTF-8");
+		}
+		catch (Exception e)
+		{
+			e.printStackTrace();
+		}
+		wv.getSettings().setDefaultTextEncodingName("UTF-8");
+		wv.loadData(content, "text/html", null);
+		
+	}
+}

+ 25 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/ApexPushService.java

@@ -0,0 +1,25 @@
+package com.usai.apex;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+
+public class ApexPushService extends Service
+{
+
+	
+//	@Override
+//	public void onCreate()
+//	{
+//		
+//		super.onCreate();
+//	}
+
+	@Override
+	public IBinder onBind(Intent intent)
+	{
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+}

+ 501 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/ApexTrackingApplication.java

@@ -0,0 +1,501 @@
+package com.usai.apex;
+
+import android.app.Activity;
+import android.app.AlarmManager;
+import android.app.AlertDialog;
+import android.app.Application;
+import android.app.DownloadManager;
+import android.app.PendingIntent;
+import android.app.ProgressDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Environment;
+import android.os.Handler;
+import android.os.Message;
+import android.os.SystemClock;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.usai.util.AES;
+import com.usai.util.Network;
+import com.usai.util.RAUtil;
+import com.usai.util.dbUtil;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.File;
+import java.lang.ref.WeakReference;
+
+public class ApexTrackingApplication extends Application
+{
+
+	static final String						TAG				= "ApexTrackingApplication";
+	private static ApexTrackingApplication	instance;
+//	private static String					m_sessionid		= "";
+	private static String					m_user			= "";
+	private static String					m_password		= "";
+	public static int						ncount			= 1;
+
+	public static boolean					m_bauthorized	= false;
+	private boolean 							personMode 		= false;
+
+	public boolean homeactive=false;
+	public boolean historyactive=false;
+	public boolean recentactive=false;
+	private static long LastAlermTime = -120000;
+	
+	public static void UpdateLastCheckMessageTime()
+	{
+		LastAlermTime = SystemClock.elapsedRealtime();
+	}
+	public static long getLastCheckMessageTime()
+	{
+		return LastAlermTime;
+	}
+
+	public void setPersonMode(boolean personMode) {
+		this.personMode = personMode;
+	}
+
+	public boolean getPersonMode() {
+		return this.personMode;
+	}
+
+	public static ApexTrackingApplication getInstance() {
+		return instance;
+	}
+	@Override
+	public void onCreate()
+	{
+
+		// TODO Auto-generated method stub
+		Log.d(TAG, "onCreate");
+		super.onCreate();
+
+
+		registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() {
+			@Override
+			public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
+				mCurrentActivity = activity;
+				Resources res = ApexTrackingApplication.getInstance().getResources();
+				Configuration config = new Configuration();
+				config.setToDefaults();
+				res.updateConfiguration(config, res.getDisplayMetrics());
+			}
+
+			@Override
+			public void onActivityStarted(Activity activity) {
+
+//				// 加载系统默认设置,字体不随用户设置变化
+//				Resources res = ApexTrackingApplication.getInstance().getResources();
+//				Configuration config = new Configuration();
+//				config.setToDefaults();
+//				res.updateConfiguration(config, res.getDisplayMetrics());
+
+
+			}
+
+			// ...
+			@Override
+			public void onActivityResumed(Activity activity) {
+//				if (isBackground) {
+//					isBackground = false;
+//					notifyForeground();
+//				}
+				mCurrentActivity = activity;
+			}
+
+			@Override
+			public void onActivityPaused(Activity activity) {
+
+			}
+
+			@Override
+			public void onActivityStopped(Activity activity) {
+
+			}
+
+			@Override
+			public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
+
+			}
+
+			@Override
+			public void onActivityDestroyed(Activity activity) {
+
+			}
+			// ...
+		});
+
+		// 加载系统默认设置,字体不随用户设置变化
+		Resources res = super.getResources();
+		Configuration config = new Configuration();
+		config.setToDefaults();
+		res.updateConfiguration(config, res.getDisplayMetrics());
+
+		instance = this;
+
+		SharedPreferences pref = ApexTrackingApplication.get_instance()
+				.getSharedPreferences("Apex", 0);
+		boolean autologin = pref.getBoolean("autologin", false);
+		if (autologin == true)
+		{
+
+			String u = pref.getString("user", "");
+			String p = pref.getString("password", "");
+//			String s = pref.getString("sessionid", "");
+
+			try
+			{
+				if (!TextUtils.isEmpty(u))
+					m_user = AES.decrypt("apexu", u);
+				if (!TextUtils.isEmpty(p))
+					m_password = AES.decrypt("apexp", p);
+//				if (!TextUtils.isEmpty(s))
+//					m_sessionid = AES.decrypt("apexp", s);
+			}
+			catch (Exception e)
+			{
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+		}
+		dbUtil.cleanhistory();
+
+		// Intent serviceintent = new Intent();
+		// serviceintent.setClass(this, ApexPushService.class);
+		//
+		//
+		// startService(serviceintent);
+
+		createAppStorageDir();
+	}
+
+	private static final int HandlerMsgTypeCheckUpdate = 0;
+	private Handler handler = new CheckUpdateHandler(this);
+	private Activity mCurrentActivity;
+
+	private static final class CheckUpdateHandler extends Handler {
+
+        WeakReference<ApexTrackingApplication> mWeakApp;
+
+        public CheckUpdateHandler(ApexTrackingApplication application) {
+            mWeakApp = new WeakReference<> (application);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            super.handleMessage(msg);
+            switch (msg.what) {
+                case HandlerMsgTypeCheckUpdate: {
+
+                    final ApexTrackingApplication app = mWeakApp.get();
+                    if (app == null) {
+                        return;
+                    }
+
+                    app.dismissProgressDialog();
+
+                    if (msg.obj == null) {
+
+                    } else {
+
+                        try {
+                            JSONObject jsonObject = new JSONObject((String) msg.obj);
+
+                            final String ver = jsonObject.optString("ver");
+                            final String url = jsonObject.optString("url");
+                            int result = jsonObject.optInt("result",0);
+
+                            if (result == 2 && ver != null && url != null) {
+
+                                new AlertDialog.Builder(app.mCurrentActivity)
+                                        .setMessage("There is a new version " + ver + " ,are you ready to update it?")
+                                        .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
+                                            @Override
+                                            public void onClick(DialogInterface dialog, int which) {
+                                                app.downloadNewVersionApp(url,ver);
+                                            }
+                                        })
+                                        .setNegativeButton("No",null)
+                                        .show();
+
+                            } else {
+                                if (!app.mSilence) {
+									new AlertDialog.Builder(app.mCurrentActivity)
+											.setMessage("Your App is the latest version")
+											.setNegativeButton("Ok",null)
+											.show();
+								}
+                            }
+
+                        } catch (JSONException e) {
+                            e.printStackTrace();
+                        }
+
+                    }
+
+                    app.mSilence = true;
+                }
+                break;
+
+            }
+        }
+    }
+
+	private void downloadNewVersionApp(String url,String ver) {
+
+	    String appName = RAUtil.getApplicationName(this);
+
+	    if (url == null || appName == null || ver == null) {
+	        return;
+        }
+
+//        DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
+//
+//        request.setDestinationInExternalPublicDir("/download/", appName + " " + ver + ".apk");
+//
+//        DownloadManager downloadManager= (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
+//
+//        downloadManager.enqueue(request);
+
+
+        DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
+        DownloadManager.Request request = new DownloadManager.Request(
+                Uri.parse(url));
+
+        request.setDescription("更新APP");
+        request.allowScanningByMediaScanner();// 设置可以被扫描到
+        request.setVisibleInDownloadsUi(true);// 设置下载可见
+        request.setNotificationVisibility(
+                DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);//下载完成后通知栏任然可见
+        String fileName = url.substring(url.lastIndexOf("/"));// 解析fileName
+        request.setDestinationInExternalPublicDir(
+                Environment.DIRECTORY_DOWNLOADS, fileName);// 设置下载位置,sdcard/Download/fileName
+        long refernece = manager.enqueue(request);// 加入下载并取得下载ID
+        SharedPreferences sPreferences = getSharedPreferences(
+                "downloadplato", 0);
+        sPreferences.edit().putLong("plato", refernece).commit();//保存此次下载ID
+    }
+
+    private boolean mSilence = true;
+	public void checkUpdate(boolean silence,String alertMsg) {
+		if (!silence) {
+			showProgressDialog(alertMsg);
+		}
+		mSilence = silence;
+		new Thread(new Runnable() {
+			@Override
+			public void run() {
+
+				String jsonStr = Network.checkUpdate(instance);
+				Message msg = new Message();
+				msg.what = HandlerMsgTypeCheckUpdate;
+				msg.obj = jsonStr;
+				handler.sendMessage(msg);
+
+			}
+		}).start();
+
+	}
+
+	private ProgressDialog mProgressDialog;
+
+	public void showProgressDialog(String msg) {
+
+		if (mProgressDialog == null) {
+			mProgressDialog = new ProgressDialog(mCurrentActivity);
+			mProgressDialog.setCancelable(false);
+
+		}
+
+        mProgressDialog.setMessage(msg);
+		mProgressDialog.show();
+	}
+
+	public void dismissProgressDialog() {
+		if (mProgressDialog != null && mProgressDialog.isShowing()) {
+			mProgressDialog.dismiss();
+		}
+	}
+
+	public void createAppStorageDir() {
+		String documentDir = getDocumentDir();
+		File docDir = new File(documentDir);
+		docDir.mkdirs();
+
+	}
+
+	public String getDocumentDir() {
+//		return RAUtil.SDCardRoot() + RAUtil.getApplicationName(getApplicationContext()) + File.separator +"Document";
+		return RAUtil.SDCardRoot() + RAUtil.getApplicationName(getApplicationContext());
+	}
+
+	// @Override
+	// protected void finalize() throws Throwable
+	// {
+	// NotificationManager nManager = (NotificationManager)
+	// instance.getSystemService(
+	// Context.NOTIFICATION_SERVICE);
+	// nManager.cancel(R.layout.activity_apex);
+	// super.finalize();
+	// }
+
+	public static ApexTrackingApplication get_instance()
+	{
+		return instance;
+	}
+
+	public static void startalarm(String caller)
+	{
+		// 新版暂时停用通知
+		if(true)
+			return;
+		SharedPreferences pref = get_instance()
+				.getSharedPreferences("Apex", 0);
+		boolean autologin = pref.getBoolean("autologin", false);
+		if (autologin == false)
+			return;
+		// 启动完成
+		Intent iAlarm = new Intent(get_instance(), Alarmreceiver.class);
+		iAlarm.putExtra("caller", caller);
+		iAlarm.setAction("com.usai.apex.push");
+		PendingIntent sender = PendingIntent.getBroadcast(get_instance(), 0,
+				iAlarm, PendingIntent.FLAG_UPDATE_CURRENT);
+
+		long firstime = SystemClock.elapsedRealtime();
+//		UpdateLastAlermTime();
+		AlarmManager am = (AlarmManager) get_instance().getSystemService(
+				Context.ALARM_SERVICE);
+
+		// 5分钟一个周期,不停的发送广播
+		am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstime,
+				300 * 1000, sender);
+	}
+
+	public static void cancelalarm()
+	{
+
+		// 启动完成
+		Intent iAlarm = new Intent(get_instance(), Alarmreceiver.class);
+		iAlarm.setAction("com.usai.apex.push");
+		PendingIntent sender = PendingIntent.getBroadcast(get_instance(), 0,
+				iAlarm, PendingIntent.FLAG_UPDATE_CURRENT);
+
+		AlarmManager am = (AlarmManager) get_instance().getSystemService(
+				Context.ALARM_SERVICE);
+
+		am.cancel(sender);
+	}
+
+	public static void logout()
+	{
+		ncount = 1;
+		cancelalarm();
+//		m_sessionid = "";
+		m_user = "";
+		m_password = "";
+		m_bauthorized = false;
+		get_instance().setPersonMode(false);
+		SharedPreferences pref = ApexTrackingApplication.get_instance()
+				.getSharedPreferences("Apex", 0);
+		SharedPreferences.Editor editor = pref.edit();
+
+		editor.putBoolean("autologin", false);
+		editor.commit();
+
+	}
+
+	public static void SetAuthorizeStatus(boolean bauthorized)
+	{
+		m_bauthorized = bauthorized;
+	}
+	public static void login(String sid, String user, String pass)
+	{
+//		m_sessionid = sid;
+		m_user = user;
+		m_password = pass;
+		m_bauthorized = true;
+		
+		SharedPreferences pref = ApexTrackingApplication.get_instance()
+				.getSharedPreferences("Apex", 0);
+		SharedPreferences.Editor editor = pref.edit();
+		try
+		{
+
+			editor.putString("user", AES.encrypt("apexu", m_user));
+			editor.putString("password", AES.encrypt("apexp", m_password));
+			editor.putBoolean("autologin", true);
+//			editor.putString("sessionid", AES.encrypt("apexp", m_sessionid));
+
+		}
+		catch (Exception e)
+		{
+			editor.putString("user", null);
+			editor.putString("password", null);
+//			editor.putString("m_sessionid", null);
+			editor.putBoolean("autologin", false);
+			m_bauthorized=false;
+			e.printStackTrace();
+		}
+		editor.commit();
+
+		startalarm("app Login");
+	}
+
+	// public static void put_sessionid(String id)
+	// {
+	//
+	// Log.e(TAG, "put_sessionid");
+	// m_sessionid = id;
+	// }
+
+	// public static void put_authorization(boolean bauth)
+	// {
+	//
+	// m_bauthorized = bauth;
+	// }
+
+	public static boolean get_authorization()
+	{
+
+		return m_bauthorized;
+	}
+
+	// public static void put_user(String user)
+	// {
+	//
+	// m_user = user;
+	// }
+	//
+	// public static void put_password(String pass)
+	// {
+	//
+	// m_password = pass;
+	// }
+
+//	public static String get_sessionid()
+//	{
+//		Log.d(TAG, "get_sessionid");
+//		return m_sessionid;
+//	}
+
+	public static String get_user()
+	{
+		Log.d(TAG, "get_user");
+		return m_user.toLowerCase();
+	}
+
+	public static String get_pass()
+	{
+		Log.d(TAG, "get_pass");
+		return m_password;
+	}
+}

+ 700 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/BaiduMapFragment.java

@@ -0,0 +1,700 @@
+package com.usai.apex;
+
+//import com.google.android.gms.maps.SupportMapFragment;
+
+//import baidumapsdk.demo.DemoApplication;
+//import baidumapsdk.demo.DemoApplication.MyGeneralListener;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+//import baidumapsdk.demo.R;
+
+
+import com.baidu.location.BDLocation;
+import com.baidu.location.BDLocationListener;
+import com.baidu.location.LocationClient;
+import com.baidu.location.LocationClientOption;
+import com.baidu.mapapi.BMapManager;
+import com.baidu.mapapi.SDKInitializer;
+import com.baidu.mapapi.map.BaiduMap.OnMapClickListener;
+import com.baidu.mapapi.map.BitmapDescriptor;
+import com.baidu.mapapi.map.BitmapDescriptorFactory;
+import com.baidu.mapapi.map.InfoWindow;
+import com.baidu.mapapi.map.MapPoi;
+import com.baidu.mapapi.map.MapStatusUpdate;
+import com.baidu.mapapi.map.MapStatusUpdateFactory;
+//import com.baidu.mapapi.MKGeneralListener;
+//import com.baidu.mapapi.map.ItemizedOverlay;
+//import com.baidu.mapapi.map.MKEvent;
+//import com.baidu.mapapi.map.MapController;
+import com.baidu.mapapi.map.MapView;
+import com.baidu.mapapi.map.Marker;
+import com.baidu.mapapi.map.MarkerOptions;
+//import com.baidu.mapapi.map.OverlayItem;
+//import com.baidu.mapapi.map.PopupClickListener;
+//import com.baidu.mapapi.map.PopupOverlay;
+import com.baidu.mapapi.map.MyLocationData;
+import com.baidu.mapapi.map.SupportMapFragment;
+import com.baidu.mapapi.map.BaiduMap.OnMarkerClickListener;
+import com.baidu.mapapi.map.InfoWindow.OnInfoWindowClickListener;
+import com.baidu.mapapi.model.LatLng;
+//import com.baidu.platform.comapi.basestruct.GeoPoint;
+import com.usai.util.Network;
+
+import android.Manifest;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.graphics.Bitmap;
+import android.graphics.drawable.Drawable;
+import android.location.LocationListener;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.support.v4.app.ActivityCompat;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentManager;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.TextView;
+import android.widget.Toast;
+
+public class BaiduMapFragment extends Fragment implements BDLocationListener
+{
+	private SearchTask				m_task				= null;
+	String							fragment_content	= null;
+	private MapView					mMapView			= null;
+	// private MyOverlay mOverlay = null;
+	// private OverlayItem mCurItem = null;
+	// private Button button = null;
+	// private ArrayList<OverlayItem> mItems = null;
+	// private PopupOverlay pop = null;
+	SupportMapFragment				fragment;
+	BMapManager						mBMapManager		= null;
+	public static boolean			m_bKeyRight			= true;
+	HashMap<String, LocationDetail>	marker_detail		= new HashMap<String, LocationDetail>();
+
+	// OverlayItem m_curitem = null;
+	/*
+	 * public class MyOverlay extends ItemizedOverlay {
+	 * 
+	 * public MyOverlay(Drawable defaultMarker, MapView mapView) {
+	 * super(defaultMarker, mapView); }
+	 * 
+	 * @Override public boolean onTap(int index) {
+	 * Log.d("baidumap...................", "ontap"); View viewCache =
+	 * getActivity().getLayoutInflater().inflate( R.layout.marker_view, null);
+	 * 
+	 * TextView tv_title = (TextView) viewCache .findViewById(R.id.tv_title);
+	 * TextView tv_info = (TextView) viewCache.findViewById(R.id.tv_info);
+	 * 
+	 * OverlayItem item = getItem(index);
+	 * 
+	 * tv_title.setText(item.getTitle()); tv_info.setText(item.getSnippet());
+	 * m_curitem = item; pop.showPopup(viewCache, item.getPoint(), 32); return
+	 * true; }
+	 * 
+	 * @Override public boolean onTap(GeoPoint pt, MapView mMapView) {
+	 * Log.d("baidu map demo ", "hide pop"); if (pop != null) {
+	 * 
+	 * pop.hidePop(); // mMapView.removeView(button); } return false; }
+	 * 
+	 * }
+	 */
+
+	void AddMarker()
+	{
+
+		if (mMapView == null)
+		{
+
+			Log.d("onResume", "get map from fragment");
+			mMapView = fragment.getMapView();
+			if (mMapView == null)
+				return;
+		}
+
+		try
+		{
+			JSONObject jsobj = new JSONObject(fragment_content);
+
+			int count = jsobj.getInt("total");
+
+			JSONObject objrecords = jsobj.getJSONObject("records");
+			// mOverlay = new MyOverlay(getResources().getDrawable(
+			// R.drawable.ic_marker), mMapView);
+			BitmapDescriptor icon = BitmapDescriptorFactory
+					.fromResource(R.drawable.ic_marker);
+			for (int i = 0; i < count; i++)
+			{
+				// offset++;
+
+				JSONObject objrec = objrecords.getJSONObject("record" + i);
+				String area = objrec.getString("area");
+				String company = objrec.getString("company");
+				String city = objrec.getString("city");
+				String longitude = objrec.getString("longitude");
+				String latitude = objrec.getString("latitude");
+				String address = objrec.getString("address");
+				String telephone = objrec.getString("telephone");
+				String fax = objrec.getString("fax");
+				String contact = objrec.getString("contact");
+				String email = objrec.getString("email");
+
+				LocationDetail detail = new LocationDetail(company, address,
+						telephone, fax, contact, email);
+				marker_detail.put(company, detail);
+
+				Bundle extrainfo = new Bundle();
+				extrainfo.putString("company", company);
+				extrainfo.putSerializable("detail", detail);
+				extrainfo.putSerializable("city", city);
+				extrainfo.putSerializable("area", area);
+				// // 准备overlay 数据
+				//
+				// GeoPoint p1 = new GeoPoint(
+				// (int) (Double.parseDouble(latitude) * 1E6),
+				// (int) (Double.parseDouble(longitude) * 1E6));
+				// OverlayItem item1 = new OverlayItem(p1, company, city + "\n"
+				// + area);
+				//
+				// //
+				// // * 将item 添加到overlay中 注意: 同一个itme只能add一次
+				// //
+				// mOverlay.addItem(item1);
+				LatLng llA = new LatLng(Double.parseDouble(latitude),
+						Double.parseDouble(longitude));
+
+				MarkerOptions markeroption = new MarkerOptions().position(llA)
+						.icon(icon).zIndex(9).title(company)
+						.extraInfo(extrainfo).draggable(true);
+
+				// if (animationBox.isChecked()) {
+				// //掉下动画
+				// ooA.animateType(MarkerAnimateType.drop);
+				// }
+				Marker mMarkerA = (Marker) (mMapView.getMap()
+						.addOverlay(markeroption));
+
+			}
+			//
+			// * 保存所有item,以便overlay在reset后重新添加
+			//
+			// mItems = new ArrayList<OverlayItem>();
+			// mItems.addAll(mOverlay.getAllItem());
+			// //
+			// // * 将overlay 添加至MapView中
+			// //
+			// mMapView.getOverlays().add(mOverlay);
+			// //
+			// // * 刷新地图
+			// //
+			// mMapView.refresh();
+			// PopupClickListener popListener = new PopupClickListener()
+			// {
+			// @Override
+			// public void onClickedPopup(int index)
+			// {
+			// Log.d("baidu map.......", "popup on click");
+			// pop.hidePop();
+			//
+			// mMapView.refresh();
+			// Intent intent = new Intent();
+			// intent.setClass(getActivity(), LocationDetailActivity.class);
+			//
+			// String markertext = m_curitem.getTitle();
+			//
+			// intent.putExtra("detail", marker_detail.get(markertext));
+			// // // intent.putExtra("password", password);
+			// // intent.putExtra("function_name", function_name);
+			// // intent.putExtra("behavior", Network.BEHAVIOR_SEARCH);
+			// startActivity(intent);
+			//
+			// }
+			// };
+			// pop = new PopupOverlay(mMapView, popListener);
+		}
+		catch (JSONException e)
+		{
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+
+	public void requestloactions()
+	{
+
+		if (m_task != null)
+		{
+			return;
+		}
+
+		if (fragment_content != null)
+		{
+			// LayoutInflater inflater = (LayoutInflater)
+			// ApexTrackingApplication
+			// .get_instance().getSystemService(
+			// Context.LAYOUT_INFLATER_SERVICE);
+			// init(fragment_content,inflater);
+			return;
+		}
+		// mStatusMessageView.setText(R.string.str_Loading);
+		// showProgress(true);
+		m_task = new SearchTask();
+
+		// TextView text_page = (TextView) view_page_footer
+		// .findViewById(R.id.text_page);
+		// text_page.setText("Loading...");
+		// text_page.setEnabled(false);
+		m_task.execute();
+
+	}
+
+
+	private LocationClient mLocationClient;
+
+	private void initLocation() {
+		//定位客户端的设置
+		mLocationClient = new LocationClient(getContext());
+
+		//注册监听
+		mLocationClient.registerLocationListener(this);
+
+		//配置定位
+		LocationClientOption option = new LocationClientOption();
+		option.setCoorType("bd09ll");//坐标类型
+		option.setIsNeedAddress(true);//可选,设置是否需要地址信息,默认不需要
+		option.setOpenGps(true);//打开Gps
+		option.setScanSpan(1000);//1000毫秒定位一次
+		option.setIsNeedLocationPoiList(true);//可选,默认false,设置是否需要POI结果,可以在BDLocation.getPoiList里得到
+		mLocationClient.setLocOption(option);
+	}
+
+	@Override
+	public void onReceiveLocation(BDLocation bdLocation) {
+
+		//将获取的location信息给百度map
+		MyLocationData data = new MyLocationData.Builder()
+				.accuracy(bdLocation.getRadius())
+				// 此处设置开发者获取到的方向信息,顺时针0-360
+				.direction(100)
+				.latitude(bdLocation.getLatitude())
+				.longitude(bdLocation.getLongitude())
+				.build();
+
+		if (fragment != null) {
+			fragment.getMapView().getMap().setMyLocationData(data);
+		}
+
+	}
+
+	class SearchTask extends AsyncTask<Void, Void, Boolean>
+	{
+		int	errorcode;
+
+		// boolean bfinish = false;
+
+		@Override
+		protected Boolean doInBackground(Void... params)
+		{
+			Log.d("SearchTask", "doInBackground");
+			if (!Network.NetworkIsAvailable())
+
+			{
+				errorcode = Network.RESULT_NET_NOTAVAILABLE;
+				return false;
+			}
+			String jstr = Network.get_servicelocation();
+
+			if (jstr == null || jstr.length() <= 0)
+			{
+				// Log.d(TAG, "json is wrong");
+
+				errorcode = Network.RESULT_NET_ERROR;
+				return false;
+			}
+
+			JSONObject jsobj;
+			//
+			// array = new JSONArray(json);
+			try
+			{
+				jsobj = new JSONObject(jstr);
+				// if (searchresult.get_fieldscount() == 0)
+				// {
+				// JSONObject objfields = jsobj.getJSONObject("fields");
+				// if (objfields != null)
+				// searchresult.init_fields(objfields.toString());
+				// }
+				int count = jsobj.getInt("total");
+				// if (count < limit)
+				// bfinish = true;
+				JSONObject objrecords = jsobj.getJSONObject("records");
+				if (objrecords != null)
+				{
+					fragment_content = jstr;
+					errorcode = Network.RESULT_TRUE;
+
+					return true;
+				}
+			}
+			catch (JSONException e)
+			{
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+			errorcode = Network.RESULT_NET_ERROR;
+			return false;
+		}
+
+		@Override
+		protected void onPostExecute(Boolean success)
+		{
+			String tag = "onPostExecute@BaiduMapFragment";
+			Log.d(tag, "entry");
+			m_task = null;
+			// showProgress(false);
+
+			switch (errorcode)
+			{
+				case Network.RESULT_NET_NOTAVAILABLE:
+				{
+					Toast toast = Toast.makeText(
+							ApexTrackingApplication.get_instance(),
+							getText(R.string.msg_connection_none),
+							Toast.LENGTH_LONG);
+					toast.setGravity(Gravity.CENTER, 0, 0);
+					toast.show();
+					break;
+				}
+				case Network.RESULT_NET_ERROR:
+				{
+					Toast toast = Toast.makeText(
+							ApexTrackingApplication.get_instance(),
+							getText(R.string.msg_net_error), Toast.LENGTH_LONG);
+					toast.setGravity(Gravity.CENTER, 0, 0);
+					toast.show();
+					break;
+				}
+				case Network.RESULT_ERROR:
+				// case Network.RESULT_RESPONSE_NULL:
+				{
+					Toast toast = Toast.makeText(
+							ApexTrackingApplication.get_instance(),
+							getText(R.string.msg_net_resulterror),
+							Toast.LENGTH_LONG);
+					toast.setGravity(Gravity.CENTER, 0, 0);
+					toast.show();
+					break;
+				}
+
+				default:
+					break;
+			}
+
+			if (success)
+			{
+				AddMarker();
+
+				mMapView.getMap().setOnMapClickListener( new OnMapClickListener()
+				{
+					
+					@Override
+					public boolean onMapPoiClick(MapPoi arg0)
+					{
+						mMapView.getMap().hideInfoWindow();
+						return false;
+					}
+					
+					@Override
+					public void onMapClick(LatLng arg0)
+					{
+						mMapView.getMap().hideInfoWindow();
+						
+					}
+				});
+				mMapView.getMap().setOnMarkerClickListener(
+						new OnMarkerClickListener()
+						{
+							public boolean onMarkerClick(final Marker marker)
+							{
+								// Button button = new
+								// Button(getActivity().getApplicationContext());
+								// button.setBackgroundResource(R.drawable.popup);
+
+								View viewCache = getActivity()
+										.getLayoutInflater().inflate(
+												R.layout.marker_view, null);
+
+								TextView tv_title = (TextView) viewCache
+										.findViewById(R.id.tv_title);
+								TextView tv_info = (TextView) viewCache
+										.findViewById(R.id.tv_info);
+
+								final String title = marker.getTitle();
+
+								Bundle bundle = marker.getExtraInfo();
+
+								final LocationDetail detail = (LocationDetail) bundle
+										.getSerializable("detail");
+								String city = bundle.getString("city");
+								String area = bundle.getString("area");
+								// OverlayItem item = getItem(index);
+
+								// marker.get
+
+								tv_title.setText(title);
+								tv_info.setText(city + "\n" + area);
+								// m_curitem = item;
+								// pop.showPopup(viewCache, item.getPoint(),
+								// 32);
+								OnInfoWindowClickListener listener = null;
+								if (true)
+								{
+									// button.setText("更改位置");
+									listener = new OnInfoWindowClickListener()
+									{
+										public void onInfoWindowClick()
+										{
+
+											mMapView.getMap().hideInfoWindow();
+
+											Log.d("baidu map.......",
+													"popup on click");
+											
+
+//											mMapView.refresh();
+											Intent intent = new Intent();
+											intent.setClass(
+													getActivity(),
+													LocationDetailActivity.class);
+
+											String markertext = title;
+
+											intent.putExtra("detail",
+													detail);
+											// // intent.putExtra("password",
+											// password);
+											// intent.putExtra("function_name",
+											// function_name);
+											// intent.putExtra("behavior",
+											// Network.BEHAVIOR_SEARCH);
+//											startActivity(intent);
+
+                                            LocationDetail detail = marker_detail.get(markertext);
+
+                                            if (markerClickListener != null) {
+                                                markerClickListener.markerClicked(detail);
+                                            }
+
+										}
+									};
+									LatLng ll = marker.getPosition();
+									InfoWindow mInfoWindow = new InfoWindow(
+											BitmapDescriptorFactory
+													.fromView(viewCache), ll,
+											-100, listener);
+									mMapView.getMap().showInfoWindow(
+											mInfoWindow);
+								}
+								// else if (marker == mMarkerB) {
+								// button.setText("更改图标");
+								// button.setOnClickListener(new
+								// OnClickListener() {
+								// public void onClick(View v) {
+								// marker.setIcon(bd);
+								// mBaiduMap.hideInfoWindow();
+								// }
+								// });
+								// LatLng ll = marker.getPosition();
+								// mInfoWindow = new InfoWindow(button, ll,
+								// -47);
+								// mBaiduMap.showInfoWindow(mInfoWindow);
+								// } else if (marker == mMarkerC) {
+								// button.setText("删除");
+								// button.setOnClickListener(new
+								// OnClickListener() {
+								// public void onClick(View v) {
+								// marker.remove();
+								// mBaiduMap.hideInfoWindow();
+								// }
+								// });
+								// LatLng ll = marker.getPosition();
+								// mInfoWindow = new InfoWindow(button, ll,
+								// -47);
+								// mBaiduMap.showInfoWindow(mInfoWindow);
+								// }
+								return true;
+							}
+						});
+				//
+				// if (bfinish)
+				// {
+				// // getListView().removeFooterView(view_page_footer);
+				// // Toast.makeText(AnnouncementActivity.this, "Load all!",
+				// // Toast.LENGTH_LONG).show();
+				//
+				// TextView tv = (TextView) view_page_footer
+				// .findViewById(R.id.text_page);
+				// tv.setText("No more items");
+				// tv.setEnabled(false);
+				// }
+				// else
+				// {
+				// TextView tv = (TextView) view_page_footer
+				// .findViewById(R.id.text_page);
+				// tv.setText("More...");
+				// tv.setEnabled(true);
+				// }
+				// adapter.notifyDataSetChanged();
+				// // getListAdapter().notifyDataSetChanged;
+				// // BaseAdapter mJson = null;
+				// // mJson.notifyDataSetChanged();
+			}
+
+			super.onPostExecute(success);
+		}
+
+		@Override
+		protected void onCancelled()
+		{
+			m_task = null;
+			// showProgress(false);
+		}
+	}
+
+	public void initEngineManager(Context context)
+	{
+
+		SDKInitializer.initialize(ApexTrackingApplication.get_instance());
+		// String strKey = ApexTrackingApplication.get_instance().getString(
+		// R.string.baidu_key);
+		// if (mBMapManager == null)
+		// {
+		// mBMapManager = new BMapManager(context);
+		// }
+		//
+		// if (!mBMapManager.init(strKey, new MyGeneralListener()))
+		// {
+		// // Toast.makeText(getActivity().getApplicationContext(),
+		// // "BMapManager  初始化错误!", Toast.LENGTH_LONG).show();
+		// }
+	}
+
+	/*
+	 * // 常用事件监听,用来处理通常的网络错误,授权验证错误等 static class MyGeneralListener implements
+	 * MKGeneralListener {
+	 * 
+	 * @Override public void onGetNetworkState(int iError) { if (iError ==
+	 * MKEvent.ERROR_NETWORK_CONNECT) { // Toast.makeText( //
+	 * ApexTrackingApplication.get_instance() // .getApplicationContext(),
+	 * "您的网络出错啦!", // Toast.LENGTH_LONG).show(); } else if (iError ==
+	 * MKEvent.ERROR_NETWORK_DATA) { // Toast.makeText( //
+	 * ApexTrackingApplication.get_instance() // .getApplicationContext(),
+	 * "输入正确的检索条件!", // Toast.LENGTH_LONG).show(); } // ... }
+	 * 
+	 * @Override public void onGetPermissionState(int iError) { // 非零值表示key验证未通过
+	 * if (iError != 0) { // 授权Key错误: // Toast.makeText( //
+	 * ApexTrackingApplication.get_instance() // .getApplicationContext(), //
+	 * "请在 DemoApplication.java文件输入正确的授权Key,并检查您的网络连接是否正常!error: " // + iError,
+	 * Toast.LENGTH_LONG).show(); m_bKeyRight = false; } else { m_bKeyRight =
+	 * true; // Toast.makeText( // ApexTrackingApplication.get_instance() //
+	 * .getApplicationContext(), "key认证成功", // Toast.LENGTH_LONG).show(); } } }
+	 */
+	@Override
+	public void onActivityCreated(Bundle savedInstanceState)
+	{
+
+		super.onActivityCreated(savedInstanceState);
+		initEngineManager(getActivity().getApplicationContext());
+
+		FragmentManager fm = getChildFragmentManager();
+		fragment = (SupportMapFragment) fm.findFragmentById(R.id.map);
+
+		if (fragment == null)
+		{
+
+			Log.d("onActivityCreated", "create support map fragment");
+			fragment = SupportMapFragment.newInstance();
+			;// .newInstance();
+			fm.beginTransaction().replace(R.id.map, fragment).commit();
+		}
+		mMapView = fragment.getMapView();
+	}
+
+	@Override
+	public View onCreateView(LayoutInflater inflater, ViewGroup container,
+			Bundle savedInstanceState)
+	{
+		// TODO Auto-generated method stub
+		// return super.onCreateView(inflater, container, savedInstanceState);
+				
+
+		requestloactions();
+
+		return inflater.inflate(R.layout.fragment_service_location, container,
+				false);
+	}
+
+	@Override
+	public void onResume()
+	{
+		super.onResume();
+
+		Log.d("onResume", "get map from fragment");
+		LatLng center = new LatLng(29.945,104.7);
+		MapStatusUpdate msu = MapStatusUpdateFactory.newLatLngZoom(center,4.8f);//MapStatusUpdateFactory.zoomTo(4.5f);
+		
+		
+		fragment.getMapView().getMap().setMapStatus(msu);
+		
+//		float zoomLevel = Float.parseFloat(t.getText().toString());
+//		MapStatusUpdate u = MapStatusUpdateFactory.zoomTo(zoomLevel);
+//		mBaiduMap.animateMapStatus(u);
+//		 MapController controller = fragment.getMapView().getController();
+//		 controller.setCenter(new GeoPoint((int) ( * 1E6),
+//		 (int)  * 1E6)));
+//		 controller.setZoom(5);
+
+		if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
+			// TODO: Consider calling
+			//    ActivityCompat#requestPermissions
+			// here to request the missing permissions, and then overriding
+			//   public void onRequestPermissionsResult(int requestCode, String[] permissions,
+			//                                          int[] grantResults)
+			// to handle the case where the user grants the permission. See the documentation
+			// for ActivityCompat#requestPermissions for more details.
+
+		} else {
+			fragment.getMapView().getMap().setMyLocationEnabled(true);
+			initLocation();
+			if(mLocationClient != null && !mLocationClient.isStarted()){//如果定位client没有开启,开启定位
+				mLocationClient.start();
+			}
+		}
+
+	}
+
+	@Override
+	public void onPause() {
+		super.onPause();
+
+		if(mLocationClient != null && mLocationClient.isStarted()){//如果定位client开启,关闭定位
+			mLocationClient.stop();
+		}
+	}
+
+	public BaiduMarkerClickListener markerClickListener;
+	public interface BaiduMarkerClickListener {
+		void markerClicked(LocationDetail detail);
+	}
+
+}

+ 97 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/BootBroadcastReceiver.java

@@ -0,0 +1,97 @@
+package com.usai.apex;
+
+
+import android.app.DownloadManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.database.Cursor;
+import android.net.Uri;
+
+public class BootBroadcastReceiver extends BroadcastReceiver
+{
+
+	@Override
+	public void onReceive(Context context, Intent intent)
+	{
+        if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {  
+//            // 启动完成  
+//            Intent iAlarm = new Intent(context, Alarmreceiver.class);  
+//            iAlarm.setAction("com.usai.apex.push");  
+//            PendingIntent sender = PendingIntent.getBroadcast(context, 0,  
+//            		iAlarm, 0);  
+//            long firstime = SystemClock.elapsedRealtime();  
+//            AlarmManager am = (AlarmManager) context  
+//                    .getSystemService(Context.ALARM_SERVICE);  
+//  
+//            // 10秒一个周期,不停的发送广播  
+//            am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstime,  
+//                    30 * 1000, sender);  
+//			Intent intentservice = new Intent();
+//			intentservice.setClass(context, ApexPushService.class);
+//			if (intent.getExtras() != null)
+//				intentservice.putExtras(intent.getExtras());
+//			intentservice.setAction(intent.getAction());
+//			context.startService(intentservice);
+        	ApexTrackingApplication.startalarm("boot completed");
+        }
+		else if(intent.getAction().equals(DownloadManager.ACTION_DOWNLOAD_COMPLETE))
+		{
+			long myDwonloadID = intent.getLongExtra(
+					DownloadManager.EXTRA_DOWNLOAD_ID, -1);
+//                    LogUtils.i("下载完成 ID = " + myDwonloadID);
+			SharedPreferences sPreferences = context.getSharedPreferences(
+					"downloadplato", 0);
+			long refernece = sPreferences.getLong("plato", 0);
+			if (refernece == myDwonloadID) {
+				String serviceString = Context.DOWNLOAD_SERVICE;
+				DownloadManager dManager = (DownloadManager) context
+						.getSystemService(serviceString);
+
+				DownloadManager.Query query = new DownloadManager.Query();
+				query.setFilterById(myDwonloadID);
+				Cursor c = dManager.query(query);
+				if(c != null) {
+					if (c.moveToFirst()) {
+						int columnIndex = c.getColumnIndex(DownloadManager.COLUMN_STATUS);
+						if (DownloadManager.STATUS_SUCCESSFUL == c.getInt(columnIndex)) {
+							String downloadFileUrl = c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
+//							startInstall(context, Uri.parse(downloadFileUrl));
+
+
+
+							Intent install = new Intent(Intent.ACTION_VIEW);
+							Uri downloadFileUri =Uri.parse(downloadFileUrl);// dManager.getUriForDownloadedFile(myDwonloadID);
+							install.setDataAndType(downloadFileUri,
+									"application/vnd.android.package-archive");
+							install.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+							context.startActivity(install);
+						}
+					}
+					c.close();
+				}
+
+
+
+
+
+			}
+		}
+//		else if (intent.getAction().equals(
+//				ConnectivityManager.CONNECTIVITY_ACTION))
+//		{
+//			
+//			ApexTrackingApplication.startalarm("connection change");
+//			// handle auto submit ,check update etc
+////			dbgUtil.Log(Log.INFO,TAG, "ConnectivityManager.CONNECTIVITY_ACTION");
+////			
+////			new AutoUpdateCheckThread(context, false).start();
+////
+////			new AutoSubmitThread(context).start();
+//
+//		}	       
+        
+	}
+
+}

+ 370 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/ChangePasswordActivity.java

@@ -0,0 +1,370 @@
+package com.usai.apex;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.annotation.TargetApi;
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.AlertDialog.Builder;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
+import android.content.Intent;
+import android.os.AsyncTask;
+import android.os.Build;
+import android.os.Bundle;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AppCompatActivity;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.EditText;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.usai.util.Network;
+
+/**
+ * Activity which displays a login screen to the user, offering registration as
+ * well.
+ */
+public class ChangePasswordActivity extends AppCompatActivity {
+	private UserLoginTask mAuthTask = null;
+
+	// Values for email and password at the time of the login attempt.
+	// private String m_sUser;
+	private String m_soldPassword;
+	private String m_snewPassword;
+	private String m_snew1Password;
+
+	// UI references.
+	private EditText mOldpassView;
+	private EditText mNewpassView;
+	private EditText mNew1passView;
+	private View mLoginFormView;
+	private View mLoginStatusView;
+	private TextView mLoginStatusMessageView;
+
+
+
+	@Override
+	public boolean onOptionsItemSelected(MenuItem item)
+	{
+		Intent intent = new Intent();
+		switch (item.getItemId())
+		{
+			case android.R.id.home:
+				finish();
+				break;
+
+			default:
+				break;
+		}
+		return super.onOptionsItemSelected(item);
+	}
+
+	private void setCustomActionBar() {
+		ActionBar.LayoutParams lp =new ActionBar.LayoutParams(ActionBar.LayoutParams.MATCH_PARENT, ActionBar.LayoutParams.MATCH_PARENT, Gravity.CENTER);
+		View mActionBarView = LayoutInflater.from(this).inflate(R.layout.actionbar_customtitle, null);
+
+		TextView titleview = mActionBarView.findViewById(R.id.title);
+		titleview.setText(getTitle());
+
+		ActionBar actionBar = getSupportActionBar();
+		actionBar.setCustomView(mActionBarView, lp);
+//		actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
+//		actionBar.setDisplayShowCustomEnabled(true);
+		actionBar.setDisplayHomeAsUpEnabled(true);
+
+
+		actionBar.setDisplayShowTitleEnabled(true);
+	}
+	@Override
+	protected void onCreate(Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
+
+		setContentView(R.layout.activity_change_password);
+
+		setCustomActionBar();
+
+		// Set up the login form.
+
+		mOldpassView = (EditText) findViewById(R.id.old_password);
+
+		mNewpassView = (EditText) findViewById(R.id.new_password);
+		mNew1passView = (EditText) findViewById(R.id.new_password_confirm);
+		mNew1passView
+		 .setOnEditorActionListener(new TextView.OnEditorActionListener() {
+		 @Override
+		 public boolean onEditorAction(TextView textView, int id,
+		 KeyEvent keyEvent) {
+		 if (id == R.id.btn_ok || id == EditorInfo.IME_ACTION_DONE) {
+			 
+			 
+			 InputMethodManager inputMethodManager = (InputMethodManager)getApplicationContext().getSystemService(
+						Context.INPUT_METHOD_SERVICE);
+
+		// EditText editText =
+		// (EditText)findViewById(R.id.xxxx);
+		inputMethodManager.hideSoftInputFromWindow(
+				mNew1passView.getWindowToken(), 0); // ����
+		 changepassword();
+		 return true;
+		 }
+		 return false;
+		 }
+		 });
+
+		mLoginFormView = findViewById(R.id.login_form);
+		mLoginStatusView = findViewById(R.id.login_status);
+		mLoginStatusMessageView = (TextView) findViewById(R.id.login_status_message);
+
+		findViewById(R.id.btn_ok).setOnClickListener(
+				new View.OnClickListener() {
+					@Override
+					public void onClick(View view) {
+						InputMethodManager inputMethodManager = (InputMethodManager)getApplicationContext().getSystemService(
+								Context.INPUT_METHOD_SERVICE);
+
+				// EditText editText =
+				// (EditText)findViewById(R.id.xxxx);
+				inputMethodManager.hideSoftInputFromWindow(
+						mNew1passView.getWindowToken(), 0); // ����
+						changepassword();
+					}
+				});
+		findViewById(R.id.btn_close).setOnClickListener(
+				new View.OnClickListener() {
+					@Override
+					public void onClick(View view) {
+						finish();
+					}
+				});
+	}
+
+	// @Override
+	// public boolean onCreateOptionsMenu(Menu menu) {
+	// super.onCreateOptionsMenu(menu);
+	// getMenuInflater().inflate(R.menu.change_password, menu);
+	// return true;
+	// }
+	//
+	// /**
+	// * Attempts to sign in or register the account specified by the login
+	// form.
+	// * If there are form errors (invalid email, missing fields, etc.), the
+	// * errors are presented and no actual login attempt is made.
+	// */
+	public void changepassword() {
+		if (mAuthTask != null) {
+			return;
+		}
+
+		// Reset errors.
+		mOldpassView.setError(null);
+		mNewpassView.setError(null);
+		mNew1passView.setError(null);
+
+		// Store values at the time of the login attempt.
+		m_soldPassword = mOldpassView.getText().toString();
+		m_snewPassword = mNewpassView.getText().toString();
+		m_snew1Password = mNew1passView.getText().toString();
+
+		boolean cancel = false;
+		View focusView = null;
+
+		// Check for a valid password.
+		if (TextUtils.isEmpty(m_soldPassword)) {
+			mOldpassView.setError(getString(R.string.error_field_required));
+			focusView = mOldpassView;
+			cancel = true;
+		} else if (TextUtils.isEmpty(m_snewPassword)) {
+			mNewpassView.setError(getString(R.string.error_field_required));
+			focusView = mNewpassView;
+			cancel = true;
+		} else if (TextUtils.isEmpty(m_snew1Password)) {
+			mNew1passView.setError(getString(R.string.error_field_required));
+			focusView = mNew1passView;
+			cancel = true;
+		} else if (m_snewPassword.equals(m_snew1Password)==false) {
+			mNew1passView.setError("New passwords not same");
+			focusView = mNew1passView;
+			cancel = true;
+		}
+
+	
+
+		if (cancel) {
+			// There was an error; don't attempt login and focus the first
+			// form field with an error.
+			focusView.requestFocus();
+		} else {
+			// Show a progress spinner, and kick off a background task to
+			// perform the user login attempt.
+			mLoginStatusMessageView.setText(R.string.login_progress_signing_in);
+			showProgress(true);
+			mAuthTask = new UserLoginTask();
+			mAuthTask.execute((Void) null);
+		}
+	}
+
+	/**
+	 * Shows the progress UI and hides the login form.
+	 */
+	@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
+	private void showProgress(final boolean show) {
+		// On Honeycomb MR2 we have the ViewPropertyAnimator APIs, which allow
+		// for very easy animations. If available, use these APIs to fade-in
+		// the progress spinner.
+		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
+			int shortAnimTime = getResources().getInteger(
+					android.R.integer.config_shortAnimTime);
+
+			mLoginStatusView.setVisibility(View.VISIBLE);
+			mLoginStatusView.animate().setDuration(shortAnimTime)
+					.alpha(show ? 1 : 0)
+					.setListener(new AnimatorListenerAdapter() {
+						@Override
+						public void onAnimationEnd(Animator animation) {
+							mLoginStatusView.setVisibility(show ? View.VISIBLE
+									: View.GONE);
+						}
+					});
+
+			mLoginFormView.setVisibility(View.VISIBLE);
+			mLoginFormView.animate().setDuration(shortAnimTime)
+					.alpha(show ? 0 : 1)
+					.setListener(new AnimatorListenerAdapter() {
+						@Override
+						public void onAnimationEnd(Animator animation) {
+							mLoginFormView.setVisibility(show ? View.GONE
+									: View.VISIBLE);
+						}
+					});
+		} else {
+			// The ViewPropertyAnimator APIs are not available, so simply show
+			// and hide the relevant UI components.
+			mLoginStatusView.setVisibility(show ? View.VISIBLE : View.GONE);
+			mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
+		}
+	}
+
+	/**
+	 * Represents an asynchronous login/registration task used to authenticate
+	 * the user.
+	 */
+	public class UserLoginTask extends AsyncTask<Void, Void, Boolean> {
+		int errorcode;
+		@Override
+		protected Boolean doInBackground(Void... params) {
+			errorcode = Network.change_pass(m_soldPassword, m_snewPassword,ApexTrackingApplication.get_user());
+			if (errorcode == Network.RESULT_TRUE)
+				return true;
+			else {
+				return false;
+			}
+		}
+
+		@Override
+		protected void onPostExecute(final Boolean success) {
+			Log.d("onPostExecute", "entry");
+			mAuthTask = null;
+			showProgress(false);
+			// if (netconnect == )
+			// {
+			//
+			// }
+
+			if (success) {
+				AlertDialog.Builder builder = new Builder(ChangePasswordActivity.this);
+				builder.setMessage(getString(R.string.str_password_changed));
+
+				builder.setTitle(getString(R.string.str_change_success));
+
+				builder.setPositiveButton(getString(android.R.string.ok), new OnClickListener() {
+
+					@Override
+					public void onClick(DialogInterface dialog, int which) {
+						dialog.dismiss();
+
+//						ApexTrackingApplication.put_password(m_snewPassword);
+						setResult(Activity.RESULT_OK, null);
+						finish();
+					}
+				});
+
+
+				builder.create().show();
+
+			} else {
+				switch (errorcode) {
+				case Network.RESULT_NET_NOTAVAILABLE: {
+					Toast toast = Toast.makeText(getApplicationContext(),
+							getText(R.string.msg_connection_none),
+							Toast.LENGTH_LONG);
+					toast.setGravity(Gravity.CENTER, 0, 0);
+					toast.show();
+					return;
+				}
+				case Network.RESULT_NET_ERROR: {
+					Toast toast = Toast.makeText(getApplicationContext(),
+							getText(R.string.msg_net_error), Toast.LENGTH_LONG);
+					toast.setGravity(Gravity.CENTER, 0, 0);
+					toast.show();
+					return;
+				}
+				case Network.RESULT_ERROR:
+				// case Network.RESULT_RESPONSE_NULL:
+				{
+					Toast toast = Toast.makeText(getApplicationContext(),
+							getText(R.string.msg_net_resulterror),
+							Toast.LENGTH_LONG);
+					toast.setGravity(Gravity.CENTER, 0, 0);
+					toast.show();
+					return;
+				}
+
+				case Network.RESULT_FALSE: {
+					AlertDialog.Builder builder = new Builder(ChangePasswordActivity.this);
+					builder.setMessage(getString(R.string.str_invalid_password));
+
+					builder.setTitle(getString(R.string.str_failed_to_changepassword));
+
+					builder.setPositiveButton(getString(android.R.string.ok), new OnClickListener() {
+
+						@Override
+						public void onClick(DialogInterface dialog, int which) {
+							dialog.dismiss();
+
+//							RetrievePasswordActivity.this.finish();
+						}
+					});
+					builder.create().show();
+
+					return;
+				}
+				default: {
+					Toast toast = Toast.makeText(getApplicationContext(),
+							getText(R.string.msg_net_resulterror) + ":"
+									+ errorcode, Toast.LENGTH_LONG);
+					toast.setGravity(Gravity.CENTER, 0, 0);
+					toast.show();
+					break;
+				}
+				}
+			}
+		}
+
+		@Override
+		protected void onCancelled() {
+			mAuthTask = null;
+			showProgress(false);
+		}
+	}
+}

+ 166 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/ContainerSearchActivity.java

@@ -0,0 +1,166 @@
+package com.usai.apex;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AppCompatActivity;
+import android.view.Gravity;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.AutoCompleteTextView;
+import android.widget.Button;
+import android.widget.TextView;
+
+import com.usai.apex.mainframe.NewDetailActivity;
+import com.usai.util.dbUtil;
+
+public class ContainerSearchActivity extends AppCompatActivity {
+
+
+    private SegmentView mSegmentView;
+    private AutoCompleteTextView searchField;
+    private Button cancelBtn;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_container_search);
+
+        cancelBtn = findViewById(R.id.button2);
+        searchField = findViewById(R.id.atv_criterion2);
+
+        cancelBtn.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View view) {
+
+                searchContainer();
+
+                searchField.clearFocus();
+                InputMethodManager inputMethodManager = (InputMethodManager) getApplicationContext().getSystemService(Context.INPUT_METHOD_SERVICE);
+                inputMethodManager.hideSoftInputFromWindow(searchField.getWindowToken(),0);
+                inputMethodManager.hideStatusIcon(searchField.getWindowToken());
+            }
+        });
+
+        searchField.setOnEditorActionListener(new TextView.OnEditorActionListener() {
+            @Override
+            public boolean onEditorAction(TextView textView, int i, KeyEvent event) {
+
+                // 当actionId == XX_SEND 或者 XX_DONE时都触发
+                // 或者event.getKeyCode == ENTER 且 event.getAction == ACTION_DOWN时也触发
+                // 注意,这是一定要判断event != null。因为在某些输入法上会返回null。
+                if (i == EditorInfo.IME_ACTION_SEND || i == EditorInfo.IME_ACTION_DONE || (event != null && KeyEvent.KEYCODE_ENTER == event.getKeyCode() && KeyEvent.ACTION_DOWN == event.getAction())) {
+                    searchContainer();
+                }
+
+                return false;
+            }
+        });
+
+        setCustomActionBar();
+    }
+
+    private void setCustomActionBar() {
+        ActionBar.LayoutParams lp =new ActionBar.LayoutParams(ActionBar.LayoutParams.MATCH_PARENT, ActionBar.LayoutParams.MATCH_PARENT, Gravity.CENTER);
+        View mActionBarVie = LayoutInflater.from(this).inflate(R.layout.actionbar_segmentview, null);
+
+
+        mSegmentView = mActionBarVie.findViewById(R.id.segmentview);
+
+//
+//        mSegmentView.setOnSegmentViewClickListener(new SegmentView.onSegmentViewClickListener() {
+//            @Override
+//            public void onSegmentViewClick(View view, int postion) {
+//                switch (postion) {
+//                    case 0:
+//                        Toast.makeText(ContainerSearchActivity.this, "点击了消息" + postion,
+//                                Toast.LENGTH_SHORT).show();
+//                        break;
+//                    case 1:
+//                        Toast.makeText(ContainerSearchActivity.this, "点击了电话" + postion,
+//                                Toast.LENGTH_SHORT).show();
+//                        break;
+//                    default:
+//                        break;
+//                }
+//            }
+//        });
+
+
+//        TextView titleview = mActionBarView.findViewById(R.id.title);
+//        titleview.setText(getIntent().getStringExtra("title"));
+//
+//        mActionBarView.setBackgroundColor(Color.YELLOW);
+//        titleview.setBackgroundColor(Color.BLUE);
+        ActionBar actionBar = getSupportActionBar();
+        actionBar.setCustomView(mActionBarVie, lp);
+        actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
+        actionBar.setDisplayShowCustomEnabled(true);
+        actionBar.setDisplayHomeAsUpEnabled(true);
+
+
+//        actionBar.setIcon(getNumberDrawable());
+//        actionBar.setDisplayShowHomeEnabled(true);
+        actionBar.setDisplayShowTitleEnabled(false);
+    }
+
+
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item)
+    {
+        Intent intent = new Intent();
+        switch (item.getItemId())
+        {
+            case android.R.id.home:
+                finish();
+                break;
+
+            default:
+                break;
+        }
+        return super.onOptionsItemSelected(item);
+    }
+
+    private void searchContainer() {
+
+        InputMethodManager inputMethodManager = (InputMethodManager) getApplicationContext().getSystemService(Context.INPUT_METHOD_SERVICE);
+        inputMethodManager.hideSoftInputFromWindow(searchField.getWindowToken(),0);
+        inputMethodManager.hideStatusIcon(searchField.getWindowToken());
+
+        String cargo_criterion = searchField.getText().toString();
+
+        Intent intent = new Intent();
+        intent.setClass(this, NewDetailActivity.class);
+
+        intent.putExtra("action0", "Tracking");
+        intent.putExtra("function_name", "Cargo Tracking");
+
+        intent.putExtra("cargo_criterion", cargo_criterion);
+        intent.putExtra("actions_count", 1);
+        intent.putExtra("_id", "dumb");
+        String h_field;
+
+        int selectedId = mSegmentView.getSelect();
+        if (selectedId == 0)
+        {
+            intent.putExtra("criterion_type", 0);
+            h_field = "h_bol";
+        }
+        else
+        {
+            intent.putExtra("criterion_type", 1);
+            h_field = "ctnr";
+        }
+
+        dbUtil.savehistory(h_field, cargo_criterion);
+
+        startActivity(intent);
+    }
+
+}

+ 330 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/CustomizeFieldsActivity.java

@@ -0,0 +1,330 @@
+package com.usai.apex;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.TextView;
+
+import com.usai.util.dbUtil;
+
+import java.util.ArrayList;
+import java.util.List;
+
+//import android.content.DialogInterface.OnClickListener;
+
+public class CustomizeFieldsActivity extends Activity implements
+		OnClickListener
+{
+	//
+	// @Override
+	// protected void onCreate(Bundle savedInstanceState)
+	// {
+	// super.onCreate(savedInstanceState);
+	// setContentView(R.layout.activity_customize_fields);
+	// }
+	//
+	@Override
+	public boolean onCreateOptionsMenu(Menu menu)
+	{
+		// Inflate the menu; this adds items to the action bar if it is present.
+		getMenuInflater().inflate(R.menu.customize_fields, menu);
+		return true;
+	}
+
+	private static List<fieldedit> list = null;
+	private DragListAdapter adapter = null;
+
+	// public static List<String> groupKey = new ArrayList<String>();
+	private List<fieldedit> showList = new ArrayList<fieldedit>();
+	private List<fieldedit> hideList = new ArrayList<fieldedit>();
+	private String user/* ,password */, function_name;
+	private int behavior;
+
+	public class fieldedit
+	{
+		public String name = null;
+		public int _id = -1;
+
+		public fieldedit(String str, int i)
+		{
+			name = str;
+			_id = i;
+
+		}
+	}
+
+	@Override
+	public void onCreate(Bundle savedInstanceState)
+	{
+		super.onCreate(savedInstanceState);
+
+		user = ApexTrackingApplication.get_user();
+		// password = getIntent().getStringExtra("password");
+		function_name = getIntent().getStringExtra("function_name");
+		behavior = getIntent().getIntExtra("behavior", -1);
+		setContentView(R.layout.activity_customize_fields);
+		Button btnok = (Button) findViewById(R.id.btnok);
+		btnok.setOnClickListener(this);
+		Button btncancel = (Button) findViewById(R.id.btncancel);
+		btncancel.setOnClickListener(this);
+
+		initData();
+
+		DragListView dragListView = (DragListView) findViewById(R.id.drag_list);
+		adapter = new DragListAdapter(this, list);
+		dragListView.setAdapter(adapter);
+		
+		SharedPreferences RunOnce = getSharedPreferences("Apex", 0);
+		
+		String vername;
+		try
+		{
+			vername = getPackageManager().getPackageInfo(
+					"com.usai.apex", 0).versionName;
+			boolean bFirstRun = RunOnce.getBoolean(
+					"FirstRun"+vername+"_fields", true);
+			if(bFirstRun&&false)
+			{
+				SharedPreferences.Editor editor = RunOnce.edit();
+				editor.putBoolean("FirstRun"+vername+"_fields", false);
+				// Don't forget to commit your edits!!!
+				editor.commit();
+				Intent intent = new Intent();
+				intent.setClass(this, HelpActivity.class);
+				intent.putExtra("caller", "fields");
+				startActivity(intent);
+				
+			}		
+		}
+		catch (NameNotFoundException e)
+		{
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+	@Override
+	public boolean onOptionsItemSelected(MenuItem item)
+	{
+		switch (item.getItemId())
+		{
+		case R.id.action_help:
+			Intent intent = new Intent();
+			intent.setClass(this, HelpActivity.class);
+			intent.putExtra("caller", "fields");
+//			// intent.putExtra("password", password);
+//			intent.putExtra("function_name", function_name);
+//			intent.putExtra("behavior", Network.BEHAVIOR_SEARCH);
+			startActivity(intent);
+			break;
+
+		default:
+			break;
+		}
+		return super.onOptionsItemSelected(item);
+	}
+	public void initData()
+	{
+		SQLiteDatabase db = dbUtil.OpenDB(this, null, false);
+		Cursor cursor = db.query("fields_info", new String[] { "aname", "show",
+				"_id" }, "function_name='" + function_name + "' and user='"
+				+ user + "' and behavior=" + behavior, null, null, null,
+				"priority , aname", null);
+		while (cursor.moveToNext())
+		{
+			int show = cursor.getInt(1);
+			if (show == 1)
+				showList.add(new fieldedit(cursor.getString(0), cursor
+						.getInt(2)));
+			else
+			{
+				hideList.add(new fieldedit(cursor.getString(0), cursor
+						.getInt(2)));
+
+			}
+		}
+		// ��ݽ��
+		list = new ArrayList<fieldedit>();
+
+		// groupKey��ŵ��Ƿ����ǩ
+		// groupKey.add("Display fields");
+		// groupKey.add("Hide fields");
+
+		// for (int i = 0; i < 5; i++)
+		// {
+		// navList.add("Aѡ��" + i);
+		// }
+		list.add(new fieldedit(getString(R.string.str_displayitem), -1));
+		list.addAll(showList);
+
+		// for (int i = 0; i <18; i++)
+		// {
+		// moreList.add("Bѡ��" + i);
+		// }
+		list.add(new fieldedit(getString(R.string.str_hideitem), -2));
+		list.addAll(hideList);
+		dbUtil.CloseCursor(cursor);
+		dbUtil.CloseDB(db);
+	}
+
+	public static class DragListAdapter extends ArrayAdapter<fieldedit>
+	{
+
+		// private Context mContext;
+
+		public DragListAdapter(Context context, List<fieldedit> objects)
+		{
+			super(context, 0, objects);
+			// this.mContext = context;
+		}
+
+		public List<fieldedit> getList()
+		{
+			return list;
+		}
+
+		@Override
+		public boolean isEnabled(int position)
+		{
+			if (getItem(position)._id < 0) // _id<0 means a group key
+				return false;
+			// if (groupKey.contains(getItem(position).name))
+			// {
+			// // ����Ƿ����ǩ������false������ѡ�У����ܵ��
+			// return false;
+			// }
+			return super.isEnabled(position);
+		}
+
+		public int switchpos()
+		{
+
+			for (int i = 1; i < getCount(); i++)
+			{
+				if (getItem(i)._id < 0)
+					return i;
+			}
+			return -1;
+		}
+
+		@Override
+		public View getView(int position, View convertView, ViewGroup parent)
+		{
+
+			View view = convertView;
+			if (getItem(position)._id < 0) // _id<0 means a group key
+			{
+				view = LayoutInflater.from(getContext()).inflate(
+						R.layout.drag_list_item_tag, null);
+			}
+			// if (groupKey.contains(getItem(position).name))
+			// {
+			// // ����Ƿ����ǩ���ͼ��ط����ǩ�IJ����ļ������������ļ���ʾЧ��ͬ
+			// view = LayoutInflater.from(getContext()).inflate(
+			// R.layout.drag_list_item_tag, null);
+			// }
+			else
+			{
+				// �������������ǩ���ͼ����������IJ����ļ�
+				view = LayoutInflater.from(getContext()).inflate(
+						R.layout.drag_list_item, null);
+			}
+
+			TextView textView = (TextView) view
+					.findViewById(R.id.drag_list_item_text);
+			textView.setText(getItem(position).name);
+
+			return view;
+		}
+	}
+
+	@Override
+	public void onClick(View v)
+	{
+		switch (v.getId())
+		{
+		case R.id.btnok:
+		{
+			// DragListView dragListView = (DragListView)
+			// findViewById(R.id.drag_list);
+			int count = 0;
+			for (int i = 0; i < adapter.getCount(); i++)
+			{
+				fieldedit fe = adapter.getItem(i);
+				if (fe._id == -2 || count > 0)
+					break;
+				if (fe._id >= 0)
+					count++;
+
+			}
+			if (count == 0)
+			{
+				new AlertDialog.Builder(CustomizeFieldsActivity.this)
+						.setIcon(android.R.drawable.ic_dialog_info)
+						.setTitle("Error!")
+						.setMessage("You must set at least 1 field visiable!")
+						.setPositiveButton("OK",
+								new DialogInterface.OnClickListener()
+								{
+									public void onClick(DialogInterface dialog,
+											int whichButton)
+									{
+
+										// finish();
+										/* User clicked OK so do some stuff */
+									}
+								}).show();
+				break;
+
+			}
+
+			int show = 1;
+			SQLiteDatabase db = dbUtil.OpenDB(this, null, true);
+			db.beginTransaction();
+			for (int i = 0; i < adapter.getCount(); i++)
+			{
+				fieldedit fe = adapter.getItem(i);
+				if (fe._id == -2)// hide group begin 
+				{
+					show = 0;
+				}
+				if (show == 1)
+					db.execSQL("update fields_info set show=" + show
+							+ " ,priority=" + i + " where _id=" + fe._id);
+				else
+					db.execSQL("update fields_info set show=" + show
+							+ " where _id=" + fe._id);
+
+			}
+			db.setTransactionSuccessful();
+			db.endTransaction();
+			dbUtil.CloseDB(db);
+			finish();
+			// Log.d("fields",);
+			break;
+		}
+		case R.id.btncancel:
+			finish();
+			break;
+		default:
+			break;
+		}
+		// TODO Auto-generated method stub
+
+	}
+
+}

+ 607 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/DetailActivity.java

@@ -0,0 +1,607 @@
+package com.usai.apex;
+
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.database.sqlite.SQLiteDatabase;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentTransaction;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AppCompatActivity;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.EditText;
+import android.widget.FrameLayout;
+import android.widget.TabHost;
+import android.widget.TabWidget;
+import android.widget.TextView;
+
+import com.usai.apex.Result.AMResultActivity;
+import com.usai.apex.mainframe.RootActivity;
+import com.usai.util.commonUtil;
+import com.usai.util.dbUtil;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+
+public class DetailActivity extends AppCompatActivity implements
+		TabHost.TabContentFactory
+{
+	boolean showlogin = false;
+	// int radomid = 1 + (int) (Math.random() * 15);
+	TabHost							mTabHost;
+	LinkedHashMap<String, Integer>	tabmap	= new LinkedHashMap<String, Integer>();
+	HashMap<String,String> contentmap = new HashMap<String ,String>();
+
+	// HashMap<String, DetailFragment> fragments = new HashMap<String,
+	// DetailFragment>();
+	String							function_name;
+	String							_id;
+	String							cargo_criterion;
+	int								criterion_type;
+
+	String email_to = null,email_subject = null,email_content = null;
+	TextView mtitleview;
+//	@Override
+//	public void setTitle(CharSequence title) {
+////        View mActionBarView = LayoutInflater.from(this).inflate(R.layout.actionbar_customtitle, null);
+////
+////        TextView mtitleviewtitleview = mActionBarView.findViewById(R.id.title);
+//
+//		if(title==null)
+//			title="";
+//		if(mtitleview!=null)
+//			mtitleview.setText(title);
+//	}
+	private void setCustomActionBar() {
+		ActionBar.LayoutParams lp =new ActionBar.LayoutParams(ActionBar.LayoutParams.MATCH_PARENT, ActionBar.LayoutParams.MATCH_PARENT, Gravity.CENTER);
+		View mActionBarView = LayoutInflater.from(this).inflate(R.layout.actionbar_customtitle, null);
+
+		mtitleview= mActionBarView.findViewById(R.id.title);
+
+
+		function_name = getIntent().getStringExtra("function_name");
+		String title = "";
+		if(function_name.equals("Ocean Booking"))
+			title="Booking Detail";
+		else if(function_name.equals("Ocean B/L info."))
+			title="B/L info. Detail";
+		else if(function_name.equals("Container detail"))
+			title="Container Detail";
+		else if(function_name.equals("Cargo Tracking"))
+			title="Cargo Detail";
+		mtitleview.setText(title);
+		setTitle(title);
+//
+//        mActionBarView.setBackgroundColor(Color.YELLOW);
+//        titleview.setBackgroundColor(Color.BLUE);
+		ActionBar actionBar = getSupportActionBar();
+		actionBar.setCustomView(mActionBarView, lp);
+//		actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
+//		actionBar.setDisplayShowCustomEnabled(true);
+		actionBar.setDisplayHomeAsUpEnabled(true);
+
+
+//        actionBar.setIcon(getNumberDrawable());
+//        actionBar.setDisplayShowHomeEnabled(true);
+		actionBar.setDisplayShowTitleEnabled(true);
+	}
+
+	public DetailActivity get_instance()
+	{
+		return this;
+	}
+
+
+//	String email_to = null,email_subject = null,email_content = null;
+
+	public void save_content(String which,String content)
+	{
+		contentmap.put(which, content);
+
+		try {
+
+			JSONObject jsonObject = new JSONObject(content);
+			email_to = jsonObject.optString("email",null);
+			email_subject = jsonObject.optString("email_subject",null);
+			email_content = jsonObject.optString("email_content",null);
+
+		} catch (JSONException e) {
+			e.printStackTrace();
+		}
+
+	}
+	@Override
+	protected void onCreate(Bundle savedInstanceState)
+	{
+		Log.d("DetailActivity", "onCreate");
+
+		super.onCreate(savedInstanceState);
+
+		setContentView(R.layout.activity_detail);
+
+		setCustomActionBar();
+
+		List<Fragment> fragments = getSupportFragmentManager().getFragments();
+		if (fragments != null)
+		{
+			Log.d("DetailActivity", "fragments count=" + fragments.size());
+//			for (int i = 0; i < fragments.size(); i++)
+//				Log.e("DetailFragment", "fragment name="
+//						+ fragments.get(i).getTag());
+
+		}
+
+		if (savedInstanceState != null)
+		{
+			tabmap = (LinkedHashMap<String, Integer>) savedInstanceState
+					.getSerializable("tabmap");
+			contentmap = (HashMap<String, String>) savedInstanceState.getSerializable("contentmap");
+		}
+		else
+		{
+			int count = getIntent().getIntExtra("actions_count", 0);
+			for (int i = 0; i < count; i++)
+			{
+				int vid = commonUtil.generateViewId();
+				tabmap.put(getIntent().getStringExtra("action" + i), vid);
+			}
+		}
+		function_name = getIntent().getStringExtra("function_name");
+		
+		if(function_name.equals("Ocean Booking"))
+			setTitle("Booking Detail");
+		else if(function_name.equals("Ocean B/L info."))
+			setTitle("B/L info. Detail");
+		else if(function_name.equals("Container detail"))
+			setTitle("Container Detail");
+//		else if(function_name.equals("Cargo Tracking"))
+//			setTitle("Cargo Detail");
+//		
+		
+		if (function_name.equals("Cargo Tracking"))
+		{
+			criterion_type = getIntent().getIntExtra("criterion_type", 0);
+			cargo_criterion = getIntent().getStringExtra("cargo_criterion");
+			setTitle("Cargo Detail");
+		}
+		_id = getIntent().getStringExtra("_id");
+		setupTabs();
+
+	}
+
+	// @Override
+	// protected void onSaveInstanceState(Bundle outState)
+	// {
+	// Iterator<String> iter=fragments.keySet().iterator();
+	//
+	// while (iter.hasNext())
+	// {
+	// String tag = (String) iter.next();
+	// getSupportFragmentManager().putFragment(outState,tag,fragments.get(tag));
+	//
+	// }
+	// outState.putStringArray("tags", fragments.keySet().toArray(new
+	// String[0]));
+	// Log.d("onSaveInstanceState","save fragments" +
+	// fragments.keySet().size());
+	// super.onSaveInstanceState(outState);
+	// }
+	//
+	// @Override
+	// protected void onRestoreInstanceState(Bundle savedInstanceState)
+	// {
+	// String [] tags =savedInstanceState.getStringArray("tags");
+	// Log.d("onRestoreInstanceState","load fragments" + tags.length);
+	// for(int i=0;i<tags.length;i++)
+	// {
+	// Log.d("onRestoreInstanceState","load fragment" + tags[i]);
+	// fragments.put(tags[i],(DetailFragment)
+	// getSupportFragmentManager().getFragment(savedInstanceState,tags[i]));
+	// }
+	//
+	// super.onRestoreInstanceState(savedInstanceState);
+	// }
+
+	/** {@inheritDoc} */
+	public View createTabContent(String tag)
+	{
+		FrameLayout fl = new FrameLayout(this);
+		fl.setId(tabmap.get(tag));
+
+		Fragment f;
+		Bundle bundle = new Bundle();
+		if (function_name.equals("Cargo Tracking"))
+		{
+			if (criterion_type == 0)
+				bundle.putString("hbol", cargo_criterion);
+			else
+				bundle.putString("container_no", cargo_criterion);
+
+		}
+		bundle.putString("action_type", tag);
+		bundle.putString("id", _id);
+		bundle.putString("module_name", function_name);
+
+//		Log.e("findFragmentByTag", "tag=" + tag + ", isnull= "
+//				+ (getSupportFragmentManager().findFragmentByTag(tag) == null));
+
+		f = getSupportFragmentManager().findFragmentById(tabmap.get(tag));
+		if (f == null)
+		{
+			Log.d("createTabContent", "create fragment" + tag);
+			f = new DetailFragment();
+
+			
+			f.setArguments(bundle);
+		}
+		((DetailFragment)f).set_content( contentmap.get(tag));
+		FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
+		ft.replace(fl.getId(), f);
+		ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
+		ft.addToBackStack(tag);
+		ft.commit();
+		return fl;
+	}
+
+	@Override
+	protected void onSaveInstanceState(Bundle outState)
+	{
+		outState.putSerializable("tabmap", tabmap);
+		outState.putSerializable("contentmap", contentmap);
+		super.onSaveInstanceState(outState);
+	}
+
+	// TabHost mTabHost;
+	// private FrameLayout mTabContent;
+	
+//	@Override
+//	public boolean onKeyDown(int keyCode, KeyEvent event)
+//	{
+//		if (keyCode == KeyEvent.KEYCODE_BACK)
+//		{
+//			// Intent myIntent = new Intent();
+//			// myIntent = new Intent(EditActivity.this, tabActivity.class);
+//			// startActivity(myIntent);
+//			finish();
+//			return true;
+//		}
+//		return super.onKeyDown(keyCode, event);
+//	}
+
+	@Override
+	public boolean onKeyUp(int keyCode, KeyEvent event)
+	{
+		if (keyCode == KeyEvent.KEYCODE_BACK)
+		{
+			// Intent myIntent = new Intent();
+			// myIntent = new Intent(EditActivity.this, tabActivity.class);
+			// startActivity(myIntent);
+			finish();
+			return true;
+		}
+		return super.onKeyUp(keyCode, event);
+	}
+	//
+	// @Override
+	// protected void onCreate(Bundle savedInstanceState)
+	// {
+	// super.onCreate(savedInstanceState);
+	// setContentView(R.layout.activity_detail);
+	// // Show the Up button in the action bar.
+	// setupActionBar();
+	// setupTabs();
+	// }
+	//
+	// /**
+	// * Set up the {@link android.app.ActionBar}.
+	// */
+	// private void setupActionBar()
+	// {
+	//
+	// getActionBar().setDisplayHomeAsUpEnabled(true);
+	//
+	// }
+	//
+	// // private View createTabIndicatorView(ViewGroup parent, CharSequence
+	// label, Drawable icon) {
+	// // final LayoutInflater inflater = LayoutInflater.from(this);
+	// // final View tabIndicator = inflater.inflate(R.layout.tab_indicator,
+	// parent, false);
+	// //
+	// //// final TextView tv = (TextView)
+	// tabIndicator.findViewById(R.id.tab_title);
+	// //// tv.setText(label);
+	// ////
+	// //// final ImageView iconView = (ImageView)
+	// tabIndicator.findViewById(R.id.tab_icon);
+	// //// iconView.setImageDrawable(icon);
+	// //
+	// // return tabIndicator;
+	// // }
+	//
+	// @Override
+	// public View createTabContent(String tag)
+	// {
+	// final TextView tv = new TextView(this);
+	// tv.setText("Content for tab with tag " + tag);
+	// return tv;
+	// }
+	private void setupTabs()
+	{
+		mTabHost = (TabHost) findViewById(R.id.tabhost);
+		// mTabContent = (FrameLayout) findViewById(android.R.id.tabcontent);
+		// FrameLayout tab1 = new FrameLayout(this);
+		mTabHost.setup();
+
+		Iterator<String> iter = tabmap.keySet().iterator();
+		while (iter.hasNext())
+		{
+			String name = (String) iter.next();
+			mTabHost.addTab(mTabHost.newTabSpec(name).setIndicator(name)
+					.setContent(this));
+			// String val = (String) tabmap.get(field);
+			// parms.putString(field, val);
+			// // Cursor c = (Cursor) m_listadapter.getItem(key);
+			// Log.d("@@@@@@@@@", field + " : " + val);
+		}
+
+
+		TabWidget tabWidget=mTabHost.getTabWidget();
+		for (int i = 0; i < tabWidget.getChildCount(); i++) {
+
+			tabWidget.getChildAt(i).getLayoutParams().height = commonUtil.dp2px(this,39);
+			tabWidget.getChildAt(i).setPadding(24,0,24,0);
+//			tabWidget.getChildAt(i).getLayoutParams().height = 60;
+			TextView tv=(TextView)tabWidget.getChildAt(i).findViewById(android.R.id.title);
+//			tv.setGravity(BIND_AUTO_CREATE);
+//			tv.setPadding(10, 10,10, 10);
+			tv.setTextSize(12);//设置字体的大小;
+//			tv.setTextColor(Color.WHITE);//设置字体的颜色;
+//获取tabs图片;
+//			ImageView iv=(ImageView)tabWidget.getChildAt(i).findViewById(android.R.id.icon);
+		}
+
+		// for (int i=1; i <= tabmap.size(); i++) {
+		// String name = tabmap.keySet().iterator().;
+		// mTabHost.addTab(mTabHost.newTabSpec(name)
+		// .setIndicator(name)
+		// .setContent(this));
+		// }
+		// // if(true)
+		// // return;
+		//
+		// // View tab1 = createTabIndicatorView(mTabHost.getTabWidget(),
+		// // "Login",null);
+		// // tabhost.addTab(
+		// // tabhost.newTabSpec("tab" + i).setIndicator(tab)
+		// // .setContent(Mytabfirst.this)); tabhost.setCurrentTab(i);
+		// // i++; tab = null;
+		//
+		// // // ��ɵײ��Զ�����ʽ�İ�ť
+		// // String[] title = new String[] { "Login", "Not login" };
+		// // int[] tabIds = new int[] { R.id.tab1, R.id.tab2 };
+		// mTabHost.addTab(mTabHost.newTabSpec("Login").setIndicator("Login")
+		// .setContent(this));
+		// //
+		// mTabHost.addTab(mTabHost.newTabSpec("Direct Tracking").setIndicator("Direct Tracking").setContent(R.id.tab2));
+		// mTabHost.addTab(mTabHost.newTabSpec("Service Location")
+		// .setIndicator("Service Location").setContent(this));
+
+		// FragmentManager manager = this.getFragmentManager();
+
+		// Instantiate a new fragment.
+		// Fragment loginFragment = new LoginFragment();
+		// // Fragment dtFragement = new DirectTrackingFragment();
+		// Fragment slFragment = new ServiceLocationFragment();
+		// // Add the fragment to the activity, pushing this transaction
+		// // on to the back stack.
+		//
+		// FragmentTransaction ft =
+		// getSupportFragmentManager().beginTransaction();
+		// ft.replace(mTabHost.getTabContentView().getChildAt(0).getId(),
+		// loginFragment);
+		// ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
+		// ft.addToBackStack("Login");
+		//
+		// // ft.replace(R.id.tab2, dtFragement);
+		// // ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
+		// // ft.addToBackStack("Tracking");
+		//
+		// ft.replace(R.id.tab3, (Fragment) slFragment);
+		// ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
+		// ft.addToBackStack("Location");
+		//
+		// ft.commit();
+
+		// if (manager.findFragmentByTag(tabId) == null)
+		// {
+		// FragmentTransaction trans = manager.beginTransaction();
+		// trans.replace(contentViewID, frag, tabId);
+		// trans.commit();
+		// }
+		// for (int i = 0; i < title.length; i++) {
+		// Button button = new Button(this);
+		// button.setText(title[i]);
+		// button.setBackgroundDrawable(this.getResources().getDrawable(
+		// R.drawable.tab_lable)); //�Զ��尴ť��ʽ
+		// mTabHost.addTab(mTabHost.newTabSpec(title[i]).setIndicator(button)
+		// .setContent(tabIds[i]));
+		// }
+
+		// mTabHost.setOnTabChangedListener(this);
+	}
+
+	@Override
+	public boolean onCreateOptionsMenu(Menu menu)
+	{
+		// Inflate the menu; this adds items to the action bar if it is present.
+
+		if (function_name.equals("Cargo Tracking")) {
+			getMenuInflater().inflate(R.menu.cargo_menu, menu);
+		} else {
+			getMenuInflater().inflate(R.menu.detail, menu);
+		}
+		return true;
+	}
+
+	@Override
+	public boolean onOptionsItemSelected(MenuItem item)
+	{
+		switch (item.getItemId())
+		{
+			case R.id.action_close:
+
+				finish();
+//				if (SearchResultActivity.instance != null) {
+//					SearchResultActivity.instance.finish();
+//				}
+//				if (SearchListActivity.instance != null) {
+//					SearchListActivity.instance.finish();
+//				}
+				Intent intent = new Intent(this, RootActivity.class);
+
+//                Intent intent = new Intent(context, LoginView.class);
+                intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+
+
+				startActivity(intent);
+				break;
+			case android.R.id.home:
+				finish();
+				break;
+			case R.id.action_addto_favorite:
+//	            LayoutInflater factory = LayoutInflater.from(this);
+//	            final View textEntryView = factory.inflate(R.layout.alert_dialog_text_entry, null);
+	            final View edit = new EditText(this);
+	             new AlertDialog.Builder(this)
+	                .setIconAttribute(android.R.attr.alertDialogIcon)
+	                .setTitle(R.string.str_createname)
+	                .setView(edit)
+	                .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+	                    public void onClick(DialogInterface dialog, int whichButton) {
+                            String name = ((EditText)edit).getText().toString();
+                            if(TextUtils.isEmpty(name))
+                            {
+                                new android.app.AlertDialog.Builder(DetailActivity.this)
+                                        .setTitle("Warning")
+                                        .setMessage("Name can not be empty.")
+
+                                        .setPositiveButton("OK", new DialogInterface.OnClickListener() {
+                                            @Override
+                                            public void onClick(DialogInterface dialog, int which) {
+
+                                            }
+                                        })
+                                        .show();
+                                return;
+                            }
+
+	                    	String param = getIntent().toUri(0);
+
+	        				SQLiteDatabase db = dbUtil.OpenDB(
+	        						ApexTrackingApplication.get_instance(), null, true);
+	        				db.execSQL("insert into favorites(name,params,user,create_time,module_name) values('"
+	        						+ name
+	        						+ "','"
+	        						+ param
+	        						+ "','"
+	        						+ ApexTrackingApplication.get_user()
+	        						+ "',"
+	        						+ System.currentTimeMillis()
+									+ ",'"
+									+getIntent().getStringExtra("function_name")+ "')");
+	        				dbUtil.CloseDB(db);
+
+	                        /* User clicked OK so do some stuff */
+	                    }
+	                })
+	                .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
+	                    public void onClick(DialogInterface dialog, int whichButton) {
+
+	                        /* User clicked cancel so do some stuff */
+	                    }
+	                })
+	                .create().show();
+	             return true;
+
+			case R.id.action_search_document: {
+				String cargo_str = contentmap.get("Tracking");
+				try {
+					JSONObject cargo_json = new JSONObject(cargo_str);
+					String hbol = cargo_json.optString("hbol");
+					if (hbol != null && hbol.length() > 0) {
+
+						Bundle parms = new Bundle();
+						parms.putString("bol",hbol);
+						parms.putString("module_name","Download Document");
+						Intent resultIntent = new Intent(this, AMResultActivity.class);
+						resultIntent.putExtra("query_params",parms);
+						startActivity(resultIntent);
+
+					} else {
+						showAlter("There is no hbol to search");
+					}
+
+				} catch (JSONException e) {
+					e.printStackTrace();
+					showAlter("There is no hbol to search");
+				}
+
+			}
+			break;
+
+			case R.id.action_share_detail: {
+
+				Intent share = new Intent();
+				share.setAction(Intent.ACTION_SEND);
+//				share.putExtra(Intent.EXTRA_STREAM, uri);
+				share.setType("text/plain");
+
+
+
+
+				if (email_content != null) {
+					share.putExtra(Intent.EXTRA_TEXT, email_content);   //附带的说明信息
+				}
+				if (email_subject != null) {
+					share.putExtra(Intent.EXTRA_SUBJECT, email_subject);
+				}
+				if (email_to != null) {
+					share.putExtra(Intent.EXTRA_EMAIL, email_to.split(","));
+				}
+
+//        share.putExtra(Intent.EXTRA_CC, new String[]{"ray.zhang@united-cn.net"});
+//        startActivity(Intent.createChooser(share,getString(R.string.str_sendto)));
+				startActivity(Intent.createChooser(share, "Share"));
+			}
+			break;
+		}
+		return super.onOptionsItemSelected(item);
+	}
+
+	public void showAlter(String msg) {
+		new AlertDialog.Builder(this)
+				.setMessage(msg)
+				.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
+					@Override
+					public void onClick(DialogInterface dialogInterface, int i) {
+
+					}
+				})
+				.show();
+	}
+
+}

+ 1726 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/DetailFragment.java

@@ -0,0 +1,1726 @@
+package com.usai.apex;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.app.AlertDialog;
+import android.app.ProgressDialog;
+import android.content.ClipboardManager;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.database.Cursor;
+import android.graphics.Bitmap;
+import android.graphics.Color;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Build;
+import android.os.Bundle;
+import android.provider.ContactsContract;
+import android.support.constraint.ConstraintLayout;
+import android.support.v4.app.Fragment;
+import android.text.Editable;
+import android.text.Html;
+import android.text.TextWatcher;
+import android.util.Log;
+import android.util.SparseIntArray;
+import android.view.GestureDetector;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.webkit.WebResourceRequest;
+import android.webkit.WebResourceResponse;
+import android.webkit.WebView;
+import android.webkit.WebViewClient;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.ImageButton;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
+import android.widget.ScrollView;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.usai.apex.ShipMap.ShipMap;
+import com.usai.apex.mainframe.NewDetailActivity;
+import com.usai.apex.pdf.PDFPreviewActivity;
+import com.usai.util.Network;
+import com.usai.util.RAUtil;
+import com.usai.util.commonUtil;
+
+import org.apache.http.util.EncodingUtils;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.InputStream;
+import java.util.regex.Pattern;
+
+public class DetailFragment extends Fragment implements OnClickListener, ShipMap.ShipMapListener /*
+																		 * ,
+																		 * OnGestureListener
+																		 */
+{
+
+	private static final int People_Pick_Code = 1357;
+
+	private String copiedKey;
+	private String copiedVal;
+	private View touchedView;
+
+	@Override
+	public void shipMapTryToZoomIn(ShipMap shipMap, boolean zoomIn) {
+
+		if (zoomIn) {
+
+			LinearLayout.LayoutParams lfLayoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0);
+			mDetailContainer.setLayoutParams(lfLayoutParams);
+
+		} else {
+
+			LinearLayout.LayoutParams lfLayoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0,2.0f);
+			mDetailContainer.setLayoutParams(lfLayoutParams);
+		}
+
+		mMapZoomIn = zoomIn;
+
+	}
+
+	private class GestureListener extends GestureDetector.SimpleOnGestureListener {
+
+		@Override
+		public boolean onDoubleTapEvent(MotionEvent e) {
+
+
+			if (e.getAction() == MotionEvent.ACTION_UP) {
+
+				if (touchedView == null) {
+
+					ClipboardManager cm = (ClipboardManager) getActivity().getSystemService(Context.CLIPBOARD_SERVICE);
+					cm.setText(copiedVal);
+
+					Toast.makeText(mContext, "Copied " + copiedKey, Toast.LENGTH_LONG).show();
+				} else {
+
+					String type = (String) touchedView.getTag();
+					if (type.equals("tracking")) {
+
+						TextView tvgroup = (TextView) touchedView.findViewById(R.id.tv_group);
+
+						if (tvgroup != null) {
+
+							String val = tvgroup.getText().toString();
+							ClipboardManager cm = (ClipboardManager) getActivity().getSystemService(Context.CLIPBOARD_SERVICE);
+							cm.setText(val);
+
+							Toast.makeText(mContext, "Copied " + val, Toast.LENGTH_LONG).show();
+						}
+					}
+				}
+			}
+
+			copiedKey = null;
+			copiedVal = null;
+			touchedView = null;
+
+			return false;
+		}
+
+		@Override
+		public boolean onSingleTapConfirmed(MotionEvent e) {
+
+			if (touchedView != null) {
+				onClick(touchedView);
+			}
+			touchedView = null;
+
+			return false;
+		}
+	}
+
+	private static final int	REQUEST_LOGINACTIVITY	= 1;
+
+	// DataFragment mdataFragment;
+
+	Context mContext;
+	ProgressDialog progressDialog;
+	private GestureDetector detector;
+
+	protected void showProgressDialog(final String title, final String msg) {
+
+		getActivity().runOnUiThread(new Runnable() {
+			@Override
+			public void run() {
+				try {
+					progressDialog.setTitle(title);
+					progressDialog.setMessage(msg);
+					progressDialog.show();
+				} catch (Exception e) {
+					e.printStackTrace();
+				}
+			}
+		});
+
+	}
+
+	/* private GestureDetector mGestureDetector; */
+	@Override
+	public void onCreate(Bundle savedInstanceState)
+	{
+		// TODO Auto-generated method stub
+		super.onCreate(savedInstanceState);
+
+		if (progressDialog == null) {
+			progressDialog = new ProgressDialog(mContext);
+			progressDialog.setCancelable(false);
+		}
+
+		if (detector == null) {
+			detector = new GestureDetector(mContext, new GestureListener());
+		}
+
+	}
+
+//	@Override
+//	public void onActivityCreated(@Nullable Bundle savedInstanceState) {
+//		super.onActivityCreated(savedInstanceState);
+//
+//		progressDialog = new ProgressDialog(mContext);
+//		progressDialog.setCancelable(false);
+//	}
+
+	@Override
+	public void onAttach(Context context) {
+		super.onAttach(context);
+		mContext = context;
+	}
+
+	@Override
+	public void onDestroyView()
+	{
+		Log.d("DetailFragment", "onDestroyView()");
+		super.onDestroyView();
+	}
+
+	// public String get_content()
+	// {
+	// return fragment_content;
+	// }
+
+	LinearLayout		ll_root;
+	ScrollView			sl_root;
+	String				mimeType			= "text/html";
+	private SearchTask	m_task				= null;
+	SparseIntArray		control				= new SparseIntArray();
+	// private TextView mStatusMessageView;
+	private View		mStatusView;
+
+	String				fragment_content	= null;
+
+	public void requestdata()
+	{
+
+		if (m_task != null)
+		{
+			return;
+		}
+		if (fragment_content != null)
+		{
+			LayoutInflater inflater = (LayoutInflater) ApexTrackingApplication
+					.get_instance().getSystemService(
+							Context.LAYOUT_INFLATER_SERVICE);
+			init(fragment_content, inflater);
+			return;
+		}
+		// if (mdataFragment.get_result() != null) {
+		// LayoutInflater inflater = (LayoutInflater) ApexTrackingApplication
+		// .get_instance().getSystemService(
+		// Context.LAYOUT_INFLATER_SERVICE);
+		// init(mdataFragment.get_result(), inflater);
+		// }
+		// if (fragment_content != null)
+		// return;
+		// mStatusMessageView.setText("Loading");
+		showProgress(true);
+		m_task = new SearchTask();
+		m_task.execute();
+
+	}
+
+	public void set_content(String content)
+	{
+		fragment_content = content;
+	}
+
+	private void showProgress(final boolean show)
+	{
+		// On Honeycomb MR2 we have the ViewPropertyAnimator APIs, which allow
+		// for very easy animations. If available, use these APIs to fade-in
+		// the progress spinner.
+		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2)
+		{
+			int shortAnimTime = ApexTrackingApplication.get_instance()
+					.getResources()
+					.getInteger(android.R.integer.config_shortAnimTime);
+
+			mStatusView.setVisibility(View.VISIBLE);
+			mStatusView.animate().setDuration(shortAnimTime)
+					.alpha(show ? 1 : 0)
+					.setListener(new AnimatorListenerAdapter()
+					{
+						@Override
+						public void onAnimationEnd(Animator animation)
+						{
+							mStatusView.setVisibility(show ? View.VISIBLE
+									: View.INVISIBLE);
+						}
+					});
+
+			ll_root.setVisibility(View.VISIBLE);
+			ll_root.animate().setDuration(shortAnimTime).alpha(show ? 0 : 1)
+					.setListener(new AnimatorListenerAdapter()
+					{
+						@Override
+						public void onAnimationEnd(Animator animation)
+						{
+							ll_root.setVisibility(show ? View.INVISIBLE
+									: View.VISIBLE);
+						}
+					});
+		}
+		else
+		{
+			// The ViewPropertyAnimator APIs are not available, so simply show
+			// and hide the relevant UI components.
+			mStatusView.setVisibility(show ? View.VISIBLE : View.INVISIBLE);
+			ll_root.setVisibility(show ? View.INVISIBLE : View.VISIBLE);
+		}
+	}
+
+	// @Override
+	// public void onActivityCreated(Bundle savedInstanceState)
+	// {
+	// FragmentManager fm = getFragmentManager();
+	//
+	// // Check to see if we have retained the worker fragment.
+	// mdataFragment = (DataFragment)fm.findFragmentByTag("work");
+	//
+	// // If not retained (or first time running), we need to create it.
+	// if (mdataFragment == null) {
+	// mdataFragment = new DataFragment();
+	// // Tell it who it is working with.
+	// mdataFragment.setTargetFragment(this, 0);
+	// fm.beginTransaction().add(mdataFragment, "work").commit();
+	// }
+	// super.onActivityCreated(savedInstanceState);
+	// }
+
+	private ShipMap mTrackingMap;
+
+
+
+	@Override
+	public void onSaveInstanceState(Bundle outState) {
+		super.onSaveInstanceState(outState);
+
+		if (mContent != null) {
+			outState.putString("content",mContent.toString());
+		}
+		outState.putInt("selectContactPosition",mSelectContactPosition);
+		outState.putInt("selectTrackingPosition",mSelectTrackingPosition);
+		outState.putInt("selectTrackingChild",mSelectTrackingChild);
+		outState.putBoolean("mapZoomIn",mMapZoomIn);
+	}
+
+	private void configureMap(ShipMap map) {
+		if (map == null) {
+			return;
+		}
+
+		map.setShowCurrent(true);
+		map.setShowDestination(true);
+		map.setShowOrigin(true);
+		map.setShowPor(true);
+		map.setShowPoe(true);
+		map.setShowPod(true);
+		map.setShowPol(true);
+
+		map.setShipMapListener(this);
+	}
+
+	private RelativeLayout mDetailContainer;
+	private boolean mMapZoomIn = false;
+
+	@Override
+	public View onCreateView(LayoutInflater inflater, ViewGroup container,
+			Bundle savedInstanceState)
+	{
+
+
+		final Context context = getContext();
+		/* mGestureDetector = new GestureDetector(this); */
+
+		View view = null;
+
+		if(this.getArguments().getString("action_type").equals("Tracing")||this.getArguments().getString("action_type").equals("Tracking")) {
+			view = inflater.inflate(R.layout.detail_fragment_withmap, null);
+			mTrackingMap = view.findViewById(R.id.tracking_map);
+			configureMap(mTrackingMap);
+			mDetailContainer = view.findViewById(R.id.detail_list_container);
+		} else {
+			view = inflater.inflate(R.layout.detail_fragment, null);
+			mTrackingMap = null;
+		}
+
+		if (savedInstanceState != null) {
+			fragment_content = savedInstanceState.getString("content");
+			mSelectContactPosition = savedInstanceState.getInt("selectContactPosition");
+			mSelectTrackingPosition = savedInstanceState.getInt("selectTrackingPosition");
+			mSelectTrackingChild = savedInstanceState.getInt("selectTrackingChild");
+			mMapZoomIn = savedInstanceState.getBoolean("mapZoomIn");
+		}
+
+		if (mTrackingMap != null) {
+			mTrackingMap.setZoomIn(mMapZoomIn);
+		}
+
+//		if(this.getArguments().getString("action_type").equals("Tracing"))
+//		{
+//			LinearLayout ll1 = view.findViewById(R.id.detail_linear);
+//
+//			ShipMap shipMap = new ShipMap(context);
+////		mShipMap = shipMap;
+//
+//
+//			LinearLayout.LayoutParams mapLayoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0,1.0f);
+//			mapLayoutParams.setMargins(commonUtil.dp2px(context,5),commonUtil.dp2px(context,2),commonUtil.dp2px(context,5),commonUtil.dp2px(context,2));
+//
+//			ll1.addView(shipMap,mapLayoutParams);
+//
+//		}
+
+
+
+
+		sl_root = (ScrollView) view.findViewById(R.id.sl_root);
+		/*
+		 * sl_root.setOnTouchListener(new View.OnTouchListener() {
+		 * 
+		 * @Override public boolean onTouch(View v, MotionEvent event) { return
+		 * mGestureDetector.onTouchEvent(event); } });
+		 */
+		ll_root = (LinearLayout) view.findViewById(R.id.ll_root);
+		mStatusView = view.findViewById(R.id.status);
+		LinearLayout ll = (LinearLayout) view.findViewById(R.id.ll_refresh);
+		Button btn_refresh = (Button) ll.findViewById(R.id.btn_refresh);
+		btn_refresh.setOnClickListener(new View.OnClickListener()
+		{
+
+			@Override
+			public void onClick(View v)
+			{
+				LinearLayout ll = (LinearLayout) ll_root
+						.findViewById(R.id.ll_refresh);
+				ll.setVisibility(View.GONE);
+
+				requestdata();
+
+			}
+		});
+		// FragmentManager fm = getFragmentManager();
+		// List<Fragment> fragments = fm.getFragments();
+		// if (fragments != null) {
+		// Log.e("DetailFragment", "fragments count=" + fragments.size());
+		// // for (int i = 0; i < fragments.size(); i++)
+		// // Log.e("DetailFragment", "fragments name=" + fragments.size());
+		//
+		// }
+		// // this.getFragmentManager();
+		// String tag = getArguments().getString("module_name");
+		// // Check to see if we have retained the worker fragment.
+		// mdataFragment = (DataFragment) fm.findFragmentById(12345);
+		//
+		// // If not retained (or first time running), we need to create it.
+		// if (mdataFragment == null) {
+		// Log.e("dataFragment creaded ", "tag=data_" + tag);
+		// mdataFragment = new DataFragment();
+		// // Tell it who it is working with.
+		// mdataFragment.setTargetFragment(this, 0);
+		// fm.beginTransaction().add(12345,mdataFragment, "data+" +
+		// tag).commit();
+		// }
+		requestdata();
+		return view;
+	}
+
+	protected JSONObject loadfakecontent(int rawid)
+	{
+
+		String jstring = "";
+		try
+		{
+			InputStream in = getResources().openRawResource(rawid);
+			// 获取文件的字节数
+			int lenght = in.available();
+			// 创建byte数组
+			byte[] buffer = new byte[lenght];
+			// 将文件中的数据读到byte数组中
+			in.read(buffer);
+			jstring = EncodingUtils.getString(buffer, "UTF-8");
+			JSONObject jsobj = new JSONObject(jstring);
+			return jsobj;
+//            JSONObject objrecords = jsobj.getJSONObject("records");
+		}
+		catch (Exception e)
+		{
+			e.printStackTrace();
+		}
+		return null;
+
+	}
+
+	public JSONObject mContent;
+
+	private int mSelectContactPosition = -1;
+	private int mSelectTrackingPosition = -1;
+	private int mSelectTrackingChild = -1;
+	private View mSelectedTrackingCell = null;
+
+	private void selectLocation(View view,int group,int child,JSONObject location) {
+
+		if (mSelectedTrackingCell != null) {
+			mSelectedTrackingCell.setBackgroundColor(Color.WHITE);
+		}
+
+		mSelectTrackingPosition = group;
+		mSelectTrackingChild = child;
+		mSelectedTrackingCell = view;
+
+		if (mSelectedTrackingCell != null) {
+			mSelectedTrackingCell.setBackgroundColor(Color.LTGRAY);
+		}
+
+		if (mTrackingMap != null && location != null) {
+			mTrackingMap.showShipAnnotation(location);
+		}
+
+	}
+
+	void init(String jstr, LayoutInflater inflater)
+	{
+//		LayoutInflater inflater = (LayoutInflater) ApexTrackingApplication
+//				.get_instance().getSystemService(
+//						Context.LAYOUT_INFLATER_SERVICE);
+
+		inflater=getActivity().getLayoutInflater();
+
+
+		String TAG = "init@DetailFragment";
+		Log.d(TAG, jstr);
+		try
+		{
+			JSONObject jsonObj = new JSONObject(jstr);
+
+			int group_count = jsonObj.getInt("count");
+
+//			if (getArguments().getString("action_type").equals("Detail")) {
+//				JSONObject commObj = loadfakecontent(R.raw.fake_comm);
+//				jsonObj.put("group" + group_count++,commObj);
+//				jsonObj.put("count",group_count);
+//			}
+
+
+
+			mContent = jsonObj;
+
+			if (group_count == 0)
+			{
+
+				TextView tv_empty = (TextView) ll_root
+						.findViewById(R.id.tv_empty);
+				tv_empty.setVisibility(View.VISIBLE);
+
+
+				NewDetailActivity activity = (NewDetailActivity) getActivity();
+				int tabCount = activity.getTabCount();
+
+				if(tabCount==1)
+				{
+					new AlertDialog.Builder(getContext())
+							.setTitle("Warning")
+							.setCancelable(false)
+							.setMessage("No Search Result.")
+							.setPositiveButton("Back", new DialogInterface.OnClickListener() {
+								@Override
+								public void onClick(DialogInterface dialog, int which) {
+									getActivity().finish();
+//                                checkAllPermission();
+//								if (finalRequest)
+//									checkAllPermission();
+//								else
+//									finish();
+								}
+							})
+//                    .setNegativeButton("No", new DialogInterface.OnClickListener() {
+//                        @Override
+//                        public void onClick(DialogInterface dialog, int which) {
+//                            finish();
+//                        }
+//                    })
+							.show();
+				}
+
+			}
+			for (int i = 0; i < group_count; i++)
+			{
+				// String key = (String) it.next();
+				// if (key.equals("result"))
+				// continue;
+				final JSONObject groupobj = jsonObj.getJSONObject("group" + i);
+				View v = inflater.inflate(R.layout.group_tag, null);
+//				v.setOnClickListener(this);
+
+
+				TextView tvgroup = (TextView) v.findViewById(R.id.tv_group);
+				String group_name = groupobj.getString("_name");
+				tvgroup.setText(group_name);
+				v.setId(commonUtil.generateViewId());
+				ll_root.addView(v);
+				String grouptype = groupobj.getString("_type");
+
+				v.setTag(grouptype);
+				v.setOnTouchListener(new View.OnTouchListener() {
+					@Override
+					public boolean onTouch(View view, MotionEvent motionEvent) {
+
+						touchedView = view;
+						detector.onTouchEvent(motionEvent);
+
+						return true;
+					}
+				});
+
+
+				// groupobj.remove("_type");
+				if (grouptype.equals("mapping"))
+				{
+					LinearLayout mappingview = (LinearLayout) inflater.inflate(
+							R.layout.key_mapping, null);
+					mappingview.setId(commonUtil.generateViewId());
+					control.put(v.getId(), mappingview.getId());
+					ll_root.addView(mappingview);
+
+					int map_count = groupobj.getInt("count");
+					for (int j = 0; j < map_count; j++)
+					{
+						// String keygroup = (String) itgroup.next();
+						JSONObject itemobj = groupobj.getJSONObject("item" + j);
+						final String key = (String) itemobj.keys().next();
+						final String val = itemobj.getString(key);
+						LinearLayout mappingitem = (LinearLayout) inflater
+								.inflate(R.layout.keymapping_item, null);
+						TextView tvkey = (TextView) mappingitem
+								.findViewById(R.id.tv_key);
+						tvkey.setText(key);
+						// tvkey.setBackgroundResource(R.drawable.detail_item);
+						TextView tvval = (TextView) mappingitem
+								.findViewById(R.id.tv_value);
+						tvval.setText(Html.fromHtml(val));
+						// tvval.setBackgroundResource(R.drawable.detail_item);
+
+						tvval.setOnTouchListener(new View.OnTouchListener() {
+							@Override
+							public boolean onTouch(View view, MotionEvent motionEvent) {
+
+								copiedKey = key;
+								copiedVal = val;
+								detector.onTouchEvent(motionEvent);
+
+								return true;
+							}
+						});
+
+						mappingview.addView(mappingitem);
+					}
+					// Iterator itgroup = groupobj.keys();
+					// while (itgroup.hasNext())
+					// {
+					//
+					//
+					// }
+				}
+				else if (grouptype.equals("table"))
+				{
+					String content = groupobj.getString("content");
+					WebView wv;
+
+					wv = (WebView) inflater.inflate(R.layout.web_content, null);
+
+					wv.getSettings().setDefaultTextEncodingName("UTF-8");
+					wv.setId(commonUtil.generateViewId());
+					wv.setWebViewClient(new MyWebViewClient());
+//					wv.setDownloadListener(new DownloadListener()
+//					{
+//
+//						@Override
+//						public void onDownloadStart(String url,
+//								String userAgent, String contentDisposition,
+//								String mimetype, long contentLength)
+//						{
+//							if(!commonUtil.localdirExist())
+//							{
+//
+//								new AlertDialog.Builder(getActivity())
+//				                .setIconAttribute(android.R.attr.alertDialogIcon)
+//				                .setTitle(R.string.str_localdir_error)
+//				                .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+//				                    public void onClick(DialogInterface dialog, int whichButton) {
+//
+//				                        /* User clicked OK so do some stuff */
+//				                    }
+//				                })
+//				                .create().show();
+//								return;
+//							}
+////							String filename = contentDisposition.replace("attachment;filename=\"", "");
+////							filename = filename.replace("\"", "");
+////
+////							Log.d("WebView", "Download Action");
+////							Log.d("tag", "url=" + url);
+////							// Log.i("tag", "userAgent="+userAgent);
+////							// Log.i("tag",
+////							// "contentDisposition="+contentDisposition);
+////							// Log.i("tag", "mimetype="+mimetype);
+////							// Log.i("tag", "contentLength="+contentLength);
+////							// Uri uri = Uri.parse(url);
+////							// Intent intent = new Intent(Intent.ACTION_VIEW,
+////							// uri);
+////							// startActivity(intent);
+////
+////							final DownloadManager downloadManager = (DownloadManager) ApexTrackingApplication
+////									.get_instance().getSystemService(
+////											Context.DOWNLOAD_SERVICE);
+////
+////							Uri uri = Uri.parse(url);
+////							final Request request = new Request(uri);
+////
+////							// 设置允许使用的网络类型,这里是移动网络和wifi都可以
+////							request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE
+////									| DownloadManager.Request.NETWORK_WIFI);
+////
+////
+////
+////							request.setDestinationInExternalPublicDir("Apex Mobile",filename);
+////
+////							// 禁止发出通知,既后台下载,如果要使用这一句必须声明一个权限:android.permission.DOWNLOAD_WITHOUT_NOTIFICATION
+////							// request.setShowRunningNotification(false);
+////
+////							// 不显示下载界面
+////							request.setVisibleInDownloadsUi(false);
+////							request.setNotificationVisibility(Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
+////
+////							/*
+////							 * 设置下载后文件存放的位置,如果sdcard不可用,那么设置这个将报错,
+////							 * 因此最好不设置如果sdcard可用,下载后的文件 在/mnt/sdcard/Android/
+////							 * data/packageName/files目录下面
+////							 * ,如果sdcard不可用,设置了下面这个将报错,不设置,下载后的文件在/cache这个 目录下面
+////							 */
+////							// request.setDestinationInExternalFilesDir(this,
+////							// null, "tar.apk");
+////
+//////							getActivity();
+////							AlertDialog.Builder builder = new Builder(
+////									getActivity());
+////							builder.setMessage(getString(R.string.str_downloadmessage));
+////
+////							builder.setTitle(getString(R.string.str_confirmdownload));
+////
+////							builder.setPositiveButton(
+////									getString(R.string.str_download),
+////									new Dialog.OnClickListener()
+////									{
+////
+////										@Override
+////										public void onClick(
+////												DialogInterface dialog,
+////												int which)
+////										{
+////											downloadManager.enqueue(request);
+////											dialog.dismiss();
+////
+////										}
+////									});
+////
+////							builder.setNegativeButton(
+////									getString(R.string.str_cancel),
+////									new Dialog.OnClickListener()
+////									{
+////
+////										@Override
+////										public void onClick(
+////												DialogInterface dialog,
+////												int which)
+////										{
+////											dialog.dismiss();
+////										}
+////									});
+////
+////							builder.create().show();
+//
+//						}
+//
+//					});
+					wv.setTag(i);
+					control.put(v.getId(), wv.getId());
+					wv.loadData(content, mimeType, null);
+
+					// wv.setOnTouchListener(new OnTouchListener()
+					// {
+					// @Override
+					// public boolean onTouch(View v, MotionEvent event)
+					// {
+					//
+					// if (event.getAction() == MotionEvent.ACTION_UP)
+					// sl_root.requestDisallowInterceptTouchEvent(false);
+					// else
+					// sl_root.requestDisallowInterceptTouchEvent(true);
+					//
+					// return false;
+					// }
+					// });
+					ll_root.addView(wv);
+					Log.d("table content", content);
+
+				}
+				if (grouptype.equals("tracking"))
+				{
+					LinearLayout listview = (LinearLayout) inflater.inflate(
+							R.layout.list_content, null);
+
+					listview.setId(commonUtil.generateViewId());
+
+
+					ViewGroup.LayoutParams lp=listview.getLayoutParams();
+					control.put(v.getId(), listview.getId());
+					ll_root.addView(listview);
+					long list_count = groupobj.getInt("count");
+					for (int j = 0; j < list_count; j++)
+					{
+						final JSONObject itemobj = groupobj.getJSONObject("item" + j);
+
+						ConstraintLayout listitem = (ConstraintLayout) inflater
+								.inflate(R.layout.detail_tracking_cell, null);
+
+
+						ImageView icon = (ImageView)  listitem
+								.findViewById(R.id.iv_thumb);
+
+						String iconname = itemobj.getString("icon");
+						int rid = commonUtil.iconName2Rid(getActivity(),iconname);
+						icon.setImageResource(rid);
+						if(j!=0)
+						{
+							icon.setColorFilter(Color.GRAY);
+//							ColorMatrix matrix = new ColorMatrix();
+//							matrix.setSaturation(0);
+//							ColorMatrixColorFilter filter = new ColorMatrixColorFilter(matrix);
+//							icon..image.setColorFilter(filter);
+						}
+
+						TextView tvitem = (TextView) listitem
+								.findViewById(R.id.tv_title);
+						String val = itemobj.getString("msg");
+						tvitem.setText(val);
+
+						// tvitem.setBackgroundResource(R.drawable.detail_item);
+					//	listitem.removeView(tvitem);
+
+						int px=commonUtil.dp2px(getActivity(),56);
+						listitem.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, px, 1));
+						listview.addView(listitem);
+//						ViewGroup.LayoutParams lp1=listitem.getLayoutParams();
+
+						final int selectIndex = i;
+						final int child = j;
+						final JSONObject location = groupobj.optJSONObject("location");
+
+						listitem.setOnClickListener(new OnClickListener() {
+							@Override
+							public void onClick(View v) {
+
+//								if (mTrackingMap != null) {
+//									JSONObject location = groupobj.optJSONObject("location");
+//									if (location != null) {
+//										mTrackingMap.showShipAnnotation(location);
+//									}
+//									mSelectTrackingPosition = selectIndex;
+//								}
+
+								selectLocation(v,selectIndex,child,location);
+
+							}
+						});
+
+						if (mSelectTrackingPosition == -1) {
+							mSelectTrackingPosition = selectIndex;
+						}
+						if (mSelectTrackingChild == -1) {
+							mSelectTrackingChild = 0;
+						}
+
+						if (mSelectTrackingPosition == selectIndex && mSelectTrackingChild == child) {
+
+//							if (mTrackingMap != null) {
+//								JSONObject location = groupobj.optJSONObject("location");
+//								if (location != null) {
+//									mTrackingMap.showShipAnnotation(location);
+//								}
+//							}
+
+							selectLocation(listitem,selectIndex,child,location);
+						}
+
+					}
+
+				}
+				if (grouptype.equals("list"))
+				{
+					LinearLayout listview = (LinearLayout) inflater.inflate(
+							R.layout.list_content, null);
+					listview.setId(commonUtil.generateViewId());
+					control.put(v.getId(), listview.getId());
+					ll_root.addView(listview);
+					long list_count = groupobj.getInt("count");
+					for (int j = 0; j < list_count; j++)
+					{
+						RelativeLayout listitem = (RelativeLayout) inflater
+								.inflate(R.layout.list_item, null);
+
+						TextView tvitem = (TextView) listitem
+								.findViewById(R.id.tv_item);
+						String val = groupobj.getString("line" + j);
+						tvitem.setText(val);
+						// tvitem.setBackgroundResource(R.drawable.detail_item);
+						listitem.removeView(tvitem);
+
+						listview.addView(tvitem);
+					}
+					// Iterator itgroup = groupobj.keys();
+					// while (itgroup.hasNext())
+					// {
+					// String keygroup = (String) itgroup.next();
+					//
+					// }
+				}
+				if (grouptype.equals("communication"))
+				{
+					LinearLayout listview = (LinearLayout) inflater.inflate(
+							R.layout.list_content, null);
+					listview.setId(commonUtil.generateViewId());
+					control.put(v.getId(), listview.getId());
+					ll_root.addView(listview);
+
+					// 添加收件人和cc
+					ConstraintLayout commu_header = (ConstraintLayout) inflater
+							.inflate(R.layout.commu_item_header, null);
+
+					TextView toTv = commu_header.findViewById(R.id.comm_to_tv);
+                    EditText ccTv = commu_header.findViewById(R.id.comm_cc_tv);
+					ImageButton contactBtn = commu_header.findViewById(R.id.comm_contact_btn);
+
+					ccTv.setTag("group_" + i + "_cc");
+
+                    String to = groupobj.optString("receipt");
+                    String cc = groupobj.optString("cc");
+
+                    toTv.setText(to);
+                    ccTv.setText(cc);
+
+                    TextFieldTextWatcher ccWatcher = new TextFieldTextWatcher(getContext(),ccTv,i,0);
+                    ccTv.addTextChangedListener(ccWatcher);
+
+                    final int selectIndex = i;
+                    contactBtn.setOnClickListener(new OnClickListener() {
+						@Override
+						public void onClick(View v) {
+
+							mSelectContactPosition = selectIndex;
+							Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
+							startActivityForResult(intent, People_Pick_Code);
+
+						}
+					});
+
+					listview.addView(commu_header);
+
+
+					long list_count = groupobj.getInt("count");
+					for (int j = 0; j < list_count; j++)
+					{
+						ConstraintLayout msgitem = (ConstraintLayout) inflater
+								.inflate(R.layout.commu_item_msg, null);
+
+						JSONObject msgObj = groupobj.getJSONObject("item" + j);
+
+						String sender = msgObj.optString("Sender");
+
+						String msg = msgObj.optString("msg");
+						String time = msgObj.optString("mst_time");
+						final String email_url = msgObj.optString("email_url");
+
+						TextView senderTv = msgitem.findViewById(R.id.comm_sender_tv);
+						TextView msgTv = msgitem.findViewById(R.id.comm_msg_tv);
+						TextView timeTv = msgitem.findViewById(R.id.comm_time_tv);
+						Button sendBtn = msgitem.findViewById(R.id.comm_send_msg_btn);
+
+						senderTv.setText(sender);
+//						msgTv.setText(msg);
+						msgTv.setText(Html.fromHtml(msg));
+						timeTv.setText(time);
+						sendBtn.setOnClickListener(new OnClickListener() {
+                            @Override
+                            public void onClick(View v) {
+
+
+								Uri content_url = Uri.parse(email_url);
+
+                            	Intent intent = new Intent(Intent.ACTION_VIEW,content_url);
+
+//								Intent intent = new Intent();
+//								intent.setAction("android.intent.action.VIEW");
+//								intent.setData(content_url);
+
+								startActivity(intent);
+                            }
+                        });
+
+						if (email_url == null || email_url.length() == 0) {
+							sendBtn.setVisibility(View.INVISIBLE);
+						}
+
+						listview.addView(msgitem);
+					}
+
+
+					//添加 消息输入和发送
+					ConstraintLayout commu_footer = (ConstraintLayout) inflater
+							.inflate(R.layout.commu_item_footer, null);
+
+					EditText editTv = commu_footer.findViewById(R.id.comm_edit_tv);
+					Button sendEmailBtn = commu_footer.findViewById(R.id.comm_send_email_btn);
+
+                    TextFieldTextWatcher editWatcher = new TextFieldTextWatcher(getContext(),editTv,i,1);
+                    editTv.addTextChangedListener(editWatcher);
+
+					String edit_content = groupobj.optString("edit_content");
+
+					editTv.setText(edit_content);
+
+					final int groupIndex = i;
+                    sendEmailBtn.setOnClickListener(new OnClickListener() {
+						@Override
+						public void onClick(View v) {
+
+							JSONObject commGroup = getGroup(groupIndex);
+							final String cc = commGroup.optString("cc");
+							final String content = commGroup.optString("edit_content");
+
+							if (content == null || content.length() == 0) {
+
+								new AlertDialog.Builder(mContext)
+										.setTitle("Warning")
+										.setMessage("The communication message that will be sent is blank")
+										.setPositiveButton("Ok",null)
+										.show();
+
+								return;
+							}
+
+							if (cc != null && cc.length() > 0) {
+
+								// 校验邮箱地址
+								String[] ccArr = cc.split(";");
+								for (int k = 0; k < ccArr.length; k++) {
+									String ccStr = ccArr[k];
+									if (ccStr.length() > 0) {
+										boolean isEmail = validateEmail(ccStr);
+										if (!isEmail) {
+
+											new AlertDialog.Builder(mContext)
+													.setTitle("Warning")
+													.setMessage("The communication cc is not right")
+													.setPositiveButton("Ok",null)
+													.show();
+
+											return;
+										}
+									}
+								}
+
+							}
+
+							// send
+							final ProgressDialog pd = new ProgressDialog(mContext);
+							pd.setTitle(null);
+							pd.setMessage("send email");
+							pd.setCancelable(false);
+							pd.show();
+
+							final String serialNo = commGroup.optString("serial_no");
+
+							new Thread(new Runnable() {
+								@Override
+								public void run() {
+
+									final JSONObject response = Network.sendEmail(content,cc,serialNo);
+
+									getActivity().runOnUiThread(new Runnable() {
+										@Override
+										public void run() {
+											pd.dismiss();
+
+											boolean showAlert = false;
+											String msg = null;
+											if (response != null) {
+												int result = response.optInt("result",Network.RESULT_FALSE);
+												if (result != Network.RESULT_TRUE) {
+													showAlert = true;
+													msg = response.optString("err_msg");
+												}
+
+
+											} else {
+												showAlert = true;
+											}
+
+											if (msg == null) {
+												msg = "Sorry,something wrong";
+											}
+
+											if (showAlert) {
+												new AlertDialog.Builder(mContext)
+														.setTitle(null)
+														.setMessage(msg)
+														.setPositiveButton("Ok",null)
+														.show();
+											}
+										}
+									});
+
+
+
+								}
+							}).start();
+
+						}
+					});
+
+					listview.addView(commu_footer);
+
+					listview.forceLayout();
+				}
+				// String value = obj.getString(key);
+				// JSONArray array = obj.getJSONArray(key);
+				// for(int i=0;i<array.length();i++){
+				// JSONObject jsonobject = array.getJSONObject(i);
+				// jsonobject.put("name", key);
+				// jsonobject.put("exp", key+"="+jsonobject.getString("value"));
+				// newArray.put(jsonobject);
+
+			}
+			// Iterator it = jsonObj.keys();
+			// while (it.hasNext())
+			// {
+			//
+			// }
+		}
+		catch (JSONException e)
+		{
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+
+	private JSONObject getGroup(int group) {
+		if (mContent != null) {
+			JSONObject groupobj = mContent.optJSONObject("group" + group);
+			return groupobj;
+		}
+		return null;
+	}
+
+	private boolean validateEmail(String email) {
+
+		String emailRegex = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}";
+
+		return Pattern.matches(emailRegex,email);
+	}
+
+	@Override
+	public void onClick(View v)
+	{
+		View view = ll_root.findViewById(control.get(v.getId()));
+		ImageView expand_iv = v.findViewById(R.id.group_expand_indicator);
+		if (view.getVisibility() == View.VISIBLE) {
+			expand_iv.setImageResource(R.drawable.ic_expand_less);
+			view.setVisibility(View.GONE);
+		}
+		else {
+			expand_iv.setImageResource(R.drawable.ic_expand_more);
+			view.setVisibility(View.VISIBLE);
+		}
+
+	}
+
+	@Override
+	public void onDestroy()
+	{
+		if (m_task != null)
+			m_task.cancel(true);
+		super.onDestroy();
+	}
+
+	@Override
+	public void onActivityResult(int requestCode, int resultCode, Intent data)
+	{
+//		((NewDetailActivity) getActivity()).showlogin = false;
+		super.onActivityResult(requestCode, resultCode, data);
+
+		if (requestCode == People_Pick_Code && data != null) {
+			Uri contactData = data.getData();
+			if (contactData == null) {
+				return;
+			}
+			Cursor c = mContext.getContentResolver().query(contactData, null, null, null, null);
+
+
+			if (c.moveToFirst()) {
+				String contactId = c.getString(c.getColumnIndex(ContactsContract.Contacts._ID));
+
+				Cursor cursor = mContext.getContentResolver().query(
+						ContactsContract.CommonDataKinds.Email.CONTENT_URI,
+						new String[]{ContactsContract.CommonDataKinds.Email.DATA, ContactsContract.CommonDataKinds.Email.TYPE}, ContactsContract.Data.CONTACT_ID + "='" + contactId + "'", null, null);
+
+				while(cursor.moveToNext()) {
+					String email = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
+					String emailType = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.TYPE));
+
+					email = email.replace("\r\n",";");
+					email = email.replace("\r",";");
+					email = email.replace("\n",";");
+
+					String[] emailArr = email.split(";");
+					for (int i = 0; i < emailArr.length; i++) {
+						email = emailArr[i];
+						if (email.length() > 0) {
+							if (emailType != null && Integer.valueOf(emailType) == ContactsContract.CommonDataKinds.Email.TYPE_WORK) {
+								appendContactEmail(email,mSelectContactPosition);
+								return;
+							}
+						}
+					}
+
+
+				}
+
+			}
+
+			mSelectContactPosition = -1;
+		}
+
+	}
+
+	@Override
+	public void onDetach()
+	{
+		if (m_task != null)
+			m_task.cancel(false);
+		super.onDetach();
+	}
+
+	class SearchTask extends AsyncTask<Void, Void, Boolean>
+	{
+		int	errorcode;
+
+		@Override
+		protected Boolean doInBackground(Void... params)
+		{
+			Log.d("SearchTask", "doInBackground");
+			if (!Network.NetworkIsAvailable())
+
+			{
+				errorcode = Network.RESULT_NET_NOTAVAILABLE;
+				return false;
+			}
+
+
+			String jstr = Network.get_detail(getArguments());
+			if (jstr == null || jstr.length() <= 0)
+			{
+				// Log.d(TAG, "json is wrong");
+
+				errorcode = Network.RESULT_NET_ERROR;
+				return false;
+			}
+
+			// mdataFragment.put_result(jstr);
+			fragment_content = jstr;
+			NewDetailActivity activity = (NewDetailActivity) getActivity();
+			activity.save_content(getArguments().getString("action_type"), jstr);
+
+			errorcode = Network.RESULT_TRUE;
+
+			return true;
+		}
+
+		@Override
+		protected void onPostExecute(Boolean success)
+		{
+			Log.i("onPostExecute", "entry");
+			m_task = null;
+			showProgress(false);
+
+//			if (ApexTrackingApplication.get_authorization() == false)
+//			{
+//				if(((DetailActivity) getActivity()).showlogin == true)
+//					return;
+//				((DetailActivity) getActivity()).showlogin = true;
+//				LinearLayout ll = (LinearLayout) ll_root
+//						.findViewById(R.id.ll_refresh);
+//				ll.setVisibility(View.VISIBLE);
+//				Toast toast = Toast.makeText(
+//						ApexTrackingApplication.get_instance(),
+//						getText(R.string.msg_net_passwordchangedremote) , Toast.LENGTH_LONG);
+//				toast.setGravity(Gravity.CENTER, 0, 0);
+//				toast.show();
+//				Intent i = new Intent();
+//				i.setClass(getActivity(), ApexActivity.class);
+//				startActivityForResult(i, REQUEST_LOGINACTIVITY);
+//				return;
+//			}
+			
+			switch (errorcode)
+			{
+				case Network.RESULT_NET_NOTAVAILABLE:
+				{
+					Toast toast = Toast.makeText(
+							ApexTrackingApplication.get_instance(),
+							getText(R.string.msg_connection_none),
+							Toast.LENGTH_LONG);
+					toast.setGravity(Gravity.CENTER, 0, 0);
+					toast.show();
+					break;
+				}
+				case Network.RESULT_NET_ERROR:
+				{
+					Toast toast = Toast.makeText(
+							ApexTrackingApplication.get_instance(),
+							getText(R.string.msg_net_error), Toast.LENGTH_LONG);
+					toast.setGravity(Gravity.CENTER, 0, 0);
+					toast.show();
+					break;
+				}
+				case Network.RESULT_ERROR:
+				// case Network.RESULT_RESPONSE_NULL:
+				{
+
+					Toast toast = Toast.makeText(
+							ApexTrackingApplication.get_instance(),
+							getText(R.string.msg_net_resulterror) + ":"
+									+ errorcode, Toast.LENGTH_LONG);
+					toast.setGravity(Gravity.CENTER, 0, 0);
+					toast.show();
+
+					break;
+				}
+
+				default:
+					break;
+			}
+
+			if (success)
+			{
+				LayoutInflater inflater = (LayoutInflater) ApexTrackingApplication
+						.get_instance().getSystemService(
+								Context.LAYOUT_INFLATER_SERVICE);
+
+				init(fragment_content, inflater/*
+												 * getActivity().
+												 * getLayoutInflater()
+												 */);
+			}
+			else
+			{
+				LinearLayout ll = (LinearLayout) ll_root
+						.findViewById(R.id.ll_refresh);
+				ll.setVisibility(View.VISIBLE);
+			}
+			super.onPostExecute(success);
+		}
+
+		@Override
+		protected void onCancelled()
+		{
+			m_task = null;
+			showProgress(false);
+		}
+	}
+    private void showQuickLook(final String url) {
+
+        showProgressDialog("Please wait","Downloading...");
+        new Thread(new Runnable() {
+            @Override
+            public void run() {
+
+                String cacheDir = ApexTrackingApplication.getInstance().getExternalCacheDir().getAbsolutePath();//ApexTrackingApplication.getInstance().getDocumentDir();
+
+                final Bundle param = new Bundle();
+                // 下载文件
+                final File downloadFile = Network.downloadFile(param,url,cacheDir);
+
+                getActivity().runOnUiThread(new Runnable() {
+                    @Override
+                    public void run() {
+                        progressDialog.dismiss();
+                        if (downloadFile != null && downloadFile.exists()) {
+                            String email = null,email_subject = null,email_content = null;
+                            //此处需要新增保存文档的本地表
+
+
+                            try {
+                                email = mContent.getString("email");
+                                email_subject = mContent.getString("email_subject");
+                                email_content = mContent.getString("email_content");
+
+                            } catch (JSONException e) {
+                                e.printStackTrace();
+                            }
+
+//                            email=param.getString("email");
+//                            email_subject=param.getString("email_subject");
+//                            email_content=param.getString("email_content");
+
+                            previewPDF(downloadFile.getAbsolutePath(),email,email_subject,email_content);
+                        } else {
+                            showAlert("Sorry,there is a wrong.");
+                        }
+                    }
+                });
+
+            }
+        }).start();
+
+
+    }
+
+	// public class DataFragment extends Fragment {
+	//
+	// String result = null;
+	//
+	// @Override
+	// public void onCreate(Bundle savedInstanceState) {
+	// setRetainInstance(true);
+	// super.onCreate(savedInstanceState);
+	// }
+	//
+	// public String get_result() {
+	// return result;
+	//
+	// }
+	//
+	// public void put_result(String s) {
+	// result = s;
+	// }
+	//
+	// }
+    public void showAlert(String msg) {
+        if (msg == null || msg.isEmpty()) {
+            return;
+        }
+
+        new android.support.v7.app.AlertDialog.Builder(mContext)
+                .setMessage(msg)
+                .show();
+    }
+
+
+
+    protected void previewPDF(String file,String email,String subject,String content) {
+        Intent myIntent = new Intent();
+        myIntent = new Intent(getActivity(), PDFPreviewActivity.class);
+
+        myIntent.putExtra("file",file);
+        myIntent.putExtra("iscache",true);
+
+        try {
+            JSONObject json = new JSONObject();
+//            email = "66666@qq.com";
+//            subject = "test subject";
+//            content = "test body";
+            if (email != null) {
+                json.put("email",email);
+            }
+            if (subject != null) {
+                json.put("subject",subject);
+            }
+            if (content != null) {
+                json.put("content",content);
+            }
+            myIntent.putExtra("email",json.toString());
+        } catch (JSONException e) {
+            e.printStackTrace();
+        }
+
+
+        startActivity(myIntent);
+    }
+
+
+    public void download(String url) {
+
+
+
+
+		final String download_url = url;
+
+		showQuickLook(url);
+		if(true)
+		    return;
+
+		showProgressDialog("Please wait","Downloading...");
+		new Thread(new Runnable() {
+			@Override
+			public void run() {
+
+//									String cacheDir = ApexTrackingApplication.getInstance().getDocumentDir();
+				// 下载文件
+				final File downloadFile = Network.downloadFile(null,download_url,null);
+
+				getActivity().runOnUiThread(new Runnable() {
+					@Override
+					public void run() {
+						progressDialog.dismiss();
+						RAUtil.openFile(getActivity(),downloadFile);
+					}
+				});
+
+			}
+		}).start();
+	}
+
+	public class MyWebViewClient extends WebViewClient
+	{
+		// 如果页面中链接,如果希望点击链接继续在当前browser中响应,
+		// 而不是新开Android的系统browser中响应该链接,必须覆盖 webview的WebViewClient对象。
+		public boolean shouldOverviewUrlLoading(WebView view, String url)
+		{
+			Log.d("Web Client", "shouldOverviewUrlLoading: " + url);
+			// L.i("shouldOverviewUrlLoading");
+			view.loadUrl(url);
+			return true;
+		}
+
+		@Override
+		public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
+			Log.d("Web Client", "shouldOverrideUrlLoading: " + request);
+			return super.shouldOverrideUrlLoading(view, request);
+		}
+
+		public void onPageStarted(WebView view, String url, Bitmap favicon)
+		{
+			// L.i("onPageStarted");
+			// showProgress();
+			Log.d("Web Client", "onPageStarted: ");
+		}
+
+		public void onPageFinished(WebView view, String url)
+		{
+			// L.i("onPageFinished");
+			// closeProgress();
+			Log.d("Web Client", "onPageFinished: ");
+		}
+
+		public void onReceivedError(WebView view, int errorCode,
+				String description, String failingUrl)
+		{
+			// L.i("onReceivedError");
+			// closeProgress();
+			Log.d("Web Client", "onReceivedError: ");
+		}
+
+
+
+		@Override
+		public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
+
+			Log.d("Web Client", "shouldInterceptRequest: " + url);
+			if (url.startsWith("http") && url.contains("action_type=download_doc")) {
+				download(url);
+
+				String content = contentOfWebView(view);
+				WebResourceResponse response = new WebResourceResponse("text/html",
+						"utf-8",
+						new ByteArrayInputStream(content.getBytes()));
+				return response;
+
+			} else {
+				return super.shouldInterceptRequest(view,url);
+			}
+		}
+
+		String contentOfWebView(WebView webView) {
+
+			int i = (int)webView.getTag();
+			try {
+
+				JSONObject groupobj = mContent.getJSONObject("group" + i);
+				String content = groupobj.getString("content");
+				return content;
+			} catch (JSONException e) {
+				e.printStackTrace();
+			}
+
+			return null;
+		}
+
+//		@Override
+//		public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
+//			Log.d("Web Client", "shouldInterceptRequest: " + request);
+//
+//			if (request.getUrl().toString().contains("action_type=download_doc")) {
+//				return null;
+//			} else {
+//				return super.shouldInterceptRequest(view,request);
+//			}
+//
+//
+//		}
+	}
+
+	private void appendContactEmail(String email,int group) {
+
+		try {
+
+			String groupKey = "group" + group;
+
+			JSONObject groupObj = mContent.getJSONObject(groupKey);
+			String groupType = groupObj.getString("_type");
+
+			if (groupType.equals("communication")) {
+
+				String oldCC = groupObj.optString("cc");
+				if (oldCC == null || oldCC.length() == 0) {
+					oldCC = email + ";";
+				} else {
+					if (oldCC.substring(oldCC.length() - 1).equals(";")) {
+						oldCC = oldCC + email + ";";
+					} else {
+						oldCC = oldCC + ";" + email + ";";
+					}
+				}
+
+				commContentChange(oldCC,group,0);
+
+				EditText ccTv = ll_root.findViewWithTag("group_" + group + "_cc");
+				if (ccTv != null) {
+					ccTv.setText(oldCC);
+					ccTv.requestFocus();
+					ccTv.setSelection(oldCC.length());
+				}
+			}
+
+		} catch (JSONException e) {
+			e.printStackTrace();
+		}
+
+	}
+
+	private void commContentChange(String content,int group,int child) {
+
+        try {
+
+            String groupKey = "group" + group;
+
+            JSONObject groupObj = mContent.getJSONObject(groupKey);
+            String groupType = groupObj.getString("_type");
+
+            if (groupType.equals("communication")) {
+
+                if (child == 0) {
+                    groupObj.put("cc",content);
+                } else if (child == 1) {
+                    groupObj.put("edit_content",content);
+                }
+                mContent.put(groupKey,groupObj);
+
+            }
+
+        } catch (JSONException e) {
+            e.printStackTrace();
+        }
+
+    }
+
+
+    public class TextFieldTextWatcher implements TextWatcher {
+
+        Context mCtx;
+        int group;
+        int child;
+        EditText textView;
+
+        public TextFieldTextWatcher(Context ctx,EditText textView,int group,int child) {
+            this.mCtx = ctx;
+            this.textView = textView;
+            this.group = group;
+            this.child = child;
+
+        }
+
+        String origin_text;
+        String string;
+        int start_position;
+        int change_length; // 修改原文长度
+        int new_string_length;
+
+
+        /**
+         * s        改变前的内容
+         * start    增加内容前光标位置,删除内容后光标位置 (起始位置)
+         * count    选中s中的内容长度(发生改变的原内容长度),未选中为0
+         * after    新添加的内容长度,删除为0
+         * */
+        @Override
+        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+//            Log.d("TextChange", "before Text Changed: " + s + " Start: " + start + " Count: " + count + " After: " + after);
+
+            origin_text = s.toString();
+            start_position = start;
+            change_length = count;
+            new_string_length = after;
+        }
+
+        /**
+         * s        改变后的内容
+         * start    增加内容前光标位置,删除内容后光标位置 (起始位置)
+         * before   选中s中的内容长度(发生改变的原内容长度),未选中为0
+         * count    增加内容长度,删除内容为0
+         * */
+        @Override
+        public void onTextChanged(CharSequence s, int start, int before, int count) {
+//            Log.d("TextChange", "on Text Changed: " + s + " Start: " + start + " Before: " + before + " Count: " + count);
+        }
+
+        @Override
+        public void afterTextChanged(Editable s) {
+
+            commContentChange(s.toString(),group,child);
+
+        }
+    }
+
+}

+ 25 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/DocumentsActivity.java

@@ -0,0 +1,25 @@
+package com.usai.apex;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+
+public class DocumentsActivity extends FragmentActivity
+{
+
+	@Override
+	protected void onCreate(Bundle savedInstanceState)
+	{
+		super.onCreate(savedInstanceState);
+		setContentView(R.layout.activity_inner_tools);
+
+		// Fragment f = new ToolsFragment();
+		if (savedInstanceState == null)
+		{
+			getSupportFragmentManager().beginTransaction()
+					.add(R.id.container, new DocumentsFragment()).commit();
+		}
+
+
+	}
+
+}

+ 86 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/DocumentsFragment.java

@@ -0,0 +1,86 @@
+package com.usai.apex;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import android.content.Intent;
+import android.graphics.Color;
+import android.os.Bundle;
+import android.support.v4.app.ListFragment;
+import android.util.Log;
+import android.view.View;
+import android.widget.ListView;
+import android.widget.SimpleAdapter;
+
+public class DocumentsFragment extends ListFragment
+{
+	
+
+	// @Override
+	// public View onCreateView(LayoutInflater inflater, ViewGroup container,
+	// Bundle savedInstanceState)
+	// {
+	// View view = inflater.inflate(R.layout.fragment_tools, null);
+	// // Button btn = (Button) view.findViewById(R.id.btn_cancel);
+	// // btn.setOnClickListener(this);
+	// return view;
+	// // return super.onCreateView(inflater, container, savedInstanceState);
+	// }
+	private List<Map<String, Object>> getData()
+	{
+		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
+
+		Map<String, Object> map = new HashMap<String, Object>();
+		map.put("title", "Search document online");
+		map.put("img", R.drawable.rect_search_documents);
+		list.add(map);
+
+		map = new HashMap<String, Object>();
+		map.put("title", "View downloaded document");
+		map.put("img", R.drawable.rect_view_download_documents);
+		list.add(map);
+
+	
+		
+		return list;
+	}
+
+	@Override
+	public void onActivityCreated(Bundle savedInstanceState)
+	{
+		super.onActivityCreated(savedInstanceState);
+		SimpleAdapter adapter = new SimpleAdapter(this.getActivity(),
+				getData(), R.layout.fragment_tools, new String[] { "title",
+						"img" }, new int[] { R.id.tv_toolname, R.id.iv_thumb});
+		setListAdapter(adapter);
+		this.getListView().setBackgroundColor(Color.WHITE);
+	}
+
+	@Override
+	public void onListItemClick(ListView l, View v, int position, long id)
+	{
+		Log.d("FragmentList", "Item clicked: " + id);
+		
+		String title = (String) getData().get(position).get("title");
+		Intent intent = new Intent();
+		if(title.equals("Search document online"))
+		{
+			intent.setClass(getActivity(), SearchListActivity.class);
+	
+			intent.putExtra("function_name", "Download Document");
+			intent.putExtra("title", "Document Search");
+
+		}
+		else if(title.equals("View downloaded document"))
+		{
+			intent.setClass(getActivity(), LocalDocumentActivity.class);
+//			intent.putExtra("module_name", "Announcements");
+		}
+
+		
+		startActivity(intent);
+
+	}
+}

+ 282 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/DragListView.java

@@ -0,0 +1,282 @@
+package com.usai.apex;
+
+import com.usai.apex.CustomizeFieldsActivity.DragListAdapter;
+import com.usai.apex.CustomizeFieldsActivity.fieldedit;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.PixelFormat;
+import android.util.AttributeSet;
+import android.view.Gravity;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.widget.AdapterView;
+import android.widget.ImageView;
+import android.widget.ListView;
+
+public class DragListView extends ListView
+{
+
+	private ImageView dragImageView;// ����ק�����ʵ����һ��ImageView
+	private int dragSrcPosition;// ��ָ�϶���ԭʼ���б��е�λ��
+	private int dragPosition;// ��ָ�϶���ʱ�򣬵�ǰ�϶������б��е�λ��
+
+	private int dragPoint;// �ڵ�ǰ������е�λ��
+	private int dragOffset;// ��ǰ��ͼ����Ļ�ľ���(����ֻʹ����y������)
+
+	private WindowManager windowManager;// windows���ڿ�����
+	private WindowManager.LayoutParams windowParams;// ���ڿ�����ק�����ʾ�IJ���
+
+	private int scaledTouchSlop;// �жϻ�����һ������
+	private int upScrollBounce;// �϶���ʱ�򣬿�ʼ���Ϲ����ı߽�
+	private int downScrollBounce;// �϶���ʱ�򣬿�ʼ���¹����ı߽�
+
+	public DragListView(Context context, AttributeSet attrs)
+	{
+		super(context, attrs);
+		scaledTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
+
+		this.setOnItemClickListener(mItemClickListenter);
+	}
+
+	private int lastClickId = -1;
+	private long lastClickTime;
+	private OnItemClickListener mItemClickListenter = new OnItemClickListener()
+	{
+		public void onItemClick(AdapterView<?> parent, View v, int pos, long id)
+		{
+			DragListAdapter adapter = (DragListAdapter) ((ListView) parent)
+					.getAdapter();
+
+			if (adapter.isEnabled(pos) == false)// return if item is a group key
+				return;
+			fieldedit dclickitem = (fieldedit) ((ListView) parent).getAdapter()
+					.getItem(pos);
+
+			// �����˫��,1�����������ж�Ϊ˫��
+			if (dclickitem._id == lastClickId
+					&& (Math.abs(lastClickTime - System.currentTimeMillis()) < 1000))
+			{
+				lastClickId = -1;
+				lastClickTime = 0;
+				if (pos < adapter.switchpos())
+				{
+					adapter.remove(dclickitem);
+					adapter.insert(dclickitem, adapter.getCount());
+				}
+				else
+				{
+					adapter.remove(dclickitem);
+					adapter.insert(dclickitem, 1);
+
+				}
+				// Intent intent = new Intent();
+				// intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
+				// intent.putExtra("matchId", mv.getId());
+				// intent.putExtra("matchKey", mv.getMatchKey());
+				// intent.setClass(SenseSoccerScoreActivity.this,
+				// MatchEventActivity.class);
+				// startActivity(intent);
+			}
+			else
+			{
+				lastClickId = dclickitem._id;
+				lastClickTime = System.currentTimeMillis();
+			}
+		}
+	};
+
+	// ����touch�¼�����ʵ���Ǽ�һ�����
+	@Override
+	public boolean onInterceptTouchEvent(MotionEvent ev)
+	{
+		if (ev.getAction() == MotionEvent.ACTION_DOWN)
+		{
+			int x = (int) ev.getX();
+			int y = (int) ev.getY();
+
+			dragSrcPosition = dragPosition = pointToPosition(x, y);
+			if (dragPosition == AdapterView.INVALID_POSITION)
+			{
+				return super.onInterceptTouchEvent(ev);
+			}
+
+			ViewGroup itemView = (ViewGroup) getChildAt(dragPosition
+					- getFirstVisiblePosition());
+			dragPoint = y - itemView.getTop();
+			dragOffset = (int) (ev.getRawY() - y);
+
+			View dragger = itemView.findViewById(R.id.drag_list_item_image);
+			if (dragger != null && x > dragger.getLeft() - 20)
+			{
+				//
+				upScrollBounce = Math.min(y - scaledTouchSlop, getHeight() / 3);
+				downScrollBounce = Math.max(y + scaledTouchSlop,
+						getHeight() * 2 / 3);
+
+				itemView.setDrawingCacheEnabled(true);
+				Bitmap bm = Bitmap.createBitmap(itemView.getDrawingCache());
+				startDrag(bm, y);
+			}
+			return false;
+		}
+		return super.onInterceptTouchEvent(ev);
+	}
+
+	/**
+	 * �����¼�
+	 */
+	@Override
+	public boolean onTouchEvent(MotionEvent ev)
+	{
+		if (dragImageView != null && dragPosition != INVALID_POSITION)
+		{
+			int action = ev.getAction();
+			switch (action)
+			{
+			case MotionEvent.ACTION_UP:
+				int upY = (int) ev.getY();
+				stopDrag();
+				onDrop(upY);
+				break;
+			case MotionEvent.ACTION_MOVE:
+				int moveY = (int) ev.getY();
+				onDrag(moveY);
+				break;
+			default:
+				break;
+			}
+			return true;
+		}
+		// Ҳ������ѡ�е�Ч��
+		return super.onTouchEvent(ev);
+	}
+
+	/**
+	 * ׼���϶�����ʼ���϶����ͼ��
+	 * 
+	 * @param bm
+	 * @param y
+	 */
+	public void startDrag(Bitmap bm, int y)
+	{
+		stopDrag();
+
+		windowParams = new WindowManager.LayoutParams();
+		windowParams.gravity = Gravity.TOP;
+		windowParams.x = 0;
+		windowParams.y = y - dragPoint + dragOffset;
+		windowParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
+		windowParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
+		windowParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+				| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
+				| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
+				| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
+		windowParams.format = PixelFormat.TRANSLUCENT;
+		windowParams.windowAnimations = 0;
+
+		ImageView imageView = new ImageView(getContext());
+		imageView.setImageBitmap(bm);
+		windowManager = (WindowManager) getContext().getSystemService("window");
+		windowManager.addView(imageView, windowParams);
+		dragImageView = imageView;
+	}
+
+	/**
+	 * ֹͣ�϶���ȥ���϶����ͷ��
+	 */
+	public void stopDrag()
+	{
+		if (dragImageView != null)
+		{
+			windowManager.removeView(dragImageView);
+			dragImageView = null;
+		}
+	}
+
+	/**
+	 * �϶�ִ�У���Move������ִ��
+	 * 
+	 * @param y
+	 */
+	public void onDrag(int y)
+	{
+		if (dragImageView != null)
+		{
+			windowParams.alpha = 0.8f;
+			windowParams.y = y - dragPoint + dragOffset;
+			windowManager.updateViewLayout(dragImageView, windowParams);
+		}
+		// Ϊ�˱��⻬�����ָ��ߵ�ʱ�򣬷���-1������
+		int tempPosition = pointToPosition(0, y);
+		if (tempPosition != INVALID_POSITION)
+		{
+			dragPosition = tempPosition;
+		}
+
+		// ����
+		int scrollHeight = 0;
+		if (y < upScrollBounce)
+		{
+			scrollHeight = 8;// �������Ϲ���8�����أ����������Ϲ����Ļ�
+		}
+		else
+			if (y > downScrollBounce)
+			{
+				scrollHeight = -8;// �������¹���8�����أ������������Ϲ����Ļ�
+			}
+
+		if (scrollHeight != 0)
+		{
+			// ����������setSelectionFromTop()
+			setSelectionFromTop(dragPosition,
+					getChildAt(dragPosition - getFirstVisiblePosition())
+							.getTop() + scrollHeight);
+		}
+	}
+
+	/**
+	 * �϶����µ�ʱ��
+	 * 
+	 * @param y
+	 */
+	public void onDrop(int y)
+	{
+
+		// Ϊ�˱��⻬�����ָ��ߵ�ʱ�򣬷���-1������
+		int tempPosition = pointToPosition(0, y);
+		if (tempPosition != INVALID_POSITION)
+		{
+			dragPosition = tempPosition;
+		}
+
+		// �����߽紦��
+		if (y < getChildAt(1).getTop())
+		{
+			// �����ϱ߽�
+			dragPosition = 1;
+		}
+		else
+			if (y > getChildAt(getChildCount() - 1).getBottom())
+			{
+				// �����±߽�
+				dragPosition = getAdapter().getCount() - 1;
+			}
+
+		// ��ݽ���
+		if (dragPosition > 0 && dragPosition < getAdapter().getCount())
+		{
+			/* @SuppressWarnings("unchecked") */
+			DragListAdapter adapter = (DragListAdapter) getAdapter();
+			fieldedit dragItem = adapter.getItem(dragSrcPosition);
+			adapter.remove(dragItem);
+			adapter.insert(dragItem, dragPosition);
+			// Toast.makeText(getContext(), adapter.getList().toString(),
+			// Toast.LENGTH_SHORT).show();
+		}
+
+	}
+}

+ 411 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/FunctionSelectActivity.java

@@ -0,0 +1,411 @@
+package com.usai.apex;
+
+import android.app.ActionBar;
+import android.app.Activity;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.database.sqlite.SQLiteDatabase;
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.ArrayAdapter;
+import android.widget.AutoCompleteTextView;
+import android.widget.Button;
+import android.widget.RadioGroup;
+import android.widget.RadioGroup.OnCheckedChangeListener;
+import android.widget.TextView;
+
+import com.usai.apex.mainframe.NewDetailActivity;
+import com.usai.util.dbUtil;
+
+public class FunctionSelectActivity extends FragmentActivity implements
+		OnClickListener, OnCheckedChangeListener
+{
+
+	static final int PASSWORD_CHANGED = 1;
+	private static final int	REQUEST_LOGINACTIVITY			= 1;
+	private static final int	REQUEST_CHANGEPASSWORD_ACTIVITY	= 2;
+	private static final int	REQUEST_TOOLS_ACTIVITY			= 3;
+	ArrayAdapter<String>		adapter							= null;
+	
+	@Override
+	public boolean onOptionsItemSelected(MenuItem item)
+	{
+		Intent intent = new Intent();
+		switch (item.getItemId())
+		{
+			case R.id.action_settings:
+				intent.setClass(this, SettingsActivity.class);
+				// intent.putExtra("user", user);
+				// intent.putExtra("password", password);
+//				intent.putExtra("function_name", function_name);
+//				intent.putExtra("behavior", Network.BEHAVIOR_SEARCH);
+				startActivity(intent);
+				break;
+
+			default:
+				break;
+		}
+		return super.onOptionsItemSelected(item);
+	}
+	@Override
+	public boolean onCreateOptionsMenu(Menu menu)
+	{
+		// Inflate the menu; this adds items to the action bar if it is present.
+		getMenuInflater().inflate(R.menu.function_select, menu);
+		return true;
+	}
+	@Override
+	protected void onCreate(Bundle savedInstanceState)
+	{
+		// user = ApexTrackingApplication.get_user();
+		// password= getIntent().getStringExtra("password");
+		super.onCreate(savedInstanceState);
+		setContentView(R.layout.new_function_select);
+
+		ActionBar bar = getActionBar();
+		bar.setTitle("");
+		//
+		TextView tv_booking = (TextView) findViewById(R.id.tv_booking);
+		tv_booking.setOnClickListener(this);
+		TextView tv_info = (TextView) findViewById(R.id.tv_info);
+		tv_info.setOnClickListener(this);
+		TextView tv_detail = (TextView) findViewById(R.id.tv_detail);
+		tv_detail.setOnClickListener(this);
+		// TextView tv_cargo = (TextView)findViewById(R.id.tv_cargo);
+		// tv_cargo.setOnClickListener(this);
+		TextView tv_doc = (TextView) findViewById(R.id.tv_doc);
+		tv_doc.setOnClickListener(this);
+		TextView tv_message = (TextView) findViewById(R.id.tv_message);
+		tv_message.setOnClickListener(this);
+		TextView tv_exit = (TextView) findViewById(R.id.tv_exit);
+		tv_exit.setOnClickListener(this);
+		TextView tv_loc = (TextView) findViewById(R.id.tv_location);
+		tv_loc.setOnClickListener(this);
+		TextView tv_tools = (TextView) findViewById(R.id.tv_tools);
+		tv_tools.setOnClickListener(this);
+		Button btn_search = (Button) findViewById(R.id.btn_search);
+		btn_search.setOnClickListener(this);
+		Button btn_clear = (Button) findViewById(R.id.btn_clear);
+		btn_clear.setOnClickListener(this);
+		RadioGroup rg = (RadioGroup) findViewById(R.id.radioGroup1);
+		rg.setOnCheckedChangeListener(this);
+		// AutoCompleteTextView et = (AutoCompleteTextView)
+		// findViewById(R.id.atv_criterion);
+		// if (rg.getCheckedRadioButtonId() == R.id.radio0)
+		// adapter = new ArrayAdapter<String>(this,
+		// android.R.layout.simple_dropdown_item_1line,
+		// dbUtil.get_searchhistory("h_bol"));
+		// else
+		// adapter = new ArrayAdapter<String>(this,
+		// android.R.layout.simple_dropdown_item_1line,
+		// dbUtil.get_searchhistory("ctnr"));
+		// et.setAdapter(adapter);
+		SharedPreferences pref = ApexTrackingApplication.get_instance()
+				.getSharedPreferences("Apex", 0);
+		boolean autologin = pref.getBoolean("autologin", false);
+
+		if (!autologin)
+		{
+			Intent i = new Intent();
+			i.setClass(this, ApexActivity.class);
+			startActivityForResult(i, REQUEST_LOGINACTIVITY);
+		}
+
+	}
+
+	@Override
+	protected void onActivityResult(int requestCode, int resultCode, Intent data)
+	{
+		switch (requestCode)
+		{
+			case REQUEST_LOGINACTIVITY:
+				if (resultCode == Activity.RESULT_CANCELED)
+					finish();
+				break;
+			case REQUEST_TOOLS_ACTIVITY:
+				if (resultCode == PASSWORD_CHANGED)
+				{
+					String UNIQUE_STRING = "com.usai.apex.push.cancel";
+					Intent intent = new Intent(UNIQUE_STRING);
+					sendBroadcast(intent);
+					Intent i = new Intent();
+					i.setClass(this, ApexActivity.class);
+					startActivityForResult(i, REQUEST_LOGINACTIVITY);
+				}
+				break;
+			default:
+				break;
+		}
+
+		super.onActivityResult(requestCode, resultCode, data);
+	}
+
+	@Override
+	protected void onDestroy()
+	{
+		// dbUtil.CloseDB(m_db);
+		super.onDestroy();
+	}
+
+	@Override
+	public void onClick(View v)
+	{
+		String TAG = "onClick@FunctionSelectActivity";
+		Log.d(TAG, "ID=" + v.getId());
+		switch (v.getId())
+		{
+			case R.id.btn_clear:
+			{
+
+				AutoCompleteTextView et = (AutoCompleteTextView) findViewById(R.id.atv_criterion);
+				et.setText("");
+				break;
+
+			}
+			case R.id.btn_search:
+			{
+
+				AutoCompleteTextView et = (AutoCompleteTextView) findViewById(R.id.atv_criterion);
+				// et.clearFocus();
+
+				InputMethodManager inputMethodManager = (InputMethodManager) getApplicationContext()
+						.getSystemService(Context.INPUT_METHOD_SERVICE);
+
+				inputMethodManager.hideSoftInputFromWindow(et.getWindowToken(),
+						0);
+				inputMethodManager.hideStatusIcon(et.getWindowToken());
+				String cargo_criterion = et.getText().toString();
+				// if (TextUtils.isEmpty(cargo_criterion))
+				// {
+				// et.setError(getString(R.string.error_field_required));
+				// et.requestFocus();
+				// }
+				// else
+				// {
+				Intent intent = new Intent();
+				intent.setClass(this, NewDetailActivity.class);
+
+				intent.putExtra("action0", "Tracking");
+				intent.putExtra("function_name", "Cargo Tracking");
+
+				intent.putExtra("cargo_criterion", cargo_criterion);
+				intent.putExtra("actions_count", 1);
+				intent.putExtra("_id", "dumb");
+				String h_field;
+				RadioGroup rg = (RadioGroup) findViewById(R.id.radioGroup1);
+				if (rg.getCheckedRadioButtonId() == R.id.radio0)
+				{
+					intent.putExtra("criterion_type", 0);
+					h_field = "h_bol";
+				}
+				else
+				{
+					intent.putExtra("criterion_type", 1);
+					h_field = "ctnr";
+				}
+
+				dbUtil.savehistory(h_field, cargo_criterion);
+
+				startActivity(intent);
+
+				break;
+			}
+			case R.id.tv_booking:
+			{
+				Intent intent = new Intent();
+				intent.setClass(this, SearchListActivity.class);
+				// intent.putExtra("user", ApexTrackingApplication.get_user());
+				// intent.putExtra("password", password);
+				intent.putExtra("function_name", "Ocean Booking");
+				intent.putExtra("title", "Booking Search");
+				startActivity(intent);
+				break;
+			}
+			case R.id.tv_info:
+			{
+				Intent intent = new Intent();
+				intent.setClass(this, SearchListActivity.class);
+				// intent.putExtra("user", user);
+				// intent.putExtra("password", password);
+				intent.putExtra("function_name", "Ocean B/L info.");
+				intent.putExtra("title", "B/L info. Search");
+				startActivity(intent);
+				break;
+			}
+			case R.id.tv_detail:
+			{
+				Intent intent = new Intent();
+				intent.setClass(this, SearchListActivity.class);
+				// intent.putExtra("user", user);
+				// intent.putExtra("password", password);
+				intent.putExtra("function_name", "Container detail");
+				intent.putExtra("title", "Container Search");
+				startActivity(intent);
+				break;
+			}
+
+			case R.id.tv_doc:
+			{
+				Intent intent = new Intent();
+				intent.setClass(this, DocumentsActivity.class);
+				// // intent.putExtra("user", user);
+				// // intent.putExtra("password", password);
+				// intent.putExtra("function_name", "Download Document");
+				// intent.putExtra("title", "Document Search");
+				startActivity(intent);
+				break;
+			}
+			case R.id.tv_message:
+			{
+
+				Intent intent = new Intent();
+				intent.setClass(this, MessageActivity.class);
+				startActivity(intent);
+				//
+				// Intent intent = new Intent();
+				// intent.setClass(this, ChangePasswordActivity.class);
+				// // intent.putExtra("function_name", "Container Detail");
+				// startActivityForResult(intent,
+				// REQUEST_CHANGEPASSWORD_ACTIVITY);
+				break;
+			}
+			case R.id.tv_exit:
+			{
+				String UNIQUE_STRING = "com.usai.apex.push.cancel";
+				Intent intent = new Intent(UNIQUE_STRING);
+				// intent.putExtra("key1", "value1");
+				// intent.putExtra("key2", "value2");
+				sendBroadcast(intent);
+
+				// ApexTrackingApplication.cancelalarm();
+				// ApexTrackingApplication.put_password("");
+				// ApexTrackingApplication.put_sessionid("");
+				// ApexTrackingApplication.put_user("");
+
+				Intent i = new Intent();
+				i.setClass(this, ApexActivity.class);
+				startActivityForResult(i, 1);
+
+				// finish();
+				// System.exit(0);
+				break;
+			}
+			case R.id.tv_tools:
+			{
+				Intent intent = new Intent();
+				intent.setClass(this, InnerToolsActivity.class);
+				intent.putExtra("launcher", "inner");
+				startActivityForResult(intent,REQUEST_TOOLS_ACTIVITY);
+				break;
+			}
+			case R.id.tv_location:
+			{
+				Log.d("==============", "start location activity");
+				Intent intent = new Intent();
+				intent.setClass(this, InnerMapActivity.class);
+				// intent.putExtra("user", user);
+				// intent.putExtra("password", password);
+				// intent.putExtra("function_name", "Container Detail");
+				startActivity(intent);
+				break;
+			}
+
+			default:
+				break;
+		}
+		// TODO Auto-generated method stub
+
+	}
+
+	// class HistoryAdapter extends SimpleCursorAdapter{
+	//
+	// public HistoryAdapter(Context context, int layout, Cursor c,
+	// String[] from, int[] to)
+	// {
+	// super(context, layout, c, from, to,FLAG_AUTO_REQUERY);
+	// // TODO Auto-generated constructor stub
+	// }
+	//
+	// }
+
+	@Override
+	protected void onResume()
+	{
+		SQLiteDatabase db = dbUtil.OpenDB(this, null, false);
+		int count = dbUtil.get_count(db, "push_message", "read = 0 and user = '"+ApexTrackingApplication.get_user()+"'");
+
+		dbUtil.CloseDB(db);
+		NotificationManager nManager = (NotificationManager) this
+				.getSystemService(Context.NOTIFICATION_SERVICE);
+		nManager.cancel(R.layout.activity_apex);
+		ApexTrackingApplication.ncount=1;
+
+		// Intent intent = new Intent();
+		// intent.setClass(ApexTrackingApplication
+		// .get_instance(), FunctionSelectActivity.class);
+		// Intent addShortcut = new Intent(
+		// "com.android.launcher.action.INSTALL_SHORTCUT");
+		// Parcelable icon = Intent.ShortcutIconResource.fromContext(this,
+		// R.drawable.ic_launcher);
+		// addShortcut.putExtra(Intent.EXTRA_SHORTCUT_NAME,
+		// getString(R.string.app_name));
+		// addShortcut.putExtra(Intent.EXTRA_SHORTCUT_INTENT, intent);
+		// addShortcut.putExtra("duplicate", 0);
+		// addShortcut.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, icon);
+		// Log.e("uuuuuuuuuuuuuuuurrrrrrrrrrrrrriiiiiiiii",
+		// intent.toUri(MODE_WORLD_WRITEABLE));
+		// sendBroadcast(addShortcut);
+		if (count > 0)
+		{
+			TextView tv_message = (TextView) findViewById(R.id.tv_message);
+			tv_message.setCompoundDrawablesWithIntrinsicBounds(0,
+					R.drawable.ic_message_new, 0, 0);
+
+		}
+		else
+		{
+			TextView tv_message = (TextView) findViewById(R.id.tv_message);
+			tv_message.setCompoundDrawablesWithIntrinsicBounds(0,
+					R.drawable.ic_message, 0, 0);
+		}
+
+		RadioGroup rg = (RadioGroup) findViewById(R.id.radioGroup1);
+		AutoCompleteTextView et = (AutoCompleteTextView) findViewById(R.id.atv_criterion);
+		if (rg.getCheckedRadioButtonId() == R.id.radio0)
+			adapter = new ArrayAdapter<String>(this,
+					android.R.layout.simple_dropdown_item_1line,
+					dbUtil.get_searchhistory("h_bol"));
+		else
+			adapter = new ArrayAdapter<String>(this,
+					android.R.layout.simple_dropdown_item_1line,
+					dbUtil.get_searchhistory("ctnr"));
+		et.setAdapter(adapter);
+		super.onResume();
+	}
+
+	@Override
+	public void onCheckedChanged(RadioGroup group, int checkedId)
+	{
+
+		AutoCompleteTextView et = (AutoCompleteTextView) findViewById(R.id.atv_criterion);
+		if (checkedId == R.id.radio0)
+			adapter = new ArrayAdapter<String>(this,
+					android.R.layout.simple_dropdown_item_1line,
+					dbUtil.get_searchhistory("h_bol"));
+		else
+			adapter = new ArrayAdapter<String>(this,
+					android.R.layout.simple_dropdown_item_1line,
+					dbUtil.get_searchhistory("ctnr"));
+		et.setAdapter(adapter);
+
+	}
+
+}

+ 48 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/HelpActivity.java

@@ -0,0 +1,48 @@
+package com.usai.apex;
+
+import android.os.Bundle;
+import android.app.Activity;
+import android.view.Menu;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.ImageView;
+
+public class HelpActivity extends Activity implements OnClickListener
+{
+
+	@Override
+	protected void onCreate(Bundle savedInstanceState)
+	{
+		super.onCreate(savedInstanceState);
+		setContentView(R.layout.activity_help);
+		String caller=getIntent().getStringExtra("caller");
+		ImageView iv= (ImageView) findViewById(R.id.iv_help);
+		iv.setOnClickListener(this);
+		if(caller.equals("fields"))
+			iv.setImageResource(R.drawable.help_fields);
+		else if(caller.equals("search"))
+			iv.setImageResource(R.drawable.help_search);
+		else if(caller.equals("result"))
+			iv.setImageResource(R.drawable.help_result);
+	}
+	
+	
+
+	@Override
+	public boolean onCreateOptionsMenu(Menu menu)
+	{
+		// Inflate the menu; this adds items to the action bar if it is present.
+		getMenuInflater().inflate(R.menu.help, menu);
+		return true;
+	}
+
+
+
+	@Override
+	public void onClick(View v)
+	{
+		finish();
+		
+	}
+
+}

+ 312 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/InnerMapActivity.java

@@ -0,0 +1,312 @@
+package com.usai.apex;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.net.Uri;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.app.FragmentTransaction;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AppCompatActivity;
+import android.view.Gravity;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.TextView;
+
+import com.baidu.mapapi.map.SupportMapFragment;
+import com.usai.Contacts.Contact;
+import com.usai.Contacts.ContactsManager;
+
+//import com.baidu.mapapi.MKGeneralListener;
+//import com.baidu.mapapi.map.MKEvent;
+
+public class InnerMapActivity extends AppCompatActivity implements BaiduMapFragment.BaiduMarkerClickListener,ServiceLocationFragment.MarkerClickListener
+{
+//	public static boolean		m_bKeyRight				= true;
+//	BMapManager					mBMapManager			= null;
+
+//    public String strKey = getString(R.string.baidu_key);//"nqBQoSDbxrslhuzW91uViQX7";//release
+	private static final String	LTAG					= "test";
+	SupportMapFragment			map;
+
+	boolean						m_bhasgoogleframework	= true;  
+
+//	static class MyGeneralListener implements MKGeneralListener
+//	{
+//
+//		@Override
+//		public void onGetNetworkState(int iError)
+//		{
+//			if (iError == MKEvent.ERROR_NETWORK_CONNECT)
+//			{
+//				Toast.makeText(
+//						ApexTrackingApplication.get_instance()
+//								.getApplicationContext(),
+//						"????????????????????????", Toast.LENGTH_LONG).show();
+//			}
+//			else if (iError == MKEvent.ERROR_NETWORK_DATA)
+//			{
+//				Toast.makeText(
+//						ApexTrackingApplication.get_instance()
+//								.getApplicationContext(),
+//						"??????????????????????????????", Toast.LENGTH_LONG)
+//						.show();
+//			}
+//			// ...
+//		}
+//
+//		@Override
+//		public void onGetPermissionState(int iError)
+//		{
+//			// ???????????????key???????????????
+//			if (iError != 0)
+//			{
+//				// ??????Key?????????
+//				Toast.makeText(
+//						ApexTrackingApplication.get_instance()
+//								.getApplicationContext(),
+//						"?????? MyApplication.java???????????????????????????Key,??????????????????????????????????????????error: "
+//								+ iError, Toast.LENGTH_LONG).show();
+//				m_bKeyRight = false;
+//			}
+//			else
+//			{
+//				m_bKeyRight = true;
+//				Toast.makeText(
+//						ApexTrackingApplication.get_instance()
+//								.getApplicationContext(), "key????????????",
+//						Toast.LENGTH_LONG).show();
+//			}
+//		}
+//	}
+
+	@Override
+	public boolean onKeyDown(int keyCode, KeyEvent event)
+	{
+		if (keyCode == KeyEvent.KEYCODE_BACK)
+		{
+			// Intent myIntent = new Intent();
+			// myIntent = new Intent(EditActivity.this, tabActivity.class);
+			// startActivity(myIntent);
+			finish();
+			return true;
+		}
+		return super.onKeyDown(keyCode, event);
+	}
+	@Override
+	public boolean onOptionsItemSelected(MenuItem item)
+	{
+		Intent intent = new Intent();
+		switch (item.getItemId())
+		{
+			case android.R.id.home:
+				finish();
+				break;
+
+			default:
+				break;
+		}
+		return super.onOptionsItemSelected(item);
+	}
+
+	private void setCustomActionBar() {
+		ActionBar.LayoutParams lp =new ActionBar.LayoutParams(ActionBar.LayoutParams.MATCH_PARENT, ActionBar.LayoutParams.MATCH_PARENT, Gravity.CENTER);
+		View mActionBarView = LayoutInflater.from(this).inflate(R.layout.actionbar_customtitle, null);
+
+		TextView titleview = mActionBarView.findViewById(R.id.title);
+		titleview.setText("Service Location");
+		setTitle("Service Location");
+		ActionBar actionBar = getSupportActionBar();
+		actionBar.setCustomView(mActionBarView, lp);
+//		actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
+//		actionBar.setDisplayShowCustomEnabled(true);
+		actionBar.setDisplayHomeAsUpEnabled(true);
+
+
+		actionBar.setDisplayShowTitleEnabled(true);
+	}
+
+	private Context mContext;
+
+	@Override
+	protected void onCreate(Bundle savedInstanceState)
+	{
+		super.onCreate(savedInstanceState);
+		mContext = this;
+		PackageInfo packageInfo;
+		try
+		{
+			packageInfo = this.getPackageManager().getPackageInfo(
+					"com.google.android.gms", 0);
+
+		}
+		catch (NameNotFoundException e)
+		{
+			packageInfo = null;
+			e.printStackTrace();
+		}
+		if (packageInfo == null)
+		{
+			m_bhasgoogleframework = false;
+			System.out.println("没有安装");
+		}
+		else
+		{
+			m_bhasgoogleframework = true;
+			System.out.println("已经安装");
+		}
+		// setUpMapIfNeeded();
+
+//		m_bhasgoogleframework = false;
+
+
+
+
+//		m_bhasgoogleframework= true;
+
+		Fragment slFragment = null;
+		if (m_bhasgoogleframework )
+		{
+			setContentView(R.layout.activity_inner_map);
+			slFragment = new ServiceLocationFragment();
+			((ServiceLocationFragment)slFragment).markerClickListener = this;
+			FragmentTransaction ft = getSupportFragmentManager()
+					.beginTransaction();
+			ft.replace(R.id.inner_map, slFragment);
+			ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
+			ft.addToBackStack("Location");
+			ft.commit();
+
+		}
+		else
+		{
+//			if (mBMapManager == null)
+//			{
+//				mBMapManager = new BMapManager(getApplicationContext());
+//				/**
+//				 * ??????BMapManager???????????????????????????BMapManager
+//				 */
+//				mBMapManager.init(strKey, new MyGeneralListener());
+//			}
+			
+//			f.initEngineManager(this);
+			setContentView(R.layout.activity_inner_map);
+//			Log.d(LTAG, "onCreate");
+//			// setContentView(R.layout.activity_main);
+//			map = SupportMapFragment.newInstance();
+			BaiduMapFragment f  = new BaiduMapFragment();
+			FragmentManager manager = getSupportFragmentManager();
+			manager.beginTransaction().add(R.id.inner_map, f, "map_fragment")
+					.commit();
+			f.markerClickListener = this;
+		}
+
+		setCustomActionBar();
+
+//		LocationDetail detail = new LocationDetail("Kerry Freight (USA), Inc","3200 NW 67th Ave. Bldg. 3 Suite 390 Miami, FL 33122 Miami","+(305)12345678","+(305)4567890",null,"mario.alfonso@kerrylogistics.com");
+//		markerClicked(detail);
+	}
+
+	// @Override
+	// public boolean onCreateOptionsMenu(Menu menu)
+	// {
+	// // Inflate the menu; this adds items to the action bar if it is present.
+	// getMenuInflater().inflate(R.menu.inner_map, menu);
+	// return true;
+	// }
+	// private void setUpMapIfNeeded() {
+	// // Do a null check to confirm that we have not already instantiated the
+	// map.
+	// if (mMap == null) {
+	// // Try to obtain the map from the SupportMapFragment.
+	// mMap = ((SupportMapFragment)
+	// getSupportFragmentManager().findFragmentById(R.id.map))
+	// .getMap();
+	// // Check if we were successful in obtaining the map.
+	// if (mMap != null) {
+	// setUpMap();
+	// }
+	// }
+	// }
+
+
+	@Override
+	public void markerClicked(LocationDetail detail) {
+
+		if (detail == null) {
+			return;
+		}
+		String homePage = "http://www.apexshipping.com";
+		Bitmap photo = BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher);
+
+		final Contact contact = new Contact();
+		contact.setName(detail.Name);
+		contact.setAddress(detail.Addr);
+		contact.setNumber(detail.Tel);
+		contact.setFax(detail.Fax);
+		contact.setEmail(detail.Email);
+		contact.setHomePage(homePage);
+		contact.setPhoto(photo);
+
+		final ContactsManager cm = new ContactsManager(this.getContentResolver());
+		if (cm.contactExist(contact.getName())) {
+
+			new AlertDialog.Builder(this)
+					.setTitle("Warning")
+					.setMessage(contact.getName() + " has exist in contacts,do you want to update it?")
+					.setNegativeButton("No", new DialogInterface.OnClickListener() {
+						@Override
+						public void onClick(DialogInterface dialog, int which) {
+							// 添加一条新记录
+							cm.insertContact(contact,mContext);
+//							Contact existContact = cm.searchContact(contact.getName());
+//							String contactId = cm.getContactID(existContact.getName());
+//							Intent editIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("content://com.android.contacts/contacts/"+contactId));
+//							startActivity(editIntent);
+						}
+					})
+					.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
+						@Override
+						public void onClick(DialogInterface dialog, int which) {
+
+							//Intent.ACTION_INSERT_OR_EDIT
+							//参考 https://blog.csdn.net/mls1454001840/article/details/60764351 之二
+							Contact existContact = cm.searchContact(contact.getName());
+							cm.updateContact(existContact,contact);
+
+							String contactId = cm.getContactID(existContact.getName());
+							Intent editIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("content://com.android.contacts/contacts/"+contactId));
+							startActivity(editIntent);
+//
+//							// 显示编辑界面
+//							String contactId = cm.getContactID(existContact.getName());
+//							cm.editContact(contactId,mContext);
+
+
+						}
+					})
+					.show();
+		} else {
+			// 自动保存,然后显示编辑
+//			cm.addContact(contact,true);
+//			// 显示编辑界面
+//			String contactId = cm.getContactID(contact.getName());
+//			editContact(contactId);
+
+			// 需要用户手动保存
+			cm.insertContact(contact,mContext);
+		}
+
+	}
+
+
+}

+ 31 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/InnerToolsActivity.java

@@ -0,0 +1,31 @@
+package com.usai.apex;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+
+import com.usai.apex.mainframe.ToolsFragment;
+
+public class InnerToolsActivity extends FragmentActivity
+{
+
+	@Override
+	protected void onCreate(Bundle savedInstanceState)
+	{
+		super.onCreate(savedInstanceState);
+		setContentView(R.layout.activity_inner_tools);
+
+		// Fragment f = new ToolsFragment();
+		if (savedInstanceState == null)
+		{
+			ToolsFragment f = new ToolsFragment();
+			Bundle b = new Bundle();
+			b.putBoolean("Login", true);
+			f.setArguments(b);
+			getSupportFragmentManager().beginTransaction()
+					.add(R.id.container, f).commit();
+		}
+
+
+	}
+
+}

+ 540 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/KPI/KPICell.java

@@ -0,0 +1,540 @@
+package com.usai.apex.KPI;
+
+import android.animation.Animator;
+import android.animation.ValueAnimator;
+import android.content.Context;
+import android.graphics.Color;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.TypedValue;
+import android.view.GestureDetector;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ImageButton;
+import android.widget.ListView;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import com.usai.apex.R;
+import com.usai.apex.mainframe.KPIFragment;
+
+import java.util.ArrayList;
+import java.util.Random;
+
+public class KPICell extends RelativeLayout implements KPIListView.KPIListViewTouchListener,View.OnTouchListener {
+
+    public KPICell(Context context) {
+        super(context);
+//        init();
+    }
+
+    public KPICell(Context context, @Nullable AttributeSet attrs) {
+        super(context, attrs);
+//        init();
+    }
+
+    public KPICell(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+//        init();
+    }
+
+
+    private KPICell mCell;
+    private ArrayList<PieChartView.ChartItem> mChartItems;
+    private PieChartView mChartView;
+    private ImageButton mPreBtn,mNextBtn;
+    private TextView mMonthTV,mShipTV,mContainerTV,mTeuTV,mSelectionTV;
+    private KPIListView mItemListView;
+    private ValueAnimator mAnimation;
+
+    public void init() {
+
+        mCell = this;
+
+        mDetector = new GestureDetector(getContext(), new GestureListener());
+        mMonthTV = findViewById(R.id.monthTV);
+        mShipTV = findViewById(R.id.shipmentTV);
+        mContainerTV = findViewById(R.id.containerTV);
+        mTeuTV = findViewById(R.id.teuTV);
+        mSelectionTV = findViewById(R.id.selectionTV);
+
+        mShipTV.setText(null);
+        mContainerTV.setText(null);
+        mTeuTV.setText(null);
+        mSelectionTV.setText(null);
+
+        mItemListView = findViewById(R.id.item_list);
+        mAdapter = new KPIItemAdapter(getContext(),R.layout.kpi_item_cell);
+        mItemListView.setAdapter(mAdapter);
+        mItemListView.setListener(this);
+
+        mChartView = findViewById(R.id.chart_view);
+
+        if (mAnimation == null) {
+            mAnimation = ValueAnimator.ofFloat(0f, 100f);
+
+            mAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+                @Override
+                public void onAnimationUpdate(ValueAnimator updatedAnimation) {
+                    // You can use the animated value in a property that uses the
+                    // same type as the animation. In this case, you can use the
+                    // float value in the translationX property.
+                    float animatedValue = (float)updatedAnimation.getAnimatedValue();
+
+                    mChartView.progress = animatedValue / 100.0f;
+                    mChartView.postInvalidate();
+                }
+            });
+
+            mAnimation.addListener(new Animator.AnimatorListener() {
+                @Override
+                public void onAnimationStart(Animator animation) {
+
+                }
+
+                @Override
+                public void onAnimationEnd(Animator animation) {
+
+                }
+
+                @Override
+                public void onAnimationCancel(Animator animation) {
+
+                }
+
+                @Override
+                public void onAnimationRepeat(Animator animation) {
+
+                }
+            });
+
+            mAnimation.setDuration(100);
+        }
+
+
+        mChartView.minTitleAngle = 20;
+        mChartView.setPieChartItemClickListener(new PieChartView.PieChartItemClickListener() {
+            @Override
+            public void pieChartItemClicked(PieChartView pieChartView, PieChartView.ChartItem item) {
+
+                if (mListener != null) {
+                    mListener.KPIPieChartClickedItem(mCell,item);
+                }
+                mAnimation.end();
+
+                mAnimation.start();
+
+            }
+
+            @Override
+            public void pieChartCenterClicked(PieChartView pieChartView) {
+
+                if (mListener != null) {
+                    mListener.KPIPieChartClickedTitle(mCell);
+                }
+            }
+
+            @Override
+            public void pieChartDidBeginTouch() {
+                if (mListener != null) {
+                    mListener.KPIPieChartDidBeginClicked();
+                }
+            }
+
+            @Override
+            public void pieChartDidEndTouch() {
+                if (mListener != null) {
+                    mListener.KPIPieChartDidEndClicked();
+                }
+            }
+        });
+
+//        mPreBtn = findViewById(R.id.preBtn);
+//        mPreBtn.setOnClickListener(new OnClickListener() {
+//            @Override
+//            public void onClick(View v) {
+//                if (mListener != null) {
+//                    mListener.KPIPreviousButtonClicked(mCell);
+//                }
+//            }
+//        });
+//
+//        mNextBtn = findViewById(R.id.nextBtn);
+//        mNextBtn.setOnClickListener(new OnClickListener() {
+//            @Override
+//            public void onClick(View v) {
+//                if (mListener != null) {
+//                    mListener.KPINextButtonClicked(mCell);
+//                }
+//            }
+//        });
+    }
+
+    private void resizePieChartView(int w) {
+
+        int leftInterval = dp2px(getContext(),60);
+        int rightInterval = dp2px(getContext(),60);
+
+        final int pieW = (w - leftInterval - rightInterval);
+
+
+        mChartView.post(new Runnable() {
+
+            @Override
+            public void run() {
+
+                LayoutParams layout = (LayoutParams)mChartView.getLayoutParams();
+                layout.width = (int)pieW;
+                layout.height = (int)pieW;
+                mChartView.setLayoutParams(layout);
+                mChartView.requestLayout();
+            }
+        });
+    }
+
+    public void setMonthShipment(String shipment, int color) {
+        mShipTV.setText("Shipment:" + shipment);
+        mShipTV.setTextColor(color);
+    }
+
+    public void setMonthContainer(String container, int color) {
+        mContainerTV.setText("Container:" + container);
+        mContainerTV.setTextColor(color);
+    }
+
+    public void setMonthTeu(String teu, int color) {
+        mTeuTV.setText("TEU:" + teu);
+        mTeuTV.setTextColor(color);
+    }
+
+    public void setNameAndCount(String name, int count) {
+        if (mChartView != null) {
+            mChartView.setNameAndCount(name,count);
+        }
+    }
+
+    private KPIFragment.KPIModel mModel;
+    public void setKPIModel(KPIFragment.KPIModel model) {
+        mModel = model;
+        if (model != null) {
+            setChartItems(model.items);
+            setNameAndCount(model.name,model.total);
+        }
+    }
+
+    public void setSelection(String selection) {
+        mSelectionTV.setText(selection);
+    }
+
+    @Override
+    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+
+        super.onSizeChanged(w, h, oldw, oldh);
+
+    }
+
+    private int mWidth = 0;
+    private int mHeight = 0;
+
+    public int getKPIWidth() {
+        return mWidth;
+    }
+
+    public int getKPIHeight() {
+        return mHeight;
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+
+        int w = getMeasuredWidth();
+        int h = getMeasuredHeight();
+
+        if (w != mWidth) {
+//            resizePieChartView(w);
+        }
+
+        mWidth = w;
+        mHeight = h;
+
+        float textSize = 7;
+        mMonthTV.setTextSize(TypedValue.COMPLEX_UNIT_PT,textSize);
+        mShipTV.setTextSize(TypedValue.COMPLEX_UNIT_PT,textSize);
+        mContainerTV.setTextSize(TypedValue.COMPLEX_UNIT_PT,textSize);
+        mTeuTV.setTextSize(TypedValue.COMPLEX_UNIT_PT,textSize);
+        mSelectionTV.setTextSize(TypedValue.COMPLEX_UNIT_PT,textSize);
+    }
+
+
+    float mTotal = 0;
+    private ArrayList<PieChartView.ChartItem> preparePieChartItems() {
+
+        float total = 0;
+        ArrayList<PieChartView.ChartItem> displayItems = new ArrayList<>();
+
+        if (mChartItems != null) {
+            total = 0;
+            for (int i = 0; i < mChartItems.size(); i++) {
+                PieChartView.ChartItem item = mChartItems.get(i);
+                if (item.display) {
+                    total += item.value;
+                }
+            }
+        } else {
+            total = 0;
+        }
+
+
+        for (int i = 0; i < mChartItems.size(); i++) {
+            PieChartView.ChartItem item = mChartItems.get(i);
+            if (item.display) {
+                if (total > 0) {
+                    item.setPercentage(item.value / total);
+                } else {
+                    item.setPercentage(0.f);
+                }
+
+                displayItems.add(item);
+            }
+        }
+
+        mTotal = total;
+        return displayItems;
+    }
+
+    private void refreshUI() {
+        ArrayList<PieChartView.ChartItem> displayItems = preparePieChartItems();
+        mChartView.setChartItems(displayItems);
+        mAdapter.notifyDataSetChanged();
+    }
+
+    public void setChartItems(ArrayList<PieChartView.ChartItem> chartItems) {
+        mChartItems = chartItems;
+        Log.d("KPI Cell", "setChartItems: ");
+        refreshUI();
+    }
+
+    public void randomColor() {
+        String r,g,b;
+        Random random = new Random();
+        r = Integer.toHexString(random.nextInt(256)).toUpperCase();
+        g = Integer.toHexString(random.nextInt(256)).toUpperCase();
+        b = Integer.toHexString(random.nextInt(256)).toUpperCase();
+
+        r = r.length()==1 ? "0" + r : r ;
+        g = g.length()==1 ? "0" + g : g ;
+        b = b.length()==1 ? "0" + b : b ;
+        int color = Color.parseColor("#" + r + g + b);
+        setBackgroundColor(color);
+    }
+
+    public static int dp2px(Context context, float dpValue) {
+        float scale = context.getResources().getDisplayMetrics().density;
+        return (int) (dpValue * scale + 0.5f);
+    }
+
+    public static int px2dp(Context context, float pxValue) {
+        float scale = context.getResources().getDisplayMetrics().density;
+        return (int) (pxValue / scale + 0.5f);
+    }
+
+    private KPIItemAdapter mAdapter;
+
+//    @Override
+//    public void onClick(View v) {
+//        if (v instanceof KPIItemButton) {
+//            KPIItemButton button = (KPIItemButton) v;
+//            Integer tag = (Integer) button.getTag();
+//            PieChartView.ChartItem item = mChartItems.get(tag);
+//            item.display = !item.display;
+//            refreshUI();
+//        }
+//    }
+
+    @Override
+    public void KPIListViewTouched(boolean t) {
+        if (mListener != null) {
+            mListener.KPIListTouched(t);
+        }
+    }
+
+    private class KPIItemAdapter extends BaseAdapter {
+
+        class ViewHolder {
+            KPIItemButton button_0, button_1;
+            ViewHolder(View root) {
+                if (root != null) {
+                    button_0 = root.findViewById(R.id.item_btn_0);
+                    button_1 = root.findViewById(R.id.item_btn_1);
+                    root.setTag(this);
+                }
+            }
+        }
+
+        int mLayoutId;
+        public KPIItemAdapter(Context context,int layoutId) {
+            mLayoutId = layoutId;
+        }
+
+        @NonNull
+        @Override
+        public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
+
+            ViewHolder holder;
+            if (convertView == null) {
+                convertView = LayoutInflater.from(getContext()).inflate(mLayoutId,null);
+                holder = new ViewHolder(convertView);
+            } else {
+                holder = (ViewHolder) convertView.getTag();
+            }
+            holder.button_0.setOnClickListener(null);
+            holder.button_1.setOnClickListener(null);
+            holder.button_0.setOnTouchListener(null);
+            holder.button_1.setOnTouchListener(null);
+
+            holder.button_0.setTitle(null);
+            holder.button_1.setTitle(null);
+            holder.button_0.setDotColor(Color.parseColor("#00000000"));
+            holder.button_1.setDotColor(Color.parseColor("#00000000"));
+
+            int index = 2 * position;
+            PieChartView.ChartItem item_0 = mChartItems.get(index);
+
+            if (item_0.display) {
+                holder.button_0.setTitle(String.format("%s(%.2f%%)",item_0.shortTitle,item_0.getPercentage() * 100));
+                holder.button_0.setTitleColor(Color.BLACK);
+                holder.button_0.setDotColor(item_0.color);
+            } else {
+                holder.button_0.setTitle(item_0.shortTitle);
+                holder.button_0.setDotColor(Color.LTGRAY);
+                holder.button_0.setTitleColor(Color.LTGRAY);
+            }
+
+            holder.button_0.setTag(index);
+            holder.button_0.setOnTouchListener(mCell);
+
+            if (index < mChartItems.size() - 1) {
+                PieChartView.ChartItem item_1 = mChartItems.get(index + 1);
+                if (item_1.display) {
+                    holder.button_1.setTitle(String.format("%s(%.2f%%)",item_1.shortTitle,item_1.getPercentage() * 100));
+                    holder.button_1.setDotColor(item_1.color);
+                    holder.button_1.setTitleColor(Color.BLACK);
+                } else {
+                    holder.button_1.setTitle(item_1.shortTitle);
+                    holder.button_1.setDotColor(Color.LTGRAY);
+                    holder.button_1.setTitleColor(Color.LTGRAY);
+                }
+
+                holder.button_1.setTag(index + 1);
+                holder.button_1.setOnTouchListener(mCell);
+            }
+
+            return convertView;
+        }
+
+        @Override
+        public int getCount() {
+
+            if (mChartItems == null) {
+                return 0;
+            }
+
+            int row = mChartItems.size() / 2;
+            int col = mChartItems.size() % 2;
+            if (col != 0) {
+                row++;
+            }
+
+            return row;
+        }
+
+        @Override
+        public Object getItem(int position) {
+            int index = 2 * position;
+            PieChartView.ChartItem item_0 = mChartItems.get(index);
+            return item_0;
+        }
+
+        @Override
+        public long getItemId(int position) {
+            return position;
+        }
+    }
+
+    private KPIListener mListener;
+    public void setListener(KPIListener listener) {
+        mListener = listener;
+    }
+
+    public KPIListener getListener() {
+        return mListener;
+    }
+
+    public interface KPIListener {
+
+        void KPIPieChartClickedItem(KPICell cell, PieChartView.ChartItem item);
+        void KPIPieChartClickedTitle(KPICell cell);
+//        void KPIPreviousButtonClicked(KPICell cell);
+//        void KPINextButtonClicked(KPICell cell);
+
+        void KPIPieChartDidBeginClicked();
+        void KPIPieChartDidEndClicked();
+
+        void KPIListTouched(boolean touch);
+
+        void KPICellDidDoubleClickItem(KPICell cell, int index, KPIFragment.KPIModel model);
+
+    }
+
+    private KPIItemButton mClickBtn;
+    private GestureDetector mDetector;
+
+    @Override
+    public boolean onTouch(View v, MotionEvent event) {
+
+        if (v instanceof KPIItemButton) {
+            mClickBtn = (KPIItemButton) v;
+            mDetector.onTouchEvent(event);
+        }
+
+        return true;
+    }
+
+    private class GestureListener extends GestureDetector.SimpleOnGestureListener {
+
+        @Override
+        public boolean onDoubleTapEvent(MotionEvent e) {
+
+
+            if (e.getAction() == MotionEvent.ACTION_UP) {
+                Log.d("KPI Cell", "onDoubleTapEvent: ");
+                if (mListener != null) {
+                    mListener.KPICellDidDoubleClickItem(mCell,(Integer) mClickBtn.getTag(),mModel);
+                }
+            }
+
+            return false;
+        }
+
+        @Override
+        public boolean onSingleTapConfirmed(MotionEvent e) {
+
+            Log.d("KPI Cell", "onSingleTapConfirmed: ");
+            if (mClickBtn != null) {
+                KPIItemButton button = mClickBtn;
+                Integer tag = (Integer) button.getTag();
+                PieChartView.ChartItem item = mChartItems.get(tag);
+                item.display = !item.display;
+                refreshUI();
+            }
+
+            return false;
+        }
+    }
+}

+ 67 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/KPI/KPIDot.java

@@ -0,0 +1,67 @@
+package com.usai.apex.KPI;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.RectF;
+import android.support.annotation.Nullable;
+import android.util.AttributeSet;
+import android.view.View;
+
+public class KPIDot extends View {
+    public KPIDot(Context context) {
+        super(context);
+    }
+
+    public KPIDot(Context context, @Nullable AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public KPIDot(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+    }
+
+    private int mWidth,mHeight;
+
+    int dotColor = -1;
+    public void setDotColor(int color) {
+        dotColor = color;
+        invalidate();
+    }
+
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+//        super.onDraw(canvas);
+
+        if (dotColor == -1) {
+            super.onDraw(canvas);
+            return;
+        }
+
+        setBackgroundColor(Color.WHITE);
+
+        Paint brush = new Paint(Paint.ANTI_ALIAS_FLAG);
+        brush.setAntiAlias(true); // 抗锯齿
+        brush.setDither(true); // 防抖动
+        brush.setStyle(Paint.Style.FILL);
+        brush.setColor(dotColor);
+
+        float r = Math.min(mWidth,mHeight) * 0.5f;
+        float x = (mWidth - 2 * r) * 0.5f;
+        float y = (mHeight - 2 * r) * 0.5f;
+        RectF rect = new RectF(x,y,x + 2 * r, y + 2 * r);
+        canvas.drawArc(rect,0,360,true,brush);
+    }
+
+    @Override
+    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+        super.onSizeChanged(w, h, oldw, oldh);
+
+        mWidth = w;
+        mHeight = h;
+
+        invalidate();
+    }
+}

+ 47 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/KPI/KPIItemButton.java

@@ -0,0 +1,47 @@
+package com.usai.apex.KPI;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import com.usai.apex.R;
+
+public class KPIItemButton extends RelativeLayout {
+
+    public KPIItemButton(Context context) {
+        super(context);
+    }
+
+    public KPIItemButton(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public KPIItemButton(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+    }
+
+    private KPIDot mDot;
+    private TextView mTextView;
+
+    public void setDotColor(int color) {
+        if (mDot == null) {
+            mDot = findViewById(R.id.icon_view);
+        }
+        mDot.setDotColor(color);
+    }
+
+    public void setTitle(String title) {
+        if (mTextView == null) {
+            mTextView = findViewById(R.id.name_tv);
+        }
+        mTextView.setText(title);
+    }
+
+    public void setTitleColor(int color) {
+        if (mTextView == null) {
+            mTextView = findViewById(R.id.name_tv);
+        }
+        mTextView.setTextColor(color);
+    }
+}

+ 47 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/KPI/KPIListView.java

@@ -0,0 +1,47 @@
+package com.usai.apex.KPI;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.widget.ListView;
+
+public class KPIListView extends ListView {
+
+    public KPIListView(Context context) {
+        super(context);
+    }
+
+    public KPIListView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public KPIListView(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent event) {
+
+         if (event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_MOVE) {
+             if (mListener != null) {
+                 mListener.KPIListViewTouched(true);
+             }
+        } else if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL) {
+             if (mListener != null) {
+                 mListener.KPIListViewTouched(false);
+             }
+        }
+
+        return super.onTouchEvent(event);
+    }
+
+    private KPIListViewTouchListener mListener;
+
+    public void setListener(KPIListViewTouchListener listener) {
+        this.mListener = mListener;
+    }
+
+    public interface KPIListViewTouchListener {
+        void KPIListViewTouched(boolean t);
+    }
+}

+ 53 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/KPI/KPISwipeRefresh.java

@@ -0,0 +1,53 @@
+package com.usai.apex.KPI;
+
+import android.content.Context;
+import android.support.v4.widget.SwipeRefreshLayout;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.MotionEvent;
+
+public class KPISwipeRefresh extends SwipeRefreshLayout {
+
+    public KPISwipeRefresh(Context context) {
+        super(context);
+    }
+
+    public KPISwipeRefresh(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    private float mFirstPointY = 0;
+
+    @Override
+    public boolean onInterceptTouchEvent(MotionEvent ev) {
+
+        Log.d("Refresh", "onInterceptTouchEvent: " + ev.getY() + "and Action: " + ev.getAction());
+
+        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
+            mFirstPointY = ev.getY();
+        }
+
+        // 防止下拉和ListView向上滑动冲突
+        if (mFirstPointY > 100) {
+            return false;
+        }
+
+        return super.onInterceptTouchEvent(ev);
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent ev) {
+
+        Log.d("Refresh OnTouch", "onInterceptTouchEvent: " + ev.getY() + "and Action: " + ev.getAction());
+        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
+            mFirstPointY = ev.getY();
+        }
+
+        // 防止下拉和ListView向上滑动冲突
+        if (mFirstPointY > 100) {
+            return false;
+        }
+
+        return super.onTouchEvent(ev);
+    }
+}

+ 88 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/KPI/KPIViewPager.java

@@ -0,0 +1,88 @@
+package com.usai.apex.KPI;
+
+import android.content.Context;
+import android.support.v4.view.ViewPager;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+
+public class KPIViewPager extends ViewPager {
+
+    private boolean scrollEnable = true;
+
+    public KPIViewPager(Context context) {
+        super(context);
+    }
+
+    public KPIViewPager(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public void setScrollEnable(boolean enable) {
+        scrollEnable = enable;
+    }
+
+    public boolean getScrollEnable() {
+        return scrollEnable;
+    }
+
+//    @Override
+//    public boolean onTouchEvent(MotionEvent ev) {
+//        if (scrollEnable) {
+//            return super.onTouchEvent(ev);
+//        }
+//        return false;
+//    }
+//
+//    @Override
+//    public boolean onInterceptTouchEvent(MotionEvent arg0) {
+//        if (scrollEnable) {
+//            return super.onInterceptTouchEvent(arg0);
+//        }
+//        return false;
+//    }
+
+
+    //mViewTouchMode表示ViewPager是否全权控制滑动事件,默认为true,即控制
+    private boolean mViewTouchMode = true;
+
+    public void setViewTouchMode(boolean b) {
+        if (b && !isFakeDragging()) {
+            //全权控制滑动事件
+            beginFakeDrag();
+        } else if (!b && isFakeDragging()) {
+            //终止控制滑动事件
+            endFakeDrag();
+        }
+        mViewTouchMode = b;
+    }
+
+    /**
+     * 在mViewTouchMode为true的时候,ViewPager不拦截点击事件,点击事件将由子View处理
+     */
+    @Override
+    public boolean onInterceptTouchEvent(MotionEvent event) {
+        if (mViewTouchMode || !scrollEnable) {
+            return false;
+        }
+        return super.onInterceptTouchEvent(event);
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent ev) {
+        if (scrollEnable) {
+            return super.onTouchEvent(ev);
+        }
+        return false;
+    }
+
+    /**
+     * 在mViewTouchMode为true或者滑动方向不是左右的时候,ViewPager将放弃控制点击事件,
+     * 这样做有利于在ViewPager中加入ListView等可以滑动的控件,否则两者之间的滑动将会有冲突
+     */
+    @Override
+    public boolean arrowScroll(int direction) {
+        if (mViewTouchMode) return false;
+        if (direction != FOCUS_LEFT && direction != FOCUS_RIGHT) return false;
+        return super.arrowScroll(direction);
+    }
+}

+ 711 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/KPI/PieChartView.java

@@ -0,0 +1,711 @@
+package com.usai.apex.KPI;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.PointF;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.graphics.drawable.ColorDrawable;
+import android.support.annotation.Nullable;
+import android.text.Layout;
+import android.text.StaticLayout;
+import android.text.TextPaint;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewParent;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Random;
+
+
+/**
+ * Created by macmini1 on 2018/3/28.
+ */
+
+public class PieChartView extends View {
+
+//    private static final long serialVersionUID = 4564384597971491851L;
+
+    private static float titleFontSize = 40.0f;
+    private static float nameFontSize = 50.0f;
+    private static float detal = 10;
+    private static double M_PI = 3.14159265358979323846264338327950288;
+    private static double M_PI_2 = 1.57079632679489661923132169163975144;
+
+    public interface PieChartItemClickListener {
+
+        void pieChartItemClicked(PieChartView pieChartView, ChartItem item);
+        void pieChartCenterClicked(PieChartView pieChartView);
+        void pieChartDidBeginTouch();
+        void pieChartDidEndTouch();
+    }
+
+    public static class ChartItem implements Serializable {
+
+        private static final long serialVersionUID = 1437379045091025768L;
+
+        public String shortTitle;
+        public boolean display = true;
+
+        public int color = -1;
+        public float value;
+        public String title;
+        public int titleColor = -1;
+
+        private float startAngle;
+        private float angle;
+        private float endAngle;
+        private boolean select;
+        private PointF titlePosition;
+        private float percentage;
+        private Size titleSize;
+
+
+
+        private int getColor() {
+            if (color == -1) {
+                String r,g,b;
+                Random random = new Random();
+                r = Integer.toHexString(random.nextInt(256)).toUpperCase();
+                g = Integer.toHexString(random.nextInt(256)).toUpperCase();
+                b = Integer.toHexString(random.nextInt(256)).toUpperCase();
+
+                r = r.length()==1 ? "0" + r : r ;
+                g = g.length()==1 ? "0" + g : g ;
+                b = b.length()==1 ? "0" + b : b ;
+                color = Color.parseColor("#" + r + g + b);
+            }
+            return color;
+        }
+
+        private int getTitleColor() {
+            if (titleColor == -1) {
+//                String r,g,b;
+//                Random random = new Random();
+//                r = Integer.toHexString(random.nextInt(256)).toUpperCase();
+//                g = Integer.toHexString(random.nextInt(256)).toUpperCase();
+//                b = Integer.toHexString(random.nextInt(256)).toUpperCase();
+//
+//                r = r.length()==1 ? "0" + r : r ;
+//                g = g.length()==1 ? "0" + g : g ;
+//                b = b.length()==1 ? "0" + b : b ;
+//                titleColor = Color.parseColor("#" + r + g + b);
+                titleColor = Color.WHITE;
+            }
+            return titleColor;
+        }
+
+        private PieChartView.Size measure() {
+
+            Paint textPaint = new Paint();
+            textPaint.setColor(getTitleColor());
+            textPaint.setTextSize(titleFontSize);
+            textPaint.setStyle(Paint.Style.FILL);
+            //该方法即为设置基线上那个点到底是left,center,还是right  这里我设置为center
+            textPaint.setTextAlign(Paint.Align.CENTER);
+
+
+            Rect rect = new Rect();
+            String msg = getMessage();
+            textPaint.getTextBounds(msg, 0, msg.length(), rect);
+            int width = rect.width();// 文字宽
+            int height = rect.height();// 文字高
+
+            Paint.FontMetrics fontMetrics = textPaint.getFontMetrics();
+            float top = fontMetrics.top;//为基线到字体上边框的距离,即上图中的top
+            float bottom = fontMetrics.bottom;//为基线到字体下边框的距离,即上图中的bottom
+            float baseY = 0 - top / 2.0f - bottom / 2.0f;//基线中间点的y轴计算公式
+
+
+            titleSize = new Size(width,height);
+            return titleSize;
+        }
+
+        public float getPercentage() {
+            return percentage;
+        }
+
+        public void setPercentage(float percent) {
+            percentage = percent;
+        }
+
+        private String getMessage() {
+            return String.format("%.2f%%",percentage * 100);
+        }
+    }
+
+    private static class Size implements Serializable {
+        private static final long serialVersionUID = 3369542887994794927L;
+        int mWidth, mHeight;
+        public Size(int width, int height) {
+            mWidth = width;
+            mHeight = height;
+        }
+    }
+
+    public static int px2dp(Context context, float pxValue) {
+        float scale = context.getResources().getDisplayMetrics().density;
+        return (int) (pxValue / scale + 0.5f);
+    }
+
+    public static int dp2px(Context context, float dpValue) {
+        float scale = context.getResources().getDisplayMetrics().density;
+        return (int) (dpValue * scale + 0.5f);
+    }
+
+    public static int px2sp(Context context, float pxValue) {
+        float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
+        return (int) (pxValue / fontScale + 0.5f);
+    }
+
+    public static int sp2px(Context context, float spValue) {
+        float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
+        return (int) (spValue * fontScale + 0.5f);
+    }
+
+
+    private Paint mBrush = new Paint(Paint.ANTI_ALIAS_FLAG);
+    private int mWidth,mHeight;
+    private Context mCtx;
+    private ArrayList<ChartItem> chartItems = new ArrayList<>();
+    private ChartItem mSelectedItem;
+    private float mRadius;
+    private PieChartItemClickListener mPieChartItemClickListener;
+    public float minTitleAngle = 0;
+
+    public float progress = 0;
+
+    public PieChartView(Context context) {
+        this(context,null);
+    }
+
+    public PieChartView(Context context, @Nullable AttributeSet attrs) {
+        this(context, attrs,0);
+    }
+
+    public PieChartView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        mCtx = context;
+        init();
+    }
+
+    public void setPieChartItemClickListener(PieChartItemClickListener listener) {
+        mPieChartItemClickListener = listener;
+    }
+
+
+    private float total = 0;
+    public void setChartItems(ArrayList<ChartItem> items) {
+        chartItems = items;
+
+        if (items != null) {
+            total = 0;
+            for (int i = 0; i < items.size(); i++) {
+                ChartItem item = items.get(i);
+                total += item.value;
+            }
+
+        } else {
+            chartItems = new ArrayList<>();
+            total = 0;
+        }
+
+        invalidate();
+    }
+
+    private String mName;
+    private int mCount;
+    public void setNameAndCount(String name, int count) {
+        mName = name;
+        mCount = count;
+    }
+
+    public void setRadius(float radius) {
+        mRadius = dp2px(getContext(),radius);
+    }
+
+    private void init() {
+
+        setBackgroundColor(Color.WHITE);
+        mBrush.setAntiAlias(true); // 抗锯齿
+        mBrush.setDither(true); // 防抖动
+        mBrush.setStyle(Paint.Style.FILL);
+    }
+
+    @Override
+    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+        super.onSizeChanged(w, h, oldw, oldh);
+        mWidth = w;
+        mHeight = h;
+
+        mRadius = radius();
+        titleFontSize = 4.0f * px2dp(getContext(),mRadius) / 18.0f;
+        nameFontSize = 5.0f * px2dp(getContext(),mRadius) / 18.0f;
+        invalidate();
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+
+        if (total == 0) {
+            super.onDraw(canvas);
+        } else {
+
+            prepareItems();
+
+            showPie(canvas);
+
+            float hollowR = radius() * 0.5f;
+            float x = (mWidth - hollowR * 2) * 0.5f;
+            float y = (mHeight - hollowR * 2) * 0.5f;
+
+            RectF rect = new RectF(x, y,x + 2 * hollowR, y + 2 * hollowR);
+
+            Paint hollowPaint = new Paint();
+            hollowPaint.setAntiAlias(true); // 抗锯齿
+            hollowPaint.setDither(true); // 防抖动
+            hollowPaint.setStyle(Paint.Style.FILL);
+            ColorDrawable colordDrawable = (ColorDrawable) getBackground();
+            int color = colordDrawable.getColor();
+            hollowPaint.setColor(color);
+            canvas.drawArc(rect,0,360,true,hollowPaint);
+
+            drawPieTitle(canvas,mName,String.format("%d",mCount));
+        }
+
+    }
+
+    private void showPie(Canvas canvas) {
+
+        for (int i = 0; i < chartItems.size(); i++) {
+            ChartItem item = chartItems.get(i);
+            drawPieItem(canvas,item);
+        }
+    }
+
+    private void prepareItems() {
+
+
+        float perIntervalAngle = 1.0f;
+
+        ArrayList<ChartItem> zeroItems = new ArrayList<>();
+        // 剔除value == 0
+        for (int i = 0; i < chartItems.size(); i++) {
+            ChartItem item = chartItems.get(i);
+            if (item.value == 0) {
+                zeroItems.add(item);
+            }
+        }
+
+        if (zeroItems.size() > 0) {
+            for (int j = 0; j < zeroItems.size(); j++) {
+                ChartItem item = zeroItems.get(j);
+                chartItems.remove(item);
+            }
+        }
+
+        if (chartItems.size() == 1) {
+            perIntervalAngle = 0;
+        }
+        float totalIntervalAngle = perIntervalAngle * chartItems.size();
+        float totalAngle = 360.f - totalIntervalAngle;
+        float currentAngle = perIntervalAngle;
+
+        for (int i = 0; i < chartItems.size(); i++) {
+            ChartItem item = chartItems.get(i);
+            if (total > 0) {
+                item.percentage = item.value / total;
+            } else {
+                item.percentage = 0.f;
+            }
+            item.startAngle = currentAngle;
+            item.angle = totalAngle * item.percentage;
+            item.endAngle = item.startAngle + item.angle;
+
+            currentAngle += item.angle + perIntervalAngle;
+
+
+            float midAngle = (item.startAngle + item.endAngle) * 0.5f;
+
+            PointF point = findTitlePosition(midAngle);
+            item.titlePosition = point;
+            Size titleSize = item.measure();
+//            float x = point.x + titleSize.mWidth * 0.5f;
+//            float y = point.y - titleSize.mHeight * 0.5f;
+//
+//            item.titlePosition = new PointF(x,y);
+
+        }
+
+        // Title
+//        int lcount = lbArr.size() + ltArr.size();
+//        int rcount = rbArr.size() + rtArr.size();
+//
+//        float lh = mHeight / (lcount * 1.0f);
+//        float rh = mHeight / (rcount * 1.0f);
+//
+//        // 0
+//        for (int i = rbArr.size() - 1; i >= 0; i--) {
+//            // 最后一个Title在最下
+//            ChartItem item = rbArr.get(i);
+//            int index = (rbArr.size() - 1) - i;
+//
+//            float maxY = mHeight - rh * index;
+//            float minY = mHeight - rh * (index + 1);
+//            Size titleSize = item.measure();
+//
+////            float y = mHeight - rh * (index + 0.5f);
+//            float y = perfectY(maxY,minY,item.lineEndPoint.y,titleSize.mHeight);
+//            float x = mWidth * 1.0f - titleSize.mWidth;
+//            item.baseX = x + 0.5f * titleSize.mWidth;
+//
+//            item.titlePoint = new PointF(x,y);
+////            Log.d("prepareItems", "RB: " + item.title);
+//        }
+//        // 1
+//        for (int i = 0; i < lbArr.size(); i++) {
+//            // 第一个Title在最下
+//            ChartItem item = lbArr.get(i);
+//            int index = i;
+//            float maxY = mHeight - lh * index;
+//            float minY = mHeight - lh * (index + 1);
+//            Size titleSize = item.measure();
+//
+////            float y = mHeight - lh * (index + 0.5f);
+//            float y = perfectY(maxY,minY,item.lineEndPoint.y,titleSize.mHeight);
+//            float x = titleSize.mWidth;
+//            item.baseX = x - 0.5f * titleSize.mWidth;
+//
+//            item.titlePoint = new PointF(x,y);
+////            Log.d("prepareItems", "LB: " + item.title);
+//        }
+//
+//        // 2
+//        for (int i = ltArr.size() - 1; i >= 0; i--) {
+//            //最后一个Title在最上
+//            ChartItem item = ltArr.get(i);
+//            int index = (ltArr.size() - 1) - i;
+//
+//            float minY = lh * index;
+//            float maxY = lh * (index + 1);
+//            Size titleSize = item.measure();
+//
+////            float y = lh * (index + 0.5f);
+//            float x = titleSize.mWidth;
+//            float y = perfectY(maxY,minY,item.lineEndPoint.y,titleSize.mHeight);
+//            item.baseX = x - 0.5f * titleSize.mWidth;
+//
+//            item.titlePoint = new PointF(x,y);
+////            Log.d("prepareItems", "LT: " + item.title);
+//        }
+//
+//        // 3
+//        for (int i = 0; i < rtArr.size(); i++) {
+//            // 第一个Title在最上
+//            ChartItem item = rtArr.get(i);
+//            int index = i;
+//
+//            float minY = rh * index;
+//            float maxY = rh * (index + 1);
+//            Size titleSize = item.measure();
+//
+////            float y = rh * (index + 0.5f);
+//            float x = mWidth * 1.0f - titleSize.mWidth;
+//            float y = perfectY(maxY,minY,item.lineEndPoint.y,titleSize.mHeight);
+//            item.baseX = x + 0.5f * titleSize.mWidth;
+//
+//            item.titlePoint = new PointF(x,y);
+//            Log.d("prepareItems", "RT: " + item.title);
+//        }
+
+    }
+
+    public float perfectY(float maxY, float minY,float py, float h) {
+        float min_y = py - h * 0.5f, max_y = py + h * 0.5f;
+        if (min_y >= minY && max_y <= maxY) {
+            return py;
+        }
+
+        if ((min_y - minY) < 0) {
+            py += minY - min_y;
+        } else {
+            py -= max_y - maxY;
+        }
+
+        return py;
+    }
+
+    private void drawPieTitle(Canvas canvas, String title, String count) {
+
+        if (canvas == null || title == null || count == null) {
+            return;
+        }
+
+        if (title.length() == 0 || count.length() == 0) {
+            return;
+        }
+
+        float centerX = mWidth * 0.5f;
+        float centerY = mHeight * 0.5f;
+
+        float r = mRadius * 0.5f;
+        float w = (float) (Math.sqrt(Math.pow(r,2) / 2)) * 2.0f;
+        float h = w;
+
+        float x = centerX - w * 0.5f;
+        float y = centerY - h * 0.5f;
+
+//        String msg = "Per ETA\r\nContainer\r\n485845";
+
+//        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
+//        paint.setStyle(Paint.Style.STROKE);
+//        canvas.drawLine(x,y,x + w,y,paint);
+
+        String msg = title + "\r\n" + count;
+
+        canvas.save();
+
+        TextPaint textPaint = new TextPaint();
+        textPaint.setColor(Color.BLACK);
+        textPaint.setTextSize(nameFontSize);
+        textPaint.setAntiAlias(true);
+
+        StaticLayout layout = new StaticLayout(msg, textPaint, (int)w, Layout.Alignment.ALIGN_CENTER, 1.0F, 0.0F, true);
+
+        y = y + (h - layout.getHeight()) * 0.5f;
+        canvas.translate(x,y);
+        layout.draw(canvas);
+
+        canvas.restore();
+
+
+
+//        canvas.drawText(msg,x,y,textPaint);
+    }
+
+    private void drawPieItem(Canvas canvas,ChartItem item) {
+        if (item == null || canvas == null) {
+            return;
+        }
+
+        // draw Pie
+        if (item.angle > 0) {
+            float r = radius();
+            if (item.select) {
+                r += detal * progress;
+            }
+            float x = (mWidth - r * 2) * 0.5f;
+            float y = (mHeight - r * 2) * 0.5f;
+
+            RectF rect = new RectF(x, y,x + 2 * r, y + 2 * r);
+
+            mBrush.setColor(item.getColor());
+            canvas.drawArc(rect,item.startAngle,item.angle,true,mBrush);
+        }
+
+        if (minTitleAngle > item.angle) {
+            return;
+        }
+
+        // draw Title
+        Paint textPaint = new Paint();
+        textPaint.setColor(item.getTitleColor());
+        textPaint.setTextSize(titleFontSize);
+        textPaint.setStyle(Paint.Style.FILL);
+        //该方法即为设置基线上那个点到底是left,center,还是right  这里我设置为center
+        textPaint.setTextAlign(Paint.Align.CENTER);
+
+        String msg = item.getMessage();
+        canvas.drawText(msg,item.titlePosition.x,item.titlePosition.y + item.titleSize.mHeight * 0.5f,textPaint);
+
+
+//        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
+//        paint.setStyle(Paint.Style.STROKE);
+//        canvas.drawLine(item.titlePosition.x - 40.0f,item.titlePosition.y,item.titlePosition.x + 40.0f, item.titlePosition.y,paint);
+//        canvas.drawLine(item.titlePosition.x,item.titlePosition.y - 400.f,item.titlePosition.x, item.titlePosition.y + 40.0f,paint);
+
+    }
+
+    private PointF center() {
+        return new PointF(mWidth * 0.5f,mHeight * 0.5f);
+    }
+
+    private float radius() {
+//        if (mRadius <= 0) {
+            return Math.min(mWidth,mHeight) * 0.5f * 0.9f;
+//        } else {
+//            return mRadius;
+//        }
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent event) {
+
+        if (event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_MOVE) {
+
+            float touchX = event.getX();
+            float touchY = event.getY();
+
+            float distance = (float) Math.sqrt(Math.pow(center().x - touchX,2) + Math.pow(center().y - touchY,2));
+
+            if (distance < radius() * 0.5f) {
+                if (event.getAction() == MotionEvent.ACTION_DOWN) {
+                    if (mPieChartItemClickListener != null) {
+                        mPieChartItemClickListener.pieChartDidBeginTouch();
+                    }
+                }
+
+                if (mPieChartItemClickListener != null) {
+                    mPieChartItemClickListener.pieChartCenterClicked(this);
+                }
+                return true;
+            }
+
+            if (distance > radius()) {
+                return super.onTouchEvent(event);
+            }
+
+            if (event.getAction() == MotionEvent.ACTION_DOWN) {
+                if (mPieChartItemClickListener != null) {
+                    mPieChartItemClickListener.pieChartDidBeginTouch();
+                }
+            }
+
+            double rad_angle = findAngleBytouchPoint(touchX,touchY);
+            float angle = (float) (180.0f / M_PI * rad_angle);
+
+            Log.d("Touch", String.format("onTouch Angle: %f",angle));
+
+            Iterator iterator = chartItems.iterator();
+            while (iterator.hasNext()) {
+                ChartItem item = (ChartItem) iterator.next();
+                if (item.startAngle <= angle && item.endAngle >= angle) {
+                    if (mSelectedItem != null) {
+                        if (mSelectedItem == item) {
+                            break;
+                        } else {
+                            mSelectedItem.select = false;
+                        }
+                    }
+                    mSelectedItem = item;
+                    mSelectedItem.select = true;
+                    invalidate();
+                    if (mPieChartItemClickListener != null) {
+                        mPieChartItemClickListener.pieChartItemClicked(this,item);
+                    }
+                    break;
+                }
+            }
+            return true;
+        } else if (event.getAction() == MotionEvent.ACTION_CANCEL || event.getAction() == MotionEvent.ACTION_UP) {
+
+            if (mPieChartItemClickListener != null) {
+                mPieChartItemClickListener.pieChartDidEndTouch();
+            }
+
+            if (mSelectedItem != null) {
+                mSelectedItem.select = false;
+                invalidate();
+                mSelectedItem = null;
+            }
+            if (mPieChartItemClickListener != null) {
+                mPieChartItemClickListener.pieChartItemClicked(this,null);
+            }
+
+        }
+
+
+
+        return super.onTouchEvent(event);
+    }
+
+    private double findAngleBytouchPoint(float touchX, float touchY) {
+
+        float r = mRadius;
+        float x = (mWidth - r * 2) * 0.5f;
+        float y = (mHeight - r * 2) * 0.5f;
+        RectF rect = new RectF(x, y,x + 2 * r, y + 2 * r);
+
+        if (rect.contains(touchX,touchY)) {
+
+            float centerX = mWidth * 0.5f;
+            float centerY = mHeight * 0.5f;
+
+            float distance = (float) Math.sqrt(Math.pow(centerX - touchX,2) + Math.pow(centerY - touchY,2));
+            float angle = (float) Math.asin(Math.abs(touchY - centerY) / distance);
+
+            float offsetX = touchX - centerX;
+            float offsetY = touchY - centerY;
+
+
+            if (offsetX > 0 && offsetY > 0) {
+                return angle;
+            }
+            if (offsetX < 0 && offsetY > 0) {
+                return M_PI - angle;
+            }
+            if (offsetX < 0 && offsetY < 0) {
+                return M_PI + angle;
+            }
+            if (offsetX > 0 && offsetY < 0) {
+                return M_PI * 2 - angle;
+            }
+            if (offsetX == 0) {
+                if (offsetY > 0) {
+                    return M_PI;
+                }
+                if (offsetY < 0) {
+                    return M_PI_2 * 3;
+                }
+            }
+            if (offsetY == 0) {
+                if (offsetX > 0) {
+                    return 0;
+                }
+                if (offsetX < 0) {
+                    return M_PI;
+                }
+            }
+
+            return 0;
+
+        }
+        return 0;
+    }
+
+    private PointF findTitlePosition(float angle) {
+
+        float centerX = mWidth * 0.5f;
+        float centerY = mHeight * 0.5f;
+        float r = mRadius * 0.75f;
+        float rad = (float) (angle * M_PI / 180.0f);
+
+        return new PointF(centerX + (float) Math.cos(rad) * r, centerY + (float) Math.sin(rad) * r);
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+
+//        KPICell p = (KPICell) getParent();
+//        int w = p.getKPIWidth();
+//
+//        int leftInterval = dp2px(getContext(),60);
+//        int rightInterval = dp2px(getContext(),60);
+//
+//        int pieW = (w - leftInterval - rightInterval);
+
+//        widthMeasureSpec = MeasureSpec.makeMeasureSpec(pieW, MeasureSpec.EXACTLY);
+//        heightMeasureSpec = MeasureSpec.makeMeasureSpec(pieW, MeasureSpec.EXACTLY);
+
+        int width = MeasureSpec.getSize(widthMeasureSpec);
+        heightMeasureSpec = MeasureSpec.makeMeasureSpec(width,MeasureSpec.EXACTLY);
+
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+    }
+}

+ 70 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/LicenseActivity.java

@@ -0,0 +1,70 @@
+package com.usai.apex;
+
+import android.os.Bundle;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AppCompatActivity;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.TextView;
+
+public class LicenseActivity extends AppCompatActivity {
+    private void setCustomActionBar() {
+        ActionBar.LayoutParams lp =new ActionBar.LayoutParams(ActionBar.LayoutParams.MATCH_PARENT, ActionBar.LayoutParams.MATCH_PARENT, Gravity.CENTER);
+        View mActionBarView = LayoutInflater.from(this).inflate(R.layout.actionbar_customtitle, null);
+
+        TextView mtitleview= mActionBarView.findViewById(R.id.title);
+
+//        String license_name=getIntent().getStringExtra("function_name");
+        String function_name = getIntent().getStringExtra("function_name");
+//        String title = "";
+//        if(function_name.equals("Ocean Booking"))
+//            title="Booking Detail";
+//        else if(function_name.equals("Ocean B/L info."))
+//            title="B/L info. Detail";
+//        else if(function_name.equals("Container detail"))
+//            title="Container Detail";
+//        else if(function_name.equals("Cargo Tracking"))
+//            title="Cargo Detail";
+        mtitleview.setText(function_name);
+        setTitle(function_name);
+////
+//        mActionBarView.setBackgroundColor(Color.YELLOW);
+//        titleview.setBackgroundColor(Color.BLUE);
+        ActionBar actionBar = getSupportActionBar();
+        actionBar.setCustomView(mActionBarView, lp);
+//        actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
+//        actionBar.setDisplayShowCustomEnabled(true);
+        actionBar.setDisplayHomeAsUpEnabled(true);
+
+
+//        actionBar.setIcon(getNumberDrawable());
+//        actionBar.setDisplayShowHomeEnabled(true);
+        actionBar.setDisplayShowTitleEnabled(true);
+    }
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_license);
+        setCustomActionBar();
+        String license_content=getIntent().getStringExtra("content");
+
+        TextView tv = findViewById(R.id.tv_license);
+        tv.setText(license_content);
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+
+
+            case android.R.id.home:
+                finish();
+                break;
+                default:
+                    break;
+        }
+        return super.onOptionsItemSelected(item);
+    }
+}

+ 203 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/LocalDocumentActivity.java

@@ -0,0 +1,203 @@
+package com.usai.apex;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.usai.util.commonUtil;
+
+import android.app.ListActivity;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Color;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Environment;
+import android.util.Log;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.SimpleAdapter;
+
+public class LocalDocumentActivity extends ListActivity
+{
+	public static final String FILETYPE ="pdf";
+	private List<Map<String, Object>> getData()
+	{
+		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
+
+		
+	
+        if(commonUtil.localdirExist())
+        {
+        	File path = new File(Environment.getExternalStorageDirectory().getPath()+"/Apex Mobile");
+            //返回文件夹中有的数据
+            File[] files = path.listFiles();
+            //先判断下有没有权限,如果没有权限的话,就不执行了
+            if(null == files)
+                return list;
+            for(int i = 0; i < files.length; i++)
+            {
+//				String filePath = files[i].getAbsolutePath();
+				String fileName = files[i].getName();
+				String[] token = fileName.split("\\.");
+				String ext = token[token.length-1];
+				if(!FILETYPE.contains(ext))
+					continue;
+
+				Map<String, Object> map = new HashMap<String, Object>();
+				map.put("title", fileName);
+				map.put("ext", ext);
+				if(ext.toLowerCase().equals("pdf"))
+					map.put("img", R.drawable.ic_pdf128);
+				else
+					map.put("img", R.drawable.ic_file128);
+				list.add(map);
+
+            }
+        }
+		return list;
+	}
+
+
+	@Override
+	protected void onCreate(Bundle savedInstanceState)
+	{
+
+		super.onCreate(savedInstanceState);
+		setContentView(R.layout.message_list);
+
+		SimpleAdapter adapter = new DocumentsAdapter(this,
+				getData(), R.layout.documents_list_item, new String[] { "title",
+						"img" }, new int[] { R.id.tv_toolname, R.id.iv_thumb});
+		setListAdapter(adapter);
+		this.getListView().setBackgroundColor(Color.WHITE);		
+		
+	}
+
+	@Override
+	public void onListItemClick(ListView l, View v, int position, long id)
+	{
+		Log.d("FragmentList", "Item clicked: " + id);
+		String filename = (String) getData().get(position).get("title");
+		Intent intent = new Intent("android.intent.action.VIEW");
+
+		intent.addCategory("android.intent.category.DEFAULT");
+
+		intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+		Uri uri = Uri.fromFile(new File(Environment
+				.getExternalStorageDirectory().getPath()
+				+ "/Apex Mobile/"
+				+ filename));
+
+		intent.setDataAndType(uri, "application/"+(String) getData().get(position).get("ext"));
+//	    startActivity(intent);
+	    startActivity(Intent.createChooser(intent,getString(R.string.str_openfile)));
+//		
+//		Intent intent = new Intent();
+//		if(title.equals("Search documents online"))
+//		{
+//			intent.setClass(this, SearchListActivity.class);
+//	
+//			intent.putExtra("function_name", "Download Document");
+//			intent.putExtra("title", "Document Search");
+//
+//		}
+//		else if(title.equals("View download documents"))
+//		{
+//			intent.setClass(this, AnnouncementActivity.class);
+//			intent.putExtra("module_name", "Announcements");
+//		}
+//
+//		
+//		startActivity(intent);
+
+	}
+	
+	private class DocumentsAdapter extends SimpleAdapter
+	{
+
+//		private LayoutInflater	mInflater;
+		@Override
+		public View getView( int position, View convertView, ViewGroup parent)
+		{
+			convertView =super.getView(position, convertView, parent);
+			// TODO Auto-generated method stub
+//			convertView = mInflater.inflate(R.layout.announcement_item, null);// 根据布局文件实例化view
+
+			ImageView iv = (ImageView)convertView.findViewById(R.id.iv_share);
+			iv.setTag( (String) getData().get(position).get("title"));
+			iv.setOnClickListener(new OnClickListener()
+			{
+				
+				@Override
+				public void onClick(View v)
+				{
+					Intent share = new Intent(Intent.ACTION_SEND);   
+					String filename = (String) v.getTag();
+					share.putExtra(Intent.EXTRA_STREAM, 
+					Uri.fromFile(new File(Environment.getExternalStorageDirectory().getPath()+"/Apex Mobile/"+filename)));
+					String[] token = filename.split("\\.");
+					String ext = token[token.length-1];
+					share.setType("application/"+ext);//此处可发送多种文件
+					startActivity(Intent.createChooser(share,getString(R.string.str_sendto)));
+					
+				}
+			});
+//			TextView title = (TextView) convertView.findViewById(R.id.tv_title);// 找某个控件
+//			title.setText(result.getData().get(position).get("title")
+//					.toString());// 给该控件设置数据(数据从集合类中来)
+//			TextView content = (TextView) convertView
+//					.findViewById(R.id.tv_content);
+//			content.setText(result.getData().get(position).get("content")
+//					.toString());
+//			if (result.getData().get(position).get("image").toString().length() > 0)
+//			{
+//				byte[] gzipBuff = Base64.decode(result.getData().get(position)
+//						.get("image").toString(), 0);
+//
+//				ByteArrayInputStream memstream = new ByteArrayInputStream(
+//						gzipBuff, 0, gzipBuff.length);
+//
+//				ByteArrayOutputStream baos = new ByteArrayOutputStream(
+//						gzipBuff.length);
+//				ImageView iv_thumb = (ImageView) convertView
+//						.findViewById(R.id.iv_thumb);
+//				try
+//				{
+//					baos.write(gzipBuff);
+//
+//					Bitmap bmp = BitmapFactory.decodeStream(memstream);
+//
+//					// ImageView image = new ImageView(this);
+//
+//					iv_thumb.setImageBitmap(bmp);
+//				}
+//				catch (IOException e)
+//				{
+//					// TODO Auto-generated catch block
+//					e.printStackTrace();
+//				}
+//			}
+//			// img.setBackgroundResource((Integer)jObject.get("img"));
+
+			return convertView;
+		}
+		public DocumentsAdapter(Context context,
+				List<? extends Map<String, ?>> data, int resource,
+				String[] from, int[] to)
+		{
+			
+			super(context, data, resource, from, to);
+			
+//			this.mInflater = LayoutInflater.from(context);
+			// TODO Auto-generated constructor stub
+		}
+		
+	}
+}

+ 29 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/LocationDetail.java

@@ -0,0 +1,29 @@
+package com.usai.apex;
+
+import java.io.Serializable;
+
+public class LocationDetail implements Serializable
+{
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = -8043239175565480418L;
+	public String Name,Addr,Tel,Fax,Contact,Email;
+	LocationDetail(String name,String addr,String tel,String fax,String contact,String email)
+	{
+//		Name="aa";
+//		Addr="aa";
+//		Tel="aa";
+//		Fax="aa";
+//		Contact="aa";
+//		Email="aa";
+		Name=name;
+		Addr=addr;
+		Tel=tel;
+		Fax=fax;
+		Contact=contact;
+		Email=email;
+		
+	}
+
+}

+ 171 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/LocationDetailActivity.java

@@ -0,0 +1,171 @@
+package com.usai.apex;
+
+import java.util.List;
+
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.CommonDataKinds.Email;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.provider.ContactsContract.Data;
+//import android.provider.Contacts;
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.database.Cursor;
+import android.util.Log;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.TextView;
+import android.widget.Toast;
+
+public class LocationDetailActivity extends Activity
+{
+	LocationDetail	detail;
+
+	boolean isIntentAvailable(Context context, Intent intent)
+	{
+		final PackageManager packageManager = context.getPackageManager();
+		List<ResolveInfo> list = packageManager.queryIntentActivities(intent,
+				PackageManager.GET_ACTIVITIES);
+		return list.size() > 0;
+	}
+
+	public int getContactid(String name)
+	{
+		int _id = -1;
+
+		Cursor cursor = getContentResolver()
+				.query(Data.CONTENT_URI,
+						new String[] { Data._ID, Data.DISPLAY_NAME,
+								Data.DISPLAY_NAME_ALTERNATIVE,
+								Data.DISPLAY_NAME_SOURCE }, Data.DISPLAY_NAME+"='"+name+"'", null, null);
+
+		Log.d("", "contact " + Data.DISPLAY_NAME + name);
+
+		// Uri uri =
+		// Uri.parse("content://com.android.contacts/data/name/filter/" +
+		// number);
+		// ContentResolver resolver = getContentResolver();
+		// Cursor cursor = resolver.query(uri, new String[]{"_id"}, null, null,
+		// null);
+		while (cursor.moveToNext())
+		{
+			Log.d("", "cursor=" + cursor.getString(1) + cursor.getString(2)
+					+ cursor.getString(3));
+			_id = cursor.getInt(0);
+
+		}
+		cursor.close();
+		return _id;
+	}
+
+	@Override
+	protected void onCreate(Bundle savedInstanceState)
+	{
+		super.onCreate(savedInstanceState);
+		setContentView(R.layout.activity_location_detail);
+		detail = (LocationDetail) getIntent().getSerializableExtra("detail");
+		TextView tv_name = (TextView) findViewById(R.id.tv_title);
+		tv_name.setText(detail.Name);
+		// tv_name.setMovementMethod(LinkMovementMethod.getInstance());
+		TextView tv_addr = (TextView) findViewById(R.id.tv_addr);
+		tv_addr.setText(getString(R.string.str_address)+detail.Addr);
+		// tv_name.setMovementMethod(LinkMovementMethod.getInstance());
+		TextView tv_tel = (TextView) findViewById(R.id.tv_tel);
+		tv_tel.setText(getString(R.string.str_tel)+detail.Tel);
+		// tv_name.setMovementMethod(LinkMovementMethod.getInstance());
+		TextView tv_fax = (TextView) findViewById(R.id.tv_fax);
+		tv_fax.setText(getString(R.string.str_fax)+detail.Fax);
+		// tv_name.setMovementMethod(LinkMovementMethod.getInstance());
+		TextView tv_contact = (TextView) findViewById(R.id.tv_contact);
+		tv_contact.setText(getString(R.string.str_contact)+detail.Contact);
+		// tv_name.setMovementMethod(LinkMovementMethod.getInstance());
+		TextView tv_email = (TextView) findViewById(R.id.tv_email);
+		tv_email.setText(getString(R.string.str_email)+detail.Email);
+		// tv_name.setMovementMethod(LinkMovementMethod.getInstance());
+
+		Button btn = (Button) findViewById(R.id.btn_addcontact);
+		btn.setOnClickListener(new OnClickListener()
+		{
+
+			@Override
+			public void onClick(View v)
+			{
+
+				int _id = getContactid(detail.Name);
+				Log.d("", "contact id = " + _id);
+				Intent it = new Intent(ContactsContract.Intents.SHOW_OR_CREATE_CONTACT, 
+		                ContactsContract.Contacts.CONTENT_URI); 
+				it.setData(Uri.parse("tel:"+detail.Tel));
+				it.putExtra(ContactsContract.Intents.EXTRA_FORCE_CREATE, true);
+//				it.setType(ContactsContract.Contacts.CONTENT_TYPE);// .People.CONTENT_TYPE);
+				it.putExtra(ContactsContract.Intents.Insert.COMPANY,
+						detail.Name);
+				
+				
+				String tel[] = detail.Tel.split("\n");
+				if(tel.length>0)
+				{
+					it.putExtra(ContactsContract.Intents.Insert.PHONE, tel[0]);
+					it.putExtra(ContactsContract.Intents.Insert.PHONE_TYPE, Phone.TYPE_WORK);
+				}
+				if(tel.length>1)
+				{
+					it.putExtra(ContactsContract.Intents.Insert.SECONDARY_PHONE, tel[1]);
+					it.putExtra(ContactsContract.Intents.Insert.SECONDARY_PHONE_TYPE, Phone.TYPE_WORK);
+				}
+				if(tel.length>2)
+				{
+					it.putExtra(ContactsContract.Intents.Insert.TERTIARY_PHONE, tel[2]);
+					it.putExtra(ContactsContract.Intents.Insert.TERTIARY_PHONE_TYPE, Phone.TYPE_WORK);
+				}
+				String email[] = detail.Email.split("\n");
+				if(email.length>0)
+				{
+					it.putExtra(ContactsContract.Intents.Insert.EMAIL, email[0]);
+					it.putExtra(ContactsContract.Intents.Insert.EMAIL_TYPE, Email.TYPE_WORK);
+				}
+				if(email.length>1)
+				{
+					it.putExtra(ContactsContract.Intents.Insert.SECONDARY_EMAIL, email[1]);
+					it.putExtra(ContactsContract.Intents.Insert.SECONDARY_EMAIL_TYPE, Email.TYPE_WORK);
+				}
+				if(email.length>2)
+				{
+					it.putExtra(ContactsContract.Intents.Insert.TERTIARY_EMAIL, email[2]);
+					it.putExtra(ContactsContract.Intents.Insert.TERTIARY_EMAIL_TYPE, Email.TYPE_WORK);
+				}
+				//
+//				intent.putExtra(Contacts.Intents.Insert.PHONE_TYPE,
+//						Contacts.PhonesColumns.TYPE_MOBILE);
+//				it.putExtra(ContactsContract.Intents.Insert.EMAIL, detail.Email);
+//				it.putExtra(ContactsContract.Intents.Insert.COMPANY,
+//						detail.Name);
+				it.putExtra(ContactsContract.Intents.Insert.POSTAL, detail.Addr);
+
+				if (!isIntentAvailable(LocationDetailActivity.this, it))
+				{
+					Toast.makeText(LocationDetailActivity.this,
+							"failed to add contact", Toast.LENGTH_LONG).show();
+					return;
+				}
+
+				startActivity(it);
+
+			}
+		});
+	}
+
+//	@Override
+//	public boolean onCreateOptionsMenu(Menu menu)
+//	{
+//		// Inflate the menu; this adds items to the action bar if it is present.
+//		getMenuInflater().inflate(R.menu.location_detail, menu);
+//		return true;
+//	}
+
+}

+ 370 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/MessageActivity.java

@@ -0,0 +1,370 @@
+package com.usai.apex;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.usai.util.Network;
+import com.usai.util.dbUtil;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.ListActivity;
+import android.app.NotificationManager;
+import android.app.AlertDialog.Builder;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.graphics.Color;
+import android.os.Bundle;
+import android.text.format.DateFormat;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.View.OnTouchListener;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.Button;
+import android.widget.ListView;
+import android.widget.TextView;
+
+public class MessageActivity extends ListActivity implements OnTouchListener
+{
+	SearchResult	searchresult	= new SearchResult();
+	BaseAdapter		adapter			= null;
+
+	private int		pointX, pointY, endX, endY;
+	private int		position, newpos;
+	private Button	curDel_btn;
+
+	@Override
+	public boolean onCreateOptionsMenu(Menu menu)
+	{
+		// Inflate the menu; this adds items to the action bar if it is present.
+		getMenuInflater().inflate(R.menu.message, menu);
+		return true;
+	}
+
+	@Override
+	public boolean onOptionsItemSelected(MenuItem item)
+	{
+		// Intent intent = new Intent();
+		switch (item.getItemId())
+		{
+			case R.id.action_deleteall:
+			{
+				AlertDialog.Builder builder = new Builder(this);
+				builder.setMessage(getString(R.string.str_deletemessage));
+
+				builder.setTitle(getString(R.string.str_confirmdelete));
+
+				builder.setPositiveButton(getString(R.string.str_del),
+						new Dialog.OnClickListener()
+						{
+
+							@Override
+							public void onClick(DialogInterface dialog,
+									int which)
+							{
+								SQLiteDatabase db = dbUtil.OpenDB(
+										MessageActivity.this, null, false);
+								db.execSQL("delete from push_message");
+								Log.d("sql delete" + position,
+										"delete from push_message where _id="
+												+ (Long) searchresult.getData()
+														.get(position)
+														.get("_id"));
+
+								dbUtil.CloseDB(db);
+								dialog.dismiss();
+								searchresult.getData().clear();// .remove(position);
+								adapter.notifyDataSetChanged();
+								NotificationManager nManager = (NotificationManager) 
+										getSystemService(Context.NOTIFICATION_SERVICE);
+								nManager.cancel(R.layout.activity_apex);
+								ApexTrackingApplication.ncount=1;
+							}
+						});
+
+				builder.setNegativeButton(getString(R.string.str_cancel),
+						new Dialog.OnClickListener()
+						{
+
+							@Override
+							public void onClick(DialogInterface dialog,
+									int which)
+							{
+								dialog.dismiss();
+							}
+						});
+
+				builder.create().show();
+
+				break;
+			}
+			case R.id.action_markallread:
+			{
+				SQLiteDatabase db = dbUtil.OpenDB(
+						MessageActivity.this, null, false);
+				db.execSQL("update push_message set read = 1 where user = '"+ApexTrackingApplication.get_user()+"'");
+				Log.d("sql delete" + position,
+						"delete from push_message where _id="
+								+ (Long) searchresult.getData()
+										.get(position)
+										.get("_id"));
+
+				dbUtil.CloseDB(db);
+				
+				for(int i=0;i<searchresult.getData().size();i++)
+				{
+					searchresult.getData().get(i).put("read", (long) 1);
+
+				}
+//				searchresult.getData().clear();// .remove(position);
+				adapter.notifyDataSetChanged();				
+			}
+			default:
+				break;
+		}
+		return super.onOptionsItemSelected(item);
+	}
+
+	@Override
+	public boolean onTouch(View v, MotionEvent event)
+	{
+		switch (event.getAction())
+		{
+			case MotionEvent.ACTION_DOWN:
+				System.out.println("====>>>>>>>>>>>>>>ACTION_DOWN"
+						+ MotionEvent.ACTION_DOWN);
+				// 手指按下,计算焦点位于ListView的那个条目
+				pointX = (int) event.getX();
+				pointY = (int) event.getY();
+				// 备注1
+				position = getListView().pointToPosition(pointX, pointY);
+				if (curDel_btn != null)
+				{
+					curDel_btn.setVisibility(View.GONE);
+				}
+				break;
+			case MotionEvent.ACTION_MOVE:
+
+				break;
+			case MotionEvent.ACTION_UP:
+				System.out.println("====>>>>>>>>>>>>>>ACTION_UP"
+						+ MotionEvent.ACTION_UP);
+				endX = (int) event.getX();
+				endY = (int) event.getY();
+				newpos = getListView().pointToPosition(endX, endY);
+				// 原本想着加上这个条件(newpos==position)是不是更精确些,
+				// 经过实践发现,其实我们在滑动listView的列表的时候有时候更渴望有滑动就ok
+				if (Math.abs(endX - pointX) > 100 && newpos == position
+						&& Math.abs(endY - pointY) < 100)
+				{
+					// 获取到ListView第一个可见条目的position
+					int firstVisiblePosition = getListView()
+							.getFirstVisiblePosition();
+
+					// --------------备注2
+					View view = getListView().getChildAt(
+							position - firstVisiblePosition);
+					Button delbtn = (Button) view.findViewById(R.id.btn_del);
+					delbtn.setVisibility(View.VISIBLE);
+					curDel_btn = delbtn;
+					delbtn.setOnClickListener(new View.OnClickListener()
+					{
+
+						@Override
+						public void onClick(View v)
+						{
+							// TODO Auto-generated method stub
+
+							SQLiteDatabase db = dbUtil.OpenDB(
+									MessageActivity.this, null, false);
+							db.execSQL("delete from push_message where _id="
+									+ (Long) searchresult.getData()
+											.get(position).get("_id"));
+							Log.d("sql delete" + position,
+									"delete from push_message where _id="
+											+ (Long) searchresult.getData()
+													.get(position).get("_id"));
+
+							dbUtil.CloseDB(db);
+							searchresult.getData().remove(position);
+							adapter.notifyDataSetChanged();
+						}
+					});
+
+				}
+				break;
+
+			default:
+				break;
+		}
+		return false;
+	}
+
+	@Override
+	protected void onListItemClick(ListView l, View v, int position, long id)
+	{
+		SQLiteDatabase db = dbUtil.OpenDB(MessageActivity.this, null, false);
+		db.execSQL("update push_message set read = 1 where _id="
+				+ (Long) searchresult.getData().get(position).get("_id"));
+		searchresult.getData().get(position).put("read", (long) 1);// .get("_id")
+		dbUtil.CloseDB(db);
+		adapter.notifyDataSetChanged();
+		super.onListItemClick(l, v, position, id);
+
+		// Log.i("FragmentList", "Item clicked: " + id);
+		Intent intent = new Intent();
+		intent.putExtra("s_id", (String) searchresult.getData().get(position)
+				.get("s_id"));
+		intent.putExtra("e_id", (String) searchresult.getData().get(position)
+				.get("e_id"));
+		intent.putExtra("msgcount", (Long) searchresult.getData().get(position)
+				.get("msgcount"));
+
+		intent.setClass(this, MessageDetailActivity.class);
+		startActivity(intent);
+	}
+
+	@Override
+	public void onCreate(Bundle savedInstanceState)
+	{
+
+		super.onCreate(savedInstanceState);
+		setContentView(R.layout.message_list);
+		adapter = new MessageAdapter(searchresult, this);
+
+		getListView().setOnTouchListener(this);
+		setListAdapter(adapter);
+
+	}
+
+	private class SearchResult
+	{
+		List<Map<String, Object>>	datalist	= new ArrayList<Map<String, Object>>();
+
+		public int get_count()
+		{
+			return datalist.size();
+		}
+
+		public void add_records(Cursor c)
+		{
+			while (c.moveToNext())
+			{
+				long _id = c.getInt(0);
+				String h_time = c.getString(1);
+				long create_time = c.getLong(2);
+				long read = c.getLong(3);
+				String s_id = c.getString(4);
+				String e_id = c.getString(5);
+				long msgcount = c.getInt(6);
+				Map<String, Object> map = new HashMap<String, Object>();
+				map.put("_id", _id);
+				map.put("h_time", h_time);
+				map.put("create_time", create_time);
+				map.put("read", read);
+				map.put("s_id", s_id);
+				map.put("e_id", e_id);
+				map.put("msgcount", msgcount);
+
+				datalist.add(map);
+			}
+
+		}
+
+		public List<Map<String, Object>> getData()
+		{
+
+			return datalist;
+		}
+	}
+
+	private class MessageAdapter extends BaseAdapter
+	{
+		private LayoutInflater	mInflater;	// 动态布局映射
+											// private SearchResult result;
+
+		// private Context context;
+		// private int i = 0;
+		public MessageAdapter(SearchResult result, Context context)
+		{
+			// this.result = result;
+			this.mInflater = LayoutInflater.from(context);
+			SQLiteDatabase db = dbUtil
+					.OpenDB(MessageActivity.this, null, false);
+			Cursor cursor = db.query("push_message",
+					new String[] { "_id", "h_time", "create_time", "read",
+							"s_id", "e_id", "msgcount" }, "user='"
+							+ ApexTrackingApplication.get_user() + "'", null,
+					null, null, "_id desc", null);
+
+			result.add_records(cursor);
+			dbUtil.CloseCursor(cursor);
+			dbUtil.CloseDB(db);
+			// this.result = result;
+			// // this.context = context;
+			// this.mInflater = LayoutInflater.from(context);
+		}
+
+		@Override
+		public View getView(int position, View convertView, ViewGroup parent)
+		{
+			// TODO Auto-generated method stub
+			convertView = mInflater.inflate(R.layout.message_list_item, null);// 根据布局文件实例化view
+
+			TextView message = (TextView) convertView
+					.findViewById(R.id.tv_message);// 找某个控件
+
+			message.setText(getString(R.string.str_notification_text));// 给该控件设置数据(数据从集合类中来)
+			TextView time = (TextView) convertView.findViewById(R.id.tv_time);
+			time.setText(DateFormat.format(
+					getString(R.string.time_format),
+					(Long) searchresult.getData().get(position)
+							.get("create_time")));
+			if ((Long) searchresult.getData().get(position).get("read") == 0)
+			{
+				message.getPaint().setFakeBoldText(true);
+				time.getPaint().setFakeBoldText(true);
+				convertView.setBackgroundColor(Color.LTGRAY);
+			}
+			else
+			{
+				message.getPaint().setFakeBoldText(false);
+				time.getPaint().setFakeBoldText(false);
+				convertView.setBackgroundColor(Color.WHITE);
+			}
+
+			return convertView;
+		}
+
+		@Override
+		public int getCount()
+		{
+			return searchresult.get_count();
+		}
+
+		@Override
+		public Object getItem(int position)
+		{
+			// TODO Auto-generated method stub
+			return null;
+		}
+
+		@Override
+		public long getItemId(int position)
+		{
+			// TODO Auto-generated method stub
+			return 0;
+		}
+	}
+
+}

+ 424 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/MessageDetailActivity.java

@@ -0,0 +1,424 @@
+package com.usai.apex;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import com.usai.util.Network;
+
+import android.app.ListActivity;
+import android.content.Context;
+import android.content.Intent;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.text.Html;
+import android.text.method.LinkMovementMethod;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AutoCompleteTextView;
+import android.widget.BaseAdapter;
+import android.widget.ListView;
+import android.widget.RadioGroup;
+import android.widget.TextView;
+import android.widget.Toast;
+
+public class MessageDetailActivity extends ListActivity
+{
+	long				msgcount		= 0;
+	String				e_id			= "";
+	String				s_id			= "";
+	int					limit			= 10;
+	int					offset			= 0;
+	private SearchTask	m_task			= null;
+	SearchResult		searchresult	= new SearchResult();
+	BaseAdapter			adapter			= null;
+	View				view_page_footer;
+
+	// String module_name = "";
+
+	public void requestdata()
+	{
+
+		if (m_task != null)
+		{
+			return;
+		}
+		// mStatusMessageView.setText(R.string.str_Loading);
+		// showProgress(true);
+		m_task = new SearchTask();
+
+		TextView text_page = (TextView) view_page_footer
+				.findViewById(R.id.text_page);
+		text_page.setText("Loading...");
+		text_page.setEnabled(false);
+		m_task.execute();
+
+	}
+
+	@Override
+	protected void onListItemClick(ListView l, View v, int position, long id)
+	{
+		super.onListItemClick(l, v, position, id);
+
+		Intent intent = new Intent();
+		intent.setClass(this, DetailActivity.class);
+
+		intent.putExtra("action0", "Tracking");
+		intent.putExtra("function_name", "Cargo Tracking");
+
+		intent.putExtra("cargo_criterion", searchresult.getData().get(position)
+				.get("url").toString());
+		intent.putExtra("actions_count", 1);
+		intent.putExtra("_id", "dumb");
+//		String h_field;
+		intent.putExtra("criterion_type", 1);
+//		h_field = "container_no";
+
+		startActivity(intent);
+
+	}
+
+	@Override
+	public void onDestroy()
+	{
+		if (m_task != null)
+			m_task.cancel(false);
+		super.onDestroy();
+	}
+
+	@Override
+	protected void onCreate(Bundle savedInstanceState)
+	{
+
+		// setTitle("Booking Result");
+
+		super.onCreate(savedInstanceState);
+		setContentView(R.layout.message_list);
+		adapter = new AnnouncementAdapter(searchresult, this);
+
+		s_id = getIntent().getStringExtra("s_id");
+		e_id = getIntent().getStringExtra("e_id");
+		msgcount = getIntent().getLongExtra("msgcount", 0);
+		view_page_footer = LayoutInflater.from(this).inflate(
+				R.layout.view_page_footer, null);
+		getListView().addFooterView(view_page_footer);// 添加底部视图
+		TextView text_page = (TextView) view_page_footer
+				.findViewById(R.id.text_page);
+		text_page.setOnClickListener(new View.OnClickListener()
+		{
+			// 点击按钮 追加数据 并通知适配器
+			@Override
+			public void onClick(View v)
+			{
+				// TODO Auto-generated method stub
+				// TextView tv = (TextView) v;
+				// tv.setText("Loading...");
+				offset += 10;
+				requestdata();
+				// tv.setText("下一页");
+				// adapter.notifyDataSetChanged();
+			}
+		});
+
+		setListAdapter(adapter);
+		// this.getListView().setBackgroundColor(Color.WHITE);
+		requestdata();
+
+	}
+
+	class SearchTask extends AsyncTask<Void, Void, Boolean>
+	{
+		int		errorcode;
+		boolean	bfinish	= false;
+
+		@Override
+		protected Boolean doInBackground(Void... params)
+		{
+			Log.d("SearchTask", "doInBackground");
+			if (!Network.NetworkIsAvailable())
+
+			{
+				errorcode = Network.RESULT_NET_NOTAVAILABLE;
+				return false;
+			}
+			String jstr = Network.get_push(e_id, s_id, limit, offset);
+			if (jstr == null || jstr.length() <= 0)
+			{
+				// Log.d(TAG, "json is wrong");
+
+				errorcode = Network.RESULT_NET_ERROR;
+				return false;
+			}
+
+			JSONObject jsobj;
+			//
+			// array = new JSONArray(json);
+			try
+			{
+				jsobj = new JSONObject(jstr);
+				// if (searchresult.get_fieldscount() == 0)
+				// {
+				// JSONObject objfields = jsobj.getJSONObject("fields");
+				// if (objfields != null)
+				// searchresult.init_fields(objfields.toString());
+				// }
+				int count = jsobj.getInt("total");
+				if (msgcount - offset <= limit)
+					bfinish = true;
+				JSONObject objrecords = jsobj.getJSONObject("records");
+				if (objrecords != null)
+					searchresult.add_records(objrecords.toString(), count);
+				errorcode = Network.RESULT_TRUE;
+
+				return true;
+
+			}
+			catch (JSONException e)
+			{
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+			errorcode = Network.RESULT_NET_ERROR;
+			return false;
+		}
+
+		@Override
+		protected void onPostExecute(Boolean success)
+		{
+			Log.d("onPostExecute", "entry");
+			m_task = null;
+			// showProgress(false);
+
+			switch (errorcode)
+			{
+				case Network.RESULT_NET_NOTAVAILABLE:
+				{
+					Toast toast = Toast.makeText(
+							ApexTrackingApplication.get_instance(),
+							getText(R.string.msg_connection_none),
+							Toast.LENGTH_LONG);
+					toast.setGravity(Gravity.CENTER, 0, 0);
+					toast.show();
+					break;
+				}
+				case Network.RESULT_NET_ERROR:
+				{
+					Toast toast = Toast.makeText(
+							ApexTrackingApplication.get_instance(),
+							getText(R.string.msg_net_error), Toast.LENGTH_LONG);
+					toast.setGravity(Gravity.CENTER, 0, 0);
+					toast.show();
+					break;
+				}
+				case Network.RESULT_ERROR:
+				// case Network.RESULT_RESPONSE_NULL:
+				{
+					Toast toast = Toast.makeText(
+							ApexTrackingApplication.get_instance(),
+							getText(R.string.msg_net_resulterror),
+							Toast.LENGTH_LONG);
+					toast.setGravity(Gravity.CENTER, 0, 0);
+					toast.show();
+					break;
+				}
+
+				default:
+					break;
+			}
+
+			if (success)
+			{
+
+				if (bfinish)
+				{
+					// getListView().removeFooterView(view_page_footer);
+					// Toast.makeText(AnnouncementActivity.this, "Load all!",
+					// Toast.LENGTH_LONG).show();
+
+					TextView tv = (TextView) view_page_footer
+							.findViewById(R.id.text_page);
+					tv.setText("No more items");
+					tv.setEnabled(false);
+				}
+				else
+				{
+					TextView tv = (TextView) view_page_footer
+							.findViewById(R.id.text_page);
+					tv.setText("More...");
+					tv.setEnabled(true);
+				}
+				adapter.notifyDataSetChanged();
+				// getListAdapter().notifyDataSetChanged;
+				// BaseAdapter mJson = null;
+				// mJson.notifyDataSetChanged();
+			}
+
+			super.onPostExecute(success);
+		}
+
+		@Override
+		protected void onCancelled()
+		{
+			m_task = null;
+			// showProgress(false);
+		}
+	}
+
+	private class SearchResult
+	{
+		List<Map<String, Object>>	datalist	= new ArrayList<Map<String, Object>>();
+
+		public int get_count()
+		{
+			return datalist.size();
+		}
+
+		public void add_records(String source, int count)
+		{
+			JSONObject objrecords;
+			try
+			{
+				objrecords = new JSONObject(source);
+
+				for (int i = 0; i < count; i++)
+				{
+					// offset++;
+					JSONObject objrec = objrecords.getJSONObject("record" + i);
+					String title = objrec.getString("title");
+					// String content = objrec.getString("content");
+					// String image = objrec.getString("image");
+					// String id = objrec.getString("id");
+					String url = objrec.getString("url");
+					// lastid = id;
+					Map<String, Object> map = new HashMap<String, Object>();
+					map.put("title", title);
+					// map.put("content", content);
+					// map.put("image", image);
+					// map.put("id", id);
+					map.put("url", url);
+					datalist.add(map);
+
+					// Iterator<?> it = rec.keys();
+					// HashMap<String, String> record = new HashMap<String,
+					// String>();
+					// while (it.hasNext()) // loop for each function
+					// {
+					// String field_name = (String) it.next();
+					// String val = rec.getString(field_name)
+					// .replace("\n", "");
+					// record.put(field_name, val);
+					// }
+					// records.add(record);
+
+				}
+			}
+			catch (JSONException e)
+			{
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+
+		}
+
+		public List<Map<String, Object>> getData()
+		{
+
+			return datalist;
+		}
+	}
+
+	private class AnnouncementAdapter extends BaseAdapter
+	{
+		private LayoutInflater	mInflater;	// 动态布局映射
+		private SearchResult	result;
+
+		// private Context context;
+		// private int i = 0;
+		public AnnouncementAdapter(SearchResult result, Context context)
+		{
+			this.result = result;
+			// this.context = context;
+			this.mInflater = LayoutInflater.from(context);
+		}
+
+		@Override
+		public int getCount()
+		{
+			// TODO Auto-generated method stub
+			return result.get_count();
+		}
+
+		@Override
+		public Object getItem(int position)
+		{
+			// TODO Auto-generated method stub
+			return null;
+		}
+
+		@Override
+		public long getItemId(int position)
+		{
+			// TODO Auto-generated method stub
+			return 0;
+		}
+
+		@Override
+		public View getView(int position, View convertView, ViewGroup parent)
+		{
+			// TODO Auto-generated method stub
+			convertView = mInflater.inflate(R.layout.message_detail_item, null);// 根据布局文件实例化view
+
+			TextView title = (TextView) convertView.findViewById(R.id.tv_title);// 找某个控件
+			title.setText(Html.fromHtml(result.getData().get(position)
+					.get("title").toString()));
+			// title.setMovementMethod(LinkMovementMethod.getInstance());
+			// title.setText(result.getData().get(position).get("title")
+			// .toString());// 给该控件设置数据(数据从集合类中来)
+			// TextView content = (TextView) convertView
+			// .findViewById(R.id.tv_content);
+			// content.setText(result.getData().get(position).get("content")
+			// .toString());
+			// if
+			// (result.getData().get(position).get("image").toString().length()
+			// > 0)
+			// {
+			// byte[] gzipBuff = Base64.decode(result.getData().get(position)
+			// .get("image").toString(), 0);
+			//
+			// ByteArrayInputStream memstream = new ByteArrayInputStream(
+			// gzipBuff, 0, gzipBuff.length);
+			//
+			// ByteArrayOutputStream baos = new ByteArrayOutputStream(
+			// gzipBuff.length);
+			// ImageView iv_thumb = (ImageView) convertView
+			// .findViewById(R.id.iv_thumb);
+			// try
+			// {
+			// baos.write(gzipBuff);
+			//
+			// Bitmap bmp = BitmapFactory.decodeStream(memstream);
+			//
+			// // ImageView image = new ImageView(this);
+			//
+			// iv_thumb.setImageBitmap(bmp);
+			// }
+			// catch (IOException e)
+			// {
+			// // TODO Auto-generated catch block
+			// e.printStackTrace();
+			// }
+			// }
+			// img.setBackgroundResource((Integer)jObject.get("img"));
+
+			return convertView;
+		}
+	}
+
+}

+ 646 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/Result/AMResultActivity.java

@@ -0,0 +1,646 @@
+package com.usai.apex.Result;
+
+import android.app.Dialog;
+import android.app.DownloadManager;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.net.Uri;
+import android.os.Bundle;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AlertDialog;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.EditText;
+import android.widget.TextView;
+
+import com.usai.apex.ApexTrackingApplication;
+import com.usai.apex.CustomizeFieldsActivity;
+import com.usai.apex.R;
+import com.usai.apex.mainframe.NewDetailActivity;
+import com.usai.apex.pdf.PDFPreviewActivity;
+import com.usai.util.Network;
+import com.usai.util.RAUtil;
+import com.usai.util.dbUtil;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * Created by macmini1 on 2018/2/23.
+ */
+
+public class AMResultActivity extends SearchResultActivity {
+    TextView mtitleview;
+    private static int REQUEST_FIELD_SETTING = 1000;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+
+        setCustomActionBar();
+
+    }
+    private void setCustomActionBar() {
+        ActionBar.LayoutParams lp =new ActionBar.LayoutParams(ActionBar.LayoutParams.MATCH_PARENT, ActionBar.LayoutParams.MATCH_PARENT, Gravity.CENTER);
+        View mActionBarView = LayoutInflater.from(this).inflate(R.layout.actionbar_customtitle, null);
+
+        mtitleview= mActionBarView.findViewById(R.id.title);
+        String title = mParams.getString("title");
+        mtitleview.setText(title);
+        setTitle(title);
+//
+//        mActionBarView.setBackgroundColor(Color.YELLOW);
+//        titleview.setBackgroundColor(Color.BLUE);
+        ActionBar actionBar = getSupportActionBar();
+        actionBar.setCustomView(mActionBarView, lp);
+//        actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
+//        actionBar.setDisplayShowCustomEnabled(true);
+        actionBar.setDisplayHomeAsUpEnabled(true);
+
+
+//        actionBar.setIcon(getNumberDrawable());
+//        actionBar.setDisplayShowHomeEnabled(true);
+        actionBar.setDisplayShowTitleEnabled(true);
+    }
+//    @Override
+//    public void setTitle(CharSequence title) {
+////        View mActionBarView = LayoutInflater.from(this).inflate(R.layout.actionbar_customtitle, null);
+////
+////        TextView mtitleviewtitleview = mActionBarView.findViewById(R.id.title);
+//
+//        if(title==null)
+//            title="";
+//        if(mtitleview!=null)
+//            mtitleview.setText(title);
+//    }
+    @Override
+    protected void loadData() {
+        if (mParams.getString("columns") == null) {
+            ArrayList<String> header_name = new ArrayList<String>();
+            ArrayList<String> header_aname = new ArrayList<String>();
+            getHeader(header_name, header_aname);
+            String fields = "";
+            Iterator<String> iterator = header_name.iterator();
+            while (iterator.hasNext()) {
+                String name = iterator.next();
+                fields = fields + name + ",";
+            }
+            if (fields.length() > 0) {
+                fields = fields.substring(0, fields.length() - 1);
+            }
+            mParams.putString("columns", fields);
+        }
+        super.loadData();
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        super.onActivityResult(requestCode, resultCode, data);
+
+//        resultListView.setAdapter(adapter);
+//
+//        Iterator<String> keyIterator = resultData.keys();
+//        ArrayList<String> keys = new ArrayList<>();
+//        while (keyIterator.hasNext()) {
+//            String key = keyIterator.next();
+//            keys.add(key);
+//        }
+//        for (int i = 0; i < keys.size(); i++) {
+//            String key = keys.get(i);
+//            resultData.remove(key);
+//        }
+//
+//        adapter.notifyDataSetChanged();
+
+        if (requestCode == REQUEST_FIELD_SETTING) {
+
+            ArrayList<String> header_name = new ArrayList<String>();
+            ArrayList<String> header_aname = new ArrayList<String>();
+            getHeader(header_name,header_aname);
+            String fields = "";
+            Iterator<String> iterator = header_name.iterator();
+            while (iterator.hasNext()) {
+                String name = iterator.next();
+                fields = fields + name + ",";
+            }
+            fields = fields.substring(0,fields.length() - 1);
+            mParams.putString("columns",fields);
+
+
+            loadData();
+
+        }
+
+    }
+
+    // 动态修改Menu
+    @Override
+    public boolean onPrepareOptionsMenu(Menu menu) {
+        super.onPrepareOptionsMenu(menu);
+        menu.clear();
+
+
+        if (resultData != null && resultData.length() > 0) {
+            try {
+                JSONArray menu_json = resultData.getJSONArray("menu");
+
+                if (menu_json != null && menu_json.length() > 0) {
+
+                    for (int i = 0; i < menu_json.length(); i++) {
+                        JSONObject json = menu_json.getJSONObject(i);
+                        String title = json.getString("title");
+                        menu.add(0, i, 0, title);
+                    }
+                }
+            } catch (JSONException e) {
+                e.printStackTrace();
+            }
+        }
+
+        return true;
+    }
+
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+
+
+        int which = item.getItemId();
+
+        switch (item.getItemId())
+        {
+
+            case android.R.id.home:
+                finish();
+                break;
+            default:
+            {
+                try {
+                    JSONArray menu = resultData.getJSONArray("menu");
+                    JSONObject json = menu.getJSONObject(which);
+
+                    String actionType = json.getString("action");
+                    String url = json.optString("url");
+
+
+
+                    if (actionType.equals("field_setting")) {
+
+                        fieldSetting();
+                    } else if (actionType.equals("save")) {
+
+                        save();
+                    } else if (actionType.equals("download")) {
+
+                        export(url);
+                    }
+
+                } catch (JSONException exception) {
+                    Log.d("Result", "onClick: ",exception);
+                }
+            }
+        }
+
+
+
+        return true;
+    }
+
+
+    @Override
+    public void cellDoubleTapAction(final int position) {
+
+        final JSONArray content_action = contentAction();
+        if (content_action != null) {
+
+            try {
+                if (content_action.length() == 1) {
+
+                    JSONObject action = content_action.getJSONObject(0);
+                    String module = action.getString("module");
+
+                    if (module.equals("quick_look")) {
+
+                        showQuickLookForPosition(position,action);
+
+                    } else if (module.equals("detail")) {
+
+                        showDetailForPosition(position);
+                    }
+
+
+                } else if (content_action.length() > 1) {
+
+                    ArrayList<String> titleList = new ArrayList<>();
+
+                    for (int i = 0; i < content_action.length(); i++) {
+                        JSONObject json = content_action.getJSONObject(i);
+                        String title = json.getString("title");
+                        titleList.add(title);
+                    }
+
+                    new AlertDialog.Builder(mContext)
+                            .setSingleChoiceItems((String[])titleList.toArray(new String[titleList.size()]), -1, new DialogInterface.OnClickListener() {
+                                @Override
+                                public void onClick(DialogInterface dialog, int which) {
+
+                                    try {
+
+                                        JSONObject json = content_action.getJSONObject(which);
+                                        String module = json.getString("module");
+
+                                        if (module.equals("quick_look")) {
+
+                                            showQuickLookForPosition(position,json);
+                                        } else if (module.equals("detail")) {
+
+                                            showDetailForPosition(position);
+                                        }
+
+
+                                    } catch (JSONException exception) {
+                                        Log.d("Result", "onClick: ",exception);
+                                    }
+                                    dialog.dismiss();
+
+                                }
+                            })
+                            .show();
+                }
+
+            } catch (JSONException e) {
+                e.printStackTrace();
+            }
+
+        }
+
+    }
+
+    public void showDetailForPosition(final int position) {
+
+        ArrayList<String> actions = getActions();
+        if (actions.size() < 1) {
+            return;
+        }
+
+        try {
+            JSONArray arr_col = contentLayout().getJSONObject("header").getJSONArray("col");
+            JSONArray item = contentData().getJSONArray("item_" + (position - 1));
+
+            String module_name = mParams.getString("module_name");
+            String detail_id = item.getString(arr_col.length());
+
+            Intent intent = new Intent(mContext, NewDetailActivity.class);
+            intent.putExtra("function_name", module_name);
+            intent.putExtra("actions_count", actions.size());
+            intent.putExtra("_id",detail_id);
+
+            Iterator<String> iterator = actions.iterator();
+            int i = 0;
+            while (iterator.hasNext()) {
+                String name = iterator.next();
+                intent.putExtra("action" + i++, name);
+            }
+            startActivity(intent);
+
+        } catch (JSONException e) {
+            e.printStackTrace();
+        }
+
+    }
+    @Override
+    public void showQuickLook(final JSONObject param, final String url) {
+
+        showProgressDialog("Please wait","Downloading...");
+        new Thread(new Runnable() {
+            @Override
+            public void run() {
+
+                String cacheDir = ApexTrackingApplication.getInstance().getExternalCacheDir().getAbsolutePath();//ApexTrackingApplication.getInstance().getDocumentDir();
+
+                // 下载文件
+                final File downloadFile = Network.downloadFile(RAUtil.Json2Bundle(param),url,cacheDir);
+
+                runOnUiThread(new Runnable() {
+                    @Override
+                    public void run() {
+                        progressDialog.dismiss();
+                        if (downloadFile != null && downloadFile.exists()) {
+                            String email = null,email_subject = null,email_content = null;
+                            try {
+                                //此处需要新增保存文档的本地表
+
+                                email=param.getString("email");
+                                email_subject=param.getString("email_subject");
+                                email_content=param.getString("email_content");
+
+                            } catch (JSONException e) {
+                                e.printStackTrace();
+                            }
+                            previewPDF(downloadFile.getAbsolutePath(),email,email_subject,email_content);
+                        } else {
+                            showAlert("Sorry,there is a wrong.");
+                        }
+                    }
+                });
+
+            }
+        }).start();
+
+
+    }
+    public void showQuickLookForPosition(final int position,JSONObject action) {
+
+        try {
+
+            JSONObject params = new JSONObject();
+            Iterator<String> iterator = action.getJSONObject("params").keys();
+            while (iterator.hasNext()) {
+                String key = iterator.next();
+                JSONArray item = contentData().getJSONArray("item_" + (position - 1));
+                int idx = action.getJSONObject("params").getInt(key);
+                params.put(key,item.get(idx));
+            }
+
+            String url = action.getString("url");
+//            String module_name = mParams.getString("module_name");
+
+            showQuickLook(params,url);
+//            downloaddoc(url);
+
+        } catch (JSONException e) {
+            e.printStackTrace();
+        }
+
+    }
+
+
+    protected void previewPDF(String file,String email,String subject,String content) {
+        Intent myIntent = new Intent();
+        myIntent = new Intent(AMResultActivity.this, PDFPreviewActivity.class);
+
+        myIntent.putExtra("file",file);
+        myIntent.putExtra("iscache",true);
+
+        try {
+            JSONObject json = new JSONObject();
+//            email = "66666@qq.com";
+//            subject = "test subject";
+//            content = "test body";
+            if (email != null) {
+                json.put("email",email);
+            }
+            if (subject != null) {
+                json.put("subject",subject);
+            }
+            if (content != null) {
+                json.put("content",content);
+            }
+            myIntent.putExtra("email",json.toString());
+        } catch (JSONException e) {
+            e.printStackTrace();
+        }
+
+
+        startActivity(myIntent);
+    }
+
+    private void downloaddoc(String url)
+    {
+
+            // if (true)
+            // return;
+//            URLSpan span[] = ((TextView) v).getUrls();
+//            if (span.length < 1)
+//                return;
+//            span[0].getURL();
+//            Log.d("Text", span[0].getURL());
+//
+//            TextView tv = (TextView)v;
+
+            final DownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
+
+            Uri uri = Uri.parse(url);
+            final DownloadManager.Request request = new DownloadManager.Request(uri);
+
+            // 设置允许使用的网络类型,这里是移动网络和wifi都可以
+            request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE
+                    | DownloadManager.Request.NETWORK_WIFI);
+
+            request.setDestinationInExternalPublicDir("Apex Mobile",url);
+
+            // 禁止发出通知,既后台下载,如果要使用这一句必须声明一个权限:android.permission.DOWNLOAD_WITHOUT_NOTIFICATION
+            // request.setShowRunningNotification(false);
+
+            // 不显示下载界面
+            request.setVisibleInDownloadsUi(false);
+            request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
+
+							/*
+							 * 设置下载后文件存放的位置,如果sdcard不可用,那么设置这个将报错,
+							 * 因此最好不设置如果sdcard可用,下载后的文件 在/mnt/sdcard/Android/
+							 * data/packageName/files目录下面
+							 * ,如果sdcard不可用,设置了下面这个将报错,不设置,下载后的文件在/cache这个 目录下面
+							 */
+            // request.setDestinationInExternalFilesDir(this,
+            // null, "tar.apk");
+
+            android.app.AlertDialog.Builder builder = new android.app.AlertDialog.Builder(
+                    AMResultActivity.this);
+            builder.setMessage(getString(R.string.str_downloadmessage));
+
+            builder.setTitle(getString(R.string.str_confirmdownload));
+
+            builder.setPositiveButton(
+                    getString(R.string.str_download),
+                    new Dialog.OnClickListener()
+                    {
+
+                        @Override
+                        public void onClick(
+                                DialogInterface dialog,
+                                int which)
+                        {
+                            downloadManager.enqueue(request);
+                            dialog.dismiss();
+
+                        }
+                    });
+
+            builder.setNegativeButton(
+                    getString(R.string.str_cancel),
+                    new Dialog.OnClickListener()
+                    {
+
+                        @Override
+                        public void onClick(
+                                DialogInterface dialog,
+                                int which)
+                        {
+                            dialog.dismiss();
+                        }
+                    });
+
+            builder.create().show();
+
+
+    }
+
+    public void getHeader(ArrayList<String> header_name, ArrayList<String> header_aname) {
+
+        String module_name = mParams.getString("module_name");
+        String user = ApexTrackingApplication.get_user();
+
+        SQLiteDatabase db = dbUtil.OpenDB(this, null, false);
+        Cursor cursor = db.query("fields_info", new String[] { "aname", "name",
+                "_id" }, "function_name='" + module_name + "' and user='"
+                + user + "' and behavior=" + Network.BEHAVIOR_RESULT
+                + " and show = 1", null, null, null, "priority , aname", null);
+        while (cursor.moveToNext())
+        {
+            String aname = cursor.getString(0);
+            String name = cursor.getString(1);
+
+            header_name.add(name);
+            header_aname.add(aname);
+        }
+        dbUtil.CloseCursor(cursor);
+        dbUtil.CloseDB(db);
+    }
+
+    public ArrayList<String> getActions() {
+
+        String module_name = mParams.getString("module_name");
+
+        SQLiteDatabase db = dbUtil.OpenDB(this, null, false);
+        Cursor cursor = db.query("actions_info",
+                new String[] { "name" }, "function_name='"
+                        + module_name + "' and user='" + ApexTrackingApplication.get_user() + "'", null,
+                null, null, "priority", null);
+
+        ArrayList<String> actions = new ArrayList<>();
+
+        while (cursor.moveToNext())
+        {
+            String name = cursor.getString(0);
+            actions.add(name);
+        }
+        dbUtil.CloseCursor(cursor);
+        dbUtil.CloseDB(db);
+
+        return actions;
+
+    }
+
+    public void save() {
+
+        final View edit = new EditText(this);
+        new android.app.AlertDialog.Builder(this)
+                .setIconAttribute(android.R.attr.alertDialogIcon)
+                .setTitle(R.string.str_createname)
+                .setView(edit)
+                .setPositiveButton(android.R.string.ok,
+                        new DialogInterface.OnClickListener()
+                        {
+                            public void onClick(DialogInterface dialog,
+                                                int whichButton)
+                            {
+                                String name = ((EditText) edit)
+                                        .getText().toString();
+
+                                if(TextUtils.isEmpty(name))
+                                {
+                                    new android.app.AlertDialog.Builder(AMResultActivity.this)
+                                            .setTitle("Warning")
+                                            .setMessage("Name can not be empty.")
+
+                                            .setPositiveButton("OK", new DialogInterface.OnClickListener() {
+                                                @Override
+                                                public void onClick(DialogInterface dialog, int which) {
+
+                                                }
+                                            })
+                                            .show();
+                                    return;
+                                }
+
+                                String param = getIntent().toUri(0);
+
+                                JSONObject obj = new JSONObject();
+                                Set<String> keys = mParams.keySet();
+                                for (String key : keys)
+                                {
+
+
+                                    try
+                                    {
+                                        obj.put(key, mParams.get(key).toString());
+
+                                    }
+                                    catch (JSONException e)
+                                    {
+                                        // TODO Auto-generated catch block
+                                        e.printStackTrace();
+                                    }
+
+                                }
+                                obj.toString();
+
+                                SQLiteDatabase db = dbUtil.OpenDB(
+                                        ApexTrackingApplication.get_instance(), null, true);
+                                db.execSQL("insert into history(params,name,criterion,module_name,user,create_time) values('"
+
+                                        + param
+                                        + "','"
+                                        + name
+                                        + "','"
+                                        + obj.toString()
+                                        + "','"
+                                        + mParams.getString("module_name")
+                                        + "','"
+                                        + ApexTrackingApplication.get_user()
+                                        + "',"
+                                        + System.currentTimeMillis() + ")");
+                                dbUtil.CloseDB(db);
+
+										/* User clicked OK so do some stuff */
+                            }
+                        })
+                .setNegativeButton(android.R.string.cancel,
+                        new DialogInterface.OnClickListener()
+                        {
+                            public void onClick(DialogInterface dialog,
+                                                int whichButton)
+                            {
+
+										/* User clicked cancel so do some stuff */
+                            }
+                        }).create().show();
+    }
+
+    public void fieldSetting() {
+
+        Intent intent = new Intent();
+        intent.setClass(this, CustomizeFieldsActivity.class);
+        intent.putExtra("user", ApexTrackingApplication.get_user());
+        intent.putExtra("function_name", mParams.getString("module_name"));
+        intent.putExtra("behavior", Network.BEHAVIOR_RESULT);
+        startActivityForResult(intent,REQUEST_FIELD_SETTING);
+
+    }
+
+}

+ 348 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/Result/PullRefreshListView.java

@@ -0,0 +1,348 @@
+package com.usai.apex.Result;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.animation.RotateAnimation;
+import android.widget.AbsListView;
+import android.widget.ListView;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public class PullRefreshListView extends ListView implements AbsListView.OnScrollListener {
+
+    /**
+     * 头布局
+     */
+    private View headerView;
+
+    /**
+     * 头部布局的高度
+     */
+    private int headerViewHeight;
+
+    /**
+     * 底部布局
+     */
+    private View footerView;
+
+
+    /**
+     * 底部布局的高度
+     */
+    private int footerViewHeight;
+
+
+    /**
+     * 按下时的Y坐标
+     */
+    private int downY;
+
+    public static final int PULL_REFRESH = 0;//下拉刷新的状态
+    public static final int RELEASE_REFRESH = 1;//松开刷新的状态
+    public static final int REFRESHING = 2;//正在刷新的状态
+
+    /**
+     * 当前下拉刷新处于的状态
+     */
+    private int currentState = PULL_REFRESH;
+
+    /**
+     * 头部布局在下拉刷新改变时,图标的动画
+     */
+    private RotateAnimation upAnimation,downAnimation;
+
+    private boolean isLoadingMore = false;
+    private boolean isRefreshing = false;
+
+    public PullRefreshListView(Context context) {
+        this(context,null);
+    }
+
+    public PullRefreshListView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        init();
+    }
+
+    private void init(){
+        //设置滑动监听
+        setOnScrollListener(this);
+        //初始化头布局
+        initHeaderView();
+        //初始化头布局中图标的旋转动画
+        initRotateAnimation();
+        //初始化为尾布局
+        initFooterView();
+    }
+
+    @Override
+    public void setLayoutParams(ViewGroup.LayoutParams params) {
+        super.setLayoutParams(params);
+    }
+
+    /**
+     * 初始化headerView
+     */
+    private void initHeaderView() {
+
+//        headerView =  View.inflate(getContext(), R.layout.refresh_header, null);
+        if (headerView != null) {
+            //测量headView的高度
+            headerView.measure(0, 0);
+            //获取高度,并保存
+            headerViewHeight = headerView.getMeasuredHeight();
+            //设置paddingTop = -headerViewHeight;这样,该控件被隐藏
+//            headerView.setPadding(0, -headerViewHeight, 0, 0);
+            headerStateChange(currentState,-headerViewHeight);
+            //添加头布局
+            addHeaderView(headerView);
+        }
+    }
+
+    /**
+     * 初始化旋转动画
+     */
+    private void initRotateAnimation() {
+
+        upAnimation = new RotateAnimation(0, -180,
+                RotateAnimation.RELATIVE_TO_SELF, 0.5f,
+                RotateAnimation.RELATIVE_TO_SELF, 0.5f);
+        upAnimation.setDuration(300);
+        upAnimation.setFillAfter(true);
+
+        downAnimation = new RotateAnimation(-180, -360,
+                RotateAnimation.RELATIVE_TO_SELF, 0.5f,
+                RotateAnimation.RELATIVE_TO_SELF, 0.5f);
+        downAnimation.setDuration(300);
+        downAnimation.setFillAfter(true);
+    }
+
+    //初始化底布局,与头布局同理
+    private void initFooterView() {
+
+//        footerView =  View.inflate(getContext(), R.layout.refresh_footer, null);
+        if (footerView != null) {
+            footerView.measure(0, 0);
+            footerViewHeight = footerView.getMeasuredHeight();
+//            footerView.setPadding(0, -footerViewHeight, 0, 0);
+            footerStateChange(PULL_REFRESH, -footerViewHeight);
+            addFooterView(footerView);
+        }
+    }
+
+    public void setRefreshHeader(View header) {
+        headerView = header;
+        initHeaderView();
+    }
+
+    public void setRefreshFooter(View footer) {
+        footerView = footer;
+        initFooterView();
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent ev) {
+
+        if (headerView == null) {
+            return super.onTouchEvent(ev);
+        }
+
+        switch (ev.getAction()) {
+            case MotionEvent.ACTION_DOWN:
+                //获取按下时y坐标
+                downY = (int) ev.getY();
+                break;
+            case MotionEvent.ACTION_MOVE:
+
+                if(currentState==REFRESHING){
+                    //如果当前处在滑动状态,则不做处理
+                    break;
+                }
+                //手指滑动偏移量
+                int deltaY = (int) (ev.getY() - downY);
+
+                //获取新的padding值
+                int paddingTop = -headerViewHeight + deltaY;
+
+                if(paddingTop>-headerViewHeight && getFirstVisiblePosition()==0){
+                    //向下滑,且处于顶部,设置padding值,该方法实现了顶布局慢慢滑动显现
+//                    headerView.setPadding(0, paddingTop, 0, 0);
+
+
+                    if(paddingTop>=0 && currentState==PULL_REFRESH){
+
+                        //从下拉刷新进入松开刷新状态
+                        currentState = RELEASE_REFRESH;
+                    }else if (paddingTop<0 && currentState==RELEASE_REFRESH) {
+
+                        //进入下拉刷新状态
+                        currentState = PULL_REFRESH;
+                    }
+
+                    headerStateChange(currentState,paddingTop);
+
+                    return true;//拦截TouchMove,不让listview处理该次move事件,会造成listview无法滑动
+                }
+
+
+                break;
+            case MotionEvent.ACTION_UP:
+
+                if(currentState==PULL_REFRESH){
+                    //仍处于下拉刷新状态,未滑动一定距离,不加载数据,隐藏headView
+//                    headerView.setPadding(0, -headerViewHeight, 0, 0);
+                    headerStateChange(currentState,-headerViewHeight);
+
+                }else if (currentState==RELEASE_REFRESH) {
+
+                    //滑倒一定距离,显示无padding值得headcView
+//                    headerView.setPadding(0, 0, 0, 0);
+
+                    //设置状态为刷新
+                    currentState = REFRESHING;
+
+                    //刷新头部布局
+                    headerStateChange(currentState,0);
+
+                }
+                break;
+        }
+        return super.onTouchEvent(ev);
+    }
+
+
+    private void headerStateChange(int state,int offset) {
+
+        if (state == REFRESHING) {
+            isRefreshing = true;
+        }
+
+        if (headerView == null) {
+            return;
+        }
+
+        headerView.setPadding(0, offset, 0, 0);
+        if (listener != null) {
+            listener.onHeaderStateChange(state,offset);
+        }
+    }
+
+    private void footerStateChange(int state,int offset) {
+
+        if (state == REFRESHING) {
+            isRefreshing = true;
+        }
+
+        if (footerView == null) {
+            return;
+        }
+
+        footerView.setPadding(0, offset, 0, 0);
+
+        if (listener != null) {
+            listener.onFooterStateChange(state,offset + footerViewHeight);
+        }
+    }
+
+    /**
+     * 完成刷新操作,重置状态,在你获取完数据并更新完adater之后,去在UI线程中调用该方法
+     */
+    public void completeRefresh(){
+
+        isRefreshing = false;
+        if(isLoadingMore){
+
+            //重置footerView状态
+//            footerView.setPadding(0, -footerViewHeight, 0, 0);
+            isLoadingMore = false;
+            footerStateChange(PULL_REFRESH,-footerViewHeight);
+        } else {
+
+            //重置headerView状态
+//            headerView.setPadding(0, -headerViewHeight, 0, 0);
+            currentState = PULL_REFRESH;
+            headerStateChange(currentState,-headerViewHeight);
+        }
+    }
+
+    /**
+     * 获取当前系统时间,并格式化
+     * @return
+     */
+    private String getCurrentTime(){
+        SimpleDateFormat format = new SimpleDateFormat("yy-MM-dd HH:mm:ss");
+        return format.format(new Date());
+    }
+
+    private OnRefreshListener listener;
+    public void setOnRefreshListener(OnRefreshListener listener){
+        this.listener = listener;
+    }
+    public interface OnRefreshListener{
+        void onHeaderStateChange(int state, int offset);
+        void onFooterStateChange(int state, int offset);
+        void shouldPullDownToRefresh(boolean should);
+    }
+
+    /**
+     * SCROLL_STATE_IDLE:闲置状态,就是手指松开
+     * SCROLL_STATE_TOUCH_SCROLL:手指触摸滑动,就是按着来滑动
+     * SCROLL_STATE_FLING:快速滑动后松开
+     */
+    @Override
+    public void onScrollStateChanged(AbsListView view, int scrollState) {
+
+        if (footerView == null) {
+            return;
+        }
+
+        if(scrollState==OnScrollListener.SCROLL_STATE_IDLE
+                && getLastVisiblePosition()==(getCount()-1) &&!isLoadingMore){
+            if (!isRefreshing) {
+
+                isRefreshing = true;
+                isLoadingMore = true;
+
+//                footerView.setPadding(0, 0, 0, 0);//显示出footerView
+                footerStateChange(REFRESHING,0);
+
+                setSelection(getCount());//让listview最后一条显示出来,在页面完全显示出底布局
+
+            }
+        }
+    }
+
+
+
+    public int getOffsetY() {
+        View c = getChildAt(0);
+        if (c == null) {
+            return 0;
+        }
+        int firstVisiblePosition = getFirstVisiblePosition();
+        int top = c.getTop();
+        return -top + firstVisiblePosition * c.getHeight() ;
+    }
+
+    @Override
+    public void onScroll(AbsListView view, int firstVisibleItem,
+                         int visibleItemCount, int totalItemCount) {
+
+
+        if (listener != null) {
+            if (getOffsetY() == 0) {
+                listener.shouldPullDownToRefresh(true);
+            } else {
+                listener.shouldPullDownToRefresh(false);
+            }
+        }
+
+        Log.d("Didida", "onScroll: " + firstVisibleItem + "  " + getOffsetY());
+
+    }
+
+}

+ 1361 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/Result/SearchResultActivity.java

@@ -0,0 +1,1361 @@
+package com.usai.apex.Result;
+
+import android.app.ProgressDialog;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.database.DataSetObserver;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.drawable.ColorDrawable;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
+import android.support.v4.content.FileProvider;
+import android.support.v4.widget.SwipeRefreshLayout;
+import android.support.v7.app.AlertDialog;
+import android.support.v7.app.AppCompatActivity;
+import android.text.Html;
+import android.text.Layout;
+import android.text.TextUtils;
+import android.util.Log;
+import android.util.TypedValue;
+import android.view.GestureDetector;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AbsListView;
+import android.widget.BaseAdapter;
+import android.widget.HorizontalScrollView;
+import android.widget.RelativeLayout;
+import android.widget.TableRow;
+import android.widget.TextView;
+
+import com.usai.apex.ApexTrackingApplication;
+import com.usai.apex.R;
+import com.usai.util.Network;
+import com.usai.util.RAUtil;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Iterator;
+
+//import com.usai.redant.Detail.KVDetailActivity;
+//import com.usai.redant.Detail.OrderDetailActivity;
+//import com.usai.apex.redantmobile.BuildConfig;
+
+//import static com.usai.redant.CommonEditor.CommonEditorActivity.URL_REMOTE;
+
+
+public class SearchResultActivity extends AppCompatActivity {
+
+    public static SearchResultActivity instance = null;
+    protected Bundle mParams;
+    protected JSONObject resultData = new JSONObject();
+
+    protected Context mContext;
+    protected PullRefreshListView resultListView;
+    protected ResultAdapter adapter;
+    protected SwipeRefreshLayout resultSwipe;
+    protected View list_footer;
+    protected View refresh_footer;
+
+    private View clickedView;
+    private View.OnTouchListener resultRowClickListener;
+    private GestureDetector detector;
+
+    protected int footer_height;
+    protected int header_height;
+
+    ProgressDialog progressDialog;
+    public boolean isLoading = false;//表示是否正处于加载状态
+
+
+    public void cellDoubleTapAction(int position) {
+
+//        try {
+//
+//            JSONArray row_action = resultData.optJSONArray("row_action");
+//            if (row_action != null) {
+//
+//                if (row_action.length() == 1) {
+//
+//                    JSONObject action = row_action.getJSONObject(0);
+//                    String module = action.getString("module");
+//
+//                    if (module.equals("quick_look")) {
+//                        JSONObject param = action.getJSONObject("params");
+//                        String url = action.getString("url");
+//                        showQuickLook(param,url);
+//                    } else if (module.equals("kv_detail")) {
+//                        JSONObject params = new JSONObject();
+//                        params.put("query_id",mParams.get("query_id"));
+//
+//                        JSONObject criteria = new JSONObject();
+//                        JSONObject action_params = action.getJSONObject("params");
+//                        Iterator<String> iterator = action_params.keys();
+//                        while (iterator.hasNext()) {
+//                            String key = iterator.next();
+//                            JSONArray item = contentData().getJSONArray("item_" + position);
+//                            int idx = action_params.getInt(key);
+//                            criteria.put(key,item.get(idx));
+//                        }
+//
+//                        params.put("criteria",criteria.toString());
+//                        showKVDetail(params);
+//
+//                    } else if (module.equals("order_detail")) {
+//
+//                        showOrderDetail();
+//
+//                    }
+//
+//
+//                } else if (row_action.length() > 1) {
+//
+//                    ArrayList<String> titleList = new ArrayList<>();
+//
+//                    for (int i = 0; i < row_action.length(); i++) {
+//                        JSONObject json = row_action.getJSONObject(i);
+//                        String title = json.getString("title");
+//                        titleList.add(title);
+//                    }
+//
+//                    new AlertDialog.Builder(mContext)
+//                            .setSingleChoiceItems((String[])titleList.toArray(new String[titleList.size()]), -1, new DialogInterface.OnClickListener() {
+//                                @Override
+//                                public void onClick(DialogInterface dialog, int which) {
+//
+//                                    try {
+//                                        JSONArray content_action = resultData.getJSONArray("row_action");
+//                                        JSONObject json = content_action.getJSONObject(which);
+//                                        String module = json.getString("module");
+//                                        JSONObject add_params = json.getJSONObject("params");
+//
+//                                        if (module.equals("quick_look")) {
+//                                            JSONObject param = json.getJSONObject("params");
+//                                            String url = json.getString("url");
+//                                            showQuickLook(param,url);
+//                                        } else if (module.equals("kv_detail")) {
+//
+//                                            JSONObject params = json.getJSONObject("params");
+//                                            showKVDetail(params);
+//
+//                                        } else if (module.equals("order_detail")) {
+//
+//                                            showOrderDetail();
+//
+//                                        }
+//
+//
+//                                    } catch (JSONException exception) {
+//                                        Log.d("Result", "onClick: ",exception);
+//                                    }
+//                                    dialog.dismiss();
+//
+//                                }
+//                            })
+//                            .show();
+//
+//                }
+//
+//            }
+//
+//        } catch (JSONException exception) {
+//            Log.e("Result", "onDoubleTapEvent: ",exception);
+//        }
+    }
+
+    void setMargin(View view,int l,int t,int r,int b) {
+        RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(view.getLayoutParams());
+        lp.setMargins(l, t, r, b);
+        view.setLayoutParams(lp);
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        if (progressDialog != null) {
+            progressDialog.dismiss();
+            progressDialog = null;
+        }
+    }
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_search_result);
+
+        instance = this;
+        mContext = this;
+        footer_height = dp2px(this,30);
+        header_height = dp2px(this,60);
+
+        resultListView = (PullRefreshListView) findViewById(R.id.result_table_list);
+        resultSwipe = findViewById(R.id.result_swipe);
+
+        progressDialog = new ProgressDialog(mContext);
+        progressDialog.setCancelable(false);
+
+        initClickListener();
+
+
+        adapter = new ResultAdapter(mContext);
+        resultListView.setAdapter(adapter);
+        resultListView.setDividerHeight(0);
+
+        // refresh header & footer
+        list_footer = View.inflate(this, R.layout.refresh_footer, null);
+        resultListView.setRefreshFooter(list_footer);
+
+        refresh_footer = findViewById(R.id.result_refresh_footer);
+        refresh_footer.bringToFront();
+
+        resultListView.setOnRefreshListener(new PullRefreshListView.OnRefreshListener() {
+            @Override
+            public void onHeaderStateChange(int state, int offset) {
+                Log.d("Pull Down", "onHeaderStateChange: " + offset);
+//                setMargin(refresh_header,0,offset,0,0);
+//                if (state == PullRefreshListView.REFRESHING) {
+//                   loadData();
+//                }
+            }
+
+            @Override
+            public void onFooterStateChange(int state, int offset) {
+
+                setMargin(refresh_footer,0,resultListView.getHeight() - offset,0,0);
+                if (state == PullRefreshListView.REFRESHING) {
+                    if (!isLoading) {
+                        loadMore();
+                    }
+                }
+            }
+
+            @Override
+            public void shouldPullDownToRefresh(boolean should) {
+                resultSwipe.setEnabled(should);
+            }
+        });
+
+        resultSwipe.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
+            @Override
+            public void onRefresh() {
+                if (isLoading) {
+                    resultSwipe.setRefreshing(false);
+                } else {
+                    loadData();
+                }
+            }
+        });
+
+
+
+        if (savedInstanceState != null) {
+            mParams = savedInstanceState.getBundle("query_params");
+        } else {
+            mParams = getIntent().getBundleExtra("query_params");
+        }
+
+        if (mParams == null) {
+            mParams = new Bundle();
+        }
+
+        String title = mParams.getString("title");
+        setTitle(title);
+
+        loadData();
+
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+
+        outState.putBundle("query_params",mParams);
+    }
+
+    // 动态修改Menu
+    @Override
+    public boolean onPrepareOptionsMenu(Menu menu) {
+        super.onPrepareOptionsMenu(menu);
+        menu.clear();
+
+
+//        if (resultData != null) {
+//            try {
+//                JSONArray menu_json = resultData.getJSONArray("menu");
+//
+//                if (menu_json != null && menu_json.length() > 0) {
+//
+//                    for (int i = 0; i < menu_json.length(); i++) {
+//                        JSONObject json = menu_json.getJSONObject(i);
+//                        String title = json.getString("title");
+//                        menu.add(0, i, 0, title);
+//                    }
+//                }
+//            } catch (JSONException e) {
+//                e.printStackTrace();
+//            }
+//        }
+
+        return true;
+    }
+
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+
+
+//        int which = item.getItemId();
+//        try {
+//            JSONArray menu = resultData.getJSONArray("menu");
+//            JSONObject json = menu.getJSONObject(which);
+//
+//            String actionType = json.getString("action");
+//            String url = json.optString("url");
+//
+//            if (actionType.equals("download")) {
+//                export(url);
+//            } else if (actionType.equals("save")) {
+//                if(BuildConfig.DEBUG && true){
+//                    //do something for assert aim
+//                    Log.e("Result", "onOptionsItemSelected DialogClick: not implement");
+//                }
+//            }
+//
+//        } catch (JSONException exception) {
+//            Log.d("Result", "onClick: ",exception);
+//        }
+
+        return true;
+    }
+
+
+//    public int last_index;
+//    public int total_index;
+//
+//    @Override
+//    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
+//        last_index = firstVisibleItem+visibleItemCount;
+//        total_index = totalItemCount;
+//    }
+//
+//    @Override
+//    public void onScrollStateChanged(AbsListView view, int scrollState) {
+//        if(last_index == total_index && (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE))
+//        {
+//            // 表示此时需要显示刷新视图界面进行新数据的加载(要等滑动停止)
+//            if(!isLoading)
+//            {
+//                // 设置刷新界面可见
+//                footer.setVisibility(View.VISIBLE);
+//                loadMore();
+//            }
+//        }
+//    }
+
+    // 设置header 和 footer宽度,否则listView会显示默认宽度
+    protected void setupUI() {
+        try {
+            if (resultData == null) {
+                return;
+            } else {
+                int result = resultData.getInt("result");
+                if (result != 2) {
+                    return;
+                }
+            }
+            JSONObject layout = resultData.getJSONObject("layout");
+
+            JSONObject header = layout.getJSONObject("header");
+            int width = header.getInt("width");
+            width = convertDp2Px(width);
+
+            AbsListView.LayoutParams footerLayoutParams = (AbsListView.LayoutParams)list_footer.getLayoutParams();
+            if (footerLayoutParams == null) {
+                footerLayoutParams = new AbsListView.LayoutParams(width,footer_height);
+            }
+            footerLayoutParams.height = footer_height;
+            footerLayoutParams.width = width;
+            list_footer.setLayoutParams(footerLayoutParams);
+
+
+        } catch (JSONException e) {
+            Log.e("Result", "setupUI: ", e);
+        }
+
+    }
+
+    public void loadComplete() {
+
+        setupUI();
+        resultListView.completeRefresh();
+        if (resultSwipe.isRefreshing()) {
+            resultSwipe.setRefreshing(false);
+        }
+        resultListView.forceLayout();
+
+        isLoading = false;//设置正在刷新标志位false
+        invalidateOptionsMenu();
+
+        String title = resultData.optString("table_title");
+        setTitleColor(Color.BLACK);
+        setTitle(title);
+
+        progressDialog.dismiss();
+    }
+
+
+    protected void showProgressDialog(String title, String msg) {
+        progressDialog.setTitle(title);
+        progressDialog.setMessage(msg);
+        progressDialog.show();
+    }
+
+    JSONObject readRawFile(int id)
+    {
+        String content;
+        Resources resources=this.getResources();
+        InputStream is=null;
+        try{
+            is=resources.openRawResource(id);
+            byte buffer[]=new byte[is.available()];
+            is.read(buffer);
+            content=new String(buffer);
+            JSONObject json = new JSONObject(content);
+            return json;
+        }
+        catch(IOException e)
+        {
+            e.printStackTrace();
+        }
+        catch (JSONException e) {
+            e.printStackTrace();
+        }
+        finally
+        {
+            if(is!=null)
+            {
+                try{
+                    is.close();
+                }catch(IOException e)
+                {
+                    e.printStackTrace();
+                }
+            }
+        }
+        return null;
+    }
+
+    protected void loadData() {
+
+//        resultData = readRawFile(R.raw.predef_query);
+//        if (1 == 1) {
+//            return;
+//        }
+
+        if (isLoading) {
+            return;
+        }
+
+        isLoading = true;
+
+        showProgressDialog(null,"Loading");
+
+        new Thread(new Runnable() {
+            @Override
+            public void run() {
+
+                try {
+
+                    mParams.putInt("offset",0);
+                    mParams.putInt("limit",25);
+                    JSONObject new_resultData = Network.query(mParams);
+
+                    if (new_resultData != null) {
+                        Iterator<String> iterator = new_resultData.keys();
+                        while (iterator.hasNext()) {
+                            String key = iterator.next();
+                            Object value = new_resultData.get(key);
+                            resultData.put(key,value);
+                        }
+                    }
+
+                    runOnUiThread(new Runnable() {
+                        @Override
+                        public void run() {
+
+                            loadComplete();
+                            int result = resultData.optInt("result",0);
+                            if (result == 2) {
+
+                            } else {
+
+                                String msg = resultData.optString("msg");
+                                if (msg == null || msg.isEmpty()) {
+                                    msg = "Sorry,some error occurred";
+                                }
+
+                                new AlertDialog.Builder(mContext)
+                                        .setTitle("Warning")
+                                        .setMessage(msg)
+                                        .show();
+                            }
+
+                            adapter.notifyDataSetChanged();
+                        }
+                    });
+
+                } catch (Exception e) {
+                    Log.e("Result", "onCreate: ",e);
+                }
+
+
+
+
+            }
+        }).start();
+
+    }
+
+    protected void loadMore() {
+
+        if (isLoading) {
+            return;
+        }
+
+        isLoading = true;
+        showProgressDialog(null,"Loading");
+
+        new Thread(new Runnable() {
+            @Override
+            public void run() {
+
+                try {
+
+//                    Thread.sleep(2000);
+//
+//                    InputStream in = getResources().openRawResource( R.raw.result);
+//                    int length = in.available();
+//                    byte[] buffer = new byte[length];
+//                    in.read(buffer);
+//                    String res = new String(buffer,"utf8");
+//                    in.close();
+//
+//                    JSONObject newJson = new JSONObject(res);
+
+                    mParams.putInt("offset",adapter.getCount());
+                    mParams.putInt("limit",25);
+                    JSONObject newJson = Network.query(mParams);
+
+                    if (newJson != null) {
+
+                        int result = newJson.getInt("result");
+                        if (result == 2) {
+                            JSONObject newData = newJson.getJSONObject("data");
+                            int add_count = newData.getInt("count");
+
+                            JSONObject data = resultData.getJSONObject("data");
+                            int count = data.getInt("count");
+
+                            for (int i = 0; i < add_count; i++) {
+                                JSONArray new_data_item = newData.getJSONArray("item_" + i);
+                                if (new_data_item != null) {
+                                    data.put("item_" + count++,new_data_item);
+                                }
+                            }
+                            data.put("count",count);
+                            resultData.put("data",data);
+
+                            runOnUiThread(new Runnable() {
+                                @Override
+                                public void run() {
+
+                                    loadComplete();
+                                    adapter.notifyDataSetChanged();
+                                }
+                            });
+                        } else {
+                            String msg = newJson.optString("msg");
+                            if (msg == null || msg.isEmpty()) {
+                                msg = "Some error occurred";
+                            }
+                            showAlert(msg);
+                        }
+
+
+                    }
+
+
+                } catch (Exception e) {
+                    Log.e("Result", "onCreate: ",e);
+                    showAlert("Some error occurred");
+                }
+
+
+
+
+            }
+        }).start();
+    }
+
+    protected JSONObject contentData() {
+        try {
+            return resultData.getJSONObject("data");
+        } catch (JSONException e) {
+            Log.e("Result", "contentData: ", e);
+        }
+        return null;
+    }
+
+    protected JSONArray contentMenu() {
+        if (resultData != null) {
+            try {
+                JSONArray menu_json = resultData.getJSONArray("menu");
+                return menu_json;
+            } catch (JSONException e) {
+                e.printStackTrace();
+            }
+        }
+        return null;
+    }
+
+    protected JSONArray contentAction() {
+        if (resultData != null) {
+            try {
+                JSONArray action_json = resultData.getJSONArray("row_action");
+                return action_json;
+            } catch (JSONException e) {
+                e.printStackTrace();
+            }
+        }
+        return null;
+    }
+
+    protected JSONObject contentLayout() {
+        if (resultData != null) {
+            try {
+                JSONObject layout = resultData.getJSONObject("layout");
+                return layout;
+            } catch (JSONException e) {
+                e.printStackTrace();
+            }
+        }
+        return null;
+
+    }
+
+
+    private class GestureListener extends GestureDetector.SimpleOnGestureListener {
+
+        @Override
+        public boolean onDoubleTapEvent(MotionEvent e) {
+
+
+            if (e.getAction() == MotionEvent.ACTION_UP) {
+
+                TableRow cellRow = (TableRow)clickedView.getParent();
+                RelativeLayout cell = (RelativeLayout)cellRow.getParent();
+
+                int position = resultListView.getPositionForView(cell);
+//                Log.d("Result", "onDoubleTapEvent: " + position);
+
+                if (position == 0) {
+                    return false;
+                }
+
+                cellDoubleTapAction(position);
+
+            }
+
+            return false;
+        }
+
+        @Override
+        public boolean onSingleTapConfirmed(MotionEvent e) {
+            if (clickedView instanceof TextView) {
+                TextView tv = (TextView)clickedView;
+                if (ellipsisTextView(tv)) {
+                    showAlert(tv.getText().toString());
+                }
+            }
+            return false;
+        }
+    }
+
+    private int normalColor;
+    private int touchColor = Color.GRAY;
+    private void initClickListener() {
+
+        // 需要作为成员变量
+        detector = new GestureDetector(mContext, new GestureListener());
+
+        resultRowClickListener = new View.OnTouchListener() {
+
+            @Override
+            public boolean onTouch(View v, MotionEvent event) {
+
+                TableRow cellRow = (TableRow)v.getParent();
+                RelativeLayout cell = (RelativeLayout)cellRow.getParent();
+
+                int position = resultListView.getPositionForView(cell);
+
+                if (position == 0) {
+                    return false;
+                }
+
+
+//                View cellRow = (View) v.getParent();
+                if (event.getAction() == MotionEvent.ACTION_DOWN) {
+
+                    if (clickedView != null) {
+                        ((View)clickedView.getParent()).setBackgroundColor(normalColor);
+                    }
+
+                    normalColor = ((ColorDrawable)cellRow.getBackground()).getColor();
+                    cellRow.setBackgroundColor(touchColor);
+
+                } else if (event.getAction() == MotionEvent.ACTION_CANCEL || event.getAction() == MotionEvent.ACTION_UP) {
+//                    cell.setBackgroundColor(normalColor);
+                }
+
+                clickedView = v;
+
+                detector.onTouchEvent(event);
+
+                return true;
+            }
+        };
+
+    }
+
+
+
+    protected class ResultAdapter extends BaseAdapter {
+
+        @Override
+        public boolean areAllItemsEnabled() {
+            return true;
+        }
+
+        @Override
+        public boolean isEnabled(int position) {
+            return true;
+        }
+
+        private class ResultHoder {
+            public ResultHoder(View view) {
+                row = (TableRow)view.findViewById(R.id.result_row);
+                view.setTag(this);
+            }
+            TableRow row;
+        }
+
+        public ResultAdapter(Context ctx) {
+
+        }
+
+        @Override
+        public void registerDataSetObserver(DataSetObserver observer) {
+            super.registerDataSetObserver(observer);
+        }
+
+        @Override
+        public void unregisterDataSetObserver(DataSetObserver observer) {
+            super.unregisterDataSetObserver(observer);
+        }
+
+        @Override
+        public int getCount() {
+            if (resultData == null) {
+                return 0;
+            } else {
+                int result = resultData.optInt("result");
+                if (result != 2) {
+                    return 0;
+                }
+            }
+            try {
+                JSONObject data = resultData.getJSONObject("data");
+                int result_count = data.getInt("count");
+                return result_count + 1; // header + data
+
+            } catch (JSONException e) {
+                Log.e("Result", "getCount: ", e);
+                return 0;
+            }
+        }
+
+        @Override
+        public Object getItem(int position) {
+            try {
+                if (position == 0) {
+                    // header
+
+                    JSONObject layout = resultData.getJSONObject("layout");
+                    JSONObject header = layout.getJSONObject("header");
+                    JSONArray col = header.getJSONArray("col");
+
+                    return col;
+
+                } else {
+                    // result row
+
+                    JSONObject data = resultData.getJSONObject("data");
+                    JSONArray item = data.getJSONArray("item_" + (position - 1));
+
+                    return item;
+                }
+
+
+            } catch (JSONException e) {
+                Log.e("Result", "getItem: ", e);
+            }
+            return null;
+        }
+
+        @Override
+        public long getItemId(int position) {
+            return position;
+        }
+
+        @Override
+        public boolean hasStableIds() {
+            return false;
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+
+            View cell;
+            ResultHoder holder;
+            if (convertView == null) {
+
+                cell = LayoutInflater.from(mContext).inflate(R.layout.result_cell,null);
+                holder = new ResultHoder(cell);
+
+
+            } else {
+
+                cell = convertView;
+                holder = (ResultHoder)cell.getTag();
+
+            }
+//            holder.row.removeAllViews();
+
+//            cell.setOnTouchListener(resultRowClickListener);
+
+            holder.row.setBackgroundColor(Color.WHITE);
+            // setup
+           try {
+
+               JSONObject layout = resultData.getJSONObject("layout");
+
+               JSONObject header = layout.getJSONObject("header");
+               int width = header.getInt("width");
+               int height = header.getInt("height");
+               int margin_t = header.getInt("margin_t");
+               int margin_l = header.getInt("margin_l");
+               int margin_b = header.getInt("margin_b");
+               int margin_r = header.getInt("margin_r");
+
+               width = convertDp2Px(width);
+               height = convertDp2Px(height);
+               margin_t = convertDp2Px(margin_t);
+               margin_l = convertDp2Px(margin_l);
+               margin_b = convertDp2Px(margin_b);
+               margin_r = convertDp2Px(margin_r);
+
+
+               HorizontalScrollView.LayoutParams listViewLayoutParams = (HorizontalScrollView.LayoutParams)resultListView.getLayoutParams();
+               listViewLayoutParams.width = width;
+               resultListView.setLayoutParams(listViewLayoutParams);
+
+
+
+               JSONArray obj = (JSONArray)getItem(position);
+               JSONArray arr_col = header.getJSONArray("col");
+
+               if (position == 0) {
+
+                   // header
+                   String bg_color = header.getString("bg_color");
+                   String f_color = header.getString("f_color");
+
+                   if (!bg_color.contains("0x")) {
+                       bg_color = "0x" + bg_color;
+                   }
+                   if (!f_color.contains("0x")) {
+                       f_color = "0x" + f_color;
+                   }
+                   bg_color = bg_color.replace("0x","#");
+                   f_color = f_color.replace("0x","#");
+
+                   RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams)holder.row.getLayoutParams();
+                   layoutParams.height = height;
+                   holder.row.setLayoutParams(layoutParams);
+
+                   // 调整显示列后,需要删除多余的列
+                   if (holder.row.getChildCount() > arr_col.length()) {
+                       for (int i = arr_col.length(); i < holder.row.getChildCount(); i++) {
+                           TextView tv = (TextView)holder.row.findViewById(i);
+                           holder.row.removeView(tv);
+                       }
+                   }
+
+                   // col
+                   for (int i = 0; i < arr_col.length(); i++) {
+
+                       JSONObject value = obj.getJSONObject(i);
+                       int col_w = value.getInt("width");
+                       col_w = convertDp2Px(col_w);
+
+                       String h_align = value.getString("h_align");
+                       String v_center = value.getString("v_center");
+                       String col_bg_color = value.getString("bg_color");
+                       String col_f_color = value.getString("f_color");
+                       String name = value.getString("name");
+
+
+                       bg_color = bg_color.replace("0x","#");
+                       f_color = f_color.replace("0x","#");
+
+                       TextView tv = (TextView)holder.row.findViewById(i);
+                       if (tv == null) {
+                           tv = new TextView(mContext);
+
+                           tv.setGravity(convertGravity("h_align",h_align) | convertGravity("v_center",v_center));
+                           tv.setSingleLine();
+                           tv.setEllipsize(TextUtils.TruncateAt.END);
+                           tv.setId(i);
+                           tv.setBackgroundDrawable(getResources().getDrawable(R.drawable.result_black_border));
+                           tv.setOnTouchListener(resultRowClickListener);
+                       } else {
+                           holder.row.removeView(tv);
+                       }
+
+                       // layout
+                       tv.setWidth(col_w);
+                       tv.setHeight(height);
+                       tv.setPadding(margin_l,margin_t,margin_r,margin_b);
+
+                       TableRow.LayoutParams tvLayoutParams = new  TableRow.LayoutParams(col_w, height);
+
+                       holder.row.addView(tv,i,tvLayoutParams);
+
+                       // content
+                       tv.setTextColor(Color.parseColor(f_color));
+                       tv.setTextSize(TypedValue.COMPLEX_UNIT_SP,14);
+                       tv.getPaint().setFakeBoldText(true);
+
+                       if (name.contains("</")) {
+                           tv.setText(Html.fromHtml(name));
+                       } else {
+                           tv.setText(name);
+                       }
+
+                   }
+                   holder.row.setBackgroundColor(Color.parseColor(bg_color));
+
+               } else {
+
+                   // row
+                   JSONObject row = layout.getJSONObject("row");
+                   String f_color = row.getString("f_color");
+                   String color_0 = row.getString("color_0");
+                   String color_1 = row.getString("color_1");
+
+                   if (!f_color.contains("0x")) {
+                       f_color = "0x" + f_color;
+                   }
+                   if (!color_0.contains("0x")) {
+                       color_0 = "0x" + color_0;
+                   }
+                   if (!color_1.contains("0x")) {
+                       color_1 = "0x" + color_1;
+                   }
+
+
+                   f_color = f_color.replace("0x","#");
+                   color_0 = color_0.replace("0x","#");
+                   color_1 = color_1.replace("0x","#");
+
+                   int row_h = row.getInt("height");
+                   row_h = convertDp2Px(row_h);
+
+                   RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams)holder.row.getLayoutParams();
+                   layoutParams.height = row_h;
+                   holder.row.setLayoutParams(layoutParams);
+
+                   // 调整显示列后,需要删除多余的列
+                   if (holder.row.getChildCount() > arr_col.length()) {
+                       for (int i = arr_col.length(); i < holder.row.getChildCount(); i++) {
+                           TextView tv = (TextView)holder.row.findViewById(i);
+                           holder.row.removeView(tv);
+                       }
+                   }
+
+                   // col
+                   for (int i = 0; i < arr_col.length(); i++) {
+
+                       JSONArray col_layout = row.getJSONArray("val");
+                       JSONObject layout_val = col_layout.getJSONObject(i);
+
+                       String type = layout_val.getString("type");
+                       String h_align = layout_val.getString("h_align");
+                       String v_center = layout_val.getString("v_center");
+                       String col_bg_color = layout_val.getString("bg_color");
+                       String col_f_color = layout_val.getString("f_color");
+
+                       col_bg_color = col_bg_color.replace("0x","#");
+                       col_f_color = col_f_color.replace("0x","#");
+
+                       String value = obj.getString(i);
+
+
+                       JSONObject size = ((JSONArray)getItem(0)).getJSONObject(i);
+                       int col_w = size.getInt("width");
+                       int col_h = row.getInt("height");
+
+                       col_w = convertDp2Px(col_w);
+                       col_h = convertDp2Px(col_h);
+
+                       TextView tv = (TextView) holder.row.findViewById(i);
+                       if (tv == null) {
+                           tv = new TextView(mContext);
+
+                           tv.setGravity(convertGravity("h_align",h_align) | convertGravity("v_center",v_center));
+                           tv.setSingleLine();
+                           tv.setEllipsize(TextUtils.TruncateAt.END);
+                           tv.setId(i);
+                           tv.setOnTouchListener(resultRowClickListener);
+                           tv.setBackgroundDrawable(getResources().getDrawable(R.drawable.result_black_border));
+                       } else {
+                           holder.row.removeView(tv);
+                       }
+
+                       // layout
+                       tv.setWidth(col_w);
+                       tv.setHeight(col_h);
+                       tv.setPadding(margin_l,margin_t,margin_r,margin_b);
+
+                       TableRow.LayoutParams tvLayoutParams = new  TableRow.LayoutParams(col_w, col_h);
+                       holder.row.addView(tv,i,tvLayoutParams);
+
+                       // content
+
+                       tv.setTextColor(Color.parseColor(f_color));
+                       tv.setTextSize(TypedValue.COMPLEX_UNIT_SP,12);
+                       tv.getPaint().setFakeBoldText(false);
+                       tv.setText(Html.fromHtml(value));
+//                       if (value.contains("</")) {
+//                           tv.setText(Html.fromHtml(value));
+//                       } else {
+//                           tv.setText(value);
+//                       }
+
+
+                   }
+
+                   if ((position - 1) % 2 == 0) {
+                       holder.row.setBackgroundColor(Color.parseColor(color_0));
+                   } else {
+                       holder.row.setBackgroundColor(Color.parseColor(color_1));
+
+                   }
+               }
+
+           } catch (JSONException e) {
+               Log.e("Result", "getView: ", e);
+           }
+
+            return cell;
+        }
+
+        private int convertGravity(String key, String align) {
+
+            if (key.equals("h_align")) {
+                if (align.equals("center")) {
+                    return Gravity.CENTER_HORIZONTAL;
+                } else if (align.equals("left")) {
+                    return Gravity.LEFT;
+                } else if (align.equals("right")) {
+                    return Gravity.RIGHT;
+                }
+
+            }
+
+            if (key.equals("v_center")) {
+
+                if (align.equals("center")) {
+                    return Gravity.CENTER_VERTICAL;
+                } else if (align.equals("top")) {
+                    return Gravity.TOP;
+                } else if (align.equals("bottom")) {
+                    return Gravity.BOTTOM;
+                }
+            }
+            return Gravity.CENTER;
+        }
+
+        @Override
+        public int getItemViewType(int position) {
+            return 0;
+        }
+
+        @Override
+        public int getViewTypeCount() {
+            return 1;
+        }
+
+        @Override
+        public boolean isEmpty() {
+            return false;
+        }
+    }
+
+
+    public boolean ellipsisTextView(TextView tv) {
+        Layout l = tv.getLayout();
+        if ( l != null){
+            int lines = l.getLineCount();
+            if ( lines > 0) {
+                if (l.getEllipsisCount(lines - 1) > 0) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    public int convertDp2Px(int dp) {
+        return dp2px(mContext,dp);
+    }
+
+    public int px2dp(Context context, float pxValue) {
+        float scale = context.getResources().getDisplayMetrics().density;
+        return (int) (pxValue / scale + 0.5f);
+    }
+
+    public int dp2px(Context context, float dpValue) {
+        float scale = context.getResources().getDisplayMetrics().density;
+        return (int) (dpValue * scale + 0.5f);
+    }
+
+    public int px2sp(Context context, float pxValue) {
+        float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
+        return (int) (pxValue / fontScale + 0.5f);
+    }
+
+    public int sp2px(Context context, float spValue) {
+        float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
+        return (int) (spValue * fontScale + 0.5f);
+    }
+
+
+    protected String documentPath;
+    protected String download_query;
+    protected void export(final String download_url) {
+
+        if (download_query != null) {
+            documentPath = download_query;
+            openFile(new File(download_query));
+            return;
+        }
+
+        showProgressDialog(null,"Please wait");
+        new Thread(new Runnable() {
+            @Override
+            public void run() {
+
+                String cacheDir = ApexTrackingApplication.getInstance().getDocumentDir();
+                // download & get path
+                final File downloadFile = Network.download_query(download_url,cacheDir);
+                final String path = downloadFile != null && downloadFile.exists() ? downloadFile.getPath() : null;
+
+
+
+                documentPath = path;
+                download_query = path;
+
+
+                if (path != null) {
+                    runOnUiThread(new Runnable() {
+                        @Override
+                        public void run() {
+                            progressDialog.dismiss();
+                            openFile(downloadFile);
+                        }
+                    });
+                }
+
+            }
+        }).start();
+
+    }
+
+    public void showAlert(final String msg) {
+        if (msg == null || msg.isEmpty()) {
+            return;
+        }
+
+        runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                new AlertDialog.Builder(mContext)
+                        .setMessage(msg)
+                        .show();
+            }
+        });
+    }
+
+    public void showOrderDetail() {
+//        Intent intent = OrderDetailActivity.build(mContext,OrderDetailActivity.class,null,URL_REMOTE,null,new Bundle());
+//
+//        startActivity(intent);
+    }
+
+    public void showKVDetail(final JSONObject param) {
+//        showProgressDialog("Please wait","Loading...");
+//
+//        new Thread(new Runnable() {
+//            @Override
+//            public void run() {
+//
+//                final JSONObject json = Network.kv_detail(RAUtil.Json2Bundle(param));
+////                final JSONObject json = readRawFile(R.raw.kv);
+//
+//                runOnUiThread(new Runnable() {
+//                    @Override
+//                    public void run() {
+//                        progressDialog.dismiss();
+//
+//                        int result = 0;
+//                        if (json != null) {
+//                            result = json.optInt("result",0);
+//                        }
+//                        if (result == 2) {
+//
+//                            Intent intent = KVDetailActivity.build(mContext,json.toString());
+//
+//                            startActivity(intent);
+//
+//                        } else {
+//                            String msg = json.optString("msg");
+//                            if (msg == null) {
+//                                msg = "Sorry,some error occurred";
+//                            }
+//                            showAlert(msg);
+//                        }
+//
+//                    }
+//                });
+//
+//            }
+//        }).start();
+
+    }
+
+    public void showQuickLook(final JSONObject param, final String url) {
+
+        showProgressDialog("Please wait","Downloading...");
+        new Thread(new Runnable() {
+            @Override
+            public void run() {
+
+                String cacheDir = ApexTrackingApplication.getInstance().getDocumentDir();
+                // 下载文件
+                final File downloadFile = Network.downloadFile(RAUtil.Json2Bundle(param),url,cacheDir);
+
+                runOnUiThread(new Runnable() {
+                    @Override
+                    public void run() {
+                        progressDialog.dismiss();
+                        if (downloadFile != null && downloadFile.exists()) {
+//                            try {
+//                                //此处需要新增保存文档的本地表
+//                                param;
+////                                String email=param.getString("email");
+////                                String email_subject=param.getString("email_subject");
+////                                String email_content=param.getString("email_content");
+//                            } catch (JSONException e) {
+//                                e.printStackTrace();
+//                            }
+                            openFile(downloadFile);
+                        } else {
+                            showAlert("Sorry,there is a wrong.");
+                        }
+                    }
+                });
+
+            }
+        }).start();
+
+
+    }
+
+    protected void openFile(File file) {
+
+        if (file == null || !file.exists()) {
+            return;
+        }
+
+        Uri uri = null;
+        String type = RAUtil.getMimeType(file.getPath());
+
+        // type "application/pdf"
+        Intent intent = new Intent(Intent.ACTION_VIEW);
+
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+
+            // "com.usai.apex.fileprovider"即是在Manifest文件中配置的authorities
+            uri = FileProvider.getUriForFile(mContext, "com.usai.apex.fileprovider", file);
+            // 给目标应用一个临时授权
+            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+        } else {
+            uri = Uri.fromFile(file);
+        }
+
+        intent.setDataAndType(uri, type);
+
+        if (getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY) != null) {
+            // someone knows how to handle this mime type with this scheme, don't download.
+            try {
+                startActivity(intent);
+                return;
+            } catch (Exception ex) {
+                Log.d("Open File", "activity not found for " + type + " over " + uri, ex);
+            }
+
+        } else {
+            Log.d("Open File", "openFileAtPath: " + "No App " + uri);
+            try {
+                shareFile(uri,type);
+            } catch (Exception e) {
+                Log.e("Show Dialog Error", "openFileAtPath: ", e);
+            }
+        }
+
+    }
+
+    protected void shareFile(Uri uri, String type) {
+
+        Intent shareIntent = new Intent();
+        shareIntent.setAction(Intent.ACTION_SEND);
+        shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
+        shareIntent.setType(type);
+        startActivity(Intent.createChooser(shareIntent, "Share"));
+    }
+
+
+}

+ 871 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/ResultActivity.java

@@ -0,0 +1,871 @@
+package com.usai.apex;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.AlertDialog.Builder;
+import android.app.Dialog;
+import android.app.DownloadManager;
+import android.app.DownloadManager.Request;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Build;
+import android.os.Bundle;
+import android.text.Html;
+import android.text.style.URLSpan;
+import android.util.Log;
+import android.util.SparseArray;
+import android.view.ContextMenu;
+import android.view.ContextMenu.ContextMenuInfo;
+import android.view.Gravity;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.View.OnCreateContextMenuListener;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+import android.widget.TableLayout;
+import android.widget.TableRow;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.usai.apex.mainframe.NewDetailActivity;
+import com.usai.util.Network;
+import com.usai.util.dbUtil;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Set;
+
+public class ResultActivity extends Activity
+{
+
+	private static final int	REQUEST_LOGINACTIVITY	= 1;
+	String						user					= null;
+	String						password				= null;
+	String						function_name			= null;
+	private SearchTask			m_task					= null;
+
+	final int					OFFSET					= 5;
+
+	int							sel						= -1;
+
+	Bundle						searchParms				= null;
+	SearchResult				searchresult			= new SearchResult();
+
+	SparseArray<String>			showfieldmap			= new SparseArray<String>();
+	// HashMap<Integer, String> showfieldmap = new HashMap<Integer, String>();
+	private TextView			mStatusMessageView;
+	// private View mSearchFormView;
+	private View				footview;
+	private View				mStatusView;
+	int							actioncount				= 0;
+
+	// private class resultAdapter extends SimpleAdapter
+	// {
+	//
+	//
+	// }
+	@Override
+	protected void onCreate(Bundle savedInstanceState)
+	{
+		user = ApexTrackingApplication.get_user();
+		password = ApexTrackingApplication.get_pass();
+		function_name = getIntent().getStringExtra("function_name");
+		if (function_name.equals("Ocean Booking"))
+			setTitle("Booking Result");
+		else if (function_name.equals("Ocean B/L info."))
+			setTitle("B/L info. Result");
+		else if (function_name.equals("Container detail"))
+			setTitle("Container Result");
+		else if (function_name.equals("Download Document"))
+			setTitle("Document Result");
+
+		searchParms = getIntent().getBundleExtra("searchParms");
+		super.onCreate(savedInstanceState);
+		setContentView(R.layout.activity_result);
+
+		SQLiteDatabase db = dbUtil.OpenDB(ResultActivity.this, null, false);
+		Cursor cursor = db
+				.query("actions_info", new String[] { "count(*)" },
+						"function_name='" + function_name + "' and user='"
+								+ user + "'", null, null, null, "priority",
+						null);
+		if (cursor.moveToNext())
+		{
+			actioncount = cursor.getInt(0);
+		}
+
+		dbUtil.CloseCursor(cursor);
+		dbUtil.CloseDB(db);
+
+		footview = findViewById(R.id.foot);
+		// mSearchFormView = findViewById(R.id.search_form);
+		Button btnnext = (Button) findViewById(R.id.btn_next);
+		btnnext.setOnClickListener(new View.OnClickListener()
+		{
+
+			@Override
+			public void onClick(View v)
+			{
+				// TextView tv_head = (TextView) findViewById(R.id.tv_head);
+
+				// searchresult.set_direction(1);
+				if (searchresult.get_totalcount() == -1)
+					requestdata(true);
+				else
+				{
+					// if (searchresult.get_direction() == -1)
+					searchresult.set_offset(searchresult.get_offset() + OFFSET);
+					requestdata(false);
+				}
+
+			}
+		});
+
+		Button btnpre = (Button) findViewById(R.id.btn_pre);
+		btnpre.setOnClickListener(new View.OnClickListener()
+		{
+
+			@Override
+			public void onClick(View v)
+			{
+				// TextView tv_head = (TextView) findViewById(R.id.tv_head);
+				// searchresult.set_direction(-1);
+				if (searchresult.get_totalcount() == -1)
+					requestdata(true);
+				else
+				{
+					searchresult.set_offset(searchresult.get_offset() - OFFSET);
+					requestdata(false);
+				}
+
+			}
+		});
+		mStatusView = findViewById(R.id.status);
+		mStatusMessageView = (TextView) findViewById(R.id.status_message);
+		LinearLayout ll = (LinearLayout) findViewById(R.id.ll_refresh);
+		Button btn_refresh = (Button) ll.findViewById(R.id.btn_refresh);
+		btn_refresh.setOnClickListener(new View.OnClickListener()
+		{
+
+			@Override
+			public void onClick(View v)
+			{
+				LinearLayout ll = (LinearLayout) findViewById(R.id.ll_refresh);
+				ll.setVisibility(View.INVISIBLE);
+				if (searchresult.get_totalcount() == -1)
+					requestdata(true);
+				else
+					requestdata(false);
+
+			}
+		});
+
+		SharedPreferences RunOnce = getSharedPreferences("Apex", 0);
+
+		String vername;
+		try
+		{
+			vername = getPackageManager().getPackageInfo("com.usai.apex", 0).versionName;
+			boolean bFirstRun = RunOnce.getBoolean("FirstRun" + vername
+					+ "_result", true);
+			if (bFirstRun&&false)
+			{
+				SharedPreferences.Editor editor = RunOnce.edit();
+				editor.putBoolean("FirstRun" + vername + "_result", false);
+				// Don't forget to commit your edits!!!
+				editor.commit();
+				Intent intent = new Intent();
+				intent.setClass(this, HelpActivity.class);
+				intent.putExtra("caller", "result");
+				startActivity(intent);
+
+			}
+		}
+		catch (NameNotFoundException e)
+		{
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		initTableHeader();
+		if (savedInstanceState != null)
+		{
+			searchresult = (SearchResult) savedInstanceState
+					.getSerializable("searchresult");
+			if (searchresult.get_totalcount() == -1)
+				requestdata(true);
+			else
+				initTable();
+		}
+		else
+			requestdata(true);
+
+	}
+
+	@Override
+	protected void onDestroy()
+	{
+		if (m_task != null)
+			m_task.cancel(false);
+		super.onDestroy();
+	}
+
+	private void initTable()
+	{
+		// int loadcount = searchresult.get_count();
+		int totalcount = searchresult.get_totalcount();
+		TextView tv_head = (TextView) findViewById(R.id.head);
+		if (totalcount == 0)
+		{
+			tv_head.setText(R.string.str_0);
+
+			return;
+		}
+		else if (searchresult.get_totalcount() > 2000)
+		{
+			tv_head.setText(R.string.str_2000);
+		}
+		else
+			tv_head.setText(/*
+							 * loadcount + "/" + //
+							 */searchresult.get_totalcount()
+					+ getText(R.string.str_records).toString());
+		TableLayout tl = (TableLayout) findViewById(R.id.result_table);
+
+		tl.removeViews(1, tl.getChildCount() - 1);
+		// int newcount = loadcount - showcount + 1;// +1 header row
+		for (int i = 0; i < searchresult.get_recordscount(); i++)
+		{
+
+			TableRow recordRow = new TableRow(ResultActivity.this);
+			recordRow.setOnLongClickListener(new View.OnLongClickListener()
+			{
+
+				@Override
+				public boolean onLongClick(View v)
+				{
+					// TODO Auto-generated method stub
+					// v.setBackgroundColor(Color.GRAY);
+					// v.showContextMenu();
+					// return true;
+					TableRow tr = (TableRow) v;
+					TextView tvno = (TextView) tr.getChildAt(0);
+					sel = (Integer.parseInt(tvno.getText().toString())-1) % 5 ;
+					registerForContextMenu(v);
+					openContextMenu(v);
+					unregisterForContextMenu(v);
+					return true;
+				}
+			});
+
+			// registerForContextMenu(recordRow);
+			// recordRow.setClickable(true);
+			// registerForContextMenu(recordRow);
+			// recordRow.setOnCreateContextMenuListener(m_tableMenu);
+			// recordRow.SETSE
+
+			HashMap<String, String> record = searchresult.get_record(i);
+			TextView field = new TextView(ResultActivity.this);
+			field.setBackgroundResource(R.drawable.tableitem);
+			field.setText(searchresult.get_offset() + i + 1 + "");
+			Log.d("offset=" + searchresult.get_offset(), "");
+			field.setGravity(Gravity.CENTER);
+			field.setPadding(10, 5, 10, 5);
+			field.setTextSize(20);
+			recordRow.addView(field);
+			for (int j = 0; j < showfieldmap.size(); j++)
+			{
+				TextView field1 = new TextView(ResultActivity.this);
+				// Log.d("onPostExecute", showfieldmap.get(j));
+				String str = record.get(showfieldmap.get(j));
+				field1.setBackgroundResource(R.drawable.tableitem);
+				if (str.toLowerCase().trim().equals("null"))
+					str = "";
+
+				// field1.setBackgroundColor(0xFFFFFFFF);
+
+				field1.setText(Html.fromHtml(str));
+
+				if (actioncount == 0)
+					field1.setOnClickListener(new OnClickListener()
+					{
+
+						@Override
+						public void onClick(View v)
+						{
+							// if (true)
+							// return;
+							URLSpan span[] = ((TextView) v).getUrls();
+							if (span.length < 1)
+								return;
+							span[0].getURL();
+							Log.d("Text", span[0].getURL());
+							
+							TextView tv = (TextView)v;
+
+							final DownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
+
+							Uri uri = Uri.parse(span[0].getURL());
+							final Request request = new Request(uri);
+
+							// 设置允许使用的网络类型,这里是移动网络和wifi都可以
+							request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE
+									| DownloadManager.Request.NETWORK_WIFI);
+							
+							request.setDestinationInExternalPublicDir("Apex Mobile",tv.getText().toString()); 
+
+							// 禁止发出通知,既后台下载,如果要使用这一句必须声明一个权限:android.permission.DOWNLOAD_WITHOUT_NOTIFICATION
+							// request.setShowRunningNotification(false);
+
+							// 不显示下载界面
+							request.setVisibleInDownloadsUi(false);
+							request.setNotificationVisibility(Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
+
+							/*
+							 * 设置下载后文件存放的位置,如果sdcard不可用,那么设置这个将报错,
+							 * 因此最好不设置如果sdcard可用,下载后的文件 在/mnt/sdcard/Android/
+							 * data/packageName/files目录下面
+							 * ,如果sdcard不可用,设置了下面这个将报错,不设置,下载后的文件在/cache这个 目录下面
+							 */
+							// request.setDestinationInExternalFilesDir(this,
+							// null, "tar.apk");
+
+							AlertDialog.Builder builder = new Builder(
+									ResultActivity.this);
+							builder.setMessage(getString(R.string.str_downloadmessage));
+
+							builder.setTitle(getString(R.string.str_confirmdownload));
+
+							builder.setPositiveButton(
+									getString(R.string.str_download),
+									new Dialog.OnClickListener()
+									{
+
+										@Override
+										public void onClick(
+												DialogInterface dialog,
+												int which)
+										{
+											downloadManager.enqueue(request);
+											dialog.dismiss();
+
+										}
+									});
+
+							builder.setNegativeButton(
+									getString(R.string.str_cancel),
+									new Dialog.OnClickListener()
+									{
+
+										@Override
+										public void onClick(
+												DialogInterface dialog,
+												int which)
+										{
+											dialog.dismiss();
+										}
+									});
+
+							builder.create().show();
+
+						}
+
+					});
+				// field1.setText(str);
+				field1.setGravity(Gravity.LEFT);
+				field1.setPadding(10, 5, 10, 5);
+				field1.setTextSize(20);
+				// field.setTextAppearance(ResultActivity.this,
+				// android.R.attr.textAppearanceMedium);
+				recordRow.addView(field1);
+			}
+			tl.addView(recordRow);
+		}
+
+		Button btnnext = (Button) findViewById(R.id.btn_next);
+
+		Button btnpre = (Button) findViewById(R.id.btn_pre);
+		if (searchresult.get_offset() == 0)
+			btnpre.setEnabled(false);
+		else
+		{
+			btnpre.setEnabled(true);
+		}
+		if ((searchresult.get_totalcount() - searchresult.get_offset() <= OFFSET)
+				|| (searchresult.get_totalcount() == 0))
+			btnnext.setEnabled(false);
+		else
+			btnnext.setEnabled(true);
+	}
+
+	private OnCreateContextMenuListener	m_tableMenu	= new OnCreateContextMenuListener()
+													{
+
+														@Override
+														public void onCreateContextMenu(
+																ContextMenu contextmenu,
+																View view,
+																ContextMenuInfo contextmenuinfo)
+														{
+
+															contextmenu
+																	.add(Menu.NONE,
+																			0,
+																			0,
+																			getString(R.string.str_detail));
+
+														}
+
+													};
+
+	@Override
+	public boolean onContextItemSelected(MenuItem item)
+	{
+		// menuInfo = (AdapterContextMenuInfo) item.getMenuInfo();
+		// Log.d("table row select", sel+ "");
+
+		Intent intent = new Intent();
+		intent.setClass(this, NewDetailActivity.class);
+
+		SQLiteDatabase db = dbUtil.OpenDB(this, null, false);
+		Cursor cursor = db.query("actions_info",
+				new String[] { "name", "_id" }, "function_name='"
+						+ function_name + "' and user='" + user + "'", null,
+				null, null, "priority", null);
+		int i = 0;
+		while (cursor.moveToNext())
+		{
+			String name = cursor.getString(0);
+			Log.d("actionname", name);
+			intent.putExtra("action" + i, name);
+			i++;
+		}
+		intent.putExtra("function_name", function_name);
+		intent.putExtra("actions_count", i);
+		intent.putExtra("_id", searchresult.get_record(sel).get("_id")
+				.toString());
+		dbUtil.CloseCursor(cursor);
+		dbUtil.CloseDB(db);
+
+		startActivity(intent);
+
+		return super.onContextItemSelected(item);
+	}
+
+	// @Override
+	// public void onCreateContextMenu(ContextMenu menu, View v,
+	// ContextMenuInfo menuInfo)
+	// {
+	// // // TODO Auto-generated method stub
+	// menu.add(Menu.NONE, 0, 0, "Detail");
+	// // // contextmenu.add(Menu.NONE, 1, 1, "�༭");
+	// super.onCreateContextMenu(menu, v, menuInfo);
+	// }
+
+	void initTableHeader()
+	{
+
+		TableLayout tl = (TableLayout) findViewById(R.id.result_table);
+		tl.setFocusable(true);
+		tl.setOnCreateContextMenuListener(m_tableMenu);
+		SQLiteDatabase db = dbUtil.OpenDB(this, null, false);
+		Cursor cursor = db.query("fields_info", new String[] { "aname", "name",
+				"_id" }, "function_name='" + function_name + "' and user='"
+				+ user + "' and behavior=" + Network.BEHAVIOR_RESULT
+				+ " and show = 1", null, null, null, "priority , aname", null);
+		TableRow headerRow = (TableRow) findViewById(R.id.tr_header);
+		int pos = 0;
+		showfieldmap.clear();
+		headerRow.removeAllViews();
+		ArrayList<HashMap<String, String>> gridheader = new ArrayList<HashMap<String, String>>();
+		HashMap<String, String> map = new HashMap<String, String>();
+		map.put("key", "no.");
+		gridheader.add(map);
+		Button btn = new Button(this);
+		btn.setBackgroundResource(R.drawable.tablehead);
+		btn.setPadding(0, 0, 0, 0);
+		btn.setText("No.");
+		headerRow.addView(btn);
+		while (cursor.moveToNext())
+		{
+			String aname = cursor.getString(0);
+			Button btn1 = new Button(this);
+			btn1.setBackgroundResource(R.drawable.tablehead);
+			btn1.setText(aname);
+			headerRow.addView(btn1);
+			showfieldmap.put(pos, cursor.getString(1));
+
+			map.put("key", "header");
+			gridheader.add(map);
+			pos++;
+		}
+		dbUtil.CloseCursor(cursor);
+		dbUtil.CloseDB(db);
+
+		// SimpleAdapter adapter = new SimpleAdapter(this,
+		// gridheader,// �����Դ
+		// R.layout.result_item,//XMLʵ��
+		// new String[] { "key" }, // ��̬������ImageItem��Ӧ������
+		// new int[] { R.id.tv_value });
+		//
+		// GridView gridview = (GridView) findViewById(R.id.grid_result);
+		// gridview.setNumColumns(2);
+		// gridview.setAdapter(adapter);
+
+	}
+
+	@Override
+	public boolean onCreateOptionsMenu(Menu menu)
+	{
+		// Inflate the menu; this adds items to the action bar if it is present.
+		getMenuInflater().inflate(R.menu.result, menu);
+		return true;
+	}
+
+	@Override
+	public boolean onOptionsItemSelected(MenuItem item)
+	{
+		Intent intent = new Intent();
+		switch (item.getItemId())
+		{
+			case R.id.action_custom_fields:
+
+				intent.setClass(this, CustomizeFieldsActivity.class);
+				intent.putExtra("user", user);
+				// intent.putExtra("password", password);
+				intent.putExtra("function_name", function_name);
+				intent.putExtra("behavior", Network.BEHAVIOR_RESULT);
+				startActivity(intent);
+				break;
+			case R.id.action_help:
+				// Intent intent = new Intent();
+				intent.setClass(this, HelpActivity.class);
+				intent.putExtra("caller", "result");
+				// // intent.putExtra("password", password);
+				// intent.putExtra("function_name", function_name);
+				// intent.putExtra("behavior", Network.BEHAVIOR_SEARCH);
+				startActivity(intent);
+				break;
+			case R.id.action_save_search:
+				// LayoutInflater factory = LayoutInflater.from(this);
+				// final View textEntryView =
+				// factory.inflate(R.layout.alert_dialog_text_entry, null);
+				final View edit = new EditText(this);
+				new AlertDialog.Builder(this)
+						.setIconAttribute(android.R.attr.alertDialogIcon)
+						.setTitle(R.string.str_createname)
+						.setView(edit)
+						.setPositiveButton(android.R.string.ok,
+								new DialogInterface.OnClickListener()
+								{
+									public void onClick(DialogInterface dialog,
+											int whichButton)
+									{
+										String name = ((EditText) edit)
+												.getText().toString();
+										String param = getIntent().toUri(0);
+
+										JSONObject obj = new JSONObject();
+										Set<String> keys = searchParms.keySet();
+										for (String key : keys)
+										{
+
+											
+											try
+											{
+												obj.put(key, searchParms.get(key).toString());
+
+											}
+											catch (JSONException e)
+											{
+												// TODO Auto-generated catch block
+												e.printStackTrace();
+											}
+
+										}
+										obj.toString();
+
+										SQLiteDatabase db = dbUtil.OpenDB(
+												ApexTrackingApplication.get_instance(), null, true);
+										db.execSQL("insert into history(params,name,criterion,module_name,user,create_time) values('"
+
+												+ param
+												+ "','"
+												+ name
+												+ "','"
+												+ obj.toString()
+												+ "','"
+												+ function_name
+												+ "','"
+												+ ApexTrackingApplication.get_user()
+												+ "',"
+												+ System.currentTimeMillis() + ")");
+										dbUtil.CloseDB(db);
+
+										/* User clicked OK so do some stuff */
+									}
+								})
+						.setNegativeButton(android.R.string.cancel,
+								new DialogInterface.OnClickListener()
+								{
+									public void onClick(DialogInterface dialog,
+											int whichButton)
+									{
+
+										/* User clicked cancel so do some stuff */
+									}
+								}).create().show();
+				break;
+			default:
+				break;
+		}
+		return super.onOptionsItemSelected(item);
+	}
+
+	public void requestdata(boolean requestcount)
+	{
+
+		if (m_task != null)
+		{
+			return;
+		}
+		mStatusMessageView.setText(R.string.str_Loading);
+		showProgress(true);
+		m_task = new SearchTask();
+		m_task.execute(requestcount);
+
+	}
+
+	private void showProgress(final boolean show)
+	{
+		// On Honeycomb MR2 we have the ViewPropertyAnimator APIs, which allow
+		// for very easy animations. If available, use these APIs to fade-in
+		// the progress spinner.
+		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2)
+		{
+			int shortAnimTime = getResources().getInteger(
+					android.R.integer.config_shortAnimTime);
+
+			mStatusView.setVisibility(View.VISIBLE);
+			mStatusView.animate().setDuration(shortAnimTime)
+					.alpha(show ? 1 : 0)
+					.setListener(new AnimatorListenerAdapter()
+					{
+						@Override
+						public void onAnimationEnd(Animator animation)
+						{
+							mStatusView.setVisibility(show ? View.VISIBLE
+									: View.INVISIBLE);
+						}
+					});
+
+			footview.setVisibility(View.VISIBLE);
+			footview.animate().setDuration(shortAnimTime).alpha(show ? 0 : 1)
+					.setListener(new AnimatorListenerAdapter()
+					{
+						@Override
+						public void onAnimationEnd(Animator animation)
+						{
+							footview.setVisibility(show ? View.INVISIBLE
+									: View.VISIBLE);
+						}
+					});
+			// mSearchFormView.setVisibility(View.VISIBLE);
+			// mSearchFormView.animate().setDuration(shortAnimTime)
+			// .alpha(show ? 0 : 1)
+			// .setListener(new AnimatorListenerAdapter()
+			// {
+			// @Override
+			// public void onAnimationEnd(Animator animation)
+			// {
+			// mSearchFormView.setVisibility(show ? View.INVISIBLE
+			// : View.VISIBLE);
+			// }
+			// });
+		}
+		else
+		{
+			// The ViewPropertyAnimator APIs are not available, so simply show
+			// and hide the relevant UI components.
+			mStatusView.setVisibility(show ? View.VISIBLE : View.INVISIBLE);
+			footview.setVisibility(show ? View.INVISIBLE : View.VISIBLE);
+			// mSearchFormView.setVisibility(show ? View.INVISIBLE :
+			// View.VISIBLE);
+		}
+	}
+
+	public class SearchTask extends AsyncTask<Boolean, Void, Boolean>
+	{
+		// int err_code = ERR_CODE_NONE;
+		int	errorcode;
+
+		@Override
+		protected Boolean doInBackground(Boolean... params)
+		{
+
+			if (!Network.NetworkIsAvailable())
+
+			{
+				errorcode = Network.RESULT_NET_NOTAVAILABLE;
+				return false;
+			}
+
+			if (params[0])
+			{
+				int ret = Network.get_recordcount(searchParms);
+				if (ret >= 0)
+				{
+					searchresult.put_totalcount(ret);
+					if (ret == 0)
+						return true;
+				}
+				else
+				{
+					errorcode = ret;
+					return false;
+				}
+			}
+
+			// if (searchresult.get_direction() == -1)
+			// searchresult.set_offset(searchresult.get_offset() - 20);
+			searchParms.putString("offset", searchresult.get_offset() + "");
+
+			String jstr = Network.get_records(user, password, searchParms);
+			if (jstr == null || jstr.length() <= 0)
+			{
+				// Log.d(TAG, "json is wrong");
+				errorcode = Network.RESULT_NET_ERROR;
+				return false;
+			}
+
+			JSONObject jsobj;
+			//
+			// array = new JSONArray(json);
+			try
+			{
+				jsobj = new JSONObject(jstr);
+				// if (searchresult.get_fieldscount() == 0)
+				// {
+				// JSONObject objfields = jsobj.getJSONObject("fields");
+				// if (objfields != null)
+				// searchresult.init_fields(objfields.toString());
+				// }
+				JSONObject objrecords = jsobj.getJSONObject("records");
+				if (objrecords != null)
+					searchresult.add_records(objrecords.toString());
+				errorcode = Network.RESULT_TRUE;
+
+				return true;
+
+			}
+			catch (JSONException e)
+			{
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+			errorcode = Network.RESULT_NET_ERROR;
+			return false;
+
+		}
+
+		@Override
+		protected void onPostExecute(final Boolean success)
+		{
+			Log.d("onPostExecute", "entry");
+			m_task = null;
+			showProgress(false);
+			if (ApexTrackingApplication.get_authorization() == false)
+			{
+				LinearLayout ll = (LinearLayout) findViewById(R.id.ll_refresh);
+				ll.setVisibility(View.VISIBLE);
+				Toast toast = Toast.makeText(
+						ApexTrackingApplication.get_instance(),
+						getText(R.string.msg_net_passwordchangedremote),
+						Toast.LENGTH_LONG);
+				toast.setGravity(Gravity.CENTER, 0, 0);
+				toast.show();
+				Intent i = new Intent();
+				i.setClass(ResultActivity.this, ApexActivity.class);
+				startActivityForResult(i, REQUEST_LOGINACTIVITY);
+				return;
+			}
+			switch (errorcode)
+			{
+				case Network.RESULT_NET_NOTAVAILABLE:
+				{
+					Toast toast = Toast.makeText(getApplicationContext(),
+							getText(R.string.msg_connection_none),
+							Toast.LENGTH_LONG);
+					toast.setGravity(Gravity.CENTER, 0, 0);
+					toast.show();
+					break;
+				}
+				case Network.RESULT_NET_ERROR:
+				{
+
+					Toast toast = Toast.makeText(
+							ApexTrackingApplication.get_instance(),
+							getText(R.string.msg_net_resulterror) + ":"
+									+ errorcode, Toast.LENGTH_LONG);
+					toast.setGravity(Gravity.CENTER, 0, 0);
+					toast.show();
+
+					break;
+				}
+				case Network.RESULT_ERROR:
+				// case Network.RESULT_RESPONSE_NULL:
+				{
+					Toast toast = Toast.makeText(getApplicationContext(),
+							getText(R.string.msg_net_resulterror),
+							Toast.LENGTH_LONG);
+					toast.setGravity(Gravity.CENTER, 0, 0);
+					toast.show();
+					break;
+				}
+
+				default:
+					break;
+			}
+
+			if (success)
+			{
+
+				initTable();
+
+			}
+			else
+			{
+				LinearLayout ll = (LinearLayout) findViewById(R.id.ll_refresh);
+				ll.setVisibility(View.VISIBLE);
+			}
+		}
+
+		@Override
+		protected void onCancelled()
+		{
+			m_task = null;
+			showProgress(false);
+		}
+	}
+
+	@Override
+	protected void onSaveInstanceState(Bundle outState)
+	{
+		outState.putSerializable("searchresult", searchresult);
+		super.onSaveInstanceState(outState);
+	}
+
+}

+ 424 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/RetrievePasswordActivity.java

@@ -0,0 +1,424 @@
+package com.usai.apex;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.annotation.TargetApi;
+import android.app.AlertDialog;
+import android.app.AlertDialog.Builder;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
+import android.content.Intent;
+import android.os.AsyncTask;
+import android.os.Build;
+import android.os.Bundle;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AppCompatActivity;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.EditText;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.usai.util.Network;
+
+/**
+ * Activity which displays a login screen to the user, offering registration as
+ * well.
+ */
+public class RetrievePasswordActivity extends AppCompatActivity
+{
+
+	/**
+	 * Keep track of the login task to ensure we can cancel it if requested.
+	 */
+	private UserLoginTask	mAuthTask	= null;
+
+	// Values for email and password at the time of the login attempt.
+	private String			m_sEmail;
+	private String			m_sUser;
+
+	// UI references.
+	private EditText		mEmailView;
+	private EditText		m_userView;
+	private View			mLoginFormView;
+	private View			mLoginStatusView;
+	private TextView		mLoginStatusMessageView;
+
+
+
+	@Override
+	public boolean onOptionsItemSelected(MenuItem item)
+	{
+		Intent intent = new Intent();
+		switch (item.getItemId())
+		{
+			case android.R.id.home:
+				finish();
+				break;
+
+			default:
+				break;
+		}
+		return super.onOptionsItemSelected(item);
+	}
+
+	private void setCustomActionBar() {
+		ActionBar.LayoutParams lp =new ActionBar.LayoutParams(ActionBar.LayoutParams.MATCH_PARENT, ActionBar.LayoutParams.MATCH_PARENT, Gravity.CENTER);
+		View mActionBarView = LayoutInflater.from(this).inflate(R.layout.actionbar_customtitle, null);
+
+		TextView titleview = mActionBarView.findViewById(R.id.title);
+		titleview.setText("Retrieve Password");
+		setTitle("Retrieve Password");
+
+		ActionBar actionBar = getSupportActionBar();
+		actionBar.setCustomView(mActionBarView, lp);
+//		actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
+//		actionBar.setDisplayShowCustomEnabled(true);
+		actionBar.setDisplayHomeAsUpEnabled(true);
+
+
+		actionBar.setDisplayShowTitleEnabled(true);
+	}
+	@Override
+	protected void onCreate(Bundle savedInstanceState)
+	{
+		super.onCreate(savedInstanceState);
+
+		setContentView(R.layout.activity_retrieve_password);
+
+		setCustomActionBar();
+		// Set up the login form.
+		m_userView = (EditText) findViewById(R.id.user);
+		// m_sEmail = getIntent().getStringExtra(EXTRA_EMAIL);
+		mEmailView = (EditText) findViewById(R.id.email);
+		// mEmailView.setText(m_sEmail);
+
+		mEmailView
+				.setOnEditorActionListener(new TextView.OnEditorActionListener()
+				{
+					@Override
+					public boolean onEditorAction(TextView textView, int id,
+							KeyEvent keyEvent)
+					{
+						if (id == R.id.btn_ok
+								|| id == EditorInfo.IME_ACTION_DONE)
+						{
+
+							InputMethodManager inputMethodManager = (InputMethodManager) getApplicationContext()
+									.getSystemService(
+											Context.INPUT_METHOD_SERVICE);
+
+							// EditText editText =
+							// (EditText)findViewById(R.id.xxxx);
+							inputMethodManager.hideSoftInputFromWindow(
+									mEmailView.getWindowToken(), 0); // ����
+							retrivev();
+							return true;
+						}
+						return false;
+					}
+				});
+
+		mLoginFormView = findViewById(R.id.login_form);
+		mLoginStatusView = findViewById(R.id.login_status);
+		mLoginStatusMessageView = (TextView) findViewById(R.id.login_status_message);
+
+		findViewById(R.id.btn_ok).setOnClickListener(new View.OnClickListener()
+		{
+			@Override
+			public void onClick(View view)
+			{
+				InputMethodManager inputMethodManager = (InputMethodManager) getApplicationContext()
+						.getSystemService(Context.INPUT_METHOD_SERVICE);
+
+				// EditText editText =
+				// (EditText)findViewById(R.id.xxxx);
+				inputMethodManager.hideSoftInputFromWindow(
+						mEmailView.getWindowToken(), 0); // ����
+				retrivev();
+			}
+		});
+		findViewById(R.id.btn_close).setOnClickListener(
+				new View.OnClickListener()
+				{
+					@Override
+					public void onClick(View view)
+					{
+						finish();
+					}
+				});
+	}
+
+	//
+	// @Override
+	// public boolean onCreateOptionsMenu(Menu menu) {
+	// super.onCreateOptionsMenu(menu);
+	// getMenuInflater().inflate(R.menu.retrieve_password, menu);
+	// return true;
+	// }
+
+	/**
+	 * Attempts to sign in or register the account specified by the login form.
+	 * If there are form errors (invalid email, missing fields, etc.), the
+	 * errors are presented and no actual login attempt is made.
+	 */
+	public void retrivev()
+	{
+		if (mAuthTask != null)
+		{
+			return;
+		}
+
+		// Reset errors.
+		mEmailView.setError(null);
+		m_userView.setError(null);
+
+		// Store values at the time of the login attempt.
+		m_sEmail = mEmailView.getText().toString();
+		m_sUser = m_userView.getText().toString();
+
+		boolean cancel = false;
+		View focusView = null;
+
+		// Check for a valid password.
+		if (TextUtils.isEmpty(m_sUser))
+		{
+			m_userView.setError(getString(R.string.error_field_required));
+			focusView = m_userView;
+			cancel = true;
+		}
+		// else if (m_sUser.length() < 4) {
+		// m_userView.setError(getString(R.string.error_invalid_password));
+		// focusView = m_userView;
+		// cancel = true;
+		// }
+
+		// Check for a valid email address.
+		if (TextUtils.isEmpty(m_sEmail))
+		{
+			mEmailView.setError(getString(R.string.error_field_required));
+			focusView = mEmailView;
+			cancel = true;
+		}
+		else if (!m_sEmail.contains("@"))
+		{
+			mEmailView.setError(getString(R.string.error_invalid_email));
+			focusView = mEmailView;
+			cancel = true;
+		}
+
+		if (cancel)
+		{
+			// There was an error; don't attempt login and focus the first
+			// form field with an error.
+			focusView.requestFocus();
+		}
+		else
+		{
+			// Show a progress spinner, and kick off a background task to
+			// perform the user login attempt.
+			mLoginStatusMessageView.setText(R.string.login_progress_signing_in);
+			showProgress(true);
+			mAuthTask = new UserLoginTask();
+			mAuthTask.execute((Void) null);
+		}
+	}
+
+	/**
+	 * Shows the progress UI and hides the login form.
+	 */
+	@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
+	private void showProgress(final boolean show)
+	{
+		// On Honeycomb MR2 we have the ViewPropertyAnimator APIs, which allow
+		// for very easy animations. If available, use these APIs to fade-in
+		// the progress spinner.
+		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2)
+		{
+			int shortAnimTime = getResources().getInteger(
+					android.R.integer.config_shortAnimTime);
+
+			mLoginStatusView.setVisibility(View.VISIBLE);
+			mLoginStatusView.animate().setDuration(shortAnimTime)
+					.alpha(show ? 1 : 0)
+					.setListener(new AnimatorListenerAdapter()
+					{
+						@Override
+						public void onAnimationEnd(Animator animation)
+						{
+							mLoginStatusView.setVisibility(show ? View.VISIBLE
+									: View.GONE);
+						}
+					});
+
+			mLoginFormView.setVisibility(View.VISIBLE);
+			mLoginFormView.animate().setDuration(shortAnimTime)
+					.alpha(show ? 0 : 1)
+					.setListener(new AnimatorListenerAdapter()
+					{
+						@Override
+						public void onAnimationEnd(Animator animation)
+						{
+							mLoginFormView.setVisibility(show ? View.GONE
+									: View.VISIBLE);
+						}
+					});
+		}
+		else
+		{
+			// The ViewPropertyAnimator APIs are not available, so simply show
+			// and hide the relevant UI components.
+			mLoginStatusView.setVisibility(show ? View.VISIBLE : View.GONE);
+			mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
+		}
+	}
+
+	/**
+	 * Represents an asynchronous login/registration task used to authenticate
+	 * the user.
+	 */
+	public class UserLoginTask extends AsyncTask<Void, Void, Boolean>
+	{
+		int	errorcode;
+
+		@Override
+		protected Boolean doInBackground(Void... params)
+		{
+			errorcode = Network.retrieve_pass(m_sUser, m_sEmail);
+			if (errorcode == Network.RESULT_TRUE)
+				return true;
+			else
+			{
+				return false;
+			}
+
+		}
+
+		@Override
+		protected void onPostExecute(final Boolean success)
+		{
+			Log.d("onPostExecute", "entry");
+			mAuthTask = null;
+			showProgress(false);
+			// if (netconnect == )
+			// {
+			//
+			// }
+
+			if (success)
+			{
+				AlertDialog.Builder builder = new Builder(
+						RetrievePasswordActivity.this);
+				builder.setMessage(getString(R.string.str_email_sent));
+
+				builder.setTitle(getString(R.string.str_retrieve_success));
+
+				builder.setPositiveButton(getString(android.R.string.ok), new OnClickListener()
+				{
+
+					@Override
+					public void onClick(DialogInterface dialog, int which)
+					{
+						dialog.dismiss();
+
+						RetrievePasswordActivity.this.finish();
+					}
+				});
+
+				// builder.setNegativeButton("取消", new OnClickListener() {
+				//
+				// @Override
+				// public void onClick(DialogInterface dialog, int which) {
+				// dialog.dismiss();
+				// }
+				// });
+
+				builder.create().show();
+
+			}
+			else
+			{
+				switch (errorcode)
+				{
+					case Network.RESULT_NET_NOTAVAILABLE:
+					{
+						Toast toast = Toast.makeText(getApplicationContext(),
+								getText(R.string.msg_connection_none),
+								Toast.LENGTH_LONG);
+						toast.setGravity(Gravity.CENTER, 0, 0);
+						toast.show();
+						return;
+					}
+					case Network.RESULT_NET_ERROR:
+					{
+						Toast toast = Toast.makeText(getApplicationContext(),
+								getText(R.string.msg_net_error),
+								Toast.LENGTH_LONG);
+						toast.setGravity(Gravity.CENTER, 0, 0);
+						toast.show();
+						return;
+					}
+					case Network.RESULT_ERROR:
+					// case Network.RESULT_RESPONSE_NULL:
+					{
+						Toast toast = Toast.makeText(getApplicationContext(),
+								getText(R.string.msg_net_resulterror),
+								Toast.LENGTH_LONG);
+						toast.setGravity(Gravity.CENTER, 0, 0);
+						toast.show();
+						return;
+					}
+
+					case Network.RESULT_FALSE:
+					{
+						AlertDialog.Builder builder = new Builder(
+								RetrievePasswordActivity.this);
+						builder.setMessage(getString(R.string.str_invalid_pore));
+
+						builder.setTitle(getString(R.string.str_retrieve_failed));
+
+						builder.setPositiveButton(getString(android.R.string.ok), new OnClickListener()
+						{
+
+							@Override
+							public void onClick(DialogInterface dialog,
+									int which)
+							{
+								dialog.dismiss();
+
+								// RetrievePasswordActivity.this.finish();
+							}
+						});
+						builder.create().show();
+						return;
+
+					}
+					default:
+					{
+						Toast toast = Toast.makeText(getApplicationContext(),
+								getText(R.string.msg_net_resulterror) + ":"
+										+ errorcode, Toast.LENGTH_LONG);
+						toast.setGravity(Gravity.CENTER, 0, 0);
+						toast.show();
+						break;
+					}
+				}
+			}
+		}
+
+		@Override
+		protected void onCancelled()
+		{
+			mAuthTask = null;
+			showProgress(false);
+		}
+	}
+}

+ 412 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/SearchActivity.java

@@ -0,0 +1,412 @@
+package com.usai.apex;
+
+import android.app.ListActivity;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.os.Bundle;
+import android.text.InputType;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.SimpleCursorAdapter;
+import android.widget.Switch;
+
+import com.usai.util.Network;
+import com.usai.util.dbUtil;
+
+import java.util.HashMap;
+import java.util.Iterator;
+
+public class SearchActivity extends ListActivity implements OnClickListener
+{
+	private SQLiteDatabase m_db = null;
+	private Cursor m_cursor = null;
+	String user = null;
+	String password = null;
+	String function_name = null;
+	RecordsAdapter m_listadapter;
+	// private ListView m_ListView = null;
+	HashMap<String, String> hashMap = new HashMap<String, String>();
+
+	public class RecordsAdapter extends SimpleCursorAdapter
+	{
+
+		public RecordsAdapter(Context context, int layout, Cursor c,
+				String[] from, int[] to)
+		{
+			super(context, layout, c, from, to);
+			// TODO Auto-generated constructor stub
+		}
+
+		// @Override
+		// public View getView(int position, View convertView, ViewGroup parent)
+		// {
+		// // if(true)
+		// // return super.getView(position, convertView, parent);
+		// if(convertView==null)
+		// convertView = LayoutInflater.from(getApplication()).inflate(
+		// R.layout.search_lvitem_edit, null);
+		// // holder = new ViewHolder();
+		// // holder.textView = (TextView)convertView.findViewById(R.id.text);
+		// // convertView.setTag(holder);
+		// final int pos=position;
+		// // convertView = LayoutInflater.from(getApplication()).inflate(
+		// // R.layout.search_lvitem_edit, null);
+		//
+		// EditText editText = (EditText) convertView
+		// .findViewById(R.id.edit_val);
+		// // editText.setText(str);
+		//
+		// // 为editText设置TextChangedListener,每次改变的值设置到hashMap
+		// // 我们要拿到里面的值根据position拿值
+		// editText.addTextChangedListener(new TextWatcher()
+		// {
+		// @Override
+		// public void onTextChanged(CharSequence s, int start,
+		// int before, int count)
+		// {
+		//
+		// }
+		//
+		// @Override
+		// public void beforeTextChanged(CharSequence s, int start,
+		// int count, int after)
+		// {
+		//
+		// }
+		//
+		// @Override
+		// public void afterTextChanged(Editable s)
+		// {
+		// // int a = position;
+		// // 将editText中改变的值设置的HashMap中
+		// hashMap.put(pos, s.toString());
+		// }
+		// });
+		//
+		// // // 如果hashMap不为空,就设置的editText
+		// // if (hashMap.get(position) != null)
+		// // {
+		// // editText.setText(hashMap.get(position));
+		// // }
+		// return convertView;
+		// }
+
+		@Override
+		public void bindView(View view, Context context, Cursor cursor)
+		{
+			final String f0 = cursor.getString(0);
+			final String field_type = cursor.getString(1);
+			final String name = cursor.getString(2);
+
+			Log.d("cursor val", "name=" + f0 + " , type=" + field_type);
+			final EditText edit = (EditText) view.findViewById(R.id.edit_val);
+			edit.setText(hashMap.get(name));
+			Log.v("from hashmap",
+					"name=" + name + " , val=" + hashMap.get(name));
+
+//			edit.seton
+//			edit.addTextChangedListener(new TextWatcher()
+//			{
+//				@Override
+//				public void onTextChanged(CharSequence s, int start,
+//						int before, int count)
+//				{
+//
+//				}
+//
+//				@Override
+//				public void beforeTextChanged(CharSequence s, int start,
+//						int count, int after)
+//				{
+//
+//				}
+//
+//				@Override
+//				public void afterTextChanged(Editable s)
+//				{
+//					// 将editText中改变的值设置的HashMap中
+//					String val = s.toString();
+//					val.trim();
+//					if (val.length() > 0)
+//					{
+//						hashMap.put(name, val);
+//
+//						Log.i("to hashmap", "name=" + name + " , val=" + val);
+//					}
+//				}
+//			});
+			Switch switch_bool = (Switch) view.findViewById(R.id.switch_bool);
+			if (field_type.equals("boolean"))
+			{
+				edit.setVisibility(View.GONE);
+				switch_bool.setVisibility(View.VISIBLE);
+			}
+			else
+			{
+				edit.setVisibility(View.VISIBLE);
+				switch_bool.setVisibility(View.GONE);
+				if (field_type.equals("time"))
+				{
+					edit.setInputType(InputType.TYPE_DATETIME_VARIATION_DATE
+							| InputType.TYPE_CLASS_DATETIME);
+
+				}
+				else
+					if (field_type.equals("int"))
+					{
+
+						edit.setInputType(InputType.TYPE_CLASS_NUMBER);
+					}
+					else
+					{
+						edit.setInputType(InputType.TYPE_CLASS_TEXT);
+					}
+				Log.d("ime debug", "name=" + f0 + " , type=" + field_type
+						+ ", ime=" + edit.getInputType());
+			}
+			super.bindView(view, context, cursor);
+
+			// TextView tvname = (TextView) view.findViewById(R.id.name);
+			// TextView tvinfo = (TextView) view.findViewById(R.id.info);
+			// String sname = cursor.getString(1);
+			// int iburntype = cursor.getInt(2);
+			// dbgUtil.Log(Log.INFO, "============>", "BURN TYPE =" +
+			// iburntype);
+			// if (sname == null || sname.equals(""))
+			// tvname.setVisibility(TextView.GONE);
+			// else
+			// tvname.setVisibility(View.VISIBLE);
+			// if (m_Activityinfo.NumberType != dbUtil.NUMBER_TYPE_WHITE
+			// && iburntype >= 0)
+			// {
+			//
+			// tvinfo.setText(m_arrBurntype[iburntype]);
+			// tvinfo.setVisibility(View.VISIBLE);
+			// }
+			// else
+			// {
+			// tvinfo.setVisibility(View.GONE);
+			// }
+
+		}
+
+	}
+
+	@Override
+	protected void onDestroy()
+	{
+		dbUtil.CloseDB(m_db);
+		super.onDestroy();
+	}
+
+	@Override
+	protected void onCreate(Bundle savedInstanceState)
+	{
+		super.onCreate(savedInstanceState);
+		user = ApexTrackingApplication.get_user();
+		
+		password = ApexTrackingApplication.get_pass();
+		function_name = getIntent().getStringExtra("function_name");
+		setContentView(R.layout.activity_search);
+		m_db = dbUtil.OpenDB(this, null, true);
+		// m_TextView = (TextView) findViewById(R.id.summarytext);
+		// m_TextView.setText(getString(m_Activityinfo.TextViewValue));
+		// m_ListView = (ListView) findViewById(android.R.id.list);
+		m_cursor = m_db.query("fields_info", new String[] { "aname",
+				"field_type", "name", "_id" }, "function_name='"
+				+ function_name + "' and user='" + user + "' and behavior="
+				+ Network.BEHAVIOR_SEARCH + " and show = 1", null, null, null,
+				"priority , aname", null);
+		startManagingCursor(m_cursor);
+		m_listadapter = new RecordsAdapter(this,
+		// Use a template that displays a text view
+				R.layout.search_lvitem_edit,
+				// Give the cursor to the list adatper
+				m_cursor,
+				// Map the NAME column in the people database to...
+				new String[] { "aname", "field_type", "name" },
+				// The "text1" view defined in the XML template
+				new int[] { R.id.aname, R.id.tv_type });
+		setListAdapter(m_listadapter);
+		Button btnok = (Button) findViewById(R.id.btnok);
+		btnok.setOnClickListener(this);
+		Button btncancel = (Button) findViewById(R.id.btncancel);
+		btncancel.setOnClickListener(this);
+
+		SharedPreferences RunOnce = getSharedPreferences("Apex", 0);
+
+		String vername;
+		try
+		{
+			vername = getPackageManager().getPackageInfo("com.usai.apex", 0).versionName;
+			boolean bFirstRun = RunOnce.getBoolean("FirstRun" + vername
+					+ "_search", true);
+			if (bFirstRun&&false)
+			{
+				SharedPreferences.Editor editor = RunOnce.edit();
+				editor.putBoolean("FirstRun" + vername + "_search", false);
+				// Don't forget to commit your edits!!!
+				editor.commit();
+				Intent intent = new Intent();
+				intent.setClass(this, HelpActivity.class);
+				intent.putExtra("caller", "search");
+				startActivity(intent);
+
+			}
+		}
+		catch (NameNotFoundException e)
+		{
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		// initlist();
+
+		// m_ListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
+
+		// m_listadapter = new FieldsAdapter(this, data, resource, from, to);
+
+		// m_listadapter = new RecordsAdapter(this,
+		// // Use a template that displays a text view
+		// m_iListItemID,
+		// // Give the cursor to the list adatper
+		// m_cursor,
+		// // Map the NAME column in the people database to...
+		// m_sDispFields,
+		// // The "text1" view defined in the XML template
+		// m_iViewIDs);
+
+	}
+
+//	private void RefreshList()
+//	{
+//		// if (dbUtil.isRecordExist(m_db,
+//		// "user_numberlist","type = "+m_Activityinfo.NumberType))
+//		// {
+//		// m_TextView.setVisibility(ListView.INVISIBLE);
+//		// m_ListView.setVisibility(ListView.VISIBLE);
+//		//
+//		// }
+//		// else
+//		// {
+//		// m_TextView.setVisibility(ListView.VISIBLE);
+//		// m_ListView.setVisibility(ListView.INVISIBLE);
+//		// }
+//		hashMap.clear();
+//		m_cursor.requery();
+//	}
+
+	// private void initlist()
+	// {
+	// m_ListView = (ListView) findViewById(android.R.id.list);
+	// ArrayList<HashMap<String, Object>> list = new ArrayList<HashMap<String,
+	// Object>>();
+	// HashMap<String, Object> map = null;
+	//
+	// String[] strings = { "alias", "type", "name" };// Map的key集合数组
+	// int[] ids = { R.id.aliasName, R.id.tv_type };// 对应布局文件的id
+	// SimpleAdapter simpleAdapter = new SimpleAdapter(this, list,
+	// R.layout.search_lvitem_edit, strings, ids);
+	//
+	// // listView1.setAdapter(simpleAdapter);//绑定适配器
+	// setListAdapter(simpleAdapter);
+	// }
+
+	@Override
+	public boolean onCreateOptionsMenu(Menu menu)
+	{
+		// Inflate the menu; this adds items to the action bar if it is present.
+		getMenuInflater().inflate(R.menu.search, menu);
+		return true;
+	}
+
+	@Override
+	public boolean onOptionsItemSelected(MenuItem item)
+	{
+		Intent intent = new Intent();
+		switch (item.getItemId())
+		{
+		case R.id.action_custom_fields:
+			intent.setClass(this, CustomizeFieldsActivity.class);
+			intent.putExtra("user", user);
+			// intent.putExtra("password", password);
+			intent.putExtra("function_name", function_name);
+			intent.putExtra("behavior", Network.BEHAVIOR_SEARCH);
+			startActivity(intent);
+			break;
+		case R.id.action_help:
+			// Intent intent = new Intent();
+			intent.setClass(this, HelpActivity.class);
+			intent.putExtra("caller", "search");
+			// // intent.putExtra("password", password);
+			// intent.putExtra("function_name", function_name);
+			// intent.putExtra("behavior", Network.BEHAVIOR_SEARCH);
+			startActivity(intent);
+			break;
+		default:
+			break;
+		}
+		return super.onOptionsItemSelected(item);
+	}
+
+	@Override
+	public void onClick(View v)
+	{
+		switch (v.getId())
+		{
+		case R.id.btnok:
+		{
+			Intent intent = new Intent();
+			intent.setClass(this, ResultActivity.class);
+			intent.putExtra("user", user);
+			intent.putExtra("password", password);
+			intent.putExtra("function_name", function_name);
+			Bundle parms = new Bundle();
+			parms.putString("module_name", function_name);
+			parms.putString("columns", dbUtil.get_fields(user, function_name));
+			Iterator<String> iter = hashMap.keySet().iterator();
+			while (iter.hasNext())
+			{
+				String field = (String) iter.next();
+				String val = (String) hashMap.get(field);
+				parms.putString(field, val);
+				// Cursor c = (Cursor) m_listadapter.getItem(key);
+				Log.d("@@@@@@@@@", field + " : " + val);
+			}
+			intent.putExtra("searchParms", parms);
+
+			startActivity(intent);
+
+			break;
+		}
+		case R.id.btncancel:
+			finish();
+			break;
+		default:
+			break;
+		}
+
+	}
+
+	// class FieldsAdapter extends SimpleAdapter
+	// {
+	//
+	// public FieldsAdapter(Context context,
+	// List<? extends Map<String, ?>> data, int resource,
+	// String[] from, int[] to)
+	// {
+	// super(context, data, resource, from, to);
+	// // TODO Auto-generated constructor stub
+	// }
+	//
+	// }
+
+}

+ 161 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/SearchHistoryActivity.java

@@ -0,0 +1,161 @@
+package com.usai.apex;
+
+import android.app.AlertDialog;
+import android.app.AlertDialog.Builder;
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.database.sqlite.SQLiteDatabase;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentActivity;
+import android.support.v4.app.FragmentTransaction;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.widget.TabHost;
+
+import com.usai.apex.saved.SavedDetailFragment;
+import com.usai.apex.saved.SavedSearchFragment;
+import com.usai.util.dbUtil;
+
+public class SearchHistoryActivity extends FragmentActivity
+{
+	TabHost	mTabHost;
+	@Override
+	public boolean onCreateOptionsMenu(Menu menu)
+	{
+		// Inflate the menu; this adds items to the action bar if it is present.
+		getMenuInflater().inflate(R.menu.checksaved, menu);
+		return true;
+	}
+
+	@Override
+	public boolean onOptionsItemSelected(MenuItem item)
+	{
+		// Intent intent = new Intent();
+		switch (item.getItemId())
+		{
+			case R.id.action_deleteall:
+			{
+				AlertDialog.Builder builder = new Builder(this);
+				builder.setMessage(getString(R.string.str_deletemessage));
+
+				builder.setTitle(getString(R.string.str_confirmdelete));
+
+				builder.setPositiveButton(getString(R.string.str_del),
+						new Dialog.OnClickListener()
+						{
+
+							@Override
+							public void onClick(DialogInterface dialog,
+									int which)
+							{
+								SQLiteDatabase db = dbUtil.OpenDB(
+										SearchHistoryActivity.this, null, false);
+								int a=mTabHost.getCurrentTab();
+								if(mTabHost.getCurrentTab()==0)
+								{
+									
+									db.execSQL("delete from history");
+									SavedSearchFragment f = (SavedSearchFragment)getSupportFragmentManager().findFragmentById(R.id.tab1);
+//									f.searchresult.getData().clear();
+//									f.adapter.notifyDataSetChanged();
+								}
+								else
+								{
+									db.execSQL("delete from favorites");
+									SavedDetailFragment f = (SavedDetailFragment)getSupportFragmentManager().findFragmentById(R.id.tab2);
+//									f.searchresult.getData().clear();
+//									f.adapter.notifyDataSetChanged();
+								}	
+
+
+								dbUtil.CloseDB(db);
+								dialog.dismiss();
+
+							}
+						});
+
+				builder.setNegativeButton(getString(R.string.str_cancel),
+						new Dialog.OnClickListener()
+						{
+
+							@Override
+							public void onClick(DialogInterface dialog,
+									int which)
+							{
+								dialog.dismiss();
+							}
+						});
+
+				builder.create().show();
+
+				break;
+			}
+			default:
+				break;
+		}
+		return super.onOptionsItemSelected(item);
+	}
+	@Override
+	protected void onCreate(Bundle savedInstanceState)
+	{
+		Log.d("SearchHistoryActivity", "onCreate");
+
+		super.onCreate(savedInstanceState);
+		setContentView(R.layout.activity_search_history);
+		// ActionBar bar = getActionBar();
+		// bar.setTitle("");
+		setupTabs();
+
+	}
+	@Override
+	public boolean onKeyDown(int keyCode, KeyEvent event)
+	{
+		if (keyCode == KeyEvent.KEYCODE_BACK)
+		{
+			// Intent myIntent = new Intent();
+			// myIntent = new Intent(EditActivity.this, tabActivity.class);
+			// startActivity(myIntent);
+			finish();
+			
+			return false;
+		}
+		return super.onKeyDown(keyCode, event);
+	}
+	private void setupTabs()
+	{
+		mTabHost = (TabHost) this.findViewById(R.id.tabhost);
+
+		mTabHost.setup();
+
+		mTabHost.addTab(mTabHost
+				.newTabSpec(getString(R.string.action_saved_search))
+				.setIndicator(getString(R.string.action_saved_search))
+				.setContent(R.id.tab1));
+
+		mTabHost.addTab(mTabHost.newTabSpec(getString(R.string.action_saved_detail))
+				.setIndicator(getString(R.string.action_saved_detail))
+				.setContent(R.id.tab2));
+
+
+		Fragment favorites = new SavedDetailFragment();
+		Fragment history = new SavedSearchFragment();
+
+		// Add the fragment to the activity, pushing this transaction
+		// on to the back stack.
+
+		FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
+		ft.replace(R.id.tab1, history);
+		ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
+		ft.addToBackStack("search");
+
+		ft.replace(R.id.tab2, favorites);
+		ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
+		ft.addToBackStack("detail");
+
+		ft.commit();
+
+	}
+}

+ 695 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/SearchListActivity.java

@@ -0,0 +1,695 @@
+package com.usai.apex;
+
+import android.app.AlertDialog;
+import android.app.AlertDialog.Builder;
+import android.app.DatePickerDialog;
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.os.Bundle;
+import android.support.constraint.ConstraintLayout;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AppCompatActivity;
+import android.support.v7.widget.SearchView;
+import android.text.Editable;
+import android.text.InputType;
+import android.text.TextUtils;
+import android.text.TextWatcher;
+import android.view.Gravity;
+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.view.inputmethod.EditorInfo;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemSelectedListener;
+import android.widget.ArrayAdapter;
+import android.widget.AutoCompleteTextView;
+import android.widget.Button;
+import android.widget.DatePicker;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+import android.widget.Spinner;
+import android.widget.TextView;
+
+import com.usai.apex.Result.AMResultActivity;
+import com.usai.util.Network;
+import com.usai.util.dbUtil;
+
+import java.util.Calendar;
+import java.util.HashMap;
+
+public class SearchListActivity extends AppCompatActivity implements OnClickListener
+{
+
+
+	public static SearchListActivity instance = null;
+
+	// String[] spin_valbool = { "True", "False" };
+	LinearLayout			ll_list;
+	String					user			= null;
+	// String password = null;
+	String					function_name	= null;
+	HashMap<String, String>	hashMap			= new HashMap<String, String>();
+
+	// private class Field
+	// {
+	// String name;
+	// String value;
+	// public Field(String n,String v)
+	// {
+	// name=n;
+	// value=v;
+	// }
+	// }
+//    private Drawable getNumberDrawable() {
+//        int width = commonUtil.dp2px(getBaseContext(), 58);
+//        int height = commonUtil.dp2px(getBaseContext(), 48);
+//        Bitmap bmp = Bitmap
+//                .createBitmap(width, height, Bitmap.Config.ARGB_8888);// 这个返回的bitmap
+//        // 就是透明的
+//        Canvas canvas = new Canvas(bmp);
+//        Paint paint = new Paint();
+//
+//        RectF oval = new RectF(0, 0, width, height);
+//
+//        // canvas.drawRect(oval, paint);//画上这个就会有黑底
+//        paint.setTextSize(commonUtil.sp2px(getBaseContext(), 28));
+//        Paint.FontMetricsInt fontMetrics = paint.getFontMetricsInt();// 文字大小的设置,要在这个前面,否则文字计算不居中
+//
+//        float baseline = oval.top
+//                + (oval.bottom - oval.top - fontMetrics.bottom + fontMetrics.top)
+//                / 2 - fontMetrics.top;
+//
+//        paint.setTextAlign(Paint.Align.CENTER);
+//        paint.setFlags(Paint.ANTI_ALIAS_FLAG);
+//        paint.setColor(Color.BLACK);
+//        canvas.drawText("Return", oval.centerX(), baseline, paint);
+//
+//        return new BitmapDrawable(getResources(), bmp);
+//    }
+
+    private void setCustomActionBar() {
+        ActionBar.LayoutParams lp =new ActionBar.LayoutParams(ActionBar.LayoutParams.MATCH_PARENT, ActionBar.LayoutParams.MATCH_PARENT, Gravity.CENTER);
+        View mActionBarView = LayoutInflater.from(this).inflate(R.layout.actionbar_customtitle, null);
+
+        TextView titleview = mActionBarView.findViewById(R.id.title);
+        titleview.setText(getIntent().getStringExtra("title"));
+
+        setTitle(getIntent().getStringExtra("title"));
+//
+//        mActionBarView.setBackgroundColor(Color.YELLOW);
+//        titleview.setBackgroundColor(Color.BLUE);
+        ActionBar actionBar = getSupportActionBar();
+        actionBar.setCustomView(mActionBarView, lp);
+//        actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
+//        actionBar.setDisplayShowCustomEnabled(true);
+        actionBar.setDisplayHomeAsUpEnabled(true);
+
+
+//        actionBar.setIcon(getNumberDrawable());
+//        actionBar.setDisplayShowHomeEnabled(true);
+        actionBar.setDisplayShowTitleEnabled(true);
+    }
+
+    private EditText mSearchView;
+    private Button mTableExpandBtn;
+    private boolean mShowTable;
+    private SearchListActivity self = this;
+    private LinearLayout mSearchToolbar;
+
+    @Override
+	protected void onCreate(Bundle savedInstanceState)
+	{
+		super.onCreate(savedInstanceState);
+		setContentView(R.layout.activity_search_list);
+		instance = this;
+        setCustomActionBar();
+//		ActionBar actionBar = getSupportActionBar();
+////		actionBar.setLogo(R.drawable.apexlogo);
+////        actionBar.setIcon(R.drawable.ic_launcher);
+//
+////		actionBar.setDisplayUseLogoEnabled(true);
+//		actionBar.setDisplayShowHomeEnabled(true);
+////        actionBar.setHomeAsUpIndicator(R.drawable.ic_launcher);
+//		actionBar.setHomeButtonEnabled(true);
+//		actionBar.setDisplayHomeAsUpEnabled(false);
+//		actionBar.setHomeActionContentDescription("Return");
+////		actionBar.setDisplayShowTitleEnabled(true);
+//
+		mShowTable = false;
+
+		user = ApexTrackingApplication.get_user();
+
+		// password = ApexTrackingApplication.get_pass();
+		function_name = getIntent().getStringExtra("function_name");
+
+		setTitle(getIntent().getStringExtra("title"));
+
+		ll_list = (LinearLayout) findViewById(R.id.ll_list);
+		final Button btnok = (Button) findViewById(R.id.btnok);
+		btnok.setOnClickListener(this);
+		Button btncancel = (Button) findViewById(R.id.btncancel);
+		btncancel.setOnClickListener(this);
+		Button btnclear = (Button) findViewById(R.id.btn_clear);
+		btnclear.setOnClickListener(this);
+		if (savedInstanceState != null)
+		{
+			hashMap = (HashMap<String, String>) savedInstanceState
+					.getSerializable("hashMap");
+			mShowTable = savedInstanceState.getBoolean("show_table");
+		}
+
+
+		mSearchView = findViewById(R.id.search_view);
+		mSearchView.setOnEditorActionListener(new TextView.OnEditorActionListener() {
+			@Override
+			public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
+				if (actionId == EditorInfo.IME_ACTION_SEARCH || actionId == EditorInfo.IME_ACTION_UNSPECIFIED) { {
+
+					self.onClick(btnok);
+
+					return true;
+				}}
+				return false;
+			}
+		});
+
+		mTableExpandBtn = findViewById(R.id.search_table_expand_btn);
+		mTableExpandBtn.setOnClickListener(new OnClickListener() {
+			@Override
+			public void onClick(View v) {
+				boolean show = (boolean) v.getTag();
+				mShowTable = !show;
+				v.setTag(mShowTable);
+				if (mShowTable) {
+					mTableExpandBtn.setText("Hide Fields");
+				} else {
+					mTableExpandBtn.setText("Show Fields");
+				}
+				init();
+
+			}
+		});
+
+		if (mShowTable) {
+			mTableExpandBtn.setText("Hide Fields");
+		} else {
+			mTableExpandBtn.setText("Show Fields");
+		}
+		mTableExpandBtn.setTag(mShowTable);
+
+		mSearchToolbar = findViewById(R.id.search_tool_bar);
+		if (function_name.equals("Download Document")) {
+			mSearchToolbar.setVisibility(View.GONE);
+			mShowTable = true;
+		}
+
+	}
+
+	@Override
+	protected void onResume()
+	{
+		init();
+		super.onResume();
+	}
+
+	void init()
+	{
+		// hashMap.clear();
+		ll_list.removeAllViews();
+
+		if (!mShowTable) {
+			hashMap.clear();
+			return;
+		}
+
+		SQLiteDatabase db = dbUtil.OpenDB(this, null, true);
+		Cursor cursor = db.query("fields_info", new String[] { "aname",
+				"field_type", "name", "_id" }, "function_name='"
+				+ function_name + "' and user='" + user + "' and behavior="
+				+ Network.BEHAVIOR_SEARCH + " and show = 1", null, null, null,
+				"priority , aname", null);
+		while (cursor.moveToNext())
+		{
+			final String aname = cursor.getString(0);
+			String field_type = cursor.getString(1);
+			final String name = cursor.getString(2);
+
+			// hashMap.put(aname, field);
+
+			if (field_type.equals("boolean"))
+			{
+				ConstraintLayout spinneritem = (ConstraintLayout) this
+						.getLayoutInflater().inflate(
+								R.layout.search_item_spinner, null);
+				spinneritem.setTag("search_item_spinner");
+				TextView tvname = (TextView) spinneritem
+						.findViewById(R.id.aname);
+				tvname.setText(aname);
+				tvname.setTag(name);
+				Spinner spinner_bool = (Spinner) spinneritem
+						.findViewById(R.id.sp_bool);
+				ArrayAdapter<CharSequence> adapter = ArrayAdapter
+						.createFromResource(this, R.array.spinner_bool_val,
+								android.R.layout.simple_spinner_item);
+				adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+				spinner_bool.setAdapter(adapter);
+				String val = hashMap.get(name);
+				if (val != null)
+				{
+					if (val.equals("true"))
+						spinner_bool.setSelection(1);
+					else if (val.equals("false"))
+						spinner_bool.setSelection(2);
+					else
+						spinner_bool.setSelection(0);
+				}
+
+				spinner_bool
+						.setOnItemSelectedListener(new OnItemSelectedListener()
+						{
+
+							@Override
+							public void onItemSelected(AdapterView<?> arg0,
+									View arg1, int arg2, long arg3)
+							{
+								if (arg2 == 1)
+									hashMap.put(name, "true");
+								else if (arg2 == 2)
+									hashMap.put(name, "false");
+
+							}
+
+							@Override
+							public void onNothingSelected(AdapterView<?> arg0)
+							{
+
+							}
+
+						});
+				// String val = hashMap.get(name);
+				// if(val!=null)
+
+				// switch_bool.setOnCheckedChangeListener(new
+				// CompoundButton.OnCheckedChangeListener(){
+				//
+				// @Override
+				// public void onCheckedChanged(CompoundButton buttonView,
+				// boolean isChecked)
+				// {
+				// String val;
+				// if(isChecked)
+				// val="true";
+				// else
+				// val="false";
+				// Field field = new Field(name,val);
+				// field.name = name;
+				// hashMap.put(aname,field);
+				//
+				// }
+				//
+				// });
+				ll_list.addView(spinneritem);
+			}
+			else if (field_type.equals("time"))
+			{
+
+				ConstraintLayout timeitem = (ConstraintLayout) this
+						.getLayoutInflater().inflate(
+								R.layout.search_item_datepicker, null);
+				timeitem.setTag("search_item_datepicker");
+				TextView tvname = (TextView) timeitem.findViewById(R.id.aname);
+				tvname.setText(aname);
+				tvname.setTag(name);
+				final EditText edit_from = (EditText) timeitem
+						.findViewById(R.id.et_from);
+				final EditText edit_to = (EditText) timeitem
+						.findViewById(R.id.et_to);
+
+				String val_from = hashMap.get(name + "_from");
+				String val_to = hashMap.get(name + "_to");
+				if (val_from != null)
+				{
+					edit_from.setText(val_from);
+				}
+				if (val_to != null)
+					edit_to.setText(val_to);
+				// edit_from.setInputType(InputType.TYPE_DATETIME_VARIATION_DATE
+				// | InputType.TYPE_CLASS_DATETIME);
+				final Calendar c = Calendar.getInstance();
+				// int mYear =
+				// int mMonth = c.get(Calendar.MONTH);
+				// int mDay = c.get(Calendar.DAY_OF_MONTH);
+				// final DatePickerDialog dialog =
+				Button btn_clear_from = (Button) timeitem
+						.findViewById(R.id.btn_clear_from);
+				btn_clear_from.setOnClickListener(new OnClickListener()
+				{
+
+					@Override
+					public void onClick(View v)
+					{
+						edit_from.setText("");
+						hashMap.remove(name + "_from");
+
+					}
+
+				});
+				Button btn_clear_to = (Button) timeitem
+						.findViewById(R.id.btn_clear_to);
+				btn_clear_to.setOnClickListener(new OnClickListener()
+				{
+
+					@Override
+					public void onClick(View v)
+					{
+						edit_to.setText("");
+						hashMap.remove(name + "_to");
+
+					}
+
+				});
+
+				edit_from.setOnClickListener(new OnClickListener()
+				{
+					public void onClick(View v)
+					{
+						new DatePickerDialog(SearchListActivity.this,
+								new DatePickerDialog.OnDateSetListener()
+								{
+
+									@Override
+									public void onDateSet(DatePicker view,
+											int year, int monthOfYear,
+											int dayOfMonth)
+									{
+										edit_from
+												.setText((monthOfYear + 1)
+														+ "/" + dayOfMonth
+														+ "/" + year);
+										hashMap.put(name + "_from",
+												(monthOfYear + 1) + "/"
+														+ dayOfMonth + "/"
+														+ year);
+
+									}
+
+								}, c.get(Calendar.YEAR), c.get(Calendar.MONTH),
+								c.get(Calendar.DAY_OF_MONTH)).show();
+
+					}
+				});
+
+				edit_to.setOnClickListener(new OnClickListener()
+				{
+					public void onClick(View v)
+					{
+						new DatePickerDialog(SearchListActivity.this,
+								new DatePickerDialog.OnDateSetListener()
+								{
+
+									@Override
+									public void onDateSet(DatePicker view,
+											int year, int monthOfYear,
+											int dayOfMonth)
+									{
+										edit_to.setText((monthOfYear + 1) + "/"
+												+ dayOfMonth + "/" + year);
+										hashMap.put(name + "_to",
+												(monthOfYear + 1) + "/"
+														+ dayOfMonth + "/"
+														+ year);
+
+									}
+
+								}, c.get(Calendar.YEAR), c.get(Calendar.MONTH),
+								c.get(Calendar.DAY_OF_MONTH)).show();
+
+					}
+				});
+
+				ll_list.addView(timeitem);
+			}
+			else
+			{
+				ConstraintLayout edititem = (ConstraintLayout) this
+						.getLayoutInflater().inflate(R.layout.search_item_edit,
+								null);
+				edititem.setTag("search_item_edit");
+				TextView tvname = (TextView) edititem.findViewById(R.id.aname);
+				tvname.setText(aname);
+				tvname.setTag(name);
+
+				AutoCompleteTextView edit = (AutoCompleteTextView) edititem
+						.findViewById(R.id.edit_val);
+				ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
+						android.R.layout.simple_dropdown_item_1line,
+						dbUtil.get_searchhistory(name));
+				edit.setAdapter(adapter);
+
+				String val = hashMap.get(name);
+				if (val != null)
+				{
+					edit.setText(val);
+				}
+				edit.addTextChangedListener(new TextWatcher()
+				{
+					@Override
+					public void onTextChanged(CharSequence s, int start,
+							int before, int count)
+					{
+
+					}
+
+					@Override
+					public void beforeTextChanged(CharSequence s, int start,
+							int count, int after)
+					{
+
+					}
+
+					@Override
+					public void afterTextChanged(Editable s)
+					{
+						String val = s.toString();
+						val.trim();
+						if (val.length() >= 0)
+						{
+
+							hashMap.put(name, val);
+						}
+					}
+
+				});
+				if (field_type.equals("int"))
+					edit.setInputType(InputType.TYPE_CLASS_NUMBER);
+
+				ll_list.addView(edititem);
+			}
+		}
+		dbUtil.CloseCursor(cursor);
+		dbUtil.CloseDB(db);
+	}
+
+	@Override
+	public boolean onCreateOptionsMenu(Menu menu)
+	{
+		// Inflate the menu; this adds items to the action bar if it is present.
+		getMenuInflater().inflate(R.menu.search_list, menu);
+		return true;
+	}
+
+	@Override
+	protected void onSaveInstanceState(Bundle outState)
+	{
+		outState.putBoolean("show_table",mShowTable);
+		outState.putSerializable("hashmap", hashMap);
+		super.onSaveInstanceState(outState);
+	}
+
+	@Override
+	public void onClick(View v)
+	{
+		switch (v.getId())
+		{
+			case R.id.btnok:
+			{
+//				Intent intent = new Intent();
+//				intent.setClass(this, ResultActivity.class);
+//				// intent.putExtra("user", user);
+//				// intent.putExtra("password", password);
+//				intent.putExtra("function_name", function_name);
+				Bundle parms = new Bundle();
+
+				boolean hascriterion = false;
+				for (int i = 0; i < ll_list.getChildCount(); i++)
+				{
+					View item = ll_list.getChildAt(i);
+					String tag = item.getTag().toString();
+					TextView tv_aname = (TextView) item
+							.findViewById(R.id.aname);
+					String field_name = tv_aname.getTag().toString();
+					String val = "";
+					if (tag.equals("search_item_spinner"))
+					{
+						Spinner spinner_bool = (Spinner) item
+								.findViewById(R.id.sp_bool);
+						long sel = spinner_bool.getSelectedItemId();
+						if (sel == 1)
+							val = "true";
+						else if (sel == 2)
+							val = "false";
+						else
+							val = "";
+						if (!TextUtils.isEmpty(val))
+						{
+							parms.putString(field_name, val);
+							hascriterion = true;
+						}
+					}
+					else if (tag.equals("search_item_edit"))
+					{
+						AutoCompleteTextView edit = (AutoCompleteTextView) item
+								.findViewById(R.id.edit_val);
+						val = edit.getText().toString().trim();
+						if (!TextUtils.isEmpty(val))
+						{
+							parms.putString(field_name, val);
+							hascriterion = true;
+
+							dbUtil.savehistory(field_name, val);
+						}
+					}
+					else if (tag.equals("search_item_datepicker"))
+					{
+						EditText et_from = (EditText) item
+								.findViewById(R.id.et_from);
+						String val_from = et_from.getText().toString().trim();
+						EditText et_to = (EditText) item
+								.findViewById(R.id.et_to);
+						String val_to = et_to.getText().toString().trim();
+						if (!TextUtils.isEmpty(val_from))
+						{
+							parms.putString(field_name + "_from", val_from);
+							hascriterion = true;
+						}
+						if (!TextUtils.isEmpty(val_to))
+						{
+							parms.putString(field_name + "_to", val_to);
+							hascriterion = true;
+						}
+					}
+
+				}
+				// String criterion = "";
+				// if (hascriterion)
+				// {
+				// criterion = parms.toString();
+				// }
+
+				CharSequence keywordChar = mSearchView.getText();
+				if (keywordChar != null) {
+					String keyword = keywordChar.toString();
+					parms.putString("keyword",keyword);
+				}
+
+				parms.putString("module_name", function_name);
+				parms.putString("columns",
+						dbUtil.get_fields(user, function_name));
+				// Iterator<String> iter = hashMap.keySet().iterator();
+				// while (iter.hasNext())
+				// {
+				// String aname = (String) iter.next();
+				// Field field = (Field) hashMap.get(aname);
+				// parms.putString(field.name, field.value);
+				// }
+//				intent.putExtra("searchParms", parms);
+
+//				startActivity(intent);
+
+				Intent intent = new Intent(this, AMResultActivity.class);
+				intent.putExtra("query_params",parms);
+				startActivity(intent);
+				break;
+			}
+			case R.id.btncancel:
+				finish();
+				break;
+			case R.id.btn_clear:
+			{
+				AlertDialog.Builder builder = new Builder(
+						SearchListActivity.this);
+				builder.setMessage("Click Reset button to reset");
+
+				builder.setTitle("Confirm reset");
+
+				builder.setPositiveButton("Reset", new Dialog.OnClickListener()
+				{
+
+					@Override
+					public void onClick(DialogInterface dialog, int which)
+					{
+						hashMap.clear();
+						init();
+						dialog.dismiss();
+
+					}
+				});
+
+				builder.setNegativeButton("Cancel",
+						new Dialog.OnClickListener()
+						{
+
+							@Override
+							public void onClick(DialogInterface dialog,
+									int which)
+							{
+								dialog.dismiss();
+							}
+						});
+
+				builder.create().show();
+			}
+			default:
+				break;
+		}
+
+	}
+
+	@Override
+	public boolean onOptionsItemSelected(MenuItem item)
+	{
+		Intent intent = new Intent();
+		switch (item.getItemId())
+		{
+            case android.R.id.home:
+                finish();
+                break;
+			case R.id.action_custom_fields:
+				intent.setClass(this, CustomizeFieldsActivity.class);
+				// intent.putExtra("user", user);
+				// intent.putExtra("password", password);
+				intent.putExtra("function_name", function_name);
+				intent.putExtra("behavior", Network.BEHAVIOR_SEARCH);
+				startActivity(intent);
+				break;
+			case R.id.action_help:
+				// Intent intent = new Intent();
+				intent.setClass(this, HelpActivity.class);
+				intent.putExtra("caller", "search");
+				// // intent.putExtra("password", password);
+				// intent.putExtra("function_name", function_name);
+				// intent.putExtra("behavior", Network.BEHAVIOR_SEARCH);
+				startActivity(intent);
+				break;
+			default:
+				break;
+		}
+		return super.onOptionsItemSelected(item);
+	}
+}

+ 78 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/SearchResult.java

@@ -0,0 +1,78 @@
+package com.usai.apex;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import android.util.Log;
+
+public class SearchResult implements Serializable
+{
+	/**
+	 * 
+	 */
+	private static final long	serialVersionUID	= 8847830656864696392L;
+	int total_count = -1;
+	// int direction = 1;
+	int offset = 0;
+	// int count = 0;
+	ArrayList<HashMap<String, String>> records = new ArrayList<HashMap<String, String>>();
+
+	public int get_recordscount() {
+		return records.size();
+	}
+
+	public HashMap<String, String> get_record(int i) {
+		return records.get(i);
+	}
+
+	public void add_records(String jsonstr) {
+		try {
+			records.clear();
+			JSONObject objrecords = new JSONObject(jsonstr);
+			for (int i = 0; i < objrecords.length(); i++) {
+				// offset++;
+				JSONObject rec = objrecords.getJSONObject("record" + i);
+				Iterator<?> it = rec.keys();
+				HashMap<String, String> record = new HashMap<String, String>();
+				while (it.hasNext()) // loop for each function
+				{
+					String field_name = (String) it.next();
+					String val = rec.getString(field_name)
+							.replace("\n", "");
+					record.put(field_name, val);
+				}
+				records.add(record);
+
+			}
+
+		} catch (JSONException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		String TAG = "init_fields@ResultActivity.SearchResult";
+		Log.d(TAG, jsonstr);
+	}
+
+	public int get_totalcount() {
+		return total_count;
+	}
+
+	public void put_totalcount(int c) {
+		total_count = c;
+	}
+
+	public int get_offset() {
+		return offset;
+	}
+
+
+	public void set_offset(int i) {
+		offset = i;
+
+	}
+}

+ 174 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/SegmentView.java

@@ -0,0 +1,174 @@
+package com.usai.apex;
+
+import android.content.Context;
+import android.content.res.ColorStateList;
+import android.util.AttributeSet;
+import android.util.TypedValue;
+import android.view.Gravity;
+import android.view.View;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+/**
+ * Created by ray on 26/02/2018.
+ */
+
+public class SegmentView extends LinearLayout {
+    private TextView leftTextView;
+    private TextView rightTextView;
+    private onSegmentViewClickListener segmentListener;
+
+    // 这是代码加载ui必须重写的方法
+    public SegmentView(Context context) {
+        super(context);
+        initView();
+    }
+
+    // 这是在xml布局使用必须重写的方法
+    public SegmentView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        initView();
+    }
+
+    private void initView() {
+        leftTextView = new TextView(getContext());
+        rightTextView = new TextView(getContext());
+
+        leftTextView.setSingleLine();
+        rightTextView.setSingleLine();
+
+//        leftTextView.setPadding(8,0,8,0);
+//        rightTextView.setPadding(8,0,8,0);
+
+        // 设置textview的布局宽高并设置为weight属性都为1
+        leftTextView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT, 1));
+        rightTextView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT, 1));
+
+        // 初始化的默认文字
+        leftTextView.setText("H BOL");
+        rightTextView.setText("Container#");
+
+        // 实现不同的按钮状态,不同的颜色
+        ColorStateList csl = getResources().getColorStateList(R.color.segment_text_color_select);
+        leftTextView.setTextColor(csl);
+        rightTextView.setTextColor(csl);
+
+        // 设置textview的内容位置居中
+        leftTextView.setGravity(Gravity.CENTER);
+        rightTextView.setGravity(Gravity.CENTER);
+
+        // 设置textview的内边距
+        leftTextView.setPadding(10, 10, 10, 10);
+        rightTextView.setPadding(10, 10, 10, 10);
+
+        // 设置文字大小
+        setSegmentTextSize(17);
+
+        // 设置背景资源
+        leftTextView.setBackgroundResource(R.drawable.segment_left_background);
+        rightTextView.setBackgroundResource(R.drawable.segment_right_background);
+
+        // 默认左侧textview为选中状态
+        leftTextView.setSelected(true);
+
+        // 加入textview
+        this.removeAllViews();
+        this.addView(leftTextView);
+        this.addView(rightTextView);
+        this.invalidate();//重新draw()
+
+        leftTextView.setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                if (leftTextView.isSelected()) {
+                    return;
+                }
+                leftTextView.setSelected(true);
+                rightTextView.setSelected(false);
+                if (segmentListener != null) {
+                    segmentListener.onSegmentViewClick(leftTextView, 0);
+                }
+            }
+        });
+
+        rightTextView.setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                if (rightTextView.isSelected()) {
+                    return;
+                }
+                rightTextView.setSelected(true);
+                leftTextView.setSelected(false);
+                if (segmentListener != null) {
+                    segmentListener.onSegmentViewClick(rightTextView, 1);
+                }
+            }
+        });
+
+    }
+
+    /**
+     * 设置字体大小
+     *
+     * @param dp
+     */
+    private void setSegmentTextSize(int dp) {
+        leftTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, dp);
+        rightTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, dp);
+    }
+
+    /**
+     * 手动设置选中的状态
+     *
+     * @param i
+     */
+    public void setSelect(int i) {
+        if (i == 0) {
+            leftTextView.setSelected(true);
+            rightTextView.setSelected(false);
+        } else {
+            leftTextView.setSelected(false);
+            rightTextView.setSelected(true);
+        }
+    }
+
+
+
+
+    /**
+     * 获取当前选中状态 0=left, 1=right
+     *
+     * @param i
+     */
+    public int getSelect() {
+        if (leftTextView.isSelected()) {
+            return  0;
+        } else {
+         return 1;
+        }
+    }
+    /**
+     * 设置控件显示的文字
+     *
+     * @param text
+     * @param position
+     */
+    public void setSegmentText(CharSequence text, int position) {
+        if (position == 0) {
+            leftTextView.setText(text);
+        }
+        if (position == 1) {
+            rightTextView.setText(text);
+        }
+    }
+
+    // 定义一个接口接收点击事件
+    public interface onSegmentViewClickListener {
+        public void onSegmentViewClick(View view, int postion);
+    }
+
+    public void setOnSegmentViewClickListener(onSegmentViewClickListener segmentListener) {
+        this.segmentListener = segmentListener;
+    }
+
+}

Fichier diff supprimé car celui-ci est trop grand
+ 79 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/ServiceLocationFragment.java


+ 371 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/SettingsActivity.java

@@ -0,0 +1,371 @@
+package com.usai.apex;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.media.Ringtone;
+import android.media.RingtoneManager;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
+import android.preference.ListPreference;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceCategory;
+import android.preference.PreferenceFragment;
+import android.preference.PreferenceManager;
+import android.preference.RingtonePreference;
+import android.text.TextUtils;
+
+import java.util.List;
+
+/**
+ * A {@link PreferenceActivity} that presents a set of application settings. On
+ * handset devices, settings are presented as a single list. On tablets,
+ * settings are split by category, with category headers shown to the left of
+ * the list of settings.
+ * <p>
+ * See <a href="http://developer.android.com/design/patterns/settings.html">
+ * Android Design: Settings</a> for design guidelines and the <a
+ * href="http://developer.android.com/guide/topics/ui/settings.html">Settings
+ * API Guide</a> for more information on developing a Settings UI.
+ */
+public class SettingsActivity extends PreferenceActivity
+{
+	/**
+	 * Determines whether to always show the simplified settings UI, where
+	 * settings are presented in a single list. When false, settings are shown
+	 * as a master/detail two-pane view on tablets. When true, a single pane is
+	 * shown on tablets.
+	 */
+//	private static final boolean	ALWAYS_SIMPLE_PREFS	= false;
+//
+//	@Override
+//	protected void onPostCreate(Bundle savedInstanceState)
+//	{
+//		super.onPostCreate(savedInstanceState);
+//
+//		
+//	}
+
+	@Override
+	protected void onCreate(Bundle savedInstanceState)
+	{
+		
+		super.onCreate(savedInstanceState);
+		setupSimplePreferencesScreen();
+		
+	}
+
+	/**
+	 * Shows the simplified settings UI if the device configuration if the
+	 * device configuration dictates that a simplified, single-pane UI should be
+	 * shown.
+	 */
+	private void setupSimplePreferencesScreen()
+	{
+//		if (!isSimplePreferences(this))
+//		{
+//			return;
+//		}
+
+		getPreferenceManager().setSharedPreferencesName("setting");
+		// In the simplified UI, fragments are not used at all and we instead
+		// use the older PreferenceActivity APIs.
+
+		// Add 'general' preferences.
+		addPreferencesFromResource(R.xml.setting);
+
+//		// Add 'notifications' preferences, and a corresponding header.
+//		PreferenceCategory fakeHeader = new PreferenceCategory(this);
+//		fakeHeader.setTitle(R.string.pref_header_notifications);
+//		getPreferenceScreen().addPreference(fakeHeader);
+//		addPreferencesFromResource(R.xml.pref_notification);
+//
+//		// Add 'data and sync' preferences, and a corresponding header.
+//		fakeHeader = new PreferenceCategory(this);
+//		fakeHeader.setTitle(R.string.pref_header_data_sync);
+//		getPreferenceScreen().addPreference(fakeHeader);
+//		addPreferencesFromResource(R.xml.pref_data_sync);
+//
+//		// Bind the summaries of EditText/List/Dialog/Ringtone preferences to
+//		// their values. When their values change, their summaries are updated
+//		// to reflect the new value, per the Android Design guidelines.
+//		bindPreferenceSummaryToValue(findPreference("example_text"));
+//		bindPreferenceSummaryToValue(findPreference("example_list"));
+//		bindPreferenceSummaryToValue(findPreference("notifications_new_message_ringtone"));
+//		bindPreferenceSummaryToValue(findPreference("sync_frequency"));
+	}
+
+//	/** {@inheritDoc} */
+//	@Override
+//	public boolean onIsMultiPane()
+//	{
+//		return isXLargeTablet(this) && !isSimplePreferences(this);
+//	}
+
+	/**
+	 * Helper method to determine if the device has an extra-large screen. For
+	 * example, 10" tablets are extra-large.
+	 */
+//	private static boolean isXLargeTablet(Context context)
+//	{
+//		return (context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_XLARGE;
+//	}
+
+	/**
+	 * Determines whether the simplified settings UI should be shown. This is
+	 * true if this is forced via {@link #ALWAYS_SIMPLE_PREFS}, or the device
+	 * doesn't have newer APIs like {@link PreferenceFragment}, or the device
+	 * doesn't have an extra-large screen. In these cases, a single-pane
+	 * "simplified" settings UI should be shown.
+	 */
+//	private static boolean isSimplePreferences(Context context)
+//	{
+//		return ALWAYS_SIMPLE_PREFS
+//				|| Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB
+//				|| !isXLargeTablet(context);
+//	}
+
+//	/** {@inheritDoc} */
+//	@Override
+//	@TargetApi(Build.VERSION_CODES.HONEYCOMB)
+//	public void onBuildHeaders(List<Header> target)
+//	{
+//		if (!isSimplePreferences(this))
+//		{
+//			loadHeadersFromResource(R.xml.pref_headers, target);
+//		}
+//	}
+
+	/**
+	 * A preference value change listener that updates the preference's summary
+	 * to reflect its new value.
+	 */
+	// private static Preference.OnPreferenceChangeListener
+	// sBindPreferenceSummaryToValueListener = new
+	// Preference.OnPreferenceChangeListener()
+	// {
+	// @Override
+	// public boolean onPreferenceChange(
+	// Preference preference,
+	// Object value)
+	// {
+	// String stringValue = value
+	// .toString();
+	//
+	// if (preference instanceof ListPreference)
+	// {
+	// // For
+	// // list
+	// // preferences,
+	// // look
+	// // up
+	// // the
+	// // correct
+	// // display
+	// // value
+	// // in
+	// // the
+	// // preference's
+	// // 'entries'
+	// // list.
+	// ListPreference listPreference = (ListPreference) preference;
+	// int index = listPreference
+	// .findIndexOfValue(stringValue);
+	//
+	// // Set
+	// // the
+	// // summary
+	// // to
+	// // reflect
+	// // the
+	// // new
+	// // value.
+	// preference
+	// .setSummary(index >= 0 ? listPreference
+	// .getEntries()[index]
+	// : null);
+	//
+	// }
+	// else if (preference instanceof RingtonePreference)
+	// {
+	// // For
+	// // ringtone
+	// // preferences,
+	// // look
+	// // up
+	// // the
+	// // correct
+	// // display
+	// // value
+	// // using
+	// // RingtoneManager.
+	// if (TextUtils
+	// .isEmpty(stringValue))
+	// {
+	// // Empty
+	// // values
+	// // correspond
+	// // to
+	// // 'silent'
+	// // (no
+	// // ringtone).
+	// preference
+	// .setSummary(R.string.pref_ringtone_silent);
+	//
+	// }
+	// else
+	// {
+	// Ringtone ringtone = RingtoneManager
+	// .getRingtone(
+	// preference
+	// .getContext(),
+	// Uri.parse(stringValue));
+	//
+	// if (ringtone == null)
+	// {
+	// // Clear
+	// // the
+	// // summary
+	// // if
+	// // there
+	// // was
+	// // a
+	// // lookup
+	// // error.
+	// preference
+	// .setSummary(null);
+	// }
+	// else
+	// {
+	// // Set
+	// // the
+	// // summary
+	// // to
+	// // reflect
+	// // the
+	// // new
+	// // ringtone
+	// // display
+	// // name.
+	// String name = ringtone
+	// .getTitle(preference
+	// .getContext());
+	// preference
+	// .setSummary(name);
+	// }
+	// }
+	//
+	// }
+	// else
+	// {
+	// // For
+	// // all
+	// // other
+	// // preferences,
+	// // set
+	// // the
+	// // summary
+	// // to
+	// // the
+	// // value's
+	// // simple
+	// // string
+	// // representation.
+	// preference
+	// .setSummary(stringValue);
+	// }
+	// return true;
+	// }
+	// };
+
+	/**
+	 * Binds a preference's summary to its value. More specifically, when the
+	 * preference's value is changed, its summary (line of text below the
+	 * preference title) is updated to reflect the value. The summary is also
+	 * immediately updated upon calling this method. The exact display format is
+	 * dependent on the type of preference.
+	 * 
+	 * @see #sBindPreferenceSummaryToValueListener
+	 */
+//	private static void bindPreferenceSummaryToValue(Preference preference)
+//	{
+//		// Set the listener to watch for value changes.
+//		preference
+//				.setOnPreferenceChangeListener(sBindPreferenceSummaryToValueListener);
+//
+//		// Trigger the listener immediately with the preference's
+//		// current value.
+//		sBindPreferenceSummaryToValueListener.onPreferenceChange(
+//				preference,
+//				PreferenceManager.getDefaultSharedPreferences(
+//						preference.getContext()).getString(preference.getKey(),
+//						""));
+//	}
+
+	/**
+	 * This fragment shows general preferences only. It is used when the
+	 * activity is showing a two-pane settings UI.
+	 */
+//	@TargetApi(Build.VERSION_CODES.HONEYCOMB)
+//	public static class GeneralPreferenceFragment extends PreferenceFragment
+//	{
+//		@Override
+//		public void onCreate(Bundle savedInstanceState)
+//		{
+//			super.onCreate(savedInstanceState);
+//			addPreferencesFromResource(R.xml.pref_general);
+//
+//			// Bind the summaries of EditText/List/Dialog/Ringtone preferences
+//			// to their values. When their values change, their summaries are
+//			// updated to reflect the new value, per the Android Design
+//			// guidelines.
+//			bindPreferenceSummaryToValue(findPreference("example_text"));
+//			bindPreferenceSummaryToValue(findPreference("example_list"));
+//		}
+//	}
+
+	/**
+	 * This fragment shows notification preferences only. It is used when the
+	 * activity is showing a two-pane settings UI.
+	 */
+//	@TargetApi(Build.VERSION_CODES.HONEYCOMB)
+//	public static class NotificationPreferenceFragment extends
+//			PreferenceFragment
+//	{
+//		@Override
+//		public void onCreate(Bundle savedInstanceState)
+//		{
+//			super.onCreate(savedInstanceState);
+//			addPreferencesFromResource(R.xml.pref_notification);
+//
+//			// Bind the summaries of EditText/List/Dialog/Ringtone preferences
+//			// to their values. When their values change, their summaries are
+//			// updated to reflect the new value, per the Android Design
+//			// guidelines.
+//			bindPreferenceSummaryToValue(findPreference("notifications_new_message_ringtone"));
+//		}
+//	}
+
+	/**
+	 * This fragment shows data and sync preferences only. It is used when the
+	 * activity is showing a two-pane settings UI.
+	 */
+//	@TargetApi(Build.VERSION_CODES.HONEYCOMB)
+//	public static class DataSyncPreferenceFragment extends PreferenceFragment
+//	{
+//		@Override
+//		public void onCreate(Bundle savedInstanceState)
+//		{
+//			super.onCreate(savedInstanceState);
+//			addPreferencesFromResource(R.xml.pref_data_sync);
+//
+//			// Bind the summaries of EditText/List/Dialog/Ringtone preferences
+//			// to their values. When their values change, their summaries are
+//			// updated to reflect the new value, per the Android Design
+//			// guidelines.
+//			bindPreferenceSummaryToValue(findPreference("sync_frequency"));
+//		}
+//	}
+}

+ 735 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/ShipMap/ShipMap.java

@@ -0,0 +1,735 @@
+package com.usai.apex.ShipMap;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.graphics.Color;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.support.annotation.CallSuper;
+import android.support.annotation.Nullable;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.ImageButton;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import com.baidu.mapapi.SDKInitializer;
+import com.baidu.mapapi.map.BaiduMap;
+import com.baidu.mapapi.map.BitmapDescriptor;
+import com.baidu.mapapi.map.BitmapDescriptorFactory;
+import com.baidu.mapapi.map.InfoWindow;
+import com.baidu.mapapi.map.MapStatus;
+import com.baidu.mapapi.map.MapStatusUpdate;
+import com.baidu.mapapi.map.MapStatusUpdateFactory;
+import com.baidu.mapapi.map.MapView;
+import com.baidu.mapapi.map.Marker;
+import com.baidu.mapapi.map.MarkerOptions;
+import com.baidu.mapapi.model.LatLng;
+import com.google.android.gms.maps.CameraUpdate;
+import com.google.android.gms.maps.CameraUpdateFactory;
+import com.google.android.gms.maps.GoogleMap;
+import com.google.android.gms.maps.MapFragment;
+import com.google.android.gms.maps.OnMapReadyCallback;
+import com.google.android.gms.maps.model.CameraPosition;
+import com.usai.apex.ApexTrackingApplication;
+import com.usai.apex.R;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.lang.ref.WeakReference;
+import java.util.Timer;
+import java.util.TimerTask;
+
+public class ShipMap extends RelativeLayout implements GoogleMap.OnMarkerClickListener, BaiduMap.OnMarkerClickListener, GoogleMap.OnInfoWindowClickListener, OnMapReadyCallback, InfoWindow.OnInfoWindowClickListener {
+
+    private MapFragment mGoogleMapView;
+    private GoogleMap mGoogleMap;
+    private com.google.android.gms.maps.MapView mMap;
+
+    private MapView mBaiduMap;
+    private Context mContext;
+    private Boolean mUseGoogleMap;
+
+    private ShipMapListener mListener;
+    private ShipMap self = this;
+
+    private ImageButton mResizeBtn;
+
+    public ShipMap(Context context) {
+        super(context);
+        init(context);
+    }
+
+    public ShipMap(Context context, @Nullable AttributeSet attrs) {
+        super(context, attrs);
+        init(context);
+    }
+
+    public ShipMap(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        init(context);
+    }
+
+
+    @CallSuper
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        destroy();
+    }
+    /**
+     * 防止恢复时报错Duplicate id 0x7f0b00d6, tag null, or parent id 0xffffffff with another fragment
+     * 需要在父fragment销毁时调用
+     * */
+    public void destroy() {
+        //
+        if (mUseGoogleMap && mGoogleMapView != null && mContext != null) {
+            ((Activity)mContext).getFragmentManager().beginTransaction().remove(mGoogleMapView).commit();
+        }
+
+        stopTwinkle();
+    }
+
+    private void init(Context ctx) {
+        mContext = ctx;
+
+        PackageInfo packageInfo;
+        try {
+            packageInfo = mContext.getPackageManager().getPackageInfo("com.google.android.gms", 0);
+
+        } catch (PackageManager.NameNotFoundException e) {
+            packageInfo = null;
+            e.printStackTrace();
+        }
+        if (packageInfo == null) {
+            mUseGoogleMap = false;
+            System.out.println("没有安装");
+        } else {
+            mUseGoogleMap = true;
+            System.out.println("已经安装");
+        }
+//        mUseGoogleMap = false;
+
+//        GooglePlayServicesUtil.isGooglePlayServicesAvailable(mContext.getApplicationContext());
+
+        if (mUseGoogleMap) {
+
+//            googleMap = ((MapFragment)((Activity)mContext).getFragmentManager().findFragmentById(R.id.ship_google_map));
+
+            View relativeLayout = LayoutInflater.from(mContext).inflate(R.layout.ship_google_map,null);
+//            mGoogleMapView = relativeLayout.findViewById(R.id.ship_google_map);
+//            mGoogleMapView = ((MapFragment)((Activity)mContext).getFragmentManager().findFragmentById(R.id.ship_google_map));
+//            mGoogleMapView.getMapAsync(this);
+
+            mMap = relativeLayout.findViewById(R.id.ship_google_map);
+            mMap.onCreate(null);
+            mMap.onResume();
+            mMap.getMapAsync(this);
+
+            LayoutParams layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT);
+            relativeLayout.setBackgroundColor(Color.parseColor("#EFEFF4"));
+            addView(relativeLayout,layoutParams);
+
+        } else {
+
+            SDKInitializer.initialize(ApexTrackingApplication.get_instance());
+            mBaiduMap = new MapView(mContext);
+            mBaiduMap.getMap().setOnMarkerClickListener(this);
+
+            // 设置当前缩放
+            MapStatusUpdate u = MapStatusUpdateFactory.zoomTo(mBaiduMap.getMap().getMinZoomLevel());
+            mBaiduMap.getMap().setMapStatus(u);
+            mBaiduMap.showZoomControls(false); // false不显示缩放按钮
+            mBaiduMap.getMap().getUiSettings().setRotateGesturesEnabled(false); // 禁止旋转
+            mBaiduMap.getMap().getUiSettings().setOverlookingGesturesEnabled(false); // 禁止俯视调整
+
+
+            LayoutParams layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT);
+            mBaiduMap.setBackgroundColor(Color.parseColor("#EFEFF4"));
+            addView(mBaiduMap,layoutParams);
+        }
+
+        ImageButton resizeBtn = new ImageButton(mContext);
+        resizeBtn.setImageResource(R.drawable.resize_max);
+        resizeBtn.setBackgroundResource(R.drawable.clear_background);
+        resizeBtn.setTag(false);
+
+        LayoutParams layoutParams = new LayoutParams(dp2px(mContext,30.0f),dp2px(mContext,30.0f));
+        layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
+        layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
+        layoutParams.setMargins(0,dp2px(mContext,10.0f),dp2px(mContext,10.0f),0);
+
+        addView(resizeBtn,layoutParams);
+        mResizeBtn = resizeBtn;
+
+        resizeBtn.setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                ImageButton zoomBtn = (ImageButton)v;
+                boolean selected = (boolean) zoomBtn.getTag();
+                selected = !selected;
+
+                setZoomIn(selected);
+
+            }
+        });
+
+    }
+
+    public void setZoomIn(boolean zoomIn) {
+
+        mResizeBtn.setTag(zoomIn);
+
+        if (zoomIn) {
+            mResizeBtn.setImageResource(R.drawable.resize_min);
+        } else {
+            mResizeBtn.setImageResource(R.drawable.resize_max);
+        }
+
+        if (mListener != null) {
+            mListener.shipMapTryToZoomIn(self,zoomIn);
+        }
+
+    }
+
+
+    public static int dp2px(Context context, float dpValue) {
+        float scale = context.getResources().getDisplayMetrics().density;
+        return (int) (dpValue * scale + 0.5f);
+    }
+
+    private static int AnnotationDisplayPriorityRequired = 2;
+    private static int AnnotationDisplayPriorityHigh= 1;
+    private static int AnnotationDisplayPriorityLow = 0;
+
+    private JSONObject mAnnotation;
+
+    private Marker mCurrentBaiduMarker;
+    private com.google.android.gms.maps.model.Marker mCurrentGoogleMarker;
+    public void showShipAnnotation(JSONObject annotation) {
+        if (annotation == null) {
+            return;
+        }
+
+        mCurrentGoogleMarker = null;
+        mCurrentBaiduMarker = null;
+
+        if (mUseGoogleMap) {
+           if (mGoogleMap != null) {
+               mGoogleMap.clear();
+           } else {
+               mAnnotation = annotation;
+               return;
+           }
+        } else {
+            mBaiduMap.getMap().clear();
+        }
+        mAnnotation = null;
+
+        JSONObject pol = annotation.optJSONObject("pol");
+        if (showPol()) {
+
+            if (pol != null) {
+                try {
+                    pol.put("port","Port Of Load");
+                } catch (JSONException e) {
+                    e.printStackTrace();
+                }
+                handleLocation(pol,AnnotationDisplayPriorityHigh,R.drawable.new_location_pol);
+            }
+        }
+
+        JSONObject pod = annotation.optJSONObject("pod");
+        if (showPod()) {
+
+            if (pod != null) {
+                try {
+                    pod.put("port","Port Of Discharge");
+                } catch (JSONException e) {
+                    e.printStackTrace();
+                }
+                handleLocation(pod,AnnotationDisplayPriorityHigh,R.drawable.new_location_pod);
+            }
+        }
+
+        JSONObject poe = annotation.optJSONObject("poe");
+        if (showPoe()) {
+
+            if (poe != null) {
+                try {
+                    poe.put("port","Place Of Deliver");
+                } catch (JSONException e) {
+                    e.printStackTrace();
+                }
+                handleLocation(poe,AnnotationDisplayPriorityLow,R.drawable.new_location_poe);
+            }
+        }
+
+        JSONObject por = annotation.optJSONObject("por");
+        if (showPor()) {
+
+            if (por != null) {
+                try {
+                    por.put("port","Place Of Receipt");
+                } catch (JSONException e) {
+                    e.printStackTrace();
+                }
+                handleLocation(por,AnnotationDisplayPriorityLow,R.drawable.new_location_por);
+            }
+        }
+
+        JSONObject origin = annotation.optJSONObject("origin");
+        if (showOrigin()) {
+
+            if (origin != null) {
+                try {
+                    origin.put("port","Origin");
+                } catch (JSONException e) {
+                    e.printStackTrace();
+                }
+                handleLocation(origin,AnnotationDisplayPriorityLow,R.drawable.new_location_origin);
+            }
+        }
+
+        JSONObject destination = annotation.optJSONObject("destination");
+        if (showDestination()) {
+
+            if (destination != null) {
+                try {
+                    destination.put("port","Destination");
+                } catch (JSONException e) {
+                    e.printStackTrace();
+                }
+                handleLocation(destination,AnnotationDisplayPriorityLow,R.drawable.new_location_destination);
+            }
+        }
+
+        JSONObject current = annotation.optJSONObject("current");
+        if (showCurrent()) {
+            if (current != null) {
+                try {
+                    current.put("port","Vessel");
+                } catch (JSONException e) {
+                    e.printStackTrace();
+                }
+                handleLocation(current,AnnotationDisplayPriorityRequired,R.drawable.ic_marker);
+            }
+        }
+
+
+        if (current != null && showCurrent()) {
+            moveToLocation(current);
+            if (mTwinkleCurrent) {
+                startTwinkle();
+            }
+        } else if (pol != null && showPol()) {
+            moveToLocation(pol);
+        } else if (pod != null && showPod()) {
+            moveToLocation(pod);
+        }
+
+
+    }
+
+    private Timer mTimer;
+    private TimerHandler mTimerHandler = new TimerHandler(this);
+    private TimerTask mTimerTask;
+    private void startTwinkle() {
+
+        if (mCurrentGoogleMarker == null && mCurrentBaiduMarker == null) {
+            return;
+        }
+
+        if (mTimer != null && mTimerTask != null) {
+            return;
+        }
+
+        mTimer = new Timer();
+        mTimerTask = new TimerTask() {
+            @Override
+            public void run() {
+                Message msg = new Message();
+                mTimerHandler.sendMessage(msg);
+            }
+        };
+        mTimer.schedule(mTimerTask,100,100);
+    }
+
+    private void stopTwinkle() {
+        if (mTimer != null) {
+            mTimer.cancel();
+        }
+        if (mTimerTask != null) {
+            mTimerTask.cancel();
+        }
+    }
+
+    private void twinkleCurrentAlpha(double alpha) {
+
+        if (mUseGoogleMap) {
+            if (mCurrentGoogleMarker != null) {
+                mCurrentGoogleMarker.setAlpha((float) alpha);
+            }
+
+        } else {
+            if (mCurrentBaiduMarker != null) {
+                mCurrentBaiduMarker.setAlpha((float) alpha);
+            }
+        }
+    }
+
+
+
+    private void moveToLocation(JSONObject location) {
+
+        if (location == null) {
+            return;
+        }
+
+        String lonStr = location.optString("lon");
+        String latStr = location.optString("lat");
+
+        if (lonStr != null && lonStr.length() > 0 && latStr != null && latStr.length() > 0) {
+
+            if (mUseGoogleMap) {
+
+                CameraPosition newLocation = new CameraPosition.Builder()
+                        .target(new com.google.android.gms.maps.model.LatLng(Float.valueOf(latStr), Float.valueOf(lonStr)))
+                        .zoom(2.5f)
+                        .bearing(0)
+                        .tilt(0)
+                        .build();
+                mGoogleMap.moveCamera(CameraUpdateFactory.newCameraPosition(newLocation));
+            } else {
+
+                LatLng center = new LatLng(Float.valueOf(latStr),Float.valueOf(lonStr)); //设定中心点坐标
+                MapStatus mMapStatus = new MapStatus.Builder()//定义地图状态
+                                                    .target(center)
+                                                    .zoom(2.5f)
+                                                    .build();  //定义MapStatusUpdate对象,以便描述地图状态将要发生的变化
+                MapStatusUpdate mMapStatusUpdate = MapStatusUpdateFactory.newMapStatus(mMapStatus);
+                mBaiduMap.getMap().setMapStatus(mMapStatusUpdate);//改变地图状态
+            }
+        }
+
+    }
+
+    private void handleLocation(JSONObject location,int priority, int imageId) {
+
+        if (location == null) {
+            return;
+        }
+
+        if (mUseGoogleMap) {
+            handleGoogleLocation(location,priority,imageId);
+        } else {
+            handleBaiduLocation(location,priority,imageId);
+        }
+
+    }
+
+    private void handleGoogleLocation(JSONObject location,int priority, int imageId) {
+
+        String port = location.optString("port");
+        String name = location.optString("name");
+        String addr = location.optString("addr");
+        String lonStr = location.optString("lon");
+        String latStr = location.optString("lat");
+
+        if (lonStr != null && lonStr.length() > 0 && latStr != null && latStr.length() > 0) {
+
+            if (port == null) {
+                port = "";
+            }
+            if (addr == null) {
+                addr = "";
+            }
+
+            com.google.android.gms.maps.model.MarkerOptions options = new com.google.android.gms.maps.model.MarkerOptions();
+            options.icon(com.google.android.gms.maps.model.BitmapDescriptorFactory.fromResource(imageId))
+                    .position(new com.google.android.gms.maps.model.LatLng(Double.parseDouble(latStr), Double.parseDouble(lonStr)))
+                    .title(name)
+                    .snippet(port + " " + addr);
+            options.zIndex(priority);
+
+            com.google.android.gms.maps.model.Marker marker = mGoogleMap.addMarker(options);
+
+            if (port.equals("Vessel")) {
+                mCurrentGoogleMarker = marker;
+            }
+
+        } else {
+            return;
+        }
+
+    }
+
+    private void handleBaiduLocation(JSONObject location,int priority, int imageId) {
+
+        String port = location.optString("port");
+        String name = location.optString("name");
+        String addr = location.optString("addr");
+        String lonStr = location.optString("lon");
+        String latStr = location.optString("lat");
+
+        if (lonStr != null && lonStr.length() > 0 && latStr != null && latStr.length() > 0) {
+
+            if (port == null) {
+                port = "";
+            }
+            if (addr == null) {
+                addr = "";
+            }
+
+            LatLng llA = new LatLng(Double.parseDouble(latStr), Double.parseDouble(lonStr));
+            BitmapDescriptor icon = BitmapDescriptorFactory.fromResource(imageId);
+
+            Bundle extrainfo = new Bundle();
+            extrainfo.putString("detail",port + " " + addr);
+
+            MarkerOptions markeroption = new MarkerOptions().position(llA).icon(icon).zIndex(9).title(name).extraInfo(extrainfo).draggable(true);
+            markeroption.zIndex(priority);
+
+            Marker marker = (Marker) mBaiduMap.getMap().addOverlay(markeroption);
+
+            if (port.equals("Vessel")) {
+                mCurrentBaiduMarker = marker;
+            }
+
+        } else {
+            return;
+        }
+
+    }
+
+    private boolean mShowPol = true,mShowPoe,mShowPod = true,mShowPor,mShowOrigin,mShowDestination,mShowCurrent = true,mTwinkleCurrent = true;
+
+    public void setShowPol(boolean show) {
+        mShowPol = show;
+    }
+
+    public boolean showPol() {
+        return mShowPol;
+    }
+
+    public void setShowPoe(boolean show) {
+        mShowPoe = show;
+    }
+
+    public boolean showPoe() {
+        return mShowPoe;
+    }
+
+    public void setShowPod(boolean show) {
+        mShowPod = show;
+    }
+
+    public boolean showPod() {
+        return mShowPod;
+    }
+
+    public void setShowPor(boolean show) {
+        mShowPor = show;
+    }
+
+    public boolean showPor() {
+        return mShowPor;
+    }
+
+    public void setShowOrigin(boolean show) {
+        mShowOrigin = show;
+    }
+
+    public boolean showOrigin() {
+        return mShowOrigin;
+    }
+
+    public void setShowDestination(boolean show) {
+        mShowDestination = show;
+    }
+
+    public boolean showDestination() {
+        return mShowDestination;
+    }
+
+    public void setShowCurrent(boolean show) {
+        mShowCurrent = show;
+    }
+
+    public boolean showCurrent() {
+        return mShowCurrent;
+    }
+
+    public void setShipMapListener(ShipMapListener listener) {
+        mListener = listener;
+    }
+
+    public void setTwinkleCurrent(boolean twinkleCurrent) {
+        mTwinkleCurrent = twinkleCurrent;
+    }
+
+    public boolean twinkleCurrent() {
+        return mTwinkleCurrent;
+    }
+
+    public ShipMapListener getShipMapListener() {
+        return mListener;
+    }
+
+    /**
+     * Google
+     * */
+
+    @Override
+    public boolean onMarkerClick(com.google.android.gms.maps.model.Marker marker) {
+        return false;
+    }
+
+    @Override
+    public void onInfoWindowClick(com.google.android.gms.maps.model.Marker marker) {
+
+    }
+
+    @Override
+    public void onMapReady(GoogleMap googleMap) {
+
+        mGoogleMap = googleMap;
+        if (mGoogleMap != null) {
+            mGoogleMap.setInfoWindowAdapter(new ShipMapWindowInfoAdapter());
+//            mGoogleMap.moveCamera(CameraUpdateFactory.newCameraPosition(US));
+            mGoogleMap.setOnMarkerClickListener(this);
+            mGoogleMap.setOnInfoWindowClickListener(this);
+            if (mAnnotation != null) {
+                showShipAnnotation(mAnnotation);
+            }
+            mGoogleMap.getUiSettings().setMapToolbarEnabled(false); // 隐藏底部ToolBar 导航按钮
+            mGoogleMap.getUiSettings().setRotateGesturesEnabled(false); // 禁止旋转
+
+            // 设置缩放级别
+            CameraUpdate zoom = CameraUpdateFactory.zoomTo(mGoogleMap.getMinZoomLevel());
+            mGoogleMap.animateCamera(zoom);
+        }
+    }
+
+    /**
+     * Baidu
+     * */
+
+    @Override
+    public boolean onMarkerClick(Marker marker) {
+
+//        View viewCache = LayoutInflater.from(mContext).inflate(R.layout.ship_map_bubble, null);
+//
+//        TextView tv_title = (TextView) viewCache.findViewById(R.id.bubble_title);
+//        TextView tv_info = (TextView) viewCache.findViewById(R.id.bubble_detail);
+
+        View viewCache = ((Activity)mContext)
+                .getLayoutInflater().inflate(
+                        R.layout.marker_view, null);
+
+        TextView tv_title = (TextView) viewCache
+                .findViewById(R.id.tv_title);
+        TextView tv_info = (TextView) viewCache
+                .findViewById(R.id.tv_info);
+
+        tv_title.setText(marker.getTitle());
+        tv_info.setText(marker.getExtraInfo().getString("detail"));
+
+        LatLng ll = marker.getPosition();
+        InfoWindow mInfoWindow = new InfoWindow(BitmapDescriptorFactory.fromView(viewCache), ll, -100, this);
+        mBaiduMap.getMap().showInfoWindow(mInfoWindow);
+
+        return true;
+    }
+
+    @Override
+    public void onInfoWindowClick() {
+        mBaiduMap.getMap().hideInfoWindow();
+    }
+
+    /**
+     *
+     * */
+
+    class ShipMapWindowInfoAdapter implements GoogleMap.InfoWindowAdapter
+    {
+
+        View	mContents;
+
+        ShipMapWindowInfoAdapter() {
+            mContents = LayoutInflater.from(mContext).inflate(R.layout.ship_map_bubble, null);
+        }
+
+        @Override
+        public View getInfoContents(com.google.android.gms.maps.model.Marker marker)
+        {
+
+            String title = marker.getTitle();
+            TextView titleUi = ((TextView) mContents.findViewById(R.id.bubble_title));
+
+            if (title != null)
+            {
+                titleUi.setText(title);
+            }
+            else
+            {
+                titleUi.setText("");
+            }
+
+            String snippet = marker.getSnippet();
+            TextView snippetUi = ((TextView) mContents.findViewById(R.id.bubble_detail));
+            if (snippet != null)
+            {
+                snippetUi.setText(snippet);
+            }
+            else
+            {
+                snippetUi.setText("");
+            }
+            return mContents;
+        }
+
+        @Override
+        public View getInfoWindow(com.google.android.gms.maps.model.Marker marker)
+        {
+
+            return null;
+        }
+
+    }
+
+    public interface ShipMapListener {
+
+        void shipMapTryToZoomIn(ShipMap shipMap,boolean zoomIn);
+
+    }
+
+    private static final class TimerHandler extends Handler {
+
+        double angle = 0;
+        WeakReference<ShipMap> weakMap;
+
+        TimerHandler(ShipMap map) {
+            if (map == null) {
+                return;
+            }
+            weakMap = new WeakReference<>(map);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+
+            angle += 0.1;
+            if (angle == 3.1) {
+                angle = 0;
+            }
+            double alpha = Math.abs(Math.cos(angle));
+            ShipMap shipMap = weakMap.get();
+            shipMap.twinkleCurrentAlpha(alpha);
+        }
+    }
+}

+ 71 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/TestActivity.java

@@ -0,0 +1,71 @@
+package com.usai.apex;
+
+import android.support.v7.app.AppCompatActivity;
+import android.os.Bundle;
+
+import com.usai.apex.ShipMap.ShipMap;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+public class TestActivity extends AppCompatActivity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_test);
+
+        String test = "{\n" +
+                "            \"title\":\"SH - PT. WANGSA MANUNGGAL JAYA PERKASA\",\n" +
+                "            \"icon\":\"status_vd\",\n" +
+                "            \"serial_no\":\"85625278dbaae299ffbbd10ee22cf875\",\n" +
+                "            \"hbol\":\"A1805340018\",\n" +
+                "            \"description\":\"A1805340018(1 containers)\",\n" +
+                "            \"detail\":\"Vessel Departure; IDSUB (SURABAYA, INDONESIA 2018-05-05)\",\n" +
+                "            \"date\":\"05/05/2018 - 06/02/2018\",\n" +
+                "            \"port\":\"IDSUB - USOAK\",\n" +
+                "            \"transport_stage\":\"3\",\n" +
+                "            \"locations\":{\n" +
+                "                \"por\":{\n" +
+                "                    \"icon\":\"\",\n" +
+                "                    \"lat\":\"-7.2000000000\",\n" +
+                "                    \"lon\":\"112.7333333333\",\n" +
+                "                    \"name\":\"SURABAYA\",\n" +
+                "                    \"addr\":\"\"\n" +
+                "                },\n" +
+                "                \"pol\":{\n" +
+                "                    \"icon\":\"\",\n" +
+                "                    \"lat\":\"-7.2000000000\",\n" +
+                "                    \"lon\":\"112.7333333333\",\n" +
+                "                    \"name\":\"SURABAYA\",\n" +
+                "                    \"addr\":\"\"\n" +
+                "                },\n" +
+                "                \"pod\":{\n" +
+                "                    \"icon\":\"\",\n" +
+                "                    \"lat\":\"37.7978400000\",\n" +
+                "                    \"lon\":\"-122.2864000000\",\n" +
+                "                    \"name\":\"OAKLAND\",\n" +
+                "                    \"addr\":\"\"\n" +
+                "                }\n" +
+                "            }\n" +
+                "        }";
+
+        ShipMap shipMap = findViewById(R.id.ship_map);
+
+        shipMap.setShowPol(true);
+        shipMap.setShowPod(true);
+        shipMap.setShowPoe(true);
+        shipMap.setShowPor(true);
+        shipMap.setShowOrigin(true);
+        shipMap.setShowDestination(true);
+        shipMap.setShowCurrent(true);
+
+        try {
+            JSONObject j = new JSONObject(test);
+            shipMap.showShipAnnotation(j.getJSONObject("locations"));
+
+        } catch (JSONException e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 57 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/TestAppComActivity.java

@@ -0,0 +1,57 @@
+package com.usai.apex;
+
+import android.os.Bundle;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AppCompatActivity;
+import android.view.Menu;
+
+public class TestAppComActivity extends AppCompatActivity {
+
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        getMenuInflater().inflate(R.menu.quick_search,menu);
+        return  true;
+    }
+
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_test_app_com);
+
+
+        ActionBar actionBar = getSupportActionBar();
+        actionBar.setLogo(R.drawable.apexlogo);
+//        actionBar.setIcon(R.drawable.ic_launcher);
+
+        actionBar.setDisplayUseLogoEnabled(true);
+        actionBar.setDisplayShowHomeEnabled(true);
+//        actionBar.setHomeAsUpIndicator(R.drawable.ic_launcher);
+        actionBar.setDisplayHomeAsUpEnabled(false);
+        actionBar.setDisplayShowTitleEnabled(true);
+
+
+//        actionBar.add
+//        getSupportActionBar().setIcon(R.drawable.ic_launcher);
+//        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+
+//        Toolbar toolbar =(Toolbar) findViewById(R.id.toolbar);
+//        setSupportActionBar(toolbar);
+//
+//        setSupportActionBar(toolbar);
+////        setTitle("aaaa");//设置标题
+////        toolbar.setNavigationIcon(R.mipmap.ic_launcher_round);//设置返回键,我这里没有,就有icon代替吧
+////        toolbar.setNavigationOnClickListener(new OnClickListener() {
+////            @Override
+////            public void onClick(View view) {
+////                finish();
+////            }
+////        });//返回监听
+//        toolbar.setLogo(R.drawable.apexlogo_2);//设置logo
+////        toolbar.setSubtitle("bbbb");//设置副标题
+//
+//
+
+    }
+}

+ 45 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/ViewPagerAdapter.java

@@ -0,0 +1,45 @@
+package com.usai.apex;
+
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.app.FragmentStatePagerAdapter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by bruce on 2016/11/1.
+ * ViewPagerAdapter
+ */
+
+public class ViewPagerAdapter extends FragmentStatePagerAdapter {
+
+    private final List<Fragment> mFragmentList = new ArrayList<>();
+
+    public ViewPagerAdapter(FragmentManager manager) {
+        super(manager);
+    }
+
+    @Override
+    public Fragment getItem(int position) {
+        return mFragmentList.get(position);
+    }
+
+    @Override
+    public int getCount() {
+        return mFragmentList.size();
+    }
+
+    public void addFragment(Fragment fragment) {
+        mFragmentList.add(fragment);
+    }
+    //解决ViewPager数据源改变时,刷新无效的解决办法
+    @Override
+    public int getItemPosition(Object object) {
+        return POSITION_NONE;
+    }
+//    public void clear()
+//    {
+//        mFragmentList.clear();
+//    }
+}

+ 87 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/WebActivity.java

@@ -0,0 +1,87 @@
+package com.usai.apex;
+
+import android.content.Intent;
+import android.graphics.Color;
+import android.os.Bundle;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AppCompatActivity;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.webkit.WebSettings;
+import android.webkit.WebView;
+import android.widget.TextView;
+
+public class WebActivity extends AppCompatActivity
+{
+	@Override
+	public boolean onOptionsItemSelected(MenuItem item)
+	{
+		Intent intent = new Intent();
+		switch (item.getItemId())
+		{
+			case android.R.id.home:
+				finish();
+				break;
+
+			default:
+				break;
+		}
+		return super.onOptionsItemSelected(item);
+	}
+
+	private void setCustomActionBar() {
+		ActionBar.LayoutParams lp =new ActionBar.LayoutParams(ActionBar.LayoutParams.MATCH_PARENT, ActionBar.LayoutParams.MATCH_PARENT, Gravity.CENTER);
+		View mActionBarView = LayoutInflater.from(this).inflate(R.layout.actionbar_customtitle, null);
+
+		TextView titleview = mActionBarView.findViewById(R.id.title);
+		titleview.setText(getTitle());
+
+		ActionBar actionBar = getSupportActionBar();
+		actionBar.setCustomView(mActionBarView, lp);
+//		actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
+//		actionBar.setDisplayShowCustomEnabled(true);
+		actionBar.setDisplayHomeAsUpEnabled(true);
+
+
+		actionBar.setDisplayShowTitleEnabled(true);
+	}
+	@Override
+	protected void onCreate(Bundle savedInstanceState)
+	{
+
+		// setTitle("Booking Result");
+
+		super.onCreate(savedInstanceState);
+
+		String title = getIntent().getStringExtra("title");
+
+		setTitle(title);
+		setContentView(R.layout.fragment_web);
+
+
+		setCustomActionBar();
+		String url = getIntent().getStringExtra("url");
+		WebView wv = (WebView) findViewById(R.id.wv_content);
+
+		wv.setBackgroundColor(Color.TRANSPARENT); // 设置背景色
+
+
+		WebSettings settings=wv.getSettings();
+		// 设置可以支持缩放
+//		settings.setSupportZoom(true);
+// 设置出现缩放工具
+//		settings.setBuiltInZoomControls(true);
+//扩大比例的缩放
+//		settings.setUseWideViewPort(true);
+		//自适应屏幕
+		settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
+		settings.setLoadWithOverviewMode(true);
+		settings.setTextZoom(150);
+
+		wv.loadUrl(url);
+
+	}
+
+}

+ 94 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/mainframe/BottomNavigationViewHelper.java

@@ -0,0 +1,94 @@
+package com.usai.apex.mainframe;
+
+import android.support.design.internal.BaselineLayout;
+import android.support.design.internal.BottomNavigationItemView;
+import android.support.design.internal.BottomNavigationMenuView;
+import android.support.design.widget.BottomNavigationView;
+import android.util.DisplayMetrics;
+import android.util.TypedValue;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+
+import com.usai.apex.ApexTrackingApplication;
+
+import java.lang.reflect.Field;
+
+// 利用反射,改变 item 中 mShiftingMode 的值
+public class BottomNavigationViewHelper {
+
+    public static void disableShiftMode(BottomNavigationView navigationView, boolean showIcon) {
+
+
+        BottomNavigationMenuView menuView = (BottomNavigationMenuView) navigationView.getChildAt(0);
+
+
+
+//        for (int i = 0; i < menuView.getChildCount(); i++) {
+//            final View iconView = menuView.getChildAt(i).findViewById(android.support.design.R.id.icon);
+//            final ViewGroup.LayoutParams layoutParams = iconView.getLayoutParams();
+//            final DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
+//            layoutParams.height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 32, displayMetrics);
+//            layoutParams.width = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 32, displayMetrics);
+//            iconView.setLayoutParams(layoutParams);
+//        }
+
+        try {
+            Field shiftingMode = menuView.getClass().getDeclaredField("mShiftingMode");
+            shiftingMode.setAccessible(true);
+            shiftingMode.setBoolean(menuView, false);
+            shiftingMode.setAccessible(false);
+
+            for (int i = 0; i < menuView.getChildCount(); i++) {
+                BottomNavigationItemView itemView = (BottomNavigationItemView) menuView.getChildAt(i);
+
+
+
+
+
+
+                 View iconView = itemView.findViewById(android.support.design.R.id.icon);
+
+                final ViewGroup.LayoutParams layoutParams = iconView.getLayoutParams();
+                final DisplayMetrics displayMetrics = ApexTrackingApplication.get_instance().getResources().getDisplayMetrics();
+                layoutParams.height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 26, displayMetrics);
+                layoutParams.width = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 26, displayMetrics);
+                iconView.setLayoutParams(layoutParams);
+
+
+//                itemView.removeView(iconView);
+//                iconView.remove
+
+                if(!showIcon)
+                {
+                    for(int k=0;k<itemView.getChildCount();k++)
+                    {
+                        View v = itemView.getChildAt(k);
+                        if(v instanceof BaselineLayout)
+                        {
+//                        BaselineLayout bl = (BaselineLayout)v;
+                            FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) v.getLayoutParams();
+                            params.gravity = Gravity.CENTER;
+                            v.setLayoutParams(params);
+
+                        }
+                    }
+
+                    iconView.setVisibility(View.GONE);
+                }
+
+                itemView.setShiftingMode(false);
+                itemView.setChecked(itemView.getItemData().isChecked());
+
+
+            }
+//            navigationView.setSelectedItemId(navigationView.getMenu().getItem(0).getItemId());
+
+
+
+        } catch (NoSuchFieldException | IllegalAccessException e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 355 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/mainframe/HistoryFragment.java

@@ -0,0 +1,355 @@
+package com.usai.apex.mainframe;
+
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.text.TextUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.ListView;
+
+import com.usai.apex.ApexTrackingApplication;
+import com.usai.apex.R;
+import com.usai.apex.Result.PullRefreshListView;
+import com.usai.util.Network;
+import com.usai.util.dbUtil;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+
+/**
+ * A simple {@link Fragment} subclass.
+ */
+public class HistoryFragment extends TrackingListFragment {
+
+//
+//    boolean bactive = false;
+//    public  void setActive(boolean active){
+//        bactive = active;
+//
+//    }
+
+    private class HistoryTask extends AsyncTask<Void, Void, JSONObject> {
+
+        @Override
+        protected void onPreExecute() {
+            super.onPreExecute();
+
+            isLoading = true;
+            showProgressDialog();
+        }
+
+        @Override
+        protected JSONObject doInBackground(Void... voids) {
+
+            final Bundle params = new Bundle();
+            params.putInt("offset",mOffset);
+            params.putInt("limit",load_limit);
+
+            final JSONObject jsobj = Network.request_history(params);
+
+            return jsobj;
+        }
+
+        @Override
+        protected void onPostExecute(JSONObject jsobj) {
+            super.onPostExecute(jsobj);
+
+
+            mPullRefreshListView.completeRefresh();
+            showProgress(false);
+            if (mSwipeRefresh.isRefreshing()) {
+                mSwipeRefresh.setRefreshing(false);
+            }
+
+            dismissProgressDialog();
+
+            if (jsobj != null) {
+
+                try {
+                    int result = jsobj.getInt("result");
+                    if (result == Network.RESULT_TRUE) {
+
+                        JSONArray datalist = jsobj.getJSONArray("container_list");
+                        int count = datalist.length();
+
+                        switch (mOption) {
+                            case 0:
+                            case 1: {
+                                searchresult.clear();
+                            }
+                            break;
+                            case 2: {
+
+                            }
+                            break;
+                        }
+
+                        searchresult.add_records(datalist.toString(), count);
+
+                        if(searchresult.getData().size()==0)
+                        {
+
+                            showRefreshButton(true);
+                        }
+                        else
+                        {
+                            showRefreshButton(false);
+
+                        }
+                        adapter.notifyDataSetChanged();
+
+                        if (count < load_limit && count!=0) {
+                            showAlert("No More Data");
+                        }
+
+                        if(mOption==0)
+                            bdirty = false;
+
+                    } else {
+                        String msg = jsobj.getString("err_msg");
+                        showAlert(msg);
+                    }
+                } catch (JSONException e) {
+                    e.printStackTrace();
+                    showAlert("Sorry,there is some wrong");
+                }
+
+            } else {
+                showAlert("Sorry,there is some wrong");
+            }
+
+            isLoading = false;
+            mTask = null;
+        }
+
+        @Override
+        protected void onCancelled() {
+            super.onCancelled();
+
+            isLoading = false;
+            dismissProgressDialog();
+            mTask = null;
+        }
+    }
+
+    private int mOffset = 0;
+    private int mOption = 0;
+    private HistoryTask mTask;
+
+    protected boolean isActive()
+    {
+        return ApexTrackingApplication.getInstance().historyactive;
+    }
+    public HistoryFragment() {
+        // Required empty public constructor
+        bdirty = true;
+    }
+
+
+    @Override
+    public void onActivityCreated(Bundle savedInstanceState)
+    {
+        super.onActivityCreated(savedInstanceState);
+
+//        setupAdapter();
+//        customize_style();
+
+        refresh_footer = View.inflate(mContext, R.layout.refresh_footer, null);
+        mPullRefreshListView.setRefreshFooter(refresh_footer);
+        mPullRefreshListView.setOnRefreshListener(new PullRefreshListView.OnRefreshListener() {
+            @Override
+            public void onHeaderStateChange(int state, int offset) {
+
+            }
+
+            @Override
+            public void onFooterStateChange(int state, int offset) {
+                if (state == PullRefreshListView.REFRESHING) {
+                    if (!isLoading) {
+                        loadContent(2);
+                    }
+                }
+            }
+
+            @Override
+            public void shouldPullDownToRefresh(boolean should) {
+
+            }
+        });
+
+        // this.getListView().setBackgroundColor(Color.WHITE);
+//        if (searchresult.get_count() == 0) {
+//            requestData();
+//        }
+
+    }
+//    private void requestdata()
+//    {
+//
+//        loadContent(0);
+//
+////        JSONObject jsobj = loadfakecontent(R.raw.fake_container_list);
+////        // if (searchresult.get_fieldscount() == 0)
+////        // {
+////        // JSONObject objfields = jsobj.getJSONObject("fields");
+////        // if (objfields != null)
+////        // searchresult.init_fields(objfields.toString());
+////        // }
+////
+////
+////        try {
+////            JSONArray datalist = jsobj.getJSONArray("container_list");
+////            int count = datalist.length();
+////            searchresult.add_records(datalist.toString(), count);
+////
+////        } catch (JSONException e) {
+////            e.printStackTrace();
+////        }
+////
+//////        int count = jsobj.getInt("total");
+//////
+//////        if (count < limit)
+//////            bfinish = true;
+//////        JSONObject objrecords = jsobj.getJSONObject("records");
+//////        if (objrecords != null)
+//////            searchresult.add_records(objrecords.toString(), count);
+//////        errorcode = Network.RESULT_TRUE;
+////
+////        adapter.notifyDataSetChanged();
+//    }
+    @Override
+    protected View initHeaderView()
+    {
+
+        View headerView = LayoutInflater.from(getActivity()).inflate(R.layout.invisable_listheader, null);
+        return headerView;
+
+    }
+
+    @Override
+    protected void requestData() {
+
+        loadContent(0);
+//        super.requestData();
+    }
+
+    private static final int load_limit = 10;
+    private void loadContent(final int option) {
+
+        if (isLoading) {
+            if (mSwipeRefresh.isRefreshing()) {
+                mSwipeRefresh.setRefreshing(false);
+            }
+            return;
+        }
+
+        mOffset = 0;
+        switch (option) {
+            case 0:
+            case 1: {
+                mOffset = 0;
+            }
+            break;
+            case 2: {
+                mOffset = searchresult.get_count();
+            }
+            break;
+        }
+        mOption = option;
+
+
+        mTask = new HistoryTask();
+        mTask.execute();
+
+    }
+
+    @Override
+    public void onDetach() {
+        super.onDetach();
+
+        if (mTask != null) {
+            mTask.cancel(false);
+        }
+        dismissProgressDialog();
+    }
+
+    @Override
+    public void onListItemClick(ListView l, View v, int position, long id) {
+
+        //!!!!! listview 有header, position 需要-1
+
+
+//        Log.d("FragmentList", "Item clicked: " + id);
+//
+//        String title = (String) getData(jsonobj).get(position - 1).get("title");
+
+        position = position - 1;
+        if (position < 0) {
+            return;
+        }
+
+        setSelectedPosition(position);
+
+        String cargo_criterion = (String) searchresult.getData().get(position).get("hbol");
+        String serial_no = (String) searchresult.getData().get(position).get("serial_no");
+        if(TextUtils.isEmpty(serial_no))
+            serial_no = "dumb";
+
+        Intent intent = new Intent();
+        intent.setClass(getContext(), NewDetailActivity.class);
+
+        intent.putExtra("action0", "Tracking");
+        intent.putExtra("function_name", "Cargo Tracking");
+
+        intent.putExtra("cargo_criterion", cargo_criterion);
+        intent.putExtra("actions_count", 1);
+        intent.putExtra("_id", serial_no);
+
+        intent.putExtra("criterion_type", 0);
+        String h_field = "h_bol";
+
+        dbUtil.savehistory(h_field, cargo_criterion);
+
+        startActivity(intent);
+
+    }
+
+    private void setSelectedPosition(int position) {
+
+        if (mSelectedIndex >= 0) {
+
+            View cell = getCellForPosition(mSelectedIndex);
+            if (cell != null) {
+
+                View contentView = cell.findViewById(R.id.cell_content_view);
+                if (contentView != null) {
+                    contentView.setBackground(getResources().getDrawable(R.drawable.list_corner_round_bg));
+                }
+
+//                TrackingImageView iv_status = (TrackingImageView) cell.findViewById(R.id.iv_status);
+//                iv_status.setSelected(false);
+            }
+
+        }
+
+        mSelectedIndex = position;
+        View cell = getCellForPosition(mSelectedIndex);
+        if (cell != null) {
+            View contentView = cell.findViewById(R.id.cell_content_view);
+            if (contentView != null) {
+                contentView.setBackground(getResources().getDrawable(R.drawable.list_corner_round_selected_bg));
+            }
+
+//            TrackingImageView iv_status = (TrackingImageView) cell.findViewById(R.id.iv_status);
+//            iv_status.setSelected(true);
+        }
+
+    }
+
+}

+ 230 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/mainframe/HomeFragment.java

@@ -0,0 +1,230 @@
+package com.usai.apex.mainframe;
+
+
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.app.FragmentTransaction;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.usai.apex.ApexTrackingApplication;
+import com.usai.apex.R;
+import com.usai.apex.SegmentView;
+
+//import android.app.FragmentTransaction;
+
+/**
+ * A simple {@link Fragment} subclass.
+ */
+public class HomeFragment extends Fragment implements KPIFragment.KPIPagerScrollListener{
+
+    private SegmentView mSegmentView;
+//    boolean bdirty = false;
+    private  Fragment activeFragment;
+
+//    private
+    private KPIFragment kpiFragment;
+    private RecentFragment recentFragment;
+    public HomeFragment() {
+
+        // Required empty public constructor
+    }
+    public void checkDirty()
+    {
+//        if(bdirty)
+//            requestData();
+
+        if(ApexTrackingApplication.get_instance().recentactive)
+        {
+            recentFragment.checkDirty();
+        }
+        else
+        {
+            kpiFragment.checkDirty();
+        }
+    }
+    private int mode = 0;
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                             Bundle savedInstanceState) {
+        // Inflate the layout for this fragment
+        View v= inflater.inflate(R.layout.fragment_home, container, false);
+
+
+
+
+        if(kpiFragment==null) {
+            kpiFragment = new KPIFragment();
+
+//                    .add(R.id.container, kpiFragment).hide(kpiFragment).commit();
+        }
+
+        if(recentFragment==null) {
+            recentFragment = new RecentFragment();
+//            getChildFragmentManager().beginTransaction()
+//                    .add(R.id.container, recentFragment).commit();
+        }
+
+        showFragment(mode);
+
+//        if(mode==0)
+//            ft.replace(R.id.container,kpiFragment);
+//        else
+//            ft.replace(R.id.container,kpiFragment);
+//
+//        if(mode==0)
+//        {
+//
+//            getChildFragmentManager().beginTransaction().show(getChildFragmentManager().getFragments().get(1)).hide(getChildFragmentManager().getFragments().get(0)).commit();
+//
+////            getChildFragmentManager().beginTransaction().show(recentFragment).hide(kpiFragment).commit();
+//        }
+//        else if(mode==1)
+//        {
+//            getChildFragmentManager().beginTransaction().show(getChildFragmentManager().getFragments().get(0)).hide(getChildFragmentManager().getFragments().get(1)).commit();
+//
+////            getChildFragmentManager().beginTransaction().show(kpiFragment).hide(recentFragment).commit();
+//        }
+
+
+        mSegmentView = v.findViewById(R.id.segmentview);
+
+        mSegmentView.setSegmentText("Recent",0);
+        mSegmentView.setSegmentText("KPI",1);
+
+                mSegmentView.setOnSegmentViewClickListener(new SegmentView.onSegmentViewClickListener() {
+            @Override
+            public void onSegmentViewClick(View view, int postion) {
+                switch (postion) {
+                    case 0:
+
+                        mode = 0;
+                        ((RootActivity)getActivity()).getSupportActionBar().setDisplayShowTitleEnabled(false);
+
+
+//                        ((Activity)getActivity()).setTitle(null);
+//                        getChildFragmentManager().beginTransaction().show(recentFragment).hide(kpiFragment).commit();
+
+//                        getChildFragmentManager().beginTransaction().show(getChildFragmentManager().getFragments().get(1)).hide(getChildFragmentManager().getFragments().get(0)).commit();
+
+
+
+                        break;
+                    case 1:
+
+                        mode = 1;
+                        ((RootActivity)getActivity()).getSupportActionBar().setDisplayShowTitleEnabled(true);
+
+//                        ((Activity)getActivity()).setTitle(null);
+
+
+//                        getChildFragmentManager().beginTransaction().show(getChildFragmentManager().getFragments().get(0)).hide(getChildFragmentManager().getFragments().get(1)).commit();
+
+//                        getChildFragmentManager().beginTransaction().show(kpiFragment).hide(recentFragment).commit();
+
+                        break;
+                    default:
+                        break;
+                }
+                showFragment(mode);
+            }
+        });
+        return v;
+    }
+
+
+    void showFragment(int mode)
+    {
+
+        if(mode==0)
+            ApexTrackingApplication.getInstance().recentactive = true;
+        else
+            ApexTrackingApplication.getInstance().recentactive = false;
+        FragmentManager fm=getChildFragmentManager();
+        FragmentTransaction ft= fm .beginTransaction();
+        if(activeFragment!=null)
+            ft.hide(activeFragment);
+        Fragment fragment = null;
+        String tag = "";
+        if(mode==0) {
+            tag = "recent";
+            fragment = fm.findFragmentByTag(tag);
+            if(fragment==null)
+                fragment = recentFragment;
+            else
+                recentFragment = (RecentFragment) fragment;
+
+        }
+        else
+        {
+            tag = "kpi";
+            fragment = fm.findFragmentByTag(tag);
+            if(fragment==null)
+                fragment = kpiFragment;
+            else
+                kpiFragment = (KPIFragment) fragment;
+
+            kpiFragment.setKPIScrollListener(this);
+        }
+        activeFragment = fragment;
+
+        Log.d("Home Switch Mode", "UserHint: " + getUserVisibleHint() + " isHidden: " + isHidden());
+        if (activeFragment instanceof KPIFragment) {
+            kpiFragment.showTitle(getActivity(),true);
+        } else {
+            kpiFragment.showTitle(getActivity(),false);
+        }
+
+        if (!fragment.isAdded()) {
+            ft.add(R.id.container, fragment, tag);
+        } else {
+
+            ft.show(fragment);
+        }
+        ft.commit();
+
+
+        if(ApexTrackingApplication.get_instance().recentactive)
+        {
+            recentFragment.checkDirty();
+        }
+        else
+        {
+            kpiFragment.checkDirty();
+        }
+    }
+
+
+    @Override
+    public void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+
+        outState.putInt("mode",mode);
+
+    }
+
+    @Override
+    public void onViewStateRestored(@Nullable Bundle savedInstanceState) {
+        super.onViewStateRestored(savedInstanceState);
+
+            if(savedInstanceState!=null) {
+                mode = savedInstanceState.getInt("mode");
+                mSegmentView.setSelect(mode);
+            }
+    }
+
+    @Override
+    public void KPIPagerDidScrollToPage(int position) {
+        Log.d("Home Switch Mode", " Scroll UserHint: "  + getUserVisibleHint() + " isHidden: " + isHidden());
+        if (activeFragment instanceof KPIFragment) {
+            kpiFragment.showTitle(getActivity(),true);
+        } else {
+            kpiFragment.showTitle(getActivity(),false);
+        }
+    }
+}

+ 749 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/mainframe/KPIFragment.java

@@ -0,0 +1,749 @@
+package com.usai.apex.mainframe;
+
+
+import android.app.Activity;
+import android.app.ProgressDialog;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.graphics.Color;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.support.annotation.Nullable;
+import android.support.v4.app.Fragment;
+import android.support.v4.content.LocalBroadcastManager;
+import android.support.v4.view.PagerAdapter;
+import android.support.v4.view.ViewPager;
+import android.support.v4.widget.SwipeRefreshLayout;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ProgressBar;
+
+import com.usai.apex.ApexTrackingApplication;
+import com.usai.apex.KPI.KPICell;
+import com.usai.apex.KPI.KPIViewPager;
+import com.usai.apex.KPI.PieChartView;
+import com.usai.apex.R;
+import com.usai.apex.Result.AMResultActivity;
+import com.usai.apex.ResultActivity;
+import com.usai.util.Network;
+
+import org.json.JSONArray;
+import org.json.JSONObject;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+
+/**
+ * A simple {@link Fragment} subclass.
+ */
+public class KPIFragment extends Fragment implements KPICell.KPIListener {
+
+    boolean bdirty = false;
+
+
+    protected boolean isActive()
+    {
+        return ApexTrackingApplication.getInstance().homeactive&& !ApexTrackingApplication.get_instance().recentactive;
+    }
+//    private static final long serialVersionUID = 2873400198824958986L;
+public void checkDirty()
+{
+
+    if(bdirty) {
+        loadKPIData();
+
+    }
+}
+    public static class KPIModel implements Serializable,Parcelable {
+
+        private static final long serialVersionUID = -6280156291692980527L;
+        public ArrayList<PieChartView.ChartItem> items;
+        public String name;
+        public String module_name;
+        public int total;
+
+
+        public KPIModel() {
+
+        }
+
+        protected KPIModel(Parcel in) {
+            name = in.readString();
+            module_name = in.readString();
+            total = in.readInt();
+        }
+
+        public static final Creator<KPIModel> CREATOR = new Creator<KPIModel>() {
+            @Override
+            public KPIModel createFromParcel(Parcel in) {
+                return new KPIModel(in);
+            }
+
+            @Override
+            public KPIModel[] newArray(int size) {
+                return new KPIModel[size];
+            }
+        };
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            dest.writeString(name);
+            dest.writeString(module_name);
+            dest.writeInt(total);
+        }
+    }
+
+    private static class Month implements Serializable {
+
+        private static final long serialVersionUID = -1567922292260033377L;
+        String shipVal;
+        int shipColor = Color.WHITE;
+
+        void setShipColor(String color) {
+            if (color == null) {
+                return;
+            }
+            shipColor = Color.parseColor(color.replace("0x","#"));
+        }
+
+        String containerVal;
+        int containerColor = Color.WHITE;
+
+        void setContainerColor(String color) {
+            if (color == null) {
+                return;
+            }
+            containerColor = Color.parseColor(color.replace("0x","#"));
+        }
+
+        String teuVal;
+        int teuColor = Color.WHITE;
+
+        void setTeuColor(String color) {
+            if (color == null) {
+                return;
+            }
+            teuColor = Color.parseColor(color.replace("0x","#"));
+        }
+    }
+
+    public interface KPIPagerScrollListener {
+        /*
+         * 解决Home.KPI --> My --> History显示KPI Title
+         * isHidden()、getUserHint()取得的值不正确
+         * */
+        void KPIPagerDidScrollToPage(int position);
+    }
+    private KPIPagerScrollListener mScrollListener;
+
+    public void setKPIScrollListener(KPIPagerScrollListener mScrollListener) {
+        this.mScrollListener = mScrollListener;
+    }
+
+    Context mContext;
+    KPIViewPager mKPIPager;
+    KPIPagerAdapter mAdapter;
+    JSONObject mData;
+    ArrayList<KPIModel> mKPIArr = new ArrayList<>();
+    Month mMonthModel;
+    SwipeRefreshLayout mSwipeRefresh;
+    ProgressBar mLoadIndicator;
+    private KPIFragment self;
+
+    private int currentKPI = 1, totalKPI = 0;
+
+    private KPIBroadcastReceiver mReceiver;
+
+    public KPIFragment() {
+        // Required empty public constructor
+    }
+
+    @Override
+    public void onDestroyView() {
+
+        LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(getContext());
+        localBroadcastManager.unregisterReceiver(mReceiver);
+
+        super.onDestroyView();
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                             Bundle savedInstanceState) {
+        // Inflate the layout for this fragment
+        View root = inflater.inflate(R.layout.fragment_kpi, container, false);
+
+        mContext = getContext();
+        self = this;
+
+        if (savedInstanceState != null) {
+            bdirty = savedInstanceState.getBoolean("dirty");
+            currentKPI = savedInstanceState.getInt("currentKPI");
+            mKPIArr = (ArrayList<KPIModel>) savedInstanceState.getSerializable("KPIData");
+            mMonthModel = (Month) savedInstanceState.getSerializable("KPIMonth");
+            if (mKPIArr != null) {
+                totalKPI = mKPIArr.size();
+            }
+        }
+
+        LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(getContext());
+        IntentFilter intentFilter = new IntentFilter("com.apex.broadcast.person_mode");
+        mReceiver = new KPIBroadcastReceiver();
+        localBroadcastManager.registerReceiver(mReceiver,intentFilter);
+
+        mLoadIndicator = root.findViewById(R.id.loadKPI_indicator);
+        mSwipeRefresh = root.findViewById(R.id.kpi_swipe_refresh);
+        mSwipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
+            @Override
+            public void onRefresh() {
+                loadKPIData();
+            }
+        });
+
+        mKPIPager = mSwipeRefresh.findViewById(R.id.kpi_pager);
+//        mKPIPager = root.findViewById(R.id.kpi_pager);
+        mAdapter = new KPIPagerAdapter();
+        mKPIPager.setAdapter(mAdapter);
+        mKPIPager.setScrollEnable(true);
+        mKPIPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
+            @Override
+            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
+                Log.d("KPI", "onPageScrolled: " + position);
+            }
+
+            @Override
+            public void onPageSelected(int position) {
+
+                currentKPI = position;
+                int display_index = currentKPI;
+                Log.d("KPI", "onPageSelected: " + position);
+                if (position == 0) {
+                    display_index = totalKPI;
+//                    mKPIPager.setCurrentItem(currentKPI,false);
+                } else if (position == totalKPI + 1) {
+                    display_index = 1;
+//                    mKPIPager.setCurrentItem(currentKPI,false);
+                } else
+                    {
+                        display_index = position;
+                }
+                if (mScrollListener != null) {
+                    mScrollListener.KPIPagerDidScrollToPage(display_index);
+                }
+
+            }
+
+            @Override
+            public void onPageScrollStateChanged(int state) {
+                Log.d("KPI", "onPageScrollStateChanged: " + state);
+
+                if (state == ViewPager.SCROLL_STATE_IDLE) {
+                    if (currentKPI == mKPIPager.getAdapter().getCount() - 1) {
+                        mKPIPager.setCurrentItem(1, false);
+                    }
+                    else if (currentKPI == 0) {
+                        mKPIPager.setCurrentItem(mKPIPager.getAdapter().getCount() - 2, false);
+                    }
+                }
+                }
+        });
+
+        mSwipeRefresh.setEnabled(true);
+
+//        if (savedInstanceState != null) {
+//            String kpiString = savedInstanceState.getString("KPIData");
+//            if (kpiString != null) {
+//                try {
+//                    mData = new JSONObject(kpiString);
+//                    prepareData();
+//                } catch (JSONException e) {
+//                    e.printStackTrace();
+//                }
+//            }
+//        }
+//
+
+        if (mKPIArr != null && mKPIArr.size() > 0) {
+            int display_index = currentKPI;
+            mKPIPager.setCurrentItem(display_index,false);
+        }
+        if (mKPIArr == null || mKPIArr.size() == 0) {
+            loadKPIData();
+        }
+
+        return root;
+    }
+
+//    @Override
+//    public void setUserVisibleHint(boolean isVisibleToUser) {
+//        super.setUserVisibleHint(isVisibleToUser);
+//        showTitle(isVisibleToUser);
+//    }
+//
+//    @Override
+//    public void onHiddenChanged(boolean hidden) {
+//        super.onHiddenChanged(hidden);
+//        showTitle(!hidden);
+//    }
+
+    public void showTitle(Context ctx,boolean show) {
+        if (ctx == null) {
+            return;
+        }
+        android.support.v7.app.ActionBar bar = ((RootActivity)ctx).getSupportActionBar();
+        if (bar == null) {
+            return;
+        }
+        if (show) {
+//            bar.setDisplayShowTitleEnabled(true);
+            if (totalKPI > 0) {
+                int display_index = currentKPI % mKPIArr.size()==0?mKPIArr.size():currentKPI % mKPIArr.size();
+                ((Activity)ctx).setTitle(display_index + "/" + totalKPI);
+            } else {
+                ((Activity)ctx).setTitle(null);
+            }
+        } else {
+//            bar.setDisplayShowTitleEnabled(false);
+            ((Activity)ctx).setTitle(null);
+        }
+    }
+
+    @Override
+    public void onAttach(Context context) {
+        super.onAttach(context);
+
+    }
+
+    @Override
+    public void onDetach() {
+        super.onDetach();
+
+        if (mTask != null) {
+            mTask.cancel(false);
+        }
+        dismissProgressDialog();
+    }
+
+    @Override
+    public void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+
+        if (mKPIArr != null) {
+            outState.putSerializable("KPIData",mKPIArr);
+        }
+        if (mMonthModel != null) {
+            outState.putSerializable("KPIMonth",mMonthModel);
+        }
+        outState.putInt("currentKPI",currentKPI);
+        outState.putBoolean("dirty",bdirty);
+
+
+//        mKPIArr.clear();
+//        mAdapter.notifyDataSetChanged();
+    }
+
+    @Override
+    public void onViewStateRestored(@Nullable Bundle savedInstanceState) {
+        super.onViewStateRestored(savedInstanceState);
+        if (savedInstanceState != null) {
+
+            bdirty = savedInstanceState.getBoolean("dirty");
+//            currentKPI = savedInstanceState.getInt("currentKPI");
+//            mKPIArr = (ArrayList<KPIModel>) savedInstanceState.getSerializable("KPIData");
+//            mMonthModel = (Month) savedInstanceState.getSerializable("KPIMonth");
+//        }
+//
+//        if (mKPIArr == null || mKPIArr.size() == 0) {
+//            loadKPIData();
+        }
+    }
+
+    @Override
+    public void setUserVisibleHint(boolean isVisibleToUser) {
+        super.setUserVisibleHint(isVisibleToUser);
+    }
+
+    @Override
+    public void onHiddenChanged(boolean hidden) {
+        super.onHiddenChanged(hidden);
+    }
+
+
+    private ProgressDialog mProgressDialog;
+
+    public void showProgressDialog() {
+
+        if (mProgressDialog == null) {
+            if (getContext() == null) {
+                return;
+            }
+            mProgressDialog = new ProgressDialog(getContext());
+            mProgressDialog.setCancelable(false);
+            mProgressDialog.setMessage("Loading...");
+        }
+        mProgressDialog.show();
+    }
+
+    public void dismissProgressDialog() {
+        if (mProgressDialog != null && mProgressDialog.isShowing()) {
+            mProgressDialog.dismiss();
+        }
+    }
+
+    private class KPITask extends AsyncTask<Void, Void, JSONObject> {
+
+        @Override
+        protected void onPreExecute() {
+            super.onPreExecute();
+
+            loading = true;
+            showProgressDialog();
+        }
+
+        @Override
+        protected JSONObject doInBackground(Void... voids) {
+
+            mData = Network.request_KPI();
+            return mData;
+        }
+
+        @Override
+        protected void onPostExecute(JSONObject jsonObject) {
+            super.onPostExecute(jsonObject);
+
+            if (mLoadIndicator.getVisibility() == View.VISIBLE) {
+                mLoadIndicator.setVisibility(View.GONE);
+            }
+            if (mSwipeRefresh.isRefreshing()) {
+                mSwipeRefresh.setRefreshing(false);
+            }
+            dismissProgressDialog();
+            prepareData();
+
+            loading = false;
+            bdirty = false;
+            mTask = null;
+        }
+
+        @Override
+        protected void onCancelled() {
+            super.onCancelled();
+
+            loading = false;
+            dismissProgressDialog();
+            mTask = null;
+        }
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+
+    }
+
+    private KPITask mTask;
+
+    private boolean loading = false;
+    private void loadKPIData() {
+
+        if (loading) {
+            return;
+        }
+
+
+        mTask = new KPITask();
+        mTask.execute();
+    }
+
+    private void prepareData() {
+
+        if (mData == null) {
+            return;
+        }
+
+        JSONArray monthArray = mData.optJSONArray("month");
+        if (monthArray != null) {
+
+            Month monthModel = new Month();
+            for (int i = 0; i < monthArray.length(); i++) {
+                JSONObject month = monthArray.optJSONObject(i);
+                if (month != null) {
+                    String key = month.optString("key");
+                    String val = month.optString("val");
+                    String color = month.optString("color");
+                    if (key != null) {
+                        if (key.equals("Shipment")) {
+
+                            monthModel.shipVal = val;
+                            monthModel.setShipColor(color);
+
+                        } else if (key.equals("Container")) {
+
+                            monthModel.containerVal = val;
+                            monthModel.setContainerColor(color);
+
+                        } else if (key.equals("TEU")) {
+
+                            monthModel.teuVal = val;
+                            monthModel.setTeuColor(color);
+                        }
+                    }
+                }
+            }
+            mMonthModel = monthModel;
+
+        }
+
+        JSONArray kpiArray = mData.optJSONArray("KPI");
+
+        if (kpiArray != null) {
+            if (mKPIArr == null) {
+                mKPIArr = new ArrayList<>();
+            }
+            mKPIArr.clear();
+//            currentKPI = 1;
+            for (int i = 0; i < kpiArray.length(); i++) {
+
+                JSONObject kpi = kpiArray.optJSONObject(i);
+                if (kpi != null) {
+
+                    KPIModel model = new KPIModel();
+
+                    ArrayList<PieChartView.ChartItem> items = new ArrayList<>();
+
+                    JSONArray jsonArr = kpi.optJSONArray("arr_val");
+                    if (jsonArr != null) {
+
+                        for (int j = 0; j < jsonArr.length(); j++) {
+                            JSONObject item = jsonArr.optJSONObject(j);
+                            if (item != null) {
+                                PieChartView.ChartItem itm = new PieChartView.ChartItem();
+                                itm.value = Integer.valueOf(item.optString("A_val"));
+                                itm.title = item.optString("full_title");
+                                String color_str = item.optString("color");
+                                if (color_str != null) {
+                                    color_str = color_str.replace("0x","#");
+                                    itm.color = Color.parseColor(color_str);
+                                }
+                                itm.display = item.optBoolean("display");
+                                itm.shortTitle = item.optString("title");
+
+                                items.add(itm);
+                            }
+                        }
+
+                    }
+                    model.name = kpi.optString("name");
+                    model.total = kpi.optInt("total");
+                    model.module_name = kpi.optString("module_name");
+                    model.items = items;
+
+                    mKPIArr.add(model);
+                }
+
+            }
+            totalKPI = mKPIArr.size();
+        }
+        mAdapter.notifyDataSetChanged();
+        if (mKPIArr != null && mKPIArr.size() > 0) {
+            int display_index = currentKPI;
+            mKPIPager.setCurrentItem(display_index,false);
+        }
+    }
+
+    @Override
+    public void KPIPieChartClickedItem(KPICell cell, PieChartView.ChartItem item) {
+
+        String selection = null;
+        if (item != null) {
+            selection = String.format("%s %d %.2f%%",item.title, (int)item.value, item.getPercentage() * 100);
+        }
+        cell.setSelection(selection);
+    }
+
+    @Override
+    public void KPIPieChartClickedTitle(KPICell cell) {
+        Log.d("KPICell", "pieChartCenterClicked: ");
+    }
+
+//    @Override
+//    public void KPIPreviousButtonClicked(KPICell cell) {
+//        int index = mKPIPager.getCurrentItem();
+//        if (index == 0) {
+//            mKPIPager.setCurrentItem(mKPIArr.size() - 1,false);
+//        } else {
+//            mKPIPager.setCurrentItem(index - 1,false);
+//        }
+//    }
+//
+//    @Override
+//    public void KPINextButtonClicked(KPICell cell) {
+//        int index = mKPIPager.getCurrentItem();
+//        if (index == mKPIArr.size() - 1) {
+//            mKPIPager.setCurrentItem(0,false);
+//        } else {
+//            mKPIPager.setCurrentItem(index + 1,false);
+//        }
+//    }
+
+
+    @Override
+    public void KPIPieChartDidBeginClicked() {
+        mSwipeRefresh.setEnabled(false);
+        mKPIPager.setScrollEnable(false);
+    }
+
+    @Override
+    public void KPIPieChartDidEndClicked() {
+        mSwipeRefresh.setEnabled(true);
+        mKPIPager.setScrollEnable(true);
+    }
+
+    @Override
+    public void KPIListTouched(boolean touch) {
+        mSwipeRefresh.setEnabled(!touch);
+    }
+
+    @Override
+    public void KPICellDidDoubleClickItem(KPICell cell, int index, KPIModel model) {
+
+        if (model == null) {
+            return;
+        }
+
+        PieChartView.ChartItem legend = model.items.get(index);
+        String kpi_name = model.name;
+        String sector = legend.title;
+        String module_name = model.module_name;
+        if (kpi_name == null) {
+            kpi_name = "";
+        }
+        if (sector == null) {
+            sector = "";
+        }
+        if (module_name == null) {
+            module_name = "";
+        }
+
+        Bundle params = new Bundle();
+        params.putBoolean("is_kpi",true);
+        params.putString("name",kpi_name);
+        params.putString("sector",sector);
+        params.putString("module_name",module_name);
+
+        Intent intent = new Intent(getContext(), AMResultActivity.class);
+        intent.putExtra("query_params",params);
+        startActivity(intent);
+    }
+
+    public class KPIPagerAdapter extends PagerAdapter {
+
+        ArrayList<KPICell> mReusePool = new ArrayList<>();
+
+        @Override
+        public int getCount() {
+            if (mKPIArr == null || mKPIArr.size() == 0) {
+                return 0;
+            }
+            return mKPIArr.size() + 2;
+        }
+
+        @Override
+        public boolean isViewFromObject(View view, Object object) {
+            return view == object;
+        }
+
+        @Override
+        public int getItemPosition(Object object) {
+//            return super.getItemPosition(object);
+            return POSITION_NONE;
+        }
+
+        @Override
+        public void destroyItem(ViewGroup container, int position, Object object) {
+
+            KPICell cell = (KPICell)object;
+            cell.setListener(null);
+            container.removeView(cell);
+            mReusePool.add(cell);
+        }
+
+        @Override
+        public Object instantiateItem(ViewGroup container, int position) {
+
+            KPICell cell = null;
+            if (mReusePool.isEmpty()) {
+                cell = (KPICell) LayoutInflater.from(mContext).inflate(R.layout.kpi_cell,null);
+                cell.init();
+            } else {
+                cell = mReusePool.get(0);
+                mReusePool.remove(cell);
+            }
+
+
+
+            int index = position;
+            if (position == 0) {
+                index = mKPIArr.size() - 1;
+            } else if (position == mKPIArr.size() + 1) {
+                index = 0;
+            } else {
+                index = position - 1;
+            }
+
+            KPIModel model = mKPIArr.get(index);
+            Log.d("KPI Cell", "dequeue Cell " + index);
+//            cell.setChartItems(model.items);
+//            cell.setNameAndCount(model.name,model.total);
+//            cell.randomColor();
+            cell.setKPIModel(model);
+
+            if (mMonthModel != null) {
+                cell.setMonthShipment(mMonthModel.shipVal,mMonthModel.shipColor);
+                cell.setMonthContainer(mMonthModel.containerVal,mMonthModel.containerColor);
+                cell.setMonthTeu(mMonthModel.teuVal,mMonthModel.teuColor);
+            }
+
+            container.addView(cell);
+            cell.setListener(self);
+
+            return cell;
+        }
+    }
+
+
+    class KPIBroadcastReceiver extends BroadcastReceiver {
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+
+            if (intent.getAction().equals("com.apex.broadcast.person_mode")) {
+
+//                loadKPIData();
+                bdirty = true;
+
+                if(isActive())
+                {
+                    loadKPIData();
+                }
+            }
+//            else if (intent.getAction().equals("com.usai.apex.push.cancel")) {
+//                mData = null;
+//                mKPIArr.clear();
+//                mAdapter.notifyDataSetChanged();
+//            }
+        }
+    }
+
+}

+ 475 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/mainframe/LoginFragment.java

@@ -0,0 +1,475 @@
+package com.usai.apex.mainframe;
+
+//import android.app.Fragment;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.AsyncTask;
+import android.os.Build;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.support.v4.content.LocalBroadcastManager;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.CheckBox;
+import android.widget.EditText;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.usai.apex.ApexTrackingApplication;
+import com.usai.apex.R;
+import com.usai.apex.RetrievePasswordActivity;
+import com.usai.util.AES;
+import com.usai.util.Network;
+
+//import android.app.Fragment;
+//import android.content.SharedPreferences;
+//import android.widget.TextView;
+
+/**
+ * Activity which displays a login screen to the user, offering registration as
+ * well.
+ */
+public class LoginFragment extends Fragment/* implements OnClickListener */
+{
+
+
+	public interface LoginCallBack{
+		public abstract void onLogin();
+//		public abstract void onLogout();
+	}
+	private LoginCallBack mCallBack;
+	private String m_sUser;
+	private String m_sPassword;
+	private EditText m_etName;
+	private EditText m_etPassword;
+	private UserLoginTask mAuthTask = null;
+	private TextView mLoginStatusMessageView;
+	private View mLoginFormView;
+	private View mLoginStatusView;
+
+	private CheckBox m_cbSave;
+
+	// SQLiteDatabase m_db;
+	public void setCallBack(LoginCallBack callBack) {
+		this.mCallBack = callBack;
+	}
+//
+//	@Override
+//	public void onSaveInstanceState(Bundle outState) {
+//		super.onSaveInstanceState(outState);
+//		outState.putSerializable("hashmap", mCallBack);
+//	}
+
+	@Override
+	public View onCreateView(LayoutInflater inflater, ViewGroup container,
+			Bundle savedInstanceState) {
+		View view = inflater.inflate(R.layout.fragment_login, null);
+		TextView tv_ver = (TextView) view.findViewById(R.id.tv_ver);
+		try {
+			tv_ver.setText(getText(R.string.str_ver)+"2.20." +ApexTrackingApplication.get_instance().getPackageManager().getPackageInfo(
+						"com.usai.apex", 0).versionName);
+		} catch (NameNotFoundException e1) {
+			// TODO Auto-generated catch block
+			e1.printStackTrace();
+		}
+		// Button btn = (Button) view.findViewById(R.id.sign_in_button);
+		// btn.setOnClickListener(this);
+
+		// m_cbSave.setOnCheckedChangeListener(new OnCheckedChangeListener()
+		// {
+		//
+		// @Override
+		// public void onCheckedChanged(CompoundButton buttonView,
+		// boolean isChecked)
+		// {
+		// if (isChecked)
+		// {
+		// String user,password;
+		// SharedPreferences RunOnce = ApexTrackingApplication
+		// .get_instance().getSharedPreferences("Apex", 0);
+		// SharedPreferences.Editor editor = RunOnce.edit();
+		// editor.putString("user", user);
+		// editor.putString("password", user);
+		// }
+		// String vername;
+		// try
+		// {
+		// vername = ApexTrackingApplication.get_instance()
+		// .getPackageManager()
+		// .getPackageInfo("com.usai.apex", 0).versionName;
+		// boolean bFirstRun = RunOnce.getBoolean("FirstRun" + vername
+		// + "_result", true);
+		// if (bFirstRun)
+		// {
+		// SharedPreferences.Editor editor = RunOnce.edit();
+		// editor.putBoolean("FirstRun" + vername + "_result",
+		// false);
+		// // Don't forget to commit your edits!!!
+		// editor.commit();
+		// Intent intent = new Intent();
+		// intent.setClass(this, HelpActivity.class);
+		// intent.putExtra("caller", "result");
+		// startActivity(intent);
+		//
+		// }
+		// }
+		// catch (NameNotFoundException e)
+		// {
+		// // TODO Auto-generated catch block
+		// e.printStackTrace();
+		// }
+		//
+		// }
+		//
+		// });
+		// Set up the login form.
+		// mUser = getIntent().getStringExtra(EXTRA_EMAIL);
+		m_etName = (EditText) view.findViewById(R.id.user);
+		// mUserView.setText(mUser);
+
+		m_etPassword = (EditText) view.findViewById(R.id.password);
+
+		m_cbSave = (CheckBox) view.findViewById(R.id.cb_save);
+		SharedPreferences pref = ApexTrackingApplication.get_instance()
+				.getSharedPreferences("Apex", 0);
+		String u = pref.getString("user", null);
+		String p = pref.getString("password", null);
+		if (u != null && p != null) {
+			try {
+				m_etName.setText(AES.decrypt("apexu", u));
+				m_etPassword.setText(AES.decrypt("apexp", p));
+				m_cbSave.setChecked(true);
+			} catch (Exception e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+
+		}
+		m_etPassword
+				.setOnEditorActionListener(new TextView.OnEditorActionListener() {
+					@Override
+					public boolean onEditorAction(TextView textView, int id,
+							KeyEvent keyEvent) {
+						if (id == R.id.login
+								|| id == EditorInfo.IME_ACTION_DONE) {
+							InputMethodManager inputMethodManager = (InputMethodManager) getActivity()
+									.getApplicationContext().getSystemService(
+											Context.INPUT_METHOD_SERVICE);
+
+							// EditText editText =
+							// (EditText)findViewById(R.id.xxxx);
+							inputMethodManager.hideSoftInputFromWindow(
+									m_etPassword.getWindowToken(), 0); // ����
+							attemptLogin();
+							return true;
+						}
+						return false;
+					}
+				});
+
+		mLoginFormView = view.findViewById(R.id.login_form);
+		mLoginStatusView = view.findViewById(R.id.login_status);
+		mLoginStatusMessageView = (TextView) view
+				.findViewById(R.id.login_status_message);
+
+		view.findViewById(R.id.sign_in_button).setOnClickListener(
+				new View.OnClickListener() {
+					@Override
+					public void onClick(View view) {
+						InputMethodManager inputMethodManager = (InputMethodManager) getActivity()
+								.getApplicationContext().getSystemService(
+										Context.INPUT_METHOD_SERVICE);
+
+						// EditText editText =
+						// (EditText)findViewById(R.id.xxxx);
+						inputMethodManager.hideSoftInputFromWindow(
+								m_etPassword.getWindowToken(), 0);
+						attemptLogin();
+						// showProgress(true);
+					}
+				});
+		
+		view.findViewById(R.id.tv_retrieve_pass).setOnClickListener(
+				new View.OnClickListener() {
+					@Override
+					public void onClick(View view) {
+						Intent intent = new Intent();
+						intent.setClass(getActivity(), RetrievePasswordActivity.class);
+						startActivity(intent);
+						// showProgress(true);
+					}
+				});
+		return view;
+		// return super.onCreateView(inflater, container, savedInstanceState);
+	}
+
+	// /**
+	// * Attempts to sign in or register the account specified by the login
+	// form.
+	// * If there are form errors (invalid email, missing fields, etc.), the
+	// * errors are presented and no actual login attempt is made.
+	// */
+	public void attemptLogin() {
+
+//		if(1==1)
+//		{
+//			if(mCallBack!=null)
+//				mCallBack.onLogin();
+//			return;
+//		}
+		if (mAuthTask != null) {
+			return;
+		}
+
+		// Reset errors.
+		m_etName.setError(null);
+		m_etPassword.setError(null);
+
+		// Store values at the time of the login attempt.
+		m_sUser = m_etName.getText().toString().toLowerCase();
+		m_sPassword = m_etPassword.getText().toString();
+
+		boolean cancel = false;
+		View focusView = null;
+
+		// Check for a valid password.
+		if (TextUtils.isEmpty(m_sPassword)) {
+			m_etPassword.setError(getString(R.string.error_field_required));
+			focusView = m_etPassword;
+			cancel = true;
+		} /*else if (m_sPassword.length() < 4) {
+			m_etPassword.setError(getString(R.string.error_invalid_password));
+			focusView = m_etPassword;
+			cancel = true;
+		}*/
+
+		// Check for a valid user name.
+		if (TextUtils.isEmpty(m_sUser)) {
+			m_etName.setError(getString(R.string.error_field_required));
+			focusView = m_etName;
+			cancel = true;
+		}
+		// else if (!m_sName.contains("@")) {
+		// m_etName.setError(getString(R.string.error_invalid_email));
+		// focusView = m_etName;
+		// cancel = true;
+		// }
+
+		if (cancel) {
+			// There was an error; don't attempt login and focus the first
+			// form field with an error.
+			focusView.requestFocus();
+		} else {
+			// Show a progress spinner, and kick off a background task to
+			// perform the user login attempt.
+			mLoginStatusMessageView.setText(R.string.login_progress_signing_in);
+			showProgress(true);
+			mAuthTask = new UserLoginTask();
+			mAuthTask.execute((Void) null);
+		}
+	}
+
+	//
+	// /**
+	// * Shows the progress UI and hides the login form.
+	// */
+	// @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
+	private void showProgress(final boolean show) {
+		// On Honeycomb MR2 we have the ViewPropertyAnimator APIs, which allow
+		// for very easy animations. If available, use these APIs to fade-in
+		// the progress spinner.
+		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
+			int shortAnimTime = getResources().getInteger(
+					android.R.integer.config_shortAnimTime);
+
+			mLoginStatusView.setVisibility(View.VISIBLE);
+			mLoginStatusView.animate().setDuration(shortAnimTime)
+					.alpha(show ? 1 : 0)
+					.setListener(new AnimatorListenerAdapter() {
+						@Override
+						public void onAnimationEnd(Animator animation) {
+							mLoginStatusView.setVisibility(show ? View.VISIBLE
+									: View.INVISIBLE);
+						}
+					});
+
+			mLoginFormView.setVisibility(View.VISIBLE);
+			mLoginFormView.animate().setDuration(shortAnimTime)
+					.alpha(show ? 0 : 1)
+					.setListener(new AnimatorListenerAdapter() {
+						@Override
+						public void onAnimationEnd(Animator animation) {
+							mLoginFormView.setVisibility(show ? View.INVISIBLE
+									: View.VISIBLE);
+						}
+					});
+		} else {
+			// The ViewPropertyAnimator APIs are not available, so simply show
+			// and hide the relevant UI components.
+			mLoginStatusView
+					.setVisibility(show ? View.VISIBLE : View.INVISIBLE);
+			mLoginFormView.setVisibility(show ? View.INVISIBLE : View.VISIBLE);
+		}
+	}
+
+	//
+	// /**
+	// * Represents an asynchronous login/registration task used to authenticate
+	// * the user.
+	// */
+	public class UserLoginTask extends AsyncTask<Void, Void, Boolean> {
+		// int err_code = ERR_CODE_NONE;
+		int errorcode;
+
+		@Override
+		protected Boolean doInBackground(Void... params) {
+			errorcode = Network.get_Auth(m_sUser, m_sPassword);
+			if (errorcode == Network.RESULT_TRUE)
+				return true;
+			else {
+				return false;
+			}
+
+		}
+
+		@Override
+		protected void onPostExecute(final Boolean success) {
+			Log.d("onPostExecute", "entry");
+			mAuthTask = null;
+			showProgress(false);
+			// if (netconnect == )
+			// {
+			//
+			// }
+
+			if (success) {
+
+				// SharedPreferences.Editor editor = RunOnce.edit();
+				// editor.putBoolean("FirstRun"+globalUtil.getVerName(this),
+				// false);
+				// // Don't forget to commit your edits!!!
+				// editor.commit();
+				SharedPreferences pref = ApexTrackingApplication.get_instance()
+						.getSharedPreferences("Apex", 0);
+				SharedPreferences.Editor editor = pref.edit();
+
+				try {
+					if (/*m_cbSave.isChecked()*/ true) {
+						editor.putString("user",
+								AES.encrypt("apexu", m_sUser.toLowerCase()));
+						editor.putString("password",
+								AES.encrypt("apexp", m_sPassword));
+						editor.putBoolean("autologin", true);
+					} else {
+						editor.putString("user", null);
+						editor.putString("password", null);
+						editor.putBoolean("autologin", false);
+					}
+
+
+				} catch (Exception e) {
+					editor.putString("user", null);
+					editor.putString("password", null);
+					editor.putBoolean("autologin", false);
+					e.printStackTrace();
+				}
+				editor.commit();
+
+				if(mCallBack!=null)
+					mCallBack.onLogin();
+
+
+				{
+
+					Intent intent = new Intent("Login");
+					intent.putExtra("state", true);
+					LocalBroadcastManager.getInstance(getActivity())
+							.sendBroadcast(intent);
+				}
+
+//				Intent intent = new Intent();
+//				intent.setClass(getActivity(), FunctionSelectActivity.class);
+////				intent.putExtra("user", m_sUser);
+////				intent.putExtra("password", m_sPassword);
+//				startActivity(intent);
+//				getActivity().setResult(Activity.RESULT_OK, null);
+//				getActivity().finish();
+			} else {
+				switch (errorcode) {
+				case Network.RESULT_NET_NOTAVAILABLE: {
+					Toast toast = Toast.makeText(getActivity()
+							.getApplicationContext(),
+							getText(R.string.msg_connection_none),
+							Toast.LENGTH_LONG);
+					toast.setGravity(Gravity.CENTER, 0, 0);
+					toast.show();
+					return;
+				}
+				case Network.RESULT_NET_ERROR: {
+					Toast toast = Toast.makeText(getActivity()
+							.getApplicationContext(),
+							getText(R.string.msg_net_error), Toast.LENGTH_LONG);
+					toast.setGravity(Gravity.CENTER, 0, 0);
+					toast.show();
+					return;
+				}
+				case Network.RESULT_VER_LOW:
+				{
+					Toast toast = Toast.makeText(getActivity()
+							.getApplicationContext(),
+							getText(R.string.msg_ver_low), Toast.LENGTH_LONG);
+					toast.setGravity(Gravity.CENTER, 0, 0);
+					toast.show();
+					return;
+				}
+				case Network.RESULT_ERROR:
+				// case Network.RESULT_RESPONSE_NULL:
+				{
+					Toast toast = Toast.makeText(getActivity()
+							.getApplicationContext(),
+							getText(R.string.msg_net_resulterror),
+							Toast.LENGTH_LONG);
+					toast.setGravity(Gravity.CENTER, 0, 0);
+					toast.show();
+					return;
+				}
+
+				case Network.RESULT_FALSE: {
+					m_etPassword
+							.setError(getString(R.string.error_incorrect_password));
+					m_etPassword.requestFocus();
+					return;
+					
+				}
+				default: {
+					Toast toast = Toast.makeText(getActivity()
+							.getApplicationContext(),
+							getText(R.string.msg_net_resulterror) + ":"
+									+ errorcode, Toast.LENGTH_LONG);
+					toast.setGravity(Gravity.CENTER, 0, 0);
+					toast.show();
+					break;
+				}
+				}
+			}
+		}
+
+		@Override
+		protected void onCancelled() {
+			mAuthTask = null;
+			showProgress(false);
+		}
+	}
+}

+ 167 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/mainframe/MyFragment.java

@@ -0,0 +1,167 @@
+package com.usai.apex.mainframe;
+
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.support.v4.content.LocalBroadcastManager;
+import android.util.Log;
+import android.view.View;
+import android.widget.ListView;
+
+import com.usai.apex.ChangePasswordActivity;
+import com.usai.apex.R;
+import com.usai.apex.saved.CheckSavedActivity;
+
+import org.json.JSONObject;
+
+/**
+ * A simple {@link Fragment} subclass.
+ */
+public class MyFragment extends StaticModelistFragment {
+
+    static final int PASSWORD_CHANGED = 1;
+    private static final int	REQUEST_CHANGEPASSWORD_ACTIVITY	= 2;
+
+
+    @Override
+    public void onActivityResult(int requestCode, int resultCode, Intent data)
+    {
+        switch (requestCode)
+        {
+
+//			case REQUEST_LOGINACTIVITY:
+//				if (resultCode == Activity.RESULT_CANCELED)
+//					getActivity().finish();
+//				break;
+            case REQUEST_CHANGEPASSWORD_ACTIVITY:
+                if (resultCode == Activity.RESULT_OK)
+                {
+//					String UNIQUE_STRING = "com.usai.apex.push.cancel";
+//					Intent intent = new Intent(UNIQUE_STRING);
+//					getActivity().sendBroadcast(intent);
+//					Intent i = new Intent();
+//					i.setClass(getActivity(), ApexActivity.class);
+//					startActivityForResult(i, REQUEST_LOGINACTIVITY);
+                    getActivity().setResult(PASSWORD_CHANGED, null);
+                    getActivity().finish();
+                }
+                break;
+            default:
+                break;
+        }
+        super.onActivityResult(requestCode, resultCode, data);
+    }
+
+
+    public interface LogoutCallBack{
+        //        public abstract void onLogin();
+        public abstract void onLogout();
+    }
+    private LogoutCallBack mCallBack;
+    public void setCallBack(LogoutCallBack callBack) {
+        this.mCallBack = callBack;
+    }
+
+    public MyFragment() {
+        // Required empty public constructor
+    }
+    @Override
+    public void onActivityCreated(Bundle savedInstanceState)
+    {
+        super.onActivityCreated(savedInstanceState);
+
+        setupAdapter(R.raw.my);
+
+//        adapter.getView()
+
+        customize_style();
+//        JSONObject jsonobj=loadjson(R.raw.search);
+//        adapter        = new SimpleRoundCornerAdapter(this.getActivity(),
+//                getData(jsonobj), R.layout.static_modelist_cell, new String[] { "title",
+//                "img","detail" }, new int[] { R.id.tv_name, R.id.iv_icon,R.id.tv_detail });
+//        setListAdapter(adapter);
+////        this.getListView().setDivider(R.drawable.);
+//        this.getListView().setDividerHeight(18);
+//        this.getListView().setBackgroundColor(Color.WHITE);
+
+    }
+    @Override
+    public void onListItemClick(ListView l, View v, int position, long id)
+    {
+
+        JSONObject jsonobj=loadjson(R.raw.my);
+        Log.d("FragmentList", "Item clicked: " + id);
+
+        String 	title = (String) getData(jsonobj).get(position-1).get("title");
+
+//        Intent intent = new Intent();
+        if (title.equals("Saved Detail"))
+        {
+            Intent intent = new Intent();
+            intent.setClass(getActivity(), CheckSavedActivity.class);
+            // intent.putExtra("user", ApexTrackingApplication.get_user());
+            // intent.putExtra("password", password);
+            intent.putExtra("function_name", "Saved Detail");
+//            intent.putExtra("title", "Booking Search");
+            startActivity(intent);
+        }
+        else if (title.equals("Saved Search"))
+        {
+            Intent intent = new Intent();
+            intent.setClass(getActivity(), CheckSavedActivity.class);
+            // intent.putExtra("user", user);
+            // intent.putExtra("password", password);
+            intent.putExtra("function_name", "Saved Search");
+//            intent.putExtra("title", "B/L info. Search");
+            startActivity(intent);
+        }
+
+        else if(title.equals("Saved Documents"))
+        {
+//            Intent intent = new Intent();
+//            intent.setClass(getActivity(), LocalDocumentActivity.class);
+////			intent.putExtra("module_name", "Announcements");
+//            startActivity(intent);
+
+            Intent intent = new Intent();
+            intent.setClass(getActivity(), CheckSavedActivity.class);
+            intent.putExtra("function_name", "Saved Documents");
+
+            startActivity(intent);
+
+        }
+        else if (title.equals("Change Password"))
+        {
+            Intent intent = new Intent();
+			intent.setClass(getActivity(), ChangePasswordActivity.class);
+
+			startActivityForResult(intent, REQUEST_CHANGEPASSWORD_ACTIVITY);
+			return;
+        }
+        else if (title.equals("Logout"))
+        {
+
+            String UNIQUE_STRING = "com.usai.apex.push.cancel";
+            Intent intent = new Intent(UNIQUE_STRING);
+            // intent.putExtra("key1", "value1");
+            // intent.putExtra("key2", "value2");
+            getActivity().sendBroadcast(intent);
+            if(mCallBack!=null)
+                mCallBack.onLogout();
+
+            {
+
+                Intent bintent = new Intent("Login");
+                bintent.putExtra("state", false);
+                LocalBroadcastManager.getInstance(getActivity())
+                        .sendBroadcast(bintent);
+            }
+
+        }
+
+
+    }
+
+}

+ 934 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/mainframe/NewDetailActivity.java

@@ -0,0 +1,934 @@
+package com.usai.apex.mainframe;
+
+//import android.app.Fragment;
+import android.app.AlertDialog;
+import android.content.BroadcastReceiver;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.database.sqlite.SQLiteDatabase;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.design.widget.BottomNavigationView;
+import android.support.v4.app.Fragment;
+import android.support.v4.view.ViewPager;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AppCompatActivity;
+import android.text.TextUtils;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.EditText;
+import android.widget.TextView;
+
+import com.usai.apex.ApexTrackingApplication;
+import com.usai.apex.DetailFragment;
+import com.usai.apex.R;
+import com.usai.apex.Result.AMResultActivity;
+import com.usai.apex.ViewPagerAdapter;
+import com.usai.util.commonUtil;
+import com.usai.util.dbUtil;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.util.HashMap;
+
+public class NewDetailActivity extends AppCompatActivity {
+
+
+    HashMap<String,String> contentmap = new HashMap<String ,String>();
+    HashMap<Integer, Integer> menu_map		= new HashMap<Integer, Integer>();
+
+    String							function_name;
+    String							_id;
+    String							cargo_criterion;
+    int								criterion_type;
+
+    String email_to = null,email_subject = null,email_content = null;
+    TextView mtitleview;
+
+    private NoScrollViewPager viewPager;
+    private MenuItem menuItem;
+    private BottomNavigationView bottomNavigationView;
+    int selectedMenuItem;
+//    boolean login=false;
+    BroadcastReceiver br;
+
+//    Menu actionbutton;
+
+    public int getTabCount()
+    {
+        return bottomNavigationView.getMenu().size();
+    }
+    private void setCustomActionBar() {
+        ActionBar.LayoutParams lp =new ActionBar.LayoutParams(ActionBar.LayoutParams.MATCH_PARENT, ActionBar.LayoutParams.MATCH_PARENT, Gravity.CENTER);
+        View mActionBarView = LayoutInflater.from(this).inflate(R.layout.actionbar_customtitle, null);
+
+        mtitleview= mActionBarView.findViewById(R.id.title);
+
+
+        function_name = getIntent().getStringExtra("function_name");
+        String title = "";
+        if(function_name.equals("Ocean Booking"))
+            title="Booking Detail";
+        else if(function_name.equals("Ocean B/L info."))
+            title="B/L info. Detail";
+        else if(function_name.equals("Container detail"))
+            title="Container Detail";
+        else if(function_name.equals("Cargo Tracking"))
+            title="Cargo Detail";
+        mtitleview.setText(title);
+        setTitle(title);
+//
+//        mActionBarView.setBackgroundColor(Color.YELLOW);
+//        titleview.setBackgroundColor(Color.BLUE);
+        ActionBar actionBar = getSupportActionBar();
+        actionBar.setCustomView(mActionBarView, lp);
+//		actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
+//		actionBar.setDisplayShowCustomEnabled(true);
+        actionBar.setDisplayHomeAsUpEnabled(true);
+
+
+//        actionBar.setIcon(getNumberDrawable());
+//        actionBar.setDisplayShowHomeEnabled(true);
+        actionBar.setDisplayShowTitleEnabled(true);
+    }
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu)
+    {
+        // Inflate the menu; this adds items to the action bar if it is present.
+
+        if (function_name.equals("Cargo Tracking")) {
+            getMenuInflater().inflate(R.menu.cargo_menu, menu);
+        } else {
+            getMenuInflater().inflate(R.menu.detail, menu);
+        }
+        return true;
+    }
+
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId())
+        {
+            case R.id.action_close:
+
+                finish();
+//				if (SearchResultActivity.instance != null) {
+//					SearchResultActivity.instance.finish();
+//				}
+//				if (SearchListActivity.instance != null) {
+//					SearchListActivity.instance.finish();
+//				}
+                Intent intent = new Intent(this, RootActivity.class);
+
+//                Intent intent = new Intent(context, LoginView.class);
+                intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+
+
+                startActivity(intent);
+                break;
+            case android.R.id.home:
+                finish();
+                break;
+            case R.id.action_addto_favorite:
+//	            LayoutInflater factory = LayoutInflater.from(this);
+//	            final View textEntryView = factory.inflate(R.layout.alert_dialog_text_entry, null);
+                final View edit = new EditText(this);
+                new AlertDialog.Builder(this)
+                        .setIconAttribute(android.R.attr.alertDialogIcon)
+                        .setTitle(R.string.str_createname)
+                        .setView(edit)
+                        .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+                            public void onClick(DialogInterface dialog, int whichButton) {
+                                String name = ((EditText)edit).getText().toString();
+                                if(TextUtils.isEmpty(name))
+                                {
+                                    new android.app.AlertDialog.Builder(NewDetailActivity.this)
+                                            .setTitle("Warning")
+                                            .setMessage("Name can not be empty.")
+
+                                            .setPositiveButton("OK", new DialogInterface.OnClickListener() {
+                                                @Override
+                                                public void onClick(DialogInterface dialog, int which) {
+
+                                                }
+                                            })
+                                            .show();
+                                    return;
+                                }
+
+                                String param = getIntent().toUri(0);
+
+                                SQLiteDatabase db = dbUtil.OpenDB(
+                                        ApexTrackingApplication.get_instance(), null, true);
+                                db.execSQL("insert into favorites(name,params,user,create_time,module_name) values('"
+                                        + name
+                                        + "','"
+                                        + param
+                                        + "','"
+                                        + ApexTrackingApplication.get_user()
+                                        + "',"
+                                        + System.currentTimeMillis()
+                                        + ",'"
+                                        +getIntent().getStringExtra("function_name")+ "')");
+                                dbUtil.CloseDB(db);
+
+                                /* User clicked OK so do some stuff */
+                            }
+                        })
+                        .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
+                            public void onClick(DialogInterface dialog, int whichButton) {
+
+                                /* User clicked cancel so do some stuff */
+                            }
+                        })
+                        .create().show();
+                return true;
+
+            case R.id.action_search_document: {
+                String cargo_str = contentmap.get("Tracking");
+                try {
+                    JSONObject cargo_json = new JSONObject(cargo_str);
+                    String hbol = cargo_json.optString("hbol");
+                    if (hbol != null && hbol.length() > 0) {
+
+                        Bundle parms = new Bundle();
+                        parms.putString("bol",hbol);
+                        parms.putString("module_name","Download Document");
+                        Intent resultIntent = new Intent(this, AMResultActivity.class);
+                        resultIntent.putExtra("query_params",parms);
+                        startActivity(resultIntent);
+
+                    } else {
+                        showAlter("There is no hbol to search");
+                    }
+
+                } catch (JSONException e) {
+                    e.printStackTrace();
+                    showAlter("There is no hbol to search");
+                }
+
+            }
+            break;
+
+            case R.id.action_share_detail: {
+
+                Intent share = new Intent();
+                share.setAction(Intent.ACTION_SEND);
+//				share.putExtra(Intent.EXTRA_STREAM, uri);
+                share.setType("text/plain");
+
+
+
+
+                if (email_content != null) {
+                    share.putExtra(Intent.EXTRA_TEXT, email_content);   //附带的说明信息
+                }
+                if (email_subject != null) {
+                    share.putExtra(Intent.EXTRA_SUBJECT, email_subject);
+                }
+                if (email_to != null) {
+                    share.putExtra(Intent.EXTRA_EMAIL, email_to.split(","));
+                }
+
+//        share.putExtra(Intent.EXTRA_CC, new String[]{"ray.zhang@united-cn.net"});
+//        startActivity(Intent.createChooser(share,getString(R.string.str_sendto)));
+                startActivity(Intent.createChooser(share, "Share"));
+            }
+            break;
+        }
+        return super.onOptionsItemSelected(item);
+    }
+
+    public void showAlter(String msg) {
+        new AlertDialog.Builder(this)
+                .setMessage(msg)
+                .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
+                    @Override
+                    public void onClick(DialogInterface dialogInterface, int i) {
+
+                    }
+                })
+                .show();
+    }
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        outState.putSerializable("menu_map", menu_map);
+        outState.putSerializable("contentmap", contentmap);
+//        outState.putBoolean("login",login);
+    }
+
+//    @Override
+//    protected void onDestroy() {
+//        LocalBroadcastManager localBroadcastManager = LocalBroadcastManager
+//                .getInstance(this);
+//        localBroadcastManager.unregisterReceiver(br);
+//        super.onDestroy();
+//    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+//        if (!isTaskRoot()) {
+//            finish();
+//            return;
+//        }
+//
+//        LocalBroadcastManager localBroadcastManager = LocalBroadcastManager
+//                .getInstance(this);
+//        IntentFilter intentFilter = new IntentFilter();
+//        intentFilter.addAction("Login");
+//        br = new BroadcastReceiver() {
+//
+//            @Override
+//            public void onReceive(Context context, Intent intent) {
+//                boolean blogin = intent.getBooleanExtra("state",true);
+//                login=blogin;
+//
+//                setupViewPager(viewPager);
+//            }
+//
+//        };
+//        localBroadcastManager.registerReceiver(br, intentFilter);
+//
+
+        setContentView(R.layout.activity_new_detail);
+
+        setCustomActionBar();
+
+
+        if (savedInstanceState != null)
+        {
+            menu_map = (HashMap<Integer, Integer>) savedInstanceState
+                    .getSerializable("menu_map");
+//            tabmap = (LinkedHashMap<String, Integer>) savedInstanceState
+//                    .getSerializable("tabmap");
+            contentmap = (HashMap<String, String>) savedInstanceState.getSerializable("contentmap");
+        }
+        else
+        {
+            int count = getIntent().getIntExtra("actions_count", 0);
+            for (int i = 0; i < count; i++)
+            {
+                int vid = commonUtil.generateViewId();
+//                tabmap.put(getIntent().getStringExtra("action" + i), vid);
+            }
+        }
+
+
+        function_name = getIntent().getStringExtra("function_name");
+
+//        if(function_name.equals("Ocean Booking"))
+//            setTitle("Booking Detail");
+//        else if(function_name.equals("Ocean B/L info."))
+//            setTitle("B/L info. Detail");
+//        else if(function_name.equals("Container detail"))
+//            setTitle("Container Detail");
+////		else if(function_name.equals("Cargo Tracking"))
+////			setTitle("Cargo Detail");
+////
+//
+        if (function_name.equals("Cargo Tracking"))
+        {
+            criterion_type = getIntent().getIntExtra("criterion_type", 0);
+            cargo_criterion = getIntent().getStringExtra("cargo_criterion");
+//            setTitle("Cargo Detail");
+        }
+        _id = getIntent().getStringExtra("_id");
+//
+//        if (savedInstanceState != null) {
+//            login = savedInstanceState.getBoolean("login");
+//        }
+
+
+
+
+
+//
+//        Toolbar toolbar = (Toolbar) findViewById(R.id.tool_bar);
+//        setSupportActionBar(toolbar);
+//
+//        getSupportActionBar().setDisplayShowTitleEnabled(false);
+        /*
+        ActionBar actionBar = getSupportActionBar();
+//        actionBar.setLogo(R.drawable.apexlogo);
+        actionBar.setIcon(R.drawable.apexlogo);
+//        actionBar.setIcon(R.drawable.ic_launcher);
+
+//        actionBar.setDisplayUseLogoEnabled(true);
+        actionBar.setDisplayShowHomeEnabled(true);
+        actionBar.setHomeButtonEnabled(true);
+//        actionBar.setHomeAsUpIndicator(R.drawable.ic_launcher);
+//        actionBar.setDisplayHomeAsUpEnabled(true);
+        actionBar.setDisplayShowTitleEnabled(false);
+*/
+
+        viewPager = (NoScrollViewPager) findViewById(R.id.viewpager);
+        bottomNavigationView = (BottomNavigationView) findViewById(R.id.bottom_navigation);
+
+        bottomNavigationView.setItemIconTintList(null);
+//        bottomNavigationView.setItemTextColor();;
+//        bottomNavigationView.getItemTextColor();
+
+//        bottomNavigationView.setlistener
+
+        //默认 >3 的选中效果会影响ViewPager的滑动切换时的效果,故利用反射去掉
+        BottomNavigationViewHelper.disableShiftMode(bottomNavigationView, false);
+        bottomNavigationView.setOnNavigationItemSelectedListener(
+                new BottomNavigationView.OnNavigationItemSelectedListener() {
+                    @Override
+                    public boolean onNavigationItemSelected(@NonNull MenuItem item) {
+//                        actionbutton.getItem(0).setVisible(false);
+//                        getSupportActionBar().setHomeAsUpIndicator(R.drawable.apexlogo);
+//                        getSupportActionBar().setDisplayShowTitleEnabled(false);
+
+//                        if(item.getItemId() == menu_map.get("Tracing").intValue())
+                        {
+
+                            viewPager.setCurrentItem(menu_map.get(item.getItemId()));
+                            return true;
+                        }
+//                        else if(item.getItemId() == menu_map.get("Detail").intValue())
+//                        {
+//
+//                            viewPager.setCurrentItem(1);
+//                            return true;
+//                        }
+//
+//
+//                        switch (item.getItemId()) {
+//                            case menu_map.get("Tracing"):
+//
+//                                viewPager.setCurrentItem(0);
+//                                return true;
+//
+//                            case R.id.item_tool:
+//                                viewPager.setCurrentItem(3);
+//                                return true;
+//
+//                            case R.id.item_otool:
+//                                viewPager.setCurrentItem(1);
+//                                return true;
+//
+//                            case R.id.item_home:
+//                                actionbutton.getItem(0).setVisible(true);
+//                                if (ApexTrackingApplication.get_instance().getPersonMode()) {
+//                                    getSupportActionBar().setHomeAsUpIndicator(R.drawable.apexlogo_p);
+//                                }
+//                                getSupportActionBar().setDisplayShowTitleEnabled(true);
+//                                viewPager.setCurrentItem(0);
+//                                return true;
+//
+//                            case R.id.item_history:
+//                                if (ApexTrackingApplication.get_instance().getPersonMode()) {
+//                                    getSupportActionBar().setHomeAsUpIndicator(R.drawable.apexlogo_p);
+//                                }
+//                                viewPager.setCurrentItem(1);
+//                                return true;
+//
+//                            case R.id.item_search:
+//                                viewPager.setCurrentItem(2);
+//                                return true;
+//
+//                            case R.id.item_my:
+//                                viewPager.setCurrentItem(4);
+//                                return true;
+
+//                        }
+//                        return false;
+                    }
+                });
+
+//
+//        viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
+//            @Override
+//            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
+//
+//            }
+//
+//            @Override
+//            public void onPageSelected(int position) {
+//
+//                MenuItem item= bottomNavigationView.getMenu().getItem(position);
+//
+//                switch (item.getItemId())
+//                {
+//                    case R.id.item_login:
+//                        ApexTrackingApplication.get_instance().historyactive = false;
+//                        ApexTrackingApplication.get_instance().homeactive = false;
+//                        break;
+//
+//                    case R.id.item_tool:
+//                        ApexTrackingApplication.get_instance().historyactive = false;
+//                        ApexTrackingApplication.get_instance().homeactive = false;
+//                        break;
+//
+//                    case R.id.item_otool:
+//                        ApexTrackingApplication.get_instance().historyactive = false;
+//                        ApexTrackingApplication.get_instance().homeactive = false;
+//                        break;
+//
+//                    case R.id.item_home:
+//                        ApexTrackingApplication.get_instance().historyactive = false;
+//                        ApexTrackingApplication.get_instance().homeactive = true;
+//
+//                        HomeFragment homef=(HomeFragment)((ViewPagerAdapter)viewPager.getAdapter()).getItem(position);
+//                        homef.checkDirty();
+//                        break;
+//
+//                    case R.id.item_history:
+//
+//                        ApexTrackingApplication.get_instance().historyactive = true;
+//                        ApexTrackingApplication.get_instance().homeactive = false;
+//                        HistoryFragment historyf=(HistoryFragment)((ViewPagerAdapter)viewPager.getAdapter()).getItem(position);
+//                        historyf.checkDirty();
+//
+//                        break;
+//                    case R.id.item_search:
+//                        ApexTrackingApplication.get_instance().historyactive = false;
+//                        ApexTrackingApplication.get_instance().homeactive = false;
+//                        break;
+//
+//                    case R.id.item_my:
+//                        ApexTrackingApplication.get_instance().historyactive = false;
+//                        ApexTrackingApplication.get_instance().homeactive = false;
+//                        break;
+//                }
+//
+//
+//
+////                if(viewPager.gets)
+////                if (menuItem != null) {
+////                    menuItem.setChecked(false);
+////                } else {
+////                    bottomNavigationView.getMenu().getItem(0).setChecked(false);
+////                }
+////                menuItem = bottomNavigationView.getMenu().getItem(position);
+////                menuItem.setChecked(true);
+//            }
+//
+//            @Override
+//            public void onPageScrollStateChanged(int state) {
+//            }
+//        });
+//
+
+
+//        viewPager.set
+////        禁止ViewPager滑动
+//        viewPager.setOnTouchListener(new View.OnTouchListener() {
+//            @Override
+//            public boolean onTouch(View v, MotionEvent event) {
+//                return true;
+//            }
+//        });
+
+        setupViewPager(viewPager);
+
+
+//        boolean pop = checkAllPermission();
+//        if(!pop)
+//        {
+//            if(TextUtils.isEmpty(ApexTrackingApplication.station_name))
+//            {
+//                Intent intent = new Intent();
+//                intent.setClass(RootActivity.this,ServerSettingActivity.class);
+////            startActivity(intent);
+//                startActivityForResult(intent, 0);
+//            }
+//        }
+    }
+//    public boolean checkAllPermission() {
+//
+//
+//        /*
+//        *
+//        *     -->
+//    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+//    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+//    <uses-permission android:name="android.permission.INTERNET" />
+//    <uses-permission android:name="android.permission.READ_CONTACTS" />
+//    <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
+//    <!-- External storage for caching. -->
+//    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+//    <!-- My Location -->
+//    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+//    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+//    <!-- Maps API needs OpenGL ES 2.0. -->
+//    <uses-feature
+//        android:glEsVersion="0x00020000"
+//        android:required="true" />
+//    <!-- End of copy. -->
+//
+//
+//    <!-- Baidu Map API -->
+//
+//    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
+//    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
+//        * */
+//
+//
+//
+//        String[] permissions = {
+////                Manifest.permission.CAMERA,
+////                Manifest.permission.VIBRATE,
+//                Manifest.permission.READ_CONTACTS,
+//                Manifest.permission.READ_PHONE_STATE,
+//                Manifest.permission.WRITE_EXTERNAL_STORAGE,
+//                Manifest.permission.READ_EXTERNAL_STORAGE,
+////                Manifest.permission.RECEIVE_BOOT_COMPLETED,
+////                Manifest.permission.ACCESS_NETWORK_STATE,
+////                Manifest.permission.ACCESS_WIFI_STATE,
+////                Manifest.permission.INTERNET,
+////                Manifest.permission.ACCESS_FINE_LOCATION,
+////
+////                Manifest.permission.CHANGE_CONFIGURATION
+//
+//
+//
+//        };
+//
+//
+//
+////        RAUtil.checkPermissions1(this,permissions);
+//        boolean ret = true;
+////        for(String permission : permissions) {
+////            boolean granted = ;
+////            if (!granted) {
+////                ret= false;
+////            }
+////        }
+//
+//
+//        return commonUtil.checkPermissions(this,permissions);
+//
+////        return ret;
+//    }
+
+
+//    @Override
+//    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)
+//    {
+//
+//        if (requestCode == commonUtil.MY_PERMISSIONS_REQUEST)
+//        {
+//            boolean missing=false;
+//            boolean request = false;
+//            for(int i=0;i<grantResults.length;i++)
+//            {
+//
+//                if(grantResults[i]!= PackageManager.PERMISSION_GRANTED)
+//                    missing=true;
+//                boolean bshow= ActivityCompat.shouldShowRequestPermissionRationale(this,permissions[i]);
+//                if(bshow)
+//                    request = true;
+//            }
+//
+//            String msg=null;
+//            if(request)
+//                msg="Apex Mobile needs some essential permissions.";
+//            else
+//                msg="Apex Mobile will quit because missing some essential permissions.\nPlease check your system setting.";
+//
+//            if(missing) {
+//                final boolean finalRequest = request;
+//                new AlertDialog.Builder(this)
+//                        .setTitle("Warning")
+//                        .setMessage(msg)
+//                        .setPositiveButton("OK", new DialogInterface.OnClickListener() {
+//                            @Override
+//                            public void onClick(DialogInterface dialog, int which) {
+////                                checkAllPermission();
+//                                if (finalRequest)
+//                                    checkAllPermission();
+//                                else
+//                                    finish();
+//                            }
+//                        })
+////                    .setNegativeButton("No", new DialogInterface.OnClickListener() {
+////                        @Override
+////                        public void onClick(DialogInterface dialog, int which) {
+////                            finish();
+////                        }
+////                    })
+//                        .show();
+//            }
+//            else
+//            {
+////                if(TextUtils.isEmpty(ApexTrackingApplication.station_name))
+////                {
+////                    Intent intent = new Intent();
+////                    intent.setClass(FullScreenLoginActivity.this,ServerSettingActivity.class);
+//////            startActivity(intent);
+////                    startActivityForResult(intent, 0);
+////                }
+//            }
+////            if (grantResults[0] == PackageManager.PERMISSION_GRANTED)
+////            {
+////               // callPhone();
+////            } else
+////            {
+////
+////
+////                            new AlertDialog.Builder(this)
+////                    .setTitle("Warning")
+////                    .setMessage("RA Image missing essential permission")
+////                    .setPositiveButton("OK", new DialogInterface.OnClickListener() {
+////                        @Override
+////                        public void onClick(DialogInterface dialog, int which) {
+////                            checkAllPermission();
+////                        }
+////                    })
+//////                    .setNegativeButton("No", new DialogInterface.OnClickListener() {
+//////                        @Override
+//////                        public void onClick(DialogInterface dialog, int which) {
+//////                            finish();
+//////                        }
+//////                    })
+////                    .show();
+////
+////                // Permission Denied
+////               // Toast.makeText(MainActivity.this, "Permission Denied", Toast.LENGTH_SHORT).show();
+////            }
+//            return;
+//        }
+//        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
+//    }
+
+    private void setupViewPager(final ViewPager viewPager) {
+//        TestFragment.LoginCallBack logincallback = new TestFragment.LoginCallBack() {
+//            @Override
+//            public void onLogin() {
+//                System.out.println("login ");
+//                login = true;
+////                bottomNavigationView.setSelectedItemId(bottomNavigationView.getMenu().getItem(0).getItemId());
+//                bottomNavigationView.getChildAt(0).setSelected(true);
+//                bottomNavigationView.getMenu().clear();
+////                bottomNavigationView.getMenu().
+//                bottomNavigationView.inflateMenu(R.menu.navi_login);
+//                BottomNavigationViewHelper.disableShiftMode(bottomNavigationView);
+//                setupViewPager(viewPager);
+//
+//            }
+//
+//            @Override
+//            public void onLogout() {
+//                System.out.println("log out ");
+//                login=false;
+//
+////                BottomNavigationView v;
+//
+////                v.getse
+////                bottomNavigationView.setSelectedItemId(bottomNavigationView.getMenu().getItem(0).getItemId());
+////                navigation.setSelectedItemId(navigation.getMenu().getItem(position).getItemId());
+//                bottomNavigationView.getMenu().clear();
+//                bottomNavigationView.inflateMenu(R.menu.navi_logout);
+//                BottomNavigationViewHelper.disableShiftMode(bottomNavigationView);
+//                setupViewPager(viewPager);
+//            }
+//        };
+
+
+        ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
+
+
+//        adapter.clear();
+
+        if(true)
+        {
+//            if(actionbutton!=null)
+//                actionbutton.getItem(0).setVisible(true);
+
+            bottomNavigationView.getChildAt(0).setSelected(true);
+            bottomNavigationView.getMenu().clear();
+//                bottomNavigationView.getMenu().
+//            bottomNavigationView.inflateMenu();
+//            bottomNavigationView.inflateMenu(R.menu.navi_logout);
+
+//            PrepareMenu(bottomNavigationView.getMenu());
+
+            Menu menu = bottomNavigationView.getMenu();
+
+
+
+            int count = getIntent().getIntExtra("actions_count", 0);
+            for (int i = 0; i < count; i++)
+            {
+
+                int vid = commonUtil.generateViewId();
+                String title = getIntent().getStringExtra("action" + i);
+                menu.add(0, vid, 0, title);
+
+                menu_map.put(vid,i);
+
+
+                Bundle bundle = new Bundle();
+                if (function_name.equals("Cargo Tracking"))
+                {
+                    if (criterion_type == 0)
+                        bundle.putString("hbol", cargo_criterion);
+                    else
+                        bundle.putString("container_no", cargo_criterion);
+
+                }
+                bundle.putString("action_type", title);
+                bundle.putString("id", _id);
+                bundle.putString("module_name", function_name);
+
+
+                Fragment f;
+                f= new DetailFragment();
+                ((DetailFragment)f).set_content( contentmap.get(title));
+                f.setArguments(bundle);
+
+                adapter.addFragment(f);
+//
+//            tabmap.put(getIntent().getStringExtra("action" + i), vid);
+            }
+            BottomNavigationViewHelper.disableShiftMode(bottomNavigationView, false);
+
+
+//		Log.e("findFragmentByTag", "tag=" + tag + ", isnull= "
+//				+ (getSupportFragmentManager().findFragmentByTag(tag) == null));
+
+//            f = getSupportFragmentManager().findFragmentById(tabmap.get(tag));
+//            if (f == null)
+//            {
+//                Log.d("createTabContent", "create fragment" + tag);
+//                f = new DetailFragment();
+//
+//
+//                f.setArguments(bundle);
+//            }
+
+//            HomeFragment homeFragment = new HomeFragment();
+//            HistoryFragment historyFragment = new HistoryFragment();
+//            SearchFragment searchFragment = new SearchFragment();
+//            ToolsFragment toolsFragment = new ToolsFragment();
+//            MyFragment myFragment = new MyFragment();
+//            myFragment.setCallBack(new MyFragment.LogoutCallBack() {
+//                @Override
+//                public void onLogout() {
+//
+//                                    System.out.println("log out ");
+//                login=false;
+//
+////                BottomNavigationView v;
+//
+////                v.getse
+////                bottomNavigationView.setSelectedItemId(bottomNavigationView.getMenu().getItem(0).getItemId());
+////                navigation.setSelectedItemId(navigation.getMenu().getItem(position).getItemId());
+//
+//                setupViewPager(viewPager);
+//                }
+//            });
+
+
+//            adapter.addFragment(homeFragment);
+//            adapter.addFragment(historyFragment);
+//            adapter.addFragment(searchFragment);
+//            adapter.addFragment(toolsFragment);
+//
+//
+//            adapter.addFragment(myFragment);
+
+
+            ApexTrackingApplication.get_instance().homeactive = true;
+
+
+
+//            adapter.addFragment(BaseFragment.newInstance("home"));
+//            adapter.addFragment(BaseFragment.newInstance("history"));
+//            adapter.addFragment(BaseFragment.newInstance("search"));
+//            adapter.addFragment(BaseFragment.newInstance("tool"));
+//
+//            TestFragment logoutf = TestFragment.newInstance("logout");
+//            logoutf.setCallBack(logincallback);
+//            adapter.addFragment(logoutf);
+        }
+//        else
+//        {
+//            ApexTrackingApplication.get_instance().homeactive = false;
+//            ApexTrackingApplication.get_instance().historyactive = false;
+//            ApexTrackingApplication.get_instance().recentactive = false;
+//            if(actionbutton!=null)
+//                actionbutton.getItem(0).setVisible(false);
+//            bottomNavigationView.getChildAt(0).setSelected(true);
+//            bottomNavigationView.getMenu().clear();
+//            bottomNavigationView.inflateMenu(R.menu.navi_logout);
+//            BottomNavigationViewHelper.disableShiftMode(bottomNavigationView);
+//
+//
+//            LoginFragment loginFragment = new LoginFragment();
+////            loginFragment.setCallBack(new LoginFragment.LoginCallBack() {
+////                @Override
+////                public void onLogin() {
+////                System.out.println("login ");
+////                login = true;
+//////                bottomNavigationView.setSelectedItemId(bottomNavigationView.getMenu().getItem(0).getItemId());
+////
+////                setupViewPager(viewPager);
+////                }
+////            });
+////            TestFragment loginf = TestFragment.newInstance("login");
+////            loginf.setCallBack(logincallback);
+//
+//
+//            adapter.addFragment(loginFragment);
+//
+////            SearchFragment searchFragment = new SearchFragment();
+////            adapter.addFragment(searchFragment);
+//
+//            Fragment toolsFragment = new ToolsFragment();
+//            adapter.addFragment(toolsFragment);
+//        }
+
+
+
+
+
+
+
+//        viewPager.removeAllViews();
+
+
+        viewPager.setAdapter(adapter);
+    }
+    public void save_content(String which,String content)
+    {
+        contentmap.put(which, content);
+
+        try {
+
+            JSONObject jsonObject = new JSONObject(content);
+            email_to = jsonObject.optString("email",null);
+            email_subject = jsonObject.optString("email_subject",null);
+            email_content = jsonObject.optString("email_content",null);
+
+        } catch (JSONException e) {
+            e.printStackTrace();
+        }
+
+    }
+//    boolean PrepareMenu(Menu menu)
+//    {
+//        int count = getIntent().getIntExtra("actions_count", 0);
+//        for (int i = 0; i < count; i++)
+//        {
+//
+//            int vid = commonUtil.generateViewId();
+//            String title = getIntent().getStringExtra("action" + i);
+//            menu.add(0, vid, 0, title);
+//
+//            menu_map.put(title,vid);
+////
+////            tabmap.put(getIntent().getStringExtra("action" + i), vid);
+//        }
+//        return true;
+//    }
+}

+ 30 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/mainframe/NoScrollViewPager.java

@@ -0,0 +1,30 @@
+package com.usai.apex.mainframe;
+
+import android.content.Context;
+import android.support.v4.view.ViewPager;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+
+/**
+ * Created by ray on 05/03/2018.
+ */
+
+public class NoScrollViewPager extends ViewPager {
+    public NoScrollViewPager(Context context) {
+        super(context);
+    }
+
+    public NoScrollViewPager(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent arg0) {
+        return false;
+    }
+
+    @Override
+    public boolean onInterceptTouchEvent(MotionEvent arg0) {
+        return false;
+    }
+}

+ 333 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/mainframe/RecentFragment.java

@@ -0,0 +1,333 @@
+package com.usai.apex.mainframe;
+
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.ListView;
+
+import com.usai.apex.ApexTrackingApplication;
+import com.usai.apex.R;
+import com.usai.apex.ShipMap.ShipMap;
+import com.usai.util.Network;
+import com.usai.util.dbUtil;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.util.Map;
+
+
+/**
+ * A simple {@link Fragment} subclass.
+ */
+public class RecentFragment extends TrackingListFragment {
+
+
+    /**
+     * Param 0 启动任务时输入的参数类型
+     * Param 1 后台任务执行中返回进度值的类型
+     * Param 2 后台任务执行完成后返回结果的类型
+     * */
+    private class RecentTask extends AsyncTask<Void, Void, JSONObject> {
+
+        @Override
+        protected void onPreExecute() {
+            super.onPreExecute();
+            isLoading = true;
+            showProgressDialog();
+        }
+
+        @Override
+        protected JSONObject doInBackground(Void... voids) {
+
+            final JSONObject jsobj = Network.request_home();
+            return jsobj;
+        }
+
+        @Override
+        protected void onPostExecute(JSONObject jsobj) {
+
+            showProgress(false);
+            if (mSwipeRefresh.isRefreshing()) {
+                mSwipeRefresh.setRefreshing(false);
+            }
+
+            if (jsobj != null) {
+                handleJson(jsobj);
+                bdirty = false;
+            } else {
+                showAlert("Sorry,there is some wrong");
+            }
+
+            isLoading = false;
+            dismissProgressDialog();
+            mTask = null;
+        }
+
+        @Override
+        protected void onCancelled() {
+            super.onCancelled();
+
+            isLoading = false;
+            dismissProgressDialog();
+            mTask = null;
+        }
+    }
+
+    private RecentTask mTask;
+
+    protected boolean isActive()
+    {
+        return ApexTrackingApplication.getInstance().homeactive&&ApexTrackingApplication.getInstance().recentactive;
+    }
+
+    public RecentFragment() {
+        // Required empty public constructor
+    }
+
+    private JSONObject mJson;
+    @Override
+    public void onActivityCreated(Bundle savedInstanceState)
+    {
+        super.onActivityCreated(savedInstanceState);
+
+//        setupAdapter();
+//        customize_style();
+
+        // this.getListView().setBackgroundColor(Color.WHITE);
+//
+//        if (savedInstanceState != null) {
+//            String jsonString = savedInstanceState.getString("RecentJson");
+//            if (jsonString != null) {
+//                try {
+//                    JSONObject json = new JSONObject(jsonString);
+//                    handleJson(json);
+//                } catch (JSONException e) {
+//                    e.printStackTrace();
+//                }
+//            }
+//        }
+
+        if (savedInstanceState != null) {
+            mSelectedIndex = savedInstanceState.getInt("selectIndex");
+            setSelectedPosition(mSelectedIndex);
+        }
+
+        if (searchresult.get_count() == 0) {
+            requestData();
+        }
+
+    }
+
+//    @Override
+//    protected void requestData() {
+//
+//        requestdata();
+//    }
+//    @Override
+//<<<<<<< .mine
+//    protected void requestData()
+//=======
+//    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+//        return super.onCreateView(inflater, container, savedInstanceState);
+//    }
+//
+//    @Override
+//    public void onSaveInstanceState(Bundle outState) {
+//        super.onSaveInstanceState(outState);
+//        if (mJson != null) {
+//            outState.putString("RecentJson",mJson.toString());
+//        }
+//    }
+//
+//    @Override
+//    protected void requestData() {
+//
+//        requestdata();
+//    }
+
+    private void handleJson(JSONObject jsobj) {
+
+        mJson = jsobj;
+        if (mJson == null) {
+            return;
+        }
+        try {
+            int result = jsobj.getInt("result");
+            if (result == Network.RESULT_TRUE) {
+
+                searchresult.clear();
+                JSONArray datalist = jsobj.getJSONArray("container_list");
+                int count = datalist.length();
+                searchresult.add_records(datalist.toString(), count);
+
+                adapter.notifyDataSetChanged();
+
+                if(count==0)
+                    showRefreshButton(true);
+                else
+                    showRefreshButton(false);
+                setSelectedPosition(0);
+
+            } else {
+                String msg = jsobj.getString("err_msg");
+                showAlert(msg);
+            }
+        } catch (JSONException e) {
+            e.printStackTrace();
+            showAlert("Sorry,there is some wrong");
+        }
+    }
+@Override
+    protected void requestData()
+
+    {
+        if (isLoading) {
+            if (mSwipeRefresh.isRefreshing()) {
+                mSwipeRefresh.setRefreshing(false);
+            }
+            return;
+        }
+
+        mTask = new RecentTask();
+        mTask.execute();
+
+        super.requestData();
+    }
+
+    @Override
+    public void onDetach() {
+        super.onDetach();
+
+        if (mTask != null) {
+            mTask.cancel(false);
+        }
+        dismissProgressDialog();
+    }
+
+    @Override
+    protected View initHeaderView()
+    {
+
+        View headerView = LayoutInflater.from(getActivity()).inflate(R.layout.home_listheader, null);
+        return headerView;
+
+    }
+
+    @Override
+    public void onListItemClick(ListView l, View v, int position, long id) {
+
+        //!!!!! listview 有header, position 需要-1
+
+
+//        Log.d("FragmentList", "Item clicked: " + id);
+//
+//        String title = (String) getData(jsonobj).get(position - 1).get("title");
+
+        position = position - 1;
+        if (position < 0) {
+            return;
+        }
+
+        setSelectedPosition(position);
+
+        String cargo_criterion = (String) searchresult.getData().get(position).get("hbol");
+
+        String serial_no = (String) searchresult.getData().get(position).get("serial_no");
+if(TextUtils.isEmpty(serial_no))
+    serial_no = "dumb";
+        Intent intent = new Intent();
+        intent.setClass(getContext(), NewDetailActivity.class);
+
+        intent.putExtra("action0", "Tracking");
+        intent.putExtra("function_name", "Cargo Tracking");
+
+        intent.putExtra("cargo_criterion", cargo_criterion);
+        intent.putExtra("actions_count", 1);
+        intent.putExtra("_id", serial_no);
+
+
+        intent.putExtra("criterion_type", 0);
+        String h_field = "h_bol";
+
+        dbUtil.savehistory(h_field, cargo_criterion);
+
+        startActivity(intent);
+
+    }
+
+
+    @Override
+    public void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+
+        outState.putInt("selectIndex",mSelectedIndex);
+
+        Log.d("RecentFragment", "onSaveInstanceState: ");
+    }
+
+
+
+    @Override
+    public void onClick(View v) {
+        super.onClick(v);
+        int position = (Integer) v.getTag();
+        // 会重复调用两次
+        if (mSelectedIndex == position) {
+            return;
+        }
+        setSelectedPosition(position);
+    }
+
+
+    private void setSelectedPosition(int position) {
+
+        if (mSelectedIndex >= 0) {
+
+            View cell = getCellForPosition(mSelectedIndex);
+            if (cell != null) {
+
+                View contentView = cell.findViewById(R.id.cell_content_view);
+                if (contentView != null) {
+                    contentView.setBackground(getResources().getDrawable(R.drawable.list_corner_round_bg));
+                }
+
+                TrackingImageView iv_status = (TrackingImageView) cell.findViewById(R.id.iv_status);
+                iv_status.setSelected(false);
+            }
+
+        }
+
+        mSelectedIndex = position;
+        View cell = getCellForPosition(mSelectedIndex);
+        if (cell != null) {
+            View contentView = cell.findViewById(R.id.cell_content_view);
+            if (contentView != null) {
+                contentView.setBackground(getResources().getDrawable(R.drawable.list_corner_round_selected_bg));
+            }
+
+            TrackingImageView iv_status = (TrackingImageView) cell.findViewById(R.id.iv_status);
+            iv_status.setSelected(true);
+        }
+
+        if(searchresult.getData().size()==0)
+            return;
+        Map<String,Object> item = searchresult.getData().get(position);
+        if (item != null) {
+            JSONObject locations = (JSONObject) item.get("locations");
+            ShipMap shipMap = getShipMap();
+            if (shipMap != null) {
+                shipMap.showShipAnnotation(locations);
+            }
+        }
+    }
+
+}

+ 634 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/mainframe/RootActivity.java

@@ -0,0 +1,634 @@
+package com.usai.apex.mainframe;
+
+import android.Manifest;
+import android.app.AlertDialog;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.design.widget.BottomNavigationView;
+import android.support.v4.app.ActivityCompat;
+import android.support.v4.app.Fragment;
+import android.support.v4.content.LocalBroadcastManager;
+import android.support.v4.view.ViewPager;
+import android.support.v7.app.AppCompatActivity;
+import android.support.v7.widget.Toolbar;
+import android.view.Menu;
+import android.view.MenuItem;
+
+import com.usai.apex.ApexTrackingApplication;
+import com.usai.apex.ContainerSearchActivity;
+import com.usai.apex.R;
+import com.usai.apex.ViewPagerAdapter;
+import com.usai.util.commonUtil;
+
+/**
+ * Created by bruce on 2016/11/1.
+ * HomeActivity 主界面
+ */
+
+public class RootActivity extends AppCompatActivity {
+
+    private NoScrollViewPager viewPager;
+    private MenuItem menuItem;
+    private BottomNavigationView bottomNavigationView;
+    int selectedMenuItem;
+    boolean login=false;
+
+
+    Menu actionbutton;
+
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        actionbutton = menu;
+        getMenuInflater().inflate(R.menu.quick_search,menu);
+        return  true;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+            case android.R.id.home:
+//                Toast.makeText(this, "switch mode", Toast.LENGTH_SHORT).show();
+
+                if (login && (viewPager.getCurrentItem() == 0 || viewPager.getCurrentItem() == 1)) {
+                    boolean personMode = ApexTrackingApplication.get_instance().getPersonMode();
+                    personMode = !personMode;
+                    ApexTrackingApplication.get_instance().setPersonMode(personMode);
+
+                    if (personMode) {
+                        getSupportActionBar().setHomeAsUpIndicator(R.drawable.apexlogo_p);
+                    } else {
+                        getSupportActionBar().setHomeAsUpIndicator(R.drawable.apexlogo);
+                    }
+
+                    Intent intent = new Intent("com.apex.broadcast.person_mode");
+                    LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);
+                }
+
+                break;
+            case R.id.quick_search:
+
+                Intent intent = new Intent();
+                intent.setClass(RootActivity.this,ContainerSearchActivity.class);
+            startActivity(intent);
+
+//                Toast.makeText(this,"跳转至container search activity",Toast.LENGTH_LONG).show();
+                break;
+
+        }
+
+        return super.onOptionsItemSelected(item);
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+
+        outState.putBoolean("login",login);
+    }
+    BroadcastReceiver br;
+    @Override
+    protected void onDestroy() {
+        LocalBroadcastManager localBroadcastManager = LocalBroadcastManager
+                .getInstance(this);
+        localBroadcastManager.unregisterReceiver(br);
+        super.onDestroy();
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        if (!isTaskRoot()) {
+            finish();
+            return;
+        }
+
+        LocalBroadcastManager localBroadcastManager = LocalBroadcastManager
+                .getInstance(this);
+        IntentFilter intentFilter = new IntentFilter();
+        intentFilter.addAction("Login");
+//        intentFilter.addAction(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
+
+        br = new BroadcastReceiver() {
+
+            @Override
+            public void onReceive(Context context, Intent intent) {
+
+                if(intent.getAction().equals("Login"))
+                {
+                    boolean blogin = intent.getBooleanExtra("state",true);
+                    login=blogin;
+
+                    setupViewPager(viewPager);
+                }
+
+
+            }
+
+        };
+        localBroadcastManager.registerReceiver(br, intentFilter);
+//        registerReceiver(br, intentFilter);
+
+        setContentView(R.layout.activity_root);
+
+        if (savedInstanceState != null) {
+            login = savedInstanceState.getBoolean("login");
+        }
+
+
+
+
+
+
+        Toolbar toolbar = (Toolbar) findViewById(R.id.tool_bar);
+        setSupportActionBar(toolbar);
+
+        getSupportActionBar().setDisplayShowTitleEnabled(false);
+        /*
+        ActionBar actionBar = getSupportActionBar();
+//        actionBar.setLogo(R.drawable.apexlogo);
+        actionBar.setIcon(R.drawable.apexlogo);
+//        actionBar.setIcon(R.drawable.ic_launcher);
+
+//        actionBar.setDisplayUseLogoEnabled(true);
+        actionBar.setDisplayShowHomeEnabled(true);
+        actionBar.setHomeButtonEnabled(true);
+//        actionBar.setHomeAsUpIndicator(R.drawable.ic_launcher);
+//        actionBar.setDisplayHomeAsUpEnabled(true);
+        actionBar.setDisplayShowTitleEnabled(false);
+*/
+
+        viewPager = (NoScrollViewPager) findViewById(R.id.viewpager);
+        bottomNavigationView = (BottomNavigationView) findViewById(R.id.bottom_navigation);
+
+        bottomNavigationView.setItemIconTintList(null);
+//        bottomNavigationView.setItemTextColor();;
+//        bottomNavigationView.getItemTextColor();
+
+//        bottomNavigationView.setlistener
+
+        //默认 >3 的选中效果会影响ViewPager的滑动切换时的效果,故利用反射去掉
+        BottomNavigationViewHelper.disableShiftMode(bottomNavigationView,true);
+        bottomNavigationView.setOnNavigationItemSelectedListener(
+                new BottomNavigationView.OnNavigationItemSelectedListener() {
+                    @Override
+                    public boolean onNavigationItemSelected(@NonNull MenuItem item) {
+                        actionbutton.getItem(0).setVisible(false);
+                        getSupportActionBar().setHomeAsUpIndicator(R.drawable.apexlogo);
+                        getSupportActionBar().setDisplayShowTitleEnabled(false);
+                        switch (item.getItemId()) {
+                            case R.id.item_login:
+
+                                viewPager.setCurrentItem(0);
+                                return true;
+
+                            case R.id.item_tool:
+                                viewPager.setCurrentItem(3);
+                                return true;
+
+                            case R.id.item_otool:
+                                viewPager.setCurrentItem(1);
+                                return true;
+
+                            case R.id.item_home:
+                                actionbutton.getItem(0).setVisible(true);
+                                if (ApexTrackingApplication.get_instance().getPersonMode()) {
+                                    getSupportActionBar().setHomeAsUpIndicator(R.drawable.apexlogo_p);
+                                }
+                                getSupportActionBar().setDisplayShowTitleEnabled(true);
+                                viewPager.setCurrentItem(0);
+                                return true;
+
+                            case R.id.item_history:
+                                if (ApexTrackingApplication.get_instance().getPersonMode()) {
+                                    getSupportActionBar().setHomeAsUpIndicator(R.drawable.apexlogo_p);
+                                }
+                                viewPager.setCurrentItem(1);
+                                return true;
+
+                            case R.id.item_search:
+                                viewPager.setCurrentItem(2);
+                                return true;
+
+                            case R.id.item_my:
+                                viewPager.setCurrentItem(4);
+                                return true;
+
+                        }
+                        return false;
+                    }
+                });
+
+
+        viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
+            @Override
+            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
+
+            }
+
+            @Override
+            public void onPageSelected(int position) {
+
+                MenuItem item= bottomNavigationView.getMenu().getItem(position);
+
+                switch (item.getItemId())
+                {
+                    case R.id.item_login:
+                        ApexTrackingApplication.get_instance().historyactive = false;
+                        ApexTrackingApplication.get_instance().homeactive = false;
+                        break;
+
+                    case R.id.item_tool:
+                        ApexTrackingApplication.get_instance().historyactive = false;
+                        ApexTrackingApplication.get_instance().homeactive = false;
+                        break;
+
+                    case R.id.item_otool:
+                        ApexTrackingApplication.get_instance().historyactive = false;
+                        ApexTrackingApplication.get_instance().homeactive = false;
+                        break;
+
+                    case R.id.item_home:
+                        ApexTrackingApplication.get_instance().historyactive = false;
+                        ApexTrackingApplication.get_instance().homeactive = true;
+
+                        HomeFragment homef=(HomeFragment)((ViewPagerAdapter)viewPager.getAdapter()).getItem(position);
+                        homef.checkDirty();
+                        break;
+
+                    case R.id.item_history:
+
+                        ApexTrackingApplication.get_instance().historyactive = true;
+                        ApexTrackingApplication.get_instance().homeactive = false;
+                        HistoryFragment historyf=(HistoryFragment)((ViewPagerAdapter)viewPager.getAdapter()).getItem(position);
+                        historyf.checkDirty();
+
+                        break;
+                    case R.id.item_search:
+                        ApexTrackingApplication.get_instance().historyactive = false;
+                        ApexTrackingApplication.get_instance().homeactive = false;
+                        break;
+
+                    case R.id.item_my:
+                        ApexTrackingApplication.get_instance().historyactive = false;
+                        ApexTrackingApplication.get_instance().homeactive = false;
+                        break;
+                }
+
+
+
+//                if(viewPager.gets)
+//                if (menuItem != null) {
+//                    menuItem.setChecked(false);
+//                } else {
+//                    bottomNavigationView.getMenu().getItem(0).setChecked(false);
+//                }
+//                menuItem = bottomNavigationView.getMenu().getItem(position);
+//                menuItem.setChecked(true);
+            }
+
+            @Override
+            public void onPageScrollStateChanged(int state) {
+            }
+        });
+
+
+
+//        viewPager.set
+////        禁止ViewPager滑动
+//        viewPager.setOnTouchListener(new View.OnTouchListener() {
+//            @Override
+//            public boolean onTouch(View v, MotionEvent event) {
+//                return true;
+//            }
+//        });
+
+        setupViewPager(viewPager);
+
+
+        boolean pop = checkAllPermission();
+//        if(!pop)
+//        {
+//            if(TextUtils.isEmpty(ApexTrackingApplication.station_name))
+//            {
+//                Intent intent = new Intent();
+//                intent.setClass(RootActivity.this,ServerSettingActivity.class);
+////            startActivity(intent);
+//                startActivityForResult(intent, 0);
+//            }
+//        }
+
+        if (savedInstanceState == null) {
+            ApexTrackingApplication.get_instance().checkUpdate(true,null);
+        }
+
+    }
+    public boolean checkAllPermission() {
+
+
+        /*
+        *
+        *     -->
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.READ_CONTACTS" />
+    <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
+    <!-- External storage for caching. -->
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <!-- My Location -->
+    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+    <!-- Maps API needs OpenGL ES 2.0. -->
+    <uses-feature
+        android:glEsVersion="0x00020000"
+        android:required="true" />
+    <!-- End of copy. -->
+
+
+    <!-- Baidu Map API -->
+
+    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
+    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
+        * */
+
+
+
+        String[] permissions = {
+//                Manifest.permission.CAMERA,
+//                Manifest.permission.VIBRATE,
+                Manifest.permission.READ_CONTACTS,
+                Manifest.permission.READ_PHONE_STATE,
+                Manifest.permission.WRITE_EXTERNAL_STORAGE,
+                Manifest.permission.READ_EXTERNAL_STORAGE,
+//                Manifest.permission.RECEIVE_BOOT_COMPLETED,
+//                Manifest.permission.ACCESS_NETWORK_STATE,
+//                Manifest.permission.ACCESS_WIFI_STATE,
+//                Manifest.permission.INTERNET,
+//                Manifest.permission.ACCESS_FINE_LOCATION,
+//
+//                Manifest.permission.CHANGE_CONFIGURATION
+
+
+
+        };
+
+
+
+//        RAUtil.checkPermissions1(this,permissions);
+        boolean ret = true;
+//        for(String permission : permissions) {
+//            boolean granted = ;
+//            if (!granted) {
+//                ret= false;
+//            }
+//        }
+
+
+        return commonUtil.checkPermissions(this,permissions);
+
+//        return ret;
+    }
+
+
+    @Override
+    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)
+    {
+
+        if (requestCode == commonUtil.MY_PERMISSIONS_REQUEST)
+        {
+            boolean missing=false;
+            boolean request = false;
+            for(int i=0;i<grantResults.length;i++)
+            {
+
+                if(grantResults[i]!= PackageManager.PERMISSION_GRANTED)
+                    missing=true;
+                boolean bshow= ActivityCompat.shouldShowRequestPermissionRationale(this,permissions[i]);
+                if(bshow)
+                    request = true;
+            }
+
+            String msg=null;
+            if(request)
+                msg="Apex Mobile needs some essential permissions.";
+            else
+                msg="Apex Mobile will quit because missing some essential permissions.\nPlease check your system setting.";
+
+            if(missing) {
+                final boolean finalRequest = request;
+                new AlertDialog.Builder(this)
+                        .setTitle("Warning")
+                        .setMessage(msg)
+                        .setPositiveButton("OK", new DialogInterface.OnClickListener() {
+                            @Override
+                            public void onClick(DialogInterface dialog, int which) {
+//                                checkAllPermission();
+                                if (finalRequest)
+                                    checkAllPermission();
+                                else
+                                    finish();
+                            }
+                        })
+//                    .setNegativeButton("No", new DialogInterface.OnClickListener() {
+//                        @Override
+//                        public void onClick(DialogInterface dialog, int which) {
+//                            finish();
+//                        }
+//                    })
+                        .show();
+            }
+            else
+            {
+//                if(TextUtils.isEmpty(ApexTrackingApplication.station_name))
+//                {
+//                    Intent intent = new Intent();
+//                    intent.setClass(FullScreenLoginActivity.this,ServerSettingActivity.class);
+////            startActivity(intent);
+//                    startActivityForResult(intent, 0);
+//                }
+            }
+//            if (grantResults[0] == PackageManager.PERMISSION_GRANTED)
+//            {
+//               // callPhone();
+//            } else
+//            {
+//
+//
+//                            new AlertDialog.Builder(this)
+//                    .setTitle("Warning")
+//                    .setMessage("RA Image missing essential permission")
+//                    .setPositiveButton("OK", new DialogInterface.OnClickListener() {
+//                        @Override
+//                        public void onClick(DialogInterface dialog, int which) {
+//                            checkAllPermission();
+//                        }
+//                    })
+////                    .setNegativeButton("No", new DialogInterface.OnClickListener() {
+////                        @Override
+////                        public void onClick(DialogInterface dialog, int which) {
+////                            finish();
+////                        }
+////                    })
+//                    .show();
+//
+//                // Permission Denied
+//               // Toast.makeText(MainActivity.this, "Permission Denied", Toast.LENGTH_SHORT).show();
+//            }
+            return;
+        }
+        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
+    }
+
+    private void setupViewPager(final ViewPager viewPager) {
+//        TestFragment.LoginCallBack logincallback = new TestFragment.LoginCallBack() {
+//            @Override
+//            public void onLogin() {
+//                System.out.println("login ");
+//                login = true;
+////                bottomNavigationView.setSelectedItemId(bottomNavigationView.getMenu().getItem(0).getItemId());
+//                bottomNavigationView.getChildAt(0).setSelected(true);
+//                bottomNavigationView.getMenu().clear();
+////                bottomNavigationView.getMenu().
+//                bottomNavigationView.inflateMenu(R.menu.navi_login);
+//                BottomNavigationViewHelper.disableShiftMode(bottomNavigationView);
+//                setupViewPager(viewPager);
+//
+//            }
+//
+//            @Override
+//            public void onLogout() {
+//                System.out.println("log out ");
+//                login=false;
+//
+////                BottomNavigationView v;
+//
+////                v.getse
+////                bottomNavigationView.setSelectedItemId(bottomNavigationView.getMenu().getItem(0).getItemId());
+////                navigation.setSelectedItemId(navigation.getMenu().getItem(position).getItemId());
+//                bottomNavigationView.getMenu().clear();
+//                bottomNavigationView.inflateMenu(R.menu.navi_logout);
+//                BottomNavigationViewHelper.disableShiftMode(bottomNavigationView);
+//                setupViewPager(viewPager);
+//            }
+//        };
+
+
+        ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
+
+
+//        adapter.clear();
+
+        if(login)
+        {
+            if(actionbutton!=null)
+                actionbutton.getItem(0).setVisible(true);
+
+            bottomNavigationView.getChildAt(0).setSelected(true);
+            bottomNavigationView.getMenu().clear();
+//                bottomNavigationView.getMenu().
+            bottomNavigationView.inflateMenu(R.menu.navi_login);
+            BottomNavigationViewHelper.disableShiftMode(bottomNavigationView ,true);
+
+
+            HomeFragment homeFragment = new HomeFragment();
+            HistoryFragment historyFragment = new HistoryFragment();
+            SearchFragment searchFragment = new SearchFragment();
+            ToolsFragment toolsFragment = new ToolsFragment();
+            MyFragment myFragment = new MyFragment();
+//            myFragment.setCallBack(new MyFragment.LogoutCallBack() {
+//                @Override
+//                public void onLogout() {
+//
+//                                    System.out.println("log out ");
+//                login=false;
+//
+////                BottomNavigationView v;
+//
+////                v.getse
+////                bottomNavigationView.setSelectedItemId(bottomNavigationView.getMenu().getItem(0).getItemId());
+////                navigation.setSelectedItemId(navigation.getMenu().getItem(position).getItemId());
+//
+//                setupViewPager(viewPager);
+//                }
+//            });
+
+
+            adapter.addFragment(homeFragment);
+            adapter.addFragment(historyFragment);
+            adapter.addFragment(searchFragment);
+            adapter.addFragment(toolsFragment);
+
+
+            adapter.addFragment(myFragment);
+
+
+            ApexTrackingApplication.get_instance().homeactive = true;
+
+
+
+//            adapter.addFragment(BaseFragment.newInstance("home"));
+//            adapter.addFragment(BaseFragment.newInstance("history"));
+//            adapter.addFragment(BaseFragment.newInstance("search"));
+//            adapter.addFragment(BaseFragment.newInstance("tool"));
+//
+//            TestFragment logoutf = TestFragment.newInstance("logout");
+//            logoutf.setCallBack(logincallback);
+//            adapter.addFragment(logoutf);
+        }
+        else
+        {
+            ApexTrackingApplication.get_instance().homeactive = false;
+            ApexTrackingApplication.get_instance().historyactive = false;
+            ApexTrackingApplication.get_instance().recentactive = false;
+            if(actionbutton!=null)
+                actionbutton.getItem(0).setVisible(false);
+            bottomNavigationView.getChildAt(0).setSelected(true);
+            bottomNavigationView.getMenu().clear();
+            bottomNavigationView.inflateMenu(R.menu.navi_logout);
+            BottomNavigationViewHelper.disableShiftMode(bottomNavigationView,true);
+
+
+            LoginFragment loginFragment = new LoginFragment();
+//            loginFragment.setCallBack(new LoginFragment.LoginCallBack() {
+//                @Override
+//                public void onLogin() {
+//                System.out.println("login ");
+//                login = true;
+////                bottomNavigationView.setSelectedItemId(bottomNavigationView.getMenu().getItem(0).getItemId());
+//
+//                setupViewPager(viewPager);
+//                }
+//            });
+//            TestFragment loginf = TestFragment.newInstance("login");
+//            loginf.setCallBack(logincallback);
+
+
+            adapter.addFragment(loginFragment);
+
+//            SearchFragment searchFragment = new SearchFragment();
+//            adapter.addFragment(searchFragment);
+
+            Fragment toolsFragment = new ToolsFragment();
+            adapter.addFragment(toolsFragment);
+        }
+
+
+
+
+
+
+
+//        viewPager.removeAllViews();
+
+
+        viewPager.setAdapter(adapter);
+    }
+}

+ 131 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/mainframe/SearchFragment.java

@@ -0,0 +1,131 @@
+package com.usai.apex.mainframe;
+
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.util.Log;
+import android.view.View;
+import android.widget.ListView;
+
+import com.usai.apex.R;
+import com.usai.apex.SearchListActivity;
+
+import org.json.JSONObject;
+
+
+/**
+ * A simple {@link Fragment} subclass.
+ */
+public class SearchFragment extends StaticModelistFragment {
+
+
+    public SearchFragment() {
+        // Required empty public constructor
+    }
+
+    @Override
+    public void onActivityCreated(Bundle savedInstanceState)
+    {
+        super.onActivityCreated(savedInstanceState);
+
+        setupAdapter(R.raw.search);
+
+//        adapter.getView()
+
+        customize_style();
+//        JSONObject jsonobj=loadjson(R.raw.search);
+//        adapter        = new SimpleRoundCornerAdapter(this.getActivity(),
+//                getData(jsonobj), R.layout.static_modelist_cell, new String[] { "title",
+//                "img","detail" }, new int[] { R.id.tv_name, R.id.iv_icon,R.id.tv_detail });
+//        setListAdapter(adapter);
+////        this.getListView().setDivider(R.drawable.);
+//        this.getListView().setDividerHeight(18);
+//        this.getListView().setBackgroundColor(Color.WHITE);
+
+    }
+
+//    @Override
+//    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+//                             Bundle savedInstanceState) {
+//
+//        View v= super.onCreateView(inflater,container,savedInstanceState);
+//
+//
+//        return v;
+//        // Inflate the layout for this fragment
+////        return inflater.inflate(R.layout.fragment_search, container, false);
+//    }
+
+    @Override
+    public void onListItemClick(ListView l, View v, int position, long id)
+    {
+
+        JSONObject jsonobj=loadjson(R.raw.search);
+        Log.d("FragmentList", "Item clicked: " + id);
+
+        String 	title = (String) getData(jsonobj).get(position-1).get("title");
+
+//        Intent intent = new Intent();
+        if (title.equals("Ocean Booking"))
+        {
+            Intent intent = new Intent();
+            intent.setClass(getActivity(), SearchListActivity.class);
+            // intent.putExtra("user", ApexTrackingApplication.get_user());
+            // intent.putExtra("password", password);
+            intent.putExtra("function_name", "Ocean Booking");
+            intent.putExtra("title", "Booking Search");
+            startActivity(intent);
+        }
+        else if (title.equals("Ocean B/L Info."))
+        {
+            Intent intent = new Intent();
+            intent.setClass(getActivity(), SearchListActivity.class);
+            // intent.putExtra("user", user);
+            // intent.putExtra("password", password);
+            intent.putExtra("function_name", "Ocean B/L info.");
+            intent.putExtra("title", "B/L info. Search");
+            startActivity(intent);
+        }
+
+//		else if (title.equals("Saved Detail/Search"))
+//		{
+//			intent.setClass(getActivity(), SearchHistoryActivity.class);
+//		}
+//		else if (title.equals("Change Password"))
+//		{
+//			intent.setClass(getActivity(), ChangePasswordActivity.class);
+//
+//			startActivityForResult(intent, REQUEST_CHANGEPASSWORD_ACTIVITY);
+//			return;
+//		}
+        else if (title.equals("Container Detail"))
+        {
+            Intent intent = new Intent();
+            intent.setClass(getActivity(), SearchListActivity.class);
+            // intent.putExtra("user", user);
+            // intent.putExtra("password", password);
+            intent.putExtra("function_name", "Container detail");
+            intent.putExtra("title", "Container Search");
+            startActivity(intent);
+        }
+        else if (title.equals("Document"))
+        {
+//
+//            Intent intent = new Intent();
+//            intent.setClass(getActivity(), DocumentsActivity.class);
+//
+//            startActivity(intent);
+
+
+            Intent intent = new Intent();
+            intent.setClass(getActivity(), SearchListActivity.class);
+
+            intent.putExtra("function_name", "Download Document");
+            intent.putExtra("title", "Document Search");
+            startActivity(intent);
+        }
+
+
+    }
+}

+ 237 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/mainframe/StaticModelistFragment.java

@@ -0,0 +1,237 @@
+package com.usai.apex.mainframe;
+
+
+import android.support.v4.app.Fragment;
+import android.support.v4.app.ListFragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.SimpleAdapter;
+
+import com.usai.apex.R;
+import com.usai.util.commonUtil;
+
+import org.apache.http.util.EncodingUtils;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A simple {@link Fragment} subclass.
+ */
+public class StaticModelistFragment extends ListFragment {
+
+    String ModeName=null;
+    String ModeIcon= null;
+
+
+//    public class SimpleRoundCornerAdapter extends  SimpleAdapter{
+//        public SimpleRoundCornerAdapter(Context context, List<? extends Map<String, ?>> data,
+//                                        @LayoutRes int resource, String[] from, @IdRes int[] to) {
+//            super(context, data, resource, from, to);
+//
+//        }
+//        @Override
+//        public View getView(int position, View convertView, ViewGroup parent) {
+//            View v = super.getView(position,convertView,parent);
+////            v.setBackground(getResources().getDrawable(R.drawable.list_corner_round_bg));
+////            v.setBackgroundColor(Color.BLUE);
+//            return v;
+//        }
+//    }
+
+    SimpleAdapter adapter;
+
+
+
+
+    public StaticModelistFragment() {
+        // Required empty public constructor
+    }
+
+//
+//    @Override
+//    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+//                             Bundle savedInstanceState) {
+//
+//
+//
+//        // Inflate the layout for this fragment
+//        return inflater.inflate(R.layout.fragment_static_modelist, container, false);
+//
+//
+////        super.onActivityCreated(savedInstanceState);
+//
+//
+//    }
+
+    protected  void setupAdapter(int rawid)
+    {
+        JSONObject jsonobj=loadjson(rawid);
+        adapter        = new SimpleAdapter(this.getActivity(),
+                getData(jsonobj), R.layout.static_modelist_cell, new String[] { "title",
+                "img","detail" }, new int[] { R.id.tv_title, R.id.iv_thumb,R.id.tv_detail });
+
+        View headerView = initHeaderView();
+        if(headerView!=null) {
+//            headerView.setOnClickListener(new View.OnClickListener() {
+//                @Override
+//                public void onClick(View v) {
+//
+//                }
+//            });
+            getListView().addHeaderView(headerView);
+        }
+        setListAdapter(adapter);
+    }
+
+    protected void customize_style()
+    {
+
+
+
+//        this.getListView().setDivider(new ColorDrawable(Color.RED));
+        this.getListView().setDivider(getResources().getDrawable(R.drawable.list_div));
+        int px=commonUtil.dp2px(getActivity(), 8.75f);
+        this.getListView().setDividerHeight(px);
+
+
+//        this.getListView().setBackground(getResources().getDrawable(R.drawable.list_corner_round_bg));
+        this.getListView().setBackgroundColor(getResources().getColor(R.color.table_bg)  );
+//        this.getListView().setSelector(R.drawable.list_corner_round);
+
+
+    }
+
+    protected View initHeaderView()
+    {
+
+        View headerView = LayoutInflater.from(getActivity()).inflate(R.layout.invisable_listheader, null);
+        return headerView;
+
+    }
+    protected JSONObject loadjson(int rawid)
+    {
+
+        String jstring = "";
+        try
+        {
+            InputStream in = getResources().openRawResource(rawid);
+            // 获取文件的字节数
+            int lenght = in.available();
+            // 创建byte数组
+            byte[] buffer = new byte[lenght];
+            // 将文件中的数据读到byte数组中
+            in.read(buffer);
+            jstring = EncodingUtils.getString(buffer, "UTF-8");
+            JSONObject jsobj = new JSONObject(jstring);
+            return jsobj;
+//            JSONObject objrecords = jsobj.getJSONObject("records");
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+        return null;
+
+    }
+
+    protected List<Map<String, Object>> getData(JSONObject jsobj)
+    {
+
+        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
+
+        try {
+            ModeName=jsobj.getString("title");
+            ModeIcon=jsobj.getString("icon");
+
+            JSONArray array = jsobj.getJSONArray("modelist");
+             for(int i=0;i<array.length();i++) {
+
+                 JSONObject rowobj = array.getJSONObject(i);
+
+                 Map<String, Object> map = new HashMap<String, Object>();
+                 String name=rowobj.getString("name");
+                 String info=rowobj.getString("detail");
+                 String    icon=rowobj.getString("icon");
+                 String    type=rowobj.getString("type");
+
+
+                 int iconid = commonUtil.iconName2Rid(getContext(),icon);
+                 map.put("title", name);
+                 map.put("detail", info);
+                 map.put("img", iconid);
+                 map.put("type", type);
+                 list.add(map);
+
+
+             }
+
+
+            // jsonobject.put("name", key);
+            // jsonobject.put("exp", key+"="+jsonobject.getString("value"));
+            // newArray.put(jsonobject);
+        } catch (JSONException e) {
+            e.printStackTrace();
+        }
+
+//        boolean login = false;
+//        Bundle b = getArguments();
+//
+//        if(b!=null)
+//        {
+//            login = b.getBoolean("Login");
+//        }
+
+
+//        Map<String, Object> map = new HashMap<String, Object>();
+//        map.put("title", "Market news");
+//        map.put("info", "google 1");
+//        map.put("img", R.drawable.rect_market_news);
+//        list.add(map);
+//
+//        map = new HashMap<String, Object>();
+//        map.put("title", "Announcements");
+//        map.put("info", "google 2");
+//        map.put("img", R.drawable.rect_announcements);
+//        list.add(map);
+//
+//        if (login)
+//        {
+//            map = new HashMap<String, Object>();
+//            map.put("title", "Saved Detail/Search");
+//            map.put("info", "google 2");
+//            map.put("img", R.drawable.rect_search_history);
+//            list.add(map);
+//
+//            map = new HashMap<String, Object>();
+//            map.put("title", "Change Password");
+//            map.put("img", R.drawable.rect_change_password);
+//            list.add(map);
+//            map = new HashMap<String, Object>();
+//            map.put("title", "Setting");
+//            map.put("img", R.drawable.rect_setting);
+//            list.add(map);
+//        }
+//
+//        map = new HashMap<String, Object>();
+//        map.put("title", "Apex History");
+//
+//        map.put("img", R.drawable.rect_history);
+//        list.add(map);
+//
+//        map = new HashMap<String, Object>();
+//        map.put("title", "About this App");
+//        map.put("info", "google 2");
+//        map.put("img", R.drawable.rect_about);
+//        list.add(map);
+
+        return list;
+    }
+
+}

+ 308 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/mainframe/ToolsFragment.java

@@ -0,0 +1,308 @@
+package com.usai.apex.mainframe;
+
+import android.content.ComponentName;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.Intent.ShortcutIconResource;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.support.v4.content.LocalBroadcastManager;
+import android.support.v7.app.AlertDialog;
+import android.util.Log;
+import android.view.View;
+import android.widget.ListView;
+
+import com.usai.apex.AboutActivity;
+import com.usai.apex.AnnouncementActivity;
+import com.usai.apex.ApexHistoryActivity;
+import com.usai.apex.ApexTrackingApplication;
+import com.usai.apex.InnerMapActivity;
+import com.usai.apex.R;
+
+import org.json.JSONObject;
+
+public class ToolsFragment extends StaticModelistFragment
+{
+
+
+	private static final int	REQUEST_LOGINACTIVITY			= 1;
+
+	private void delShortcut()
+	{
+		Intent shortcut = new Intent(
+				"com.android.launcher.action.UNINSTALL_SHORTCUT");
+
+		// 快捷方式的名称
+		shortcut.putExtra(Intent.EXTRA_SHORTCUT_NAME,
+				getString(R.string.app_name));
+
+		// 指定当前的Activity为快捷方式启动的对象: 如 com.everest.video.VideoPlayer
+		// 注意: ComponentName的第二个参数必须是完整的类名(包名+类名),否则无法删除快捷方式
+		String appClass = getActivity().getPackageName() + "."
+				+ getActivity().getLocalClassName();
+		ComponentName comp = new ComponentName(getActivity().getPackageName(),
+				appClass);
+		shortcut.putExtra(Intent.EXTRA_SHORTCUT_INTENT, new Intent(
+				Intent.ACTION_MAIN).setComponent(comp));
+
+		getActivity().sendBroadcast(shortcut);
+
+	}
+
+	private void addShortcut()
+	{
+		Intent shortcut = new Intent(
+				"com.android.launcher.action.INSTALL_SHORTCUT");
+
+		// 快捷方式的名称
+		shortcut.putExtra(Intent.EXTRA_SHORTCUT_NAME,
+				getString(R.string.app_name));
+		shortcut.putExtra("duplicate", false); // 不允许重复创建
+
+		// 指定当前的Activity为快捷方式启动的对象: 如 com.everest.video.VideoPlayer
+		// 注意: ComponentName的第二个参数必须加上点号(.),否则快捷方式无法启动相应程序
+		ComponentName comp = new ComponentName(getActivity().getPackageName(),
+				"." + getActivity().getLocalClassName());
+		shortcut.putExtra(Intent.EXTRA_SHORTCUT_INTENT, new Intent(
+				Intent.ACTION_MAIN).setComponent(comp));
+		// 快捷方式的图标
+		ShortcutIconResource iconRes = Intent.ShortcutIconResource.fromContext(
+				getActivity(), R.drawable.ic_launcher);
+		shortcut.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, iconRes);
+
+		getActivity().sendBroadcast(shortcut);
+	}
+
+
+
+	// @Override
+	// public void onActivityResult(int requestCode, int resultCode, Intent
+	// data)
+	// {
+	// switch (requestCode)
+	// {
+	// case REQUEST_LOGINACTIVITY:
+	// if (resultCode == Activity.RESULT_CANCELED)
+	// finish();
+	// break;
+	// case REQUEST_CHANGEPASSWORD_ACTIVITY:
+	// if (resultCode == Activity.RESULT_OK)
+	// {
+	// String UNIQUE_STRING = "com.usai.apex.push.cancel";
+	// Intent intent = new Intent(UNIQUE_STRING);
+	// sendBroadcast(intent);
+	// Intent i = new Intent();
+	// i.setClass(this, ApexActivity.class);
+	// startActivityForResult(i, 1);
+	// }
+	// break;
+	// default:
+	// break;
+	// }
+	//
+	// super.onActivityResult(requestCode, resultCode, data);
+	// }
+//	private List<Map<String, Object>> getData()
+//	{
+//		boolean login = false;
+//		Bundle b = getArguments();
+//
+//		if(b!=null)
+//		{
+//		 login = b.getBoolean("Login");
+//		}
+//		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
+//
+//		Map<String, Object> map = new HashMap<String, Object>();
+//		map.put("title", "Market news");
+//		map.put("info", "google 1");
+//		map.put("img", R.drawable.rect_market_news);
+//		list.add(map);
+//
+//		map = new HashMap<String, Object>();
+//		map.put("title", "Announcements");
+//		map.put("info", "google 2");
+//		map.put("img", R.drawable.rect_announcements);
+//		list.add(map);
+//
+//		if (login)
+//		{
+//			map = new HashMap<String, Object>();
+//			map.put("title", "Saved Detail/Search");
+//			map.put("info", "google 2");
+//			map.put("img", R.drawable.rect_search_history);
+//			list.add(map);
+//
+//			map = new HashMap<String, Object>();
+//			map.put("title", "Change Password");
+//			map.put("img", R.drawable.rect_change_password);
+//			list.add(map);
+//			map = new HashMap<String, Object>();
+//			map.put("title", "Setting");
+//			map.put("img", R.drawable.rect_setting);
+//			list.add(map);
+//		}
+//
+//		map = new HashMap<String, Object>();
+//		map.put("title", "Apex History");
+//
+//		map.put("img", R.drawable.rect_history);
+//		list.add(map);
+//
+//		map = new HashMap<String, Object>();
+//		map.put("title", "About this App");
+//		map.put("info", "google 2");
+//		map.put("img", R.drawable.rect_about);
+//		list.add(map);
+//
+//		return list;
+//	}
+
+//	@Override
+//	public void onActivityCreated(Bundle savedInstanceState)
+//	{
+//		super.onActivityCreated(savedInstanceState);
+//		SimpleAdapter adapter = new SimpleAdapter(this.getActivity(),
+//				getData(), R.layout.fragment_tools, new String[] { "title",
+//						"img" }, new int[] { R.id.tv_toolname, R.id.iv_icon });
+//		setListAdapter(adapter);
+//		this.getListView().setBackgroundColor(Color.WHITE);
+//	}
+
+
+	@Override
+	public void onActivityCreated(Bundle savedInstanceState)
+	{
+		super.onActivityCreated(savedInstanceState);
+
+        setupAdapter(R.raw.tools);
+
+//        adapter.getView()
+
+		customize_style();
+	}
+
+	@Override
+	public void onListItemClick(ListView l, View v, int position, long id)
+	{
+
+		JSONObject jsonobj=loadjson(R.raw.tools);
+		Log.d("FragmentList", "Item clicked: " + id);
+
+		String 	title = (String) getData(jsonobj).get(position-1).get("title");
+		String type = (String) getData(jsonobj).get(position-1).get("type");
+//		try {
+////			title = jsonobj.getJSONArray("modelist").getJSONObject(position);
+////
+//
+//
+//
+//			} catch (JSONException e) {
+//			e.printStackTrace();
+//		}
+
+		if (title.equals("Market News"))
+		{
+			Intent intent = new Intent();
+			intent.setClass(getActivity(), AnnouncementActivity.class);
+			intent.putExtra("module_name", "Market News");
+			startActivity(intent);
+		}
+		else if (title.equals("Announcements"))
+		{
+			Intent intent = new Intent();
+			intent.setClass(getActivity(), AnnouncementActivity.class);
+			intent.putExtra("module_name", "Announcements");
+			startActivity(intent);
+		}
+
+//		else if (title.equals("Saved Detail/Search"))
+//		{
+//			intent.setClass(getActivity(), SearchHistoryActivity.class);
+//		}
+//		else if (title.equals("Change Password"))
+//		{
+//			intent.setClass(getActivity(), ChangePasswordActivity.class);
+//
+//			startActivityForResult(intent, REQUEST_CHANGEPASSWORD_ACTIVITY);
+//			return;
+//		}
+		else if (title.equals("Apex History"))
+		{
+			Intent intent = new Intent();
+			intent.setClass(getActivity(), ApexHistoryActivity.class);
+			startActivity(intent);
+
+//			startActivityForResult(intent, REQUEST_CHANGEPASSWORD_ACTIVITY);
+//			return;
+		}
+		else if (title.equals("Service Location"))
+		{
+//			intent.setClass(getActivity(), ApexHistoryActivity.class);
+//
+//
+//			Intent intent = new Intent();
+			Intent intent = new Intent();
+			intent.setClass(getActivity(), InnerMapActivity.class);
+			startActivity(intent);
+
+//			startActivityForResult(intent, REQUEST_CHANGEPASSWORD_ACTIVITY);
+//			return;
+		}
+		else if (type.equals("clear_login"))
+		{
+
+			String msg = "Are you sure to clear saved login account and password?";
+			if (ApexTrackingApplication.m_bauthorized) {
+				msg = "Are you sure to logout current account and clear login information?";
+			}
+
+			new AlertDialog.Builder(getContext())
+					.setTitle("Warning")
+					.setMessage(msg)
+					.setNegativeButton("No",null)
+					.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
+						@Override
+						public void onClick(DialogInterface dialogInterface, int i) {
+
+							SharedPreferences pref = ApexTrackingApplication.get_instance().getSharedPreferences("Apex", 0);
+							SharedPreferences.Editor editor = pref.edit();
+							editor.putString("user", null);
+							editor.putString("password", null);
+							editor.putBoolean("autologin", false);
+							editor.commit();
+
+							String UNIQUE_STRING = "com.usai.apex.push.cancel";
+							Intent intent = new Intent(UNIQUE_STRING);
+							getActivity().sendBroadcast(intent);
+
+							Intent bintent = new Intent("Login");
+							bintent.putExtra("state", false);
+							LocalBroadcastManager.getInstance(getActivity()).sendBroadcast(bintent);
+						}
+					})
+					.show();
+
+
+		}
+		else if (type.equals("check_update"))
+		{
+			ApexTrackingApplication.get_instance().checkUpdate(false,"check update");
+		}
+		else if (title.equals("About"))
+		{
+			Intent intent = new Intent();
+			intent.setClass(getActivity(), AboutActivity.class);
+			startActivity(intent);
+		}
+//		else if (title.equals("Setting"))
+//		{
+//			intent.setClass(getActivity(), SettingsActivity.class);
+//
+////			startActivityForResult(intent, REQUEST_CHANGEPASSWORD_ACTIVITY);
+////			return;
+//		}
+
+
+	}
+}

+ 83 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/mainframe/TrackingImageView.java

@@ -0,0 +1,83 @@
+package com.usai.apex.mainframe;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.support.annotation.Nullable;
+import android.util.AttributeSet;
+import android.widget.ImageView;
+
+
+public class TrackingImageView extends ImageView {
+
+    public TrackingImageView(Context context) {
+        super(context);
+    }
+
+    public TrackingImageView(Context context, @Nullable AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public TrackingImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+    }
+
+    private Paint mBrush = new Paint(Paint.ANTI_ALIAS_FLAG);
+
+    private boolean mSelected = false;
+
+    public void setSelected(boolean selected) {
+        mSelected = selected;
+
+        invalidate();
+    }
+
+    public boolean getSelected() {
+        return mSelected;
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+        super.onDraw(canvas);
+
+        if (mSelected) {
+
+            mBrush.setAntiAlias(true); // 抗锯齿
+            mBrush.setDither(true); // 防抖动
+            mBrush.setStyle(Paint.Style.STROKE);
+            mBrush.setColor(Color.RED);
+//            mBrush.setStrokeWidth(dp2px(getContext(),0.5f));
+
+            Path border = new Path();
+            float r = Math.max(mWidth,mHeight) * 0.5f;
+            border.addCircle(mWidth * 0.5f,mHeight * 0.5f,r, Path.Direction.CW);
+
+            canvas.drawPath(border,mBrush);
+        }
+
+    }
+
+    int mWidth,mHeight;
+
+    @Override
+    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+        super.onSizeChanged(w, h, oldw, oldh);
+
+        mWidth = w;
+        mHeight = h;
+
+        invalidate();
+    }
+
+    public static int px2dp(Context context, float pxValue) {
+        float scale = context.getResources().getDisplayMetrics().density;
+        return (int) (pxValue / scale + 0.5f);
+    }
+
+    public static int dp2px(Context context, float dpValue) {
+        float scale = context.getResources().getDisplayMetrics().density;
+        return (int) (dpValue * scale + 0.5f);
+    }
+}

+ 843 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/mainframe/TrackingListFragment.java

@@ -0,0 +1,843 @@
+package com.usai.apex.mainframe;
+
+
+import android.app.ProgressDialog;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.graphics.Color;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.ListFragment;
+import android.support.v4.content.LocalBroadcastManager;
+import android.support.v4.widget.SwipeRefreshLayout;
+import android.support.v7.app.AlertDialog;
+import android.text.TextUtils;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.Button;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+
+import com.usai.apex.ApexTrackingApplication;
+import com.usai.apex.R;
+import com.usai.apex.Result.PullRefreshListView;
+import com.usai.apex.ShipMap.ShipMap;
+import com.usai.util.commonUtil;
+
+import org.apache.http.util.EncodingUtils;
+import org.json.JSONObject;
+
+import java.io.InputStream;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A simple {@link Fragment} subclass.
+ */
+public class TrackingListFragment extends ListFragment implements View.OnClickListener, ShipMap.ShipMapListener {
+    protected BaseAdapter adapter;
+    boolean bdirty = false;
+//    List<Map<String, Object>> list_data;
+TrackingListSearchResult searchresult	= new TrackingListSearchResult();
+
+    @Override
+    public void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+
+        outState.putSerializable("searchresult",searchresult);
+        outState.putBoolean("dirty",bdirty);
+        outState.putBoolean("mapZoomIn",mMapZoomIn);
+
+    }
+
+    @Override
+    public void onDestroyView() {
+        super.onDestroyView();
+    }
+
+    @Override
+    public void onViewStateRestored(@Nullable Bundle savedInstanceState) {
+        super.onViewStateRestored(savedInstanceState);
+
+        if (savedInstanceState != null)
+        {
+            searchresult = (TrackingListSearchResult) savedInstanceState
+                    .getSerializable("searchresult");
+            bdirty = savedInstanceState.getBoolean("dirty");
+            if (searchresult.get_count() == 0 && isActive())
+                requestData();
+//            else
+//                initTable();
+        }
+//        else
+//            requestData();
+    }
+
+    public TrackingListFragment self = this;
+
+    @Override
+    public void onClick(View v) {
+
+    }
+
+    //    protected class TrackingListSearchResult implements Serializable
+//    {
+//        private static final long serialVersionUID = 335021506170621905L;
+//        List<Map<String, Object>>	datalist	= new ArrayList<Map<String, Object>>();
+//
+//        public int get_count()
+//        {
+//            return datalist.size();
+//        }
+//
+//        public void add_records(String source, int count)
+//        {
+//            JSONArray arrrecords=null;
+//            try
+//            {
+//                arrrecords = new JSONArray(source);
+//
+//                for (int i=0;i<arrrecords.length();i++)
+//                {
+//                    JSONObject objrec =arrrecords.getJSONObject(i);
+//
+//
+////                    String title = objrec.getString("title");
+////                    String icon = objrec.getString("icon");
+////                    String description = objrec.getString("description");
+////                    String detail = objrec.getString("detail");
+////                    String date = objrec.getString("date");
+////                    String port = objrec.getString("port");
+////
+////                    int iconid = commonUtil.iconName2Rid(getContext(),icon);
+////
+////
+//////                    lastid = id;
+////                    Map<String, Object> map = new HashMap<String, Object>();
+////                    map.put("title", title);
+////                    map.put("icon", iconid);
+////                    map.put("description", description);
+////                    map.put("detail", detail);
+////                    map.put("date", date);
+////                    map.put("port", port);
+//
+//
+//                    Map<String, Object> map = new HashMap<String, Object>();
+//
+//                    Iterator<String> keys = objrec.keys();
+//                    while (keys.hasNext()) {
+//                        String key = keys.next();
+//                        Object value = objrec.get(key);
+//
+//                        if (key.equals("icon")) {
+//                            int iconid = commonUtil.iconName2Rid(getContext(),(String)value);
+//                            value = iconid;
+//                        }
+//                        map.put(key, value);
+//
+//                    }
+//
+//                    datalist.add(map);
+//
+//                }
+//
+////                for (int i = 0; i < count; i++)
+////                {
+////                    // offset++;
+////                    JSONObject objrec = objrecords.getJSONObject("record" + i);
+////                    String title = objrec.getString("title");
+////                    String content = objrec.getString("content");
+////                    String image = objrec.getString("image");
+////                    String id = objrec.getString("id");
+////                    String url = objrec.getString("url");
+//////                    lastid = id;
+////                    Map<String, Object> map = new HashMap<String, Object>();
+////                    map.put("title", title);
+////                    map.put("content", content);
+////                    map.put("image", image);
+////                    map.put("id", id);
+////                    map.put("url", url);
+////                    datalist.add(map);
+////
+////                    // Iterator<?> it = rec.keys();
+////                    // HashMap<String, String> record = new HashMap<String,
+////                    // String>();
+////                    // while (it.hasNext()) // loop for each function
+////                    // {
+////                    // String field_name = (String) it.next();
+////                    // String val = rec.getString(field_name)
+////                    // .replace("\n", "");
+////                    // record.put(field_name, val);
+////                    // }
+////                    // records.add(record);
+////
+////                }
+//            }
+//            catch (JSONException e)
+//            {
+//                // TODO Auto-generated catch block
+//                e.printStackTrace();
+//            }
+//
+//        }
+//
+//        public List<Map<String, Object>> getData()
+//        {
+//
+//            return datalist;
+//        }
+//
+//        public void clear() {
+//            datalist.clear();
+//        }
+//    }
+
+    public int mSelectedIndex = -1;
+
+    private boolean mMapZoomIn = false;
+
+    @Override
+    public void shipMapTryToZoomIn(ShipMap shipMap, boolean zoomIn) {
+
+        if (zoomIn) {
+
+            LinearLayout.LayoutParams lfLayoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, dp2px(mContext,96.0f));
+            mShipTable.setLayoutParams(lfLayoutParams);
+
+        } else {
+//            LinearLayout.LayoutParams mapLayoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0,1.0f);
+//            shipMap.setLayoutParams(mapLayoutParams);
+
+
+            LinearLayout.LayoutParams lfLayoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0,2.0f);
+            mShipTable.setLayoutParams(lfLayoutParams);
+        }
+
+        mMapZoomIn = zoomIn;
+
+    }
+
+    private class TrackingAdapter extends BaseAdapter
+    {
+        private LayoutInflater mInflater;	// 动态布局映射
+        private TrackingListSearchResult result;
+
+        // private Context context;
+        // private int i = 0;
+        public TrackingAdapter(TrackingListSearchResult result, Context context)
+        {
+            this.result = result;
+            // this.context = context;
+            this.mInflater = LayoutInflater.from(context);
+        }
+
+        @Override
+        public int getCount()
+        {
+            // TODO Auto-generated method stub
+            return result.get_count();
+        }
+
+        @Override
+        public Object getItem(int position)
+        {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public long getItemId(int position)
+        {
+            // TODO Auto-generated method stub
+            return 0;
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent)
+        {
+            // TODO Auto-generated method stub
+
+            /*
+                             String title = objrec.getString("title");
+                    String icon = objrec.getString("icon");
+                    String description = objrec.getString("description");
+                    String detail = objrec.getString("detail");
+                    String date = objrec.getString("date");
+                    String port = objrec.getString("port");
+             */
+
+            if(convertView==null)
+                convertView = mInflater.inflate(R.layout.tracking_list_cell, null);// 根据布局文件实例化view
+
+            View contentView = convertView.findViewById(R.id.cell_content_view);
+            if (contentView != null) {
+                if (mSelectedIndex == position) {
+                    contentView.setBackground(getResources().getDrawable(R.drawable.list_corner_round_selected_bg));
+                } else {
+                    contentView.setBackground(getResources().getDrawable(R.drawable.list_corner_round_bg));
+                }
+            }
+
+            TextView title = (TextView) convertView.findViewById(R.id.tv_title);// 找某个控件
+            title.setText(result.getData().get(position).get("title")
+                    .toString());// 给该控件设置数据(数据从集合类中来)
+
+            TextView date = (TextView) convertView
+                    .findViewById(R.id.tv_time);
+            date.setText(result.getData().get(position).get("date")
+                    .toString());
+
+            TextView description = (TextView) convertView
+                    .findViewById(R.id.tv_description);
+            description.setText(result.getData().get(position).get("description")
+                    .toString());
+
+            TextView detail = (TextView) convertView
+                    .findViewById(R.id.tv_detail);
+            detail.setText(result.getData().get(position).get("detail")
+                    .toString());
+
+            TextView port = (TextView) convertView
+                    .findViewById(R.id.tv_port);
+            port.setText(result.getData().get(position).get("port")
+                    .toString());
+
+            TrackingImageView iv_status = (TrackingImageView) convertView.findViewById(R.id.iv_status);
+            iv_status.setImageResource((int)result.getData().get(position).get("icon"));
+            if (self instanceof RecentFragment) {
+                iv_status.setSelected(mSelectedIndex == position);
+            } else {
+                iv_status.setSelected(false);
+            }
+
+            // new icon click
+            iv_status.setOnClickListener(self);
+            iv_status.setTag(position);
+
+            View v=(View) convertView
+                    .findViewById(R.id.v_transport_stage);
+
+            String sstransport_stage =result.getData().get(position).get("transport_stage").toString();
+
+            if(TextUtils.isEmpty(sstransport_stage))
+                sstransport_stage="0";
+            int  transport_stage = Integer.valueOf(sstransport_stage).intValue();
+
+             switch(transport_stage)
+             {
+
+                 case 0:
+
+
+                     v.setBackground(ApexTrackingApplication.getInstance().getResources().getDrawable(R.drawable.list_corner_transport_stage_bg_0));
+//                     v.setBackgroundColor(.getColor(R.color.transport_stage_0));
+                     break;
+                 case 1:
+                     v.setBackground(ApexTrackingApplication.getInstance().getResources().getDrawable(R.drawable.list_corner_transport_stage_bg_1));
+//                     v.setBackgroundColor(ApexTrackingApplication.getInstance().getResources().getColor(R.color.transport_stage_1));
+                     break;
+                 case 2:
+                     v.setBackground(ApexTrackingApplication.getInstance().getResources().getDrawable(R.drawable.list_corner_transport_stage_bg_2));
+//                     v.setBackgroundColor(ApexTrackingApplication.getInstance().getResources().getColor(R.color.transport_stage_2));
+                     break;
+                 case 3:
+                     v.setBackground(ApexTrackingApplication.getInstance().getResources().getDrawable(R.drawable.list_corner_transport_stage_bg_3));
+//                     v.setBackgroundColor(ApexTrackingApplication.getInstance().getResources().getColor(R.color.transport_stage_3));
+                     break;
+                 default:
+                     v.setBackground(ApexTrackingApplication.getInstance().getResources().getDrawable(R.drawable.list_corner_transport_stage_bg_0));
+                    // v.setBackgroundColor(ApexTrackingApplication.getInstance().getResources().getColor(R.color.transport_stage_0));
+                     break;
+
+             }
+//            if (result.getData().get(position).get("image").toString().length() > 0)
+//            {
+//                byte[] gzipBuff = Base64.decode(result.getData().get(position)
+//                        .get("image").toString(), 0);
+//
+//                ByteArrayInputStream memstream = new ByteArrayInputStream(
+//                        gzipBuff, 0, gzipBuff.length);
+//
+//                ByteArrayOutputStream baos = new ByteArrayOutputStream(
+//                        gzipBuff.length);
+//                ImageView iv_thumb = (ImageView) convertView
+//                        .findViewById(R.id.iv_thumb);
+//                try
+//                {
+//                    baos.write(gzipBuff);
+//
+//                    Bitmap bmp = BitmapFactory.decodeStream(memstream);
+//
+//                    // ImageView image = new ImageView(this);
+//
+//                    iv_thumb.setImageBitmap(bmp);
+//                }
+//                catch (IOException e)
+//                {
+//                    // TODO Auto-generated catch block
+//                    e.printStackTrace();
+//                }
+//            }
+            // img.setBackgroundResource((Integer)jObject.get("img"));
+
+            convertView.setTag(position);
+
+            return convertView;
+        }
+    }
+    public TrackingListFragment() {
+        // Required empty public constructor
+    }
+    protected View initHeaderView()
+    {
+
+        return null;
+
+    }
+
+    @Override
+    public void onActivityCreated(Bundle savedInstanceState)
+    {
+        super.onActivityCreated(savedInstanceState);
+//
+//        progressDialog = new ProgressDialog(mContext);
+//        progressDialog.setCancelable(false);
+
+
+        if (savedInstanceState != null)
+        {
+            searchresult = (TrackingListSearchResult) savedInstanceState
+                    .getSerializable("searchresult");
+            bdirty = savedInstanceState.getBoolean("dirty");
+            if(searchresult.getData().size()==0)
+            {
+
+                showRefreshButton(true);
+            }
+            else
+            {
+                showRefreshButton(false);
+
+            }
+            if (searchresult.get_count() == 0 && isActive())
+                requestData();
+//            else
+//                initTable();
+        }
+//        else
+//            requestData();
+
+        setupAdapter();
+        customize_style();
+
+
+
+
+        // this.getListView().setBackgroundColor(Color.WHITE);
+//        requestdata();
+
+    }
+
+    protected  void setupAdapter()
+    {
+        adapter = new TrackingAdapter(searchresult, this.getActivity());
+
+//        module_name = getIntent().getStringExtra("module_name");
+//
+//        setTitle(module_name);
+//        view_page_footer = LayoutInflater.from(this).inflate(
+//                R.layout.view_page_footer, null);
+//        getListView().addFooterView(view_page_footer);// 添加底部视图
+//        TextView text_page = (TextView) view_page_footer
+//                .findViewById(R.id.text_page);
+//        text_page.setOnClickListener(new View.OnClickListener()
+//        {
+//            // 点击按钮 追加数据 并通知适配器
+//            @Override
+//            public void onClick(View v)
+//            {
+//                // TODO Auto-generated method stub
+//                // TextView tv = (TextView) v;
+//                // tv.setText("Loading...");
+//                requestdata();
+//                // tv.setText("下一页");
+//                // adapter.notifyDataSetChanged();
+//            }
+//        });
+
+        View headerView = initHeaderView();
+        if(headerView!=null)
+            getListView().addHeaderView(headerView);
+        setListAdapter(adapter);
+    }
+
+    protected void customize_style()
+    {
+
+
+//        Button btn = new Button(this.getContext());
+//        btn.setBackgroundResource(R.drawable.tablehead);
+//        btn.setPadding(0, 0, 0, 0);
+//        btn.setText("No.");
+//        this.getListView().getParent().addHeaderView(btn);
+
+//        this.getListView().setDivider(new ColorDrawable(Color.RED));
+        this.getListView().setDivider(getResources().getDrawable(R.drawable.list_div));
+//        this.getListView().setDividerHeight(20);
+
+        int px=commonUtil.dp2px(getActivity(), 8.75f);
+        this.getListView().setDividerHeight(px);
+
+//        this.getListView().setBackground(getResources().getDrawable(R.drawable.list_corner_round_bg));
+        this.getListView().setBackgroundColor(getResources().getColor(R.color.table_bg)  );
+//        this.getListView().setSelector(R.drawable.list_corner_round);
+
+
+    }
+
+    protected JSONObject loadfakecontent(int rawid)
+    {
+
+        String jstring = "";
+        try
+        {
+            InputStream in = getResources().openRawResource(rawid);
+            // 获取文件的字节数
+            int lenght = in.available();
+            // 创建byte数组
+            byte[] buffer = new byte[lenght];
+            // 将文件中的数据读到byte数组中
+            in.read(buffer);
+            jstring = EncodingUtils.getString(buffer, "UTF-8");
+            JSONObject jsobj = new JSONObject(jstring);
+            return jsobj;
+//            JSONObject objrecords = jsobj.getJSONObject("records");
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+        return null;
+
+    }
+
+    protected List<Map<String, Object>> getData(JSONObject jsobj)
+    {
+        return null;
+    }
+
+//    ProgressDialog progressDialog;
+    boolean isLoading = false;//表示是否正处于加载状态
+    Context mContext;
+    SwipeRefreshLayout mSwipeRefresh;
+    private TrackingBroadcastReceiver mReceiver;
+
+    @Override
+    public void onAttach(Context context) {
+        super.onAttach(context);
+        mContext = context;
+    }
+
+//    protected void showProgressDialog(String title, String msg) {
+//        if (!getUserVisibleHint()) {
+//            return;
+//        }
+//
+//        progressDialog.setTitle(title);
+//        progressDialog.setMessage(msg);
+//        progressDialog.show();
+//    }
+
+    public void showAlert(String msg) {
+
+        if (!getUserVisibleHint()) {
+            return;
+        }
+
+        if (msg == null || msg.isEmpty()) {
+            return;
+        }
+
+        new AlertDialog.Builder(mContext)
+                .setMessage(msg)
+                .show();
+    }
+
+    static final int INTERNAL_EMPTY_ID = 0x00ff0001;
+    static final int NO_RECORD_BUTTON_ID = 0x00ff0010;
+    static final int INTERNAL_PROGRESS_CONTAINER_ID = 0x00ff0002;
+    static final int INTERNAL_LIST_CONTAINER_ID = 0x00ff0003;
+
+    protected PullRefreshListView mPullRefreshListView;
+    protected View refresh_footer;
+//    protected Button btn_reload;
+    private ProgressBar mProgressLayout;
+
+    protected void showRefreshButton(boolean show) {
+        Button btn = getView().findViewById(NO_RECORD_BUTTON_ID);
+        if (show&&btn!=null) {
+            btn.setVisibility(View.VISIBLE);
+        } else {
+            btn.setVisibility(View.INVISIBLE);
+        }
+    }
+    public void showProgress(boolean show) {
+        if (show) {
+            mProgressLayout.setVisibility(View.VISIBLE);
+        } else {
+            mProgressLayout.setVisibility(View.GONE);
+        }
+    }
+
+    public static int dp2px(Context context, float dpValue) {
+        float scale = context.getResources().getDisplayMetrics().density;
+        return (int) (dpValue * scale + 0.5f);
+    }
+
+    private ShipMap mShipMap;
+
+    public ShipMap getShipMap() {
+        return mShipMap;
+    }
+
+    private void configureMap(ShipMap map) {
+        if (map == null) {
+            return;
+        }
+
+        map.setShowCurrent(true);
+        map.setShowDestination(true);
+        map.setShowOrigin(true);
+        map.setShowPor(true);
+        map.setShowPoe(true);
+        map.setShowPod(true);
+        map.setShowPol(true);
+
+        map.setShipMapListener(self);
+    }
+
+    private FrameLayout mShipTable;
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                             Bundle savedInstanceState) {
+        final Context context = getContext();
+
+        FrameLayout root = new FrameLayout(context);
+
+        // ------------------------------------------------------------------
+
+        mReceiver = new TrackingBroadcastReceiver();
+        LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(getContext());
+        IntentFilter intentFilter = new IntentFilter("com.apex.broadcast.person_mode");
+        localBroadcastManager.registerReceiver(mReceiver,intentFilter);
+
+        // -------------------------
+
+        LinearLayout linearLayout = new LinearLayout(context);
+        linearLayout.setOrientation(LinearLayout.VERTICAL);
+        linearLayout.setBackgroundColor(Color.parseColor("#EFEFF4"));
+
+        if (this instanceof RecentFragment) {
+
+            ShipMap shipMap = new ShipMap(context);
+            mShipMap = shipMap;
+
+            LinearLayout.LayoutParams mapLayoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0,1.0f);
+            mapLayoutParams.setMargins(dp2px(context,5),dp2px(context,2),dp2px(context,5),dp2px(context,2));
+
+            linearLayout.addView(shipMap,mapLayoutParams);
+
+            mShipMap.setBackgroundColor(Color.parseColor("#EFEFF4"));
+
+            configureMap(mShipMap);
+        }
+
+        // ------------------------------------------------------------------
+
+        FrameLayout lframe = new FrameLayout(context);
+        lframe.setId(INTERNAL_LIST_CONTAINER_ID);
+
+        TextView tv = new TextView(context);
+        tv.setId(INTERNAL_EMPTY_ID);
+        tv.setGravity(Gravity.CENTER);
+
+
+        Button btn = new Button(this.getContext());
+//        btn_reload = btn;
+        btn.setId(NO_RECORD_BUTTON_ID);
+        btn.setBackgroundResource(R.drawable.btn_bg);
+        btn.setPadding(15, 0, 15, 0);
+        btn.setText("No Record found.");
+        btn.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View view) {
+                requestData();
+            }
+        });
+
+        btn.setVisibility(View.INVISIBLE);
+
+        FrameLayout.LayoutParams lparams=new FrameLayout.LayoutParams(
+                ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+        lparams.gravity = Gravity.CENTER;
+        lframe.addView(btn, lparams);
+
+        lframe.addView(tv, new FrameLayout.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
+
+
+        // Swipe
+        SwipeRefreshLayout swipeRefreshLayout = new SwipeRefreshLayout(context);
+        mSwipeRefresh = swipeRefreshLayout;
+        mSwipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
+            @Override
+            public void onRefresh() {
+                requestData();
+            }
+        });
+
+        PullRefreshListView lv = new PullRefreshListView(context);
+        mPullRefreshListView = lv;
+        lv.setId(android.R.id.list);
+        lv.setDrawSelectorOnTop(false);
+        lv.setBackgroundColor(Color.parseColor("#EFEFF4"));
+
+
+        swipeRefreshLayout.addView(lv, new FrameLayout.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
+
+        lframe.addView(swipeRefreshLayout, new FrameLayout.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
+
+        LinearLayout.LayoutParams lfLayoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0,2.0f);
+        linearLayout.addView(lframe,lfLayoutParams);
+
+        mShipTable = lframe;
+
+//        root.addView(lframe, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
+        root.addView(linearLayout, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
+
+        // ------------------------------------------------------------------
+
+        root.setLayoutParams(new FrameLayout.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
+
+        ProgressBar progress = new ProgressBar(context, null, android.R.attr.progressBarStyleLarge);
+        progress.setVisibility(View.GONE);
+        FrameLayout.LayoutParams layoutParams =  new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+        layoutParams.gravity = Gravity.CENTER;
+        root.addView(progress, layoutParams);
+
+        mProgressLayout = progress;
+
+        if (savedInstanceState != null) {
+            mMapZoomIn = savedInstanceState.getBoolean("mapZoomIn");
+        }
+        if (mShipMap != null) {
+            mShipMap.setZoomIn(mMapZoomIn);
+        }
+
+        return root;
+    }
+
+    @Override
+    public void onDestroy() {
+
+        LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(getContext());
+        localBroadcastManager.unregisterReceiver(mReceiver);
+
+        if (mShipMap != null) {
+            mShipMap.destroy();
+        }
+
+        super.onDestroy();
+    }
+
+    @Override
+    public void setUserVisibleHint(boolean isVisibleToUser) {
+        super.setUserVisibleHint(isVisibleToUser);
+
+        if (isVisibleToUser) {
+
+        } else {
+
+        }
+    }
+
+    public View getCellForPosition(int position) {
+
+//        int startShowIndex = getListView().getFirstVisiblePosition();
+//        int lastShowIndex = getListView().getLastVisiblePosition();
+//        if (position >= startShowIndex && position <= lastShowIndex) {
+//            View cell = getListView().getChildAt(position - startShowIndex + 1); // 因为有个Header所以+1
+//            return cell;
+//        }
+//        return null;
+
+        return getListView().findViewWithTag(position);
+    }
+
+    public void checkDirty()
+    {
+        if(bdirty)
+            requestData();
+    }
+    protected boolean isActive()
+    {
+        return false;
+    }
+
+    protected void requestData() {
+
+
+    }
+
+    class TrackingBroadcastReceiver extends BroadcastReceiver {
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (searchresult.get_count() > 0) {
+                mPullRefreshListView.setSelection(0);
+            }
+
+            bdirty = true;
+
+            if(isActive())
+            {
+                requestData();
+            }
+//            checkDirty();
+//
+        }
+    }
+
+    private ProgressDialog mProgressDialog;
+
+    public void showProgressDialog() {
+
+        if (mProgressDialog == null) {
+            if (getContext() == null) {
+                return;
+            }
+            mProgressDialog = new ProgressDialog(getContext());
+            mProgressDialog.setCancelable(false);
+            mProgressDialog.setMessage("Loading...");
+        }
+        mProgressDialog.show();
+    }
+
+    public void dismissProgressDialog() {
+        if (mProgressDialog != null && mProgressDialog.isShowing()) {
+            mProgressDialog.dismiss();
+        }
+    }
+}

+ 159 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/mainframe/TrackingListSearchResult.java

@@ -0,0 +1,159 @@
+package com.usai.apex.mainframe;
+
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.usai.apex.ApexTrackingApplication;
+import com.usai.util.commonUtil;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+public class TrackingListSearchResult implements Serializable, Parcelable
+{
+    private static final long serialVersionUID = 335021506170621905L;
+    List<Map<String, Object>> datalist	= new ArrayList<Map<String, Object>>();
+
+    TrackingListSearchResult() {
+
+    }
+
+    protected TrackingListSearchResult(Parcel in) {
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    public static final Creator<TrackingListSearchResult> CREATOR = new Creator<TrackingListSearchResult>() {
+        @Override
+        public TrackingListSearchResult createFromParcel(Parcel in) {
+            return new TrackingListSearchResult(in);
+        }
+
+        @Override
+        public TrackingListSearchResult[] newArray(int size) {
+            return new TrackingListSearchResult[size];
+        }
+    };
+
+    public int get_count()
+    {
+        return datalist.size();
+    }
+
+    public void add_records(String source, int count)
+    {
+        JSONArray arrrecords=null;
+        try
+        {
+            arrrecords = new JSONArray(source);
+
+            for (int i=0;i<arrrecords.length();i++)
+            {
+                JSONObject objrec =arrrecords.getJSONObject(i);
+
+
+//                    String title = objrec.getString("title");
+//                    String icon = objrec.getString("icon");
+//                    String description = objrec.getString("description");
+//                    String detail = objrec.getString("detail");
+//                    String date = objrec.getString("date");
+//                    String port = objrec.getString("port");
+//
+//                    int iconid = commonUtil.iconName2Rid(getContext(),icon);
+//
+//
+////                    lastid = id;
+//                    Map<String, Object> map = new HashMap<String, Object>();
+//                    map.put("title", title);
+//                    map.put("icon", iconid);
+//                    map.put("description", description);
+//                    map.put("detail", detail);
+//                    map.put("date", date);
+//                    map.put("port", port);
+
+
+                Map<String, Object> map = new HashMap<String, Object>();
+
+                Iterator<String> keys = objrec.keys();
+                while (keys.hasNext()) {
+                    String key = keys.next();
+                    Object value = objrec.get(key);
+
+                    if (key.equals("icon")) {
+                        int iconid = commonUtil.iconName2Rid( ApexTrackingApplication.get_instance(),(String)value);
+                        value = iconid;
+                    }
+                    map.put(key, value);
+
+                }
+
+                datalist.add(map);
+
+            }
+
+//                for (int i = 0; i < count; i++)
+//                {
+//                    // offset++;
+//                    JSONObject objrec = objrecords.getJSONObject("record" + i);
+//                    String title = objrec.getString("title");
+//                    String content = objrec.getString("content");
+//                    String image = objrec.getString("image");
+//                    String id = objrec.getString("id");
+//                    String url = objrec.getString("url");
+////                    lastid = id;
+//                    Map<String, Object> map = new HashMap<String, Object>();
+//                    map.put("title", title);
+//                    map.put("content", content);
+//                    map.put("image", image);
+//                    map.put("id", id);
+//                    map.put("url", url);
+//                    datalist.add(map);
+//
+//                    // Iterator<?> it = rec.keys();
+//                    // HashMap<String, String> record = new HashMap<String,
+//                    // String>();
+//                    // while (it.hasNext()) // loop for each function
+//                    // {
+//                    // String field_name = (String) it.next();
+//                    // String val = rec.getString(field_name)
+//                    // .replace("\n", "");
+//                    // record.put(field_name, val);
+//                    // }
+//                    // records.add(record);
+//
+//                }
+        }
+        catch (JSONException e)
+        {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+
+    }
+
+    public List<Map<String, Object>> getData()
+    {
+
+        return datalist;
+    }
+
+    public void clear() {
+        datalist.clear();
+    }
+}

+ 401 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/pdf/PDFPreviewActivity.java

@@ -0,0 +1,401 @@
+package com.usai.apex.pdf;
+
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.graphics.Color;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
+import android.support.v4.content.FileProvider;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AppCompatActivity;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.TextView;
+
+import com.github.barteksc.pdfviewer.PDFView;
+import com.github.barteksc.pdfviewer.listener.OnLoadCompleteListener;
+import com.github.barteksc.pdfviewer.listener.OnPageChangeListener;
+import com.github.barteksc.pdfviewer.listener.OnPageErrorListener;
+import com.github.barteksc.pdfviewer.util.FitPolicy;
+import com.shockwave.pdfium.PdfDocument;
+import com.usai.apex.ApexTrackingApplication;
+import com.usai.apex.R;
+import com.usai.util.RAUtil;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.File;
+import java.util.List;
+
+public class PDFPreviewActivity extends AppCompatActivity implements OnPageChangeListener, OnLoadCompleteListener,
+        OnPageErrorListener {
+
+    boolean iscachefile;
+    private static final String TAG = PDFPreviewActivity.class.getSimpleName();
+//    String pdfFileName;
+    PDFView pdfView;
+//    @NonConfigurationInstance
+    Integer pageNumber = 0;
+//    public static final String SAMPLE_FILE = "sample.pdf";
+
+
+
+    protected void openFile() {
+
+        String path=getIntent().getStringExtra("file");
+        File file = new File(path);
+        if (file == null || !file.exists()) {
+            return;
+        }
+
+        Uri uri = null;
+        String type = RAUtil.getMimeType(file.getPath());
+
+        // type "application/pdf"
+        Intent intent = new Intent(Intent.ACTION_VIEW);
+
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+
+            // "com.usai.apex.fileprovider"即是在Manifest文件中配置的authorities
+            uri = FileProvider.getUriForFile(this, "com.usai.apex.fileprovider", file);
+            // 给目标应用一个临时授权
+            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+        } else {
+            uri = Uri.fromFile(file);
+        }
+
+        intent.setDataAndType(uri, type);
+
+        if (getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY) != null) {
+            // someone knows how to handle this mime type with this scheme, don't download.
+            try {
+                startActivity(intent);
+                return;
+            } catch (Exception ex) {
+                Log.d("Open File", "activity not found for " + type + " over " + uri, ex);
+            }
+
+        } else {
+            Log.d("Open File", "openFileAtPath: " + "No App " + uri);
+
+
+            AlertDialog.Builder builder = new AlertDialog.Builder(
+                    PDFPreviewActivity.this);
+            builder.setMessage("Can not open PDF file, no external App found." );
+
+            builder.setTitle("Open PDF");
+
+            builder.setPositiveButton(getString(android.R.string.ok), new DialogInterface.OnClickListener()
+            {
+
+                @Override
+                public void onClick(DialogInterface dialog, int which)
+                {
+                    dialog.dismiss();
+
+
+                }
+            });
+
+            builder.create().show();
+
+//            try {
+//                shareFile(uri,type);
+//            } catch (Exception e) {
+//                Log.e("Show Dialog Error", "openFileAtPath: ", e);
+//            }
+        }
+
+    }
+
+    protected void shareFile(/*Uri uri, String type*/) {
+
+        String path=getIntent().getStringExtra("file");
+        File file = new File(path);
+        if (file == null || !file.exists()) {
+            return;
+        }
+        Uri uri = null;
+        String type = RAUtil.getMimeType(file.getPath());
+
+
+        String email_to = null,email_subject = null,email_content = null;
+        String json_str = null;
+        if (iscachefile) {
+
+            json_str = getIntent().getStringExtra("email");
+        } else {
+
+            String filename = file.getName();
+            String dir = file.getParent();
+            json_str = RAUtil.readJson(dir + File.separator + filename + ".email");
+        }
+        if (json_str != null) {
+            try {
+                JSONObject email_json = new JSONObject(json_str);
+                email_to = email_json.getString("email");
+                email_subject = email_json.getString("subject");
+                email_content = email_json.getString("content");
+            } catch (JSONException e) {
+                e.printStackTrace();
+            }
+        }
+
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+
+            // "com.usai.apex.fileprovider"即是在Manifest文件中配置的authorities
+            uri = FileProvider.getUriForFile(this, "com.usai.apex.fileprovider", file);
+            // 给目标应用一个临时授权
+        } else {
+            uri = Uri.fromFile(file);
+        }
+
+        Intent share = new Intent();
+        share.setAction(Intent.ACTION_SEND);
+        share.putExtra(Intent.EXTRA_STREAM, uri);
+        share.setType(type);
+
+
+        if (email_content != null) {
+            share.putExtra(Intent.EXTRA_TEXT, email_content);   //附带的说明信息
+        }
+        if (email_subject != null) {
+            share.putExtra(Intent.EXTRA_SUBJECT, email_subject);
+        }
+        if (email_to != null) {
+            share.putExtra(Intent.EXTRA_EMAIL, email_to.split(","));
+        }
+
+//        share.putExtra(Intent.EXTRA_CC, new String[]{"ray.zhang@united-cn.net"});
+//        startActivity(Intent.createChooser(share,getString(R.string.str_sendto)));
+        startActivity(Intent.createChooser(share, "Share"));
+
+
+
+
+//        Intent share = new Intent(Intent.ACTION_SEND);
+//        String filename = (String) v.getTag();
+//        share.putExtra(Intent.EXTRA_STREAM,
+//                Uri.fromFile(new File(Environment.getExternalStorageDirectory().getPath()+"/Apex Mobile/"+filename)));
+//        String[] token = filename.split("\\.");
+//        String ext = token[token.length-1];
+//        share.setType("application/"+ext);//此处可发送多种文件
+
+    }
+
+    private void setCustomActionBar() {
+        ActionBar.LayoutParams lp =new ActionBar.LayoutParams(ActionBar.LayoutParams.MATCH_PARENT, ActionBar.LayoutParams.MATCH_PARENT, Gravity.CENTER);
+        View mActionBarView = LayoutInflater.from(this).inflate(R.layout.actionbar_customtitle, null);
+
+        String path=getIntent().getStringExtra("file");
+        String title=new File(path).getName();
+        TextView mtitleview= mActionBarView.findViewById(R.id.title);
+//        String title = mParams.getString("title");
+        mtitleview.setText(title);
+        setTitle(title);
+//
+//        mActionBarView.setBackgroundColor(Color.YELLOW);
+//        titleview.setBackgroundColor(Color.BLUE);
+        ActionBar actionBar = getSupportActionBar();
+        actionBar.setCustomView(mActionBarView, lp);
+//        actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
+//        actionBar.setDisplayShowCustomEnabled(true);
+        actionBar.setDisplayHomeAsUpEnabled(true);
+
+
+//        actionBar.setIcon(getNumberDrawable());
+//        actionBar.setDisplayShowHomeEnabled(true);
+        actionBar.setDisplayShowTitleEnabled(true);
+    }
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+
+            case android.R.id.home:
+                finish();
+                break;
+            case R.id.action_save:
+                SavePDF();
+                break;
+            case R.id.action_open:
+                openFile();
+                break;
+            case R.id.action_send:
+                shareFile();
+                break;
+
+            default: break;
+        }
+        return super.onOptionsItemSelected(item);
+    }
+
+    private void SavePDF()
+    {
+
+
+        String todir=ApexTrackingApplication.getInstance().getDocumentDir();
+
+//        String sourcefile=getIntent().getStringExtra("file");
+        File source =new File(getIntent().getStringExtra("file"));
+        String filename = source.getName();
+//        boolean successful= source.renameTo(new File(todir+filename));
+
+        boolean successful=RAUtil.copyFile(getIntent().getStringExtra("file"),todir+"/"+filename);
+        String json_str = getIntent().getStringExtra("email");
+        if (json_str != null) {
+            RAUtil.writeJson(json_str,todir + File.separator + filename + ".email");
+        }
+
+//        Files.copy(source, Path target, CopyOption... options)
+
+        String title= "Save document";
+        String msg = "Can not save document";
+
+        if(successful)
+        {
+            msg= "Document Saved";
+
+        }
+
+        AlertDialog.Builder builder = new AlertDialog.Builder(
+                PDFPreviewActivity.this);
+        builder.setMessage(msg);
+
+        builder.setTitle(title);
+
+        builder.setPositiveButton(getString(android.R.string.ok), new DialogInterface.OnClickListener()
+        {
+
+            @Override
+            public void onClick(DialogInterface dialog, int which)
+            {
+                dialog.dismiss();
+
+
+            }
+        });
+
+        builder.create().show();
+
+    }
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu)
+    {
+        // Inflate the menu; this adds items to the action bar if it is present.
+
+        if(iscachefile)
+            getMenuInflater().inflate(R.menu.pdf_cached_preview, menu);
+        else
+            getMenuInflater().inflate(R.menu.pdf_saved_preview, menu);
+        return true;
+    }
+    @Override
+    protected void onDestroy()
+    {
+
+        if(iscachefile) {
+            String file = getIntent().getStringExtra("file");
+            new File(file).delete();
+        }
+        super.onDestroy();
+    }
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_pdf_preview);
+
+        setCustomActionBar();
+        pdfView = findViewById(R.id.pdfView);
+        pdfView.setBackgroundColor(Color.LTGRAY);
+        pdfView.setPadding(10,10,10,10);
+
+        String file=getIntent().getStringExtra("file");
+        iscachefile = getIntent().getBooleanExtra("iscache",false);
+//        pdfFileName = assetFileName;
+        pdfView.fromFile(new File(file))
+//        pdfView.fromAsset(SAMPLE_FILE)
+                .defaultPage(pageNumber)
+                .onPageChange(this)
+                .enableAnnotationRendering(true)
+                .onLoad(this)
+//                .scrollHandle(new DefaultScrollHandle(this))
+
+                .spacing(10) // in dp
+                .onPageError(this)
+                .pageFitPolicy(FitPolicy.BOTH)
+                .load();
+
+        /*
+        pdfView.fromAsset(SAMPLE_FILE)
+//                .pages(0, 2, 1, 3, 3, 3) // all pages are displayed by default
+                .enableSwipe(true) // allows to block changing pages using swipe
+                .swipeHorizontal(false)
+                .enableDoubletap(true)
+                .defaultPage(0)
+                // allows to draw something on the current page, usually visible in the middle of the screen
+//                .onDraw(this)
+                // allows to draw something on all pages, separately for every page. Called only for visible pages
+//                .onDrawAll(onDrawListener)
+                .onLoad(this) // called after document is loaded and starts to be rendered
+                .onPageChange(this)
+//                .onPageScroll(onPageScrollListener)
+//                .onError(onErrorListener)
+                .onPageError(this)
+//                .onRender(onRenderListener) // called after document is rendered for the first time
+                // called on single tap, return true if handled, false to toggle scroll handle visibility
+//                .onTap(onTapListener)
+                .enableAnnotationRendering(false) // render annotations (such as comments, colors or forms)
+                .password(null)
+                .scrollHandle(null)
+                .enableAntialiasing(true) // improve rendering a little bit on low-res screens
+                // spacing between pages in dp. To define spacing color, set view background
+                .spacing(0)
+//                .linkHandler(DefaultLinkHandler)
+                .pageFitPolicy(FitPolicy.WIDTH)
+                .load();*/
+    }
+
+    @Override
+    public void loadComplete(int nbPages) {
+        PdfDocument.Meta meta = pdfView.getDocumentMeta();
+        Log.e(TAG, "title = " + meta.getTitle());
+        Log.e(TAG, "author = " + meta.getAuthor());
+        Log.e(TAG, "subject = " + meta.getSubject());
+        Log.e(TAG, "keywords = " + meta.getKeywords());
+        Log.e(TAG, "creator = " + meta.getCreator());
+        Log.e(TAG, "producer = " + meta.getProducer());
+        Log.e(TAG, "creationDate = " + meta.getCreationDate());
+        Log.e(TAG, "modDate = " + meta.getModDate());
+
+        printBookmarksTree(pdfView.getTableOfContents(), "-");
+    }
+
+    @Override
+    public void onPageChanged(int page, int pageCount) {
+
+    }
+
+    @Override
+    public void onPageError(int page, Throwable t) {
+
+    }
+
+    public void printBookmarksTree(List<PdfDocument.Bookmark> tree, String sep) {
+        for (PdfDocument.Bookmark b : tree) {
+
+            Log.e(TAG, String.format("%s %s, p %d", sep, b.getTitle(), b.getPageIdx()));
+
+            if (b.hasChildren()) {
+                printBookmarksTree(b.getChildren(), sep + "-");
+            }
+        }
+    }
+}

+ 98 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/saved/AMListFragment.java

@@ -0,0 +1,98 @@
+package com.usai.apex.saved;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.support.v4.app.ListFragment;
+import android.support.v4.widget.SwipeRefreshLayout;
+import android.util.TypedValue;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+
+import com.usai.apex.Result.PullRefreshListView;
+import com.usai.apex.swipemenulistview.SwipeMenuListView;
+
+/**
+ * Created by macmini1 on 2018/2/28.
+ */
+
+public class AMListFragment extends ListFragment {
+
+
+    static final int INTERNAL_EMPTY_ID = 0x00ff0001;
+    static final int INTERNAL_PROGRESS_CONTAINER_ID = 0x00ff0002;
+    static final int INTERNAL_LIST_CONTAINER_ID = 0x00ff0003;
+
+    public SwipeMenuListView mSwipeMenuListView;
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                             Bundle savedInstanceState) {
+        final Context context = getContext();
+
+        FrameLayout root = new FrameLayout(context);
+
+        // ------------------------------------------------------------------
+
+        LinearLayout pframe = new LinearLayout(context);
+        pframe.setId(INTERNAL_PROGRESS_CONTAINER_ID);
+        pframe.setOrientation(LinearLayout.VERTICAL);
+        pframe.setVisibility(View.GONE);
+        pframe.setGravity(Gravity.CENTER);
+
+        ProgressBar progress = new ProgressBar(context, null,
+                android.R.attr.progressBarStyleLarge);
+        pframe.addView(progress, new FrameLayout.LayoutParams(
+                ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
+
+        root.addView(pframe, new FrameLayout.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
+
+        // ------------------------------------------------------------------
+
+        FrameLayout lframe = new FrameLayout(context);
+        lframe.setId(INTERNAL_LIST_CONTAINER_ID);
+
+        TextView tv = new TextView(context);
+        tv.setId(INTERNAL_EMPTY_ID);
+        tv.setGravity(Gravity.CENTER);
+        lframe.addView(tv, new FrameLayout.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
+
+
+        SwipeMenuListView lv = new SwipeMenuListView(context);
+        mSwipeMenuListView = lv;
+        lv.setId(android.R.id.list);
+        lv.setDrawSelectorOnTop(false);
+
+        lframe.addView(lv, new FrameLayout.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
+
+        root.addView(lframe, new FrameLayout.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
+
+        // ------------------------------------------------------------------
+
+        root.setLayoutParams(new FrameLayout.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
+
+        return root;
+    }
+
+    public Context mContext;
+    @Override
+    public void onAttach(Context context) {
+        super.onAttach(context);
+        mContext = context;
+    }
+
+    public int dp2px(int dp) {
+        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,
+                getResources().getDisplayMetrics());
+    }
+}

+ 185 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/saved/CheckSavedActivity.java

@@ -0,0 +1,185 @@
+package com.usai.apex.saved;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.database.sqlite.SQLiteDatabase;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AppCompatActivity;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.TextView;
+
+import com.usai.apex.ApexTrackingApplication;
+import com.usai.apex.R;
+import com.usai.util.dbUtil;
+
+public class CheckSavedActivity extends AppCompatActivity {
+    Fragment f=null;
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item)
+    {
+        Intent intent = new Intent();
+        switch (item.getItemId())
+        {
+            case android.R.id.home:
+                finish();
+                break;
+            case R.id.action_deleteall:
+            {
+                AlertDialog.Builder builder = new AlertDialog.Builder(this);
+                builder.setMessage(getString(R.string.str_deletemessage));
+
+                builder.setTitle(getString(R.string.str_confirmdelete));
+
+                builder.setPositiveButton(getString(R.string.str_del),
+                        new Dialog.OnClickListener()
+                        {
+
+                            @Override
+                            public void onClick(DialogInterface dialog,
+                                                int which)
+                            {
+                                SQLiteDatabase db = dbUtil.OpenDB(
+                                        CheckSavedActivity.this, null, false);
+                                String function_name = getIntent().getStringExtra("function_name");
+                                if(function_name.equals("Saved Detail"))
+                                {
+
+                                    db.execSQL(String.format("delete from favorites where user = '%s'", ApexTrackingApplication.get_user()));
+//                                    getSupportFragmentManager().get
+//                                    SavedSearchFragment f = (SavedSearchFragment)getSupportFragmentManager().findFragmentById(R.id.tab1);
+                                    SavedDetailFragment detail =(SavedDetailFragment) f;
+                                    detail.clear_result();
+                                    detail.reload_adapter();
+                                }
+                                else if(function_name.equals("Saved Search"))
+                                {
+                                    db.execSQL(String.format("delete from history where user = '%s'",ApexTrackingApplication.get_user()));
+//                                    SavedDetailFragment f = (SavedDetailFragment)getSupportFragmentManager().findFragmentById(R.id.tab2);
+
+                                    SavedSearchFragment search =(SavedSearchFragment) f;
+                                    search.clear_result();
+                                    search.reload_adapter();
+                                }
+                                else if(function_name.equals("Saved Documents"))
+                                {
+//                                    db.execSQL("delete from favorites");
+////                                    SavedDetailFragment f = (SavedDetailFragment)getSupportFragmentManager().findFragmentById(R.id.tab2);
+//
+//                                    SavedSearchFragment search =(SavedSearchFragment) f;
+//                                    search.clear_result();
+//                                    search.reload_adapter();
+                                    SavedDocumentsFragment search =(SavedDocumentsFragment) f;
+                                    ((SavedDocumentsFragment) f).clear();
+                                }
+
+
+                                dbUtil.CloseDB(db);
+                                dialog.dismiss();
+
+                            }
+                        });
+
+                builder.setNegativeButton(getString(R.string.str_cancel),
+                        new Dialog.OnClickListener()
+                        {
+
+                            @Override
+                            public void onClick(DialogInterface dialog,
+                                                int which)
+                            {
+                                dialog.dismiss();
+                            }
+                        });
+
+                builder.create().show();
+
+                break;
+            }
+            default:
+                break;
+        }
+        return super.onOptionsItemSelected(item);
+    }
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu)
+    {
+        // Inflate the menu; this adds items to the action bar if it is present.
+        getMenuInflater().inflate(R.menu.checksaved, menu);
+        return true;
+    }
+    private void setCustomActionBar() {
+        ActionBar.LayoutParams lp =new ActionBar.LayoutParams(ActionBar.LayoutParams.MATCH_PARENT, ActionBar.LayoutParams.MATCH_PARENT, Gravity.CENTER);
+        View mActionBarView = LayoutInflater.from(this).inflate(R.layout.actionbar_customtitle, null);
+
+        TextView titleview = mActionBarView.findViewById(R.id.title);
+        titleview.setText(getIntent().getStringExtra("function_name"));
+
+        setTitle(getIntent().getStringExtra("function_name"));
+//
+//        mActionBarView.setBackgroundColor(Color.YELLOW);
+//        titleview.setBackgroundColor(Color.BLUE);
+        ActionBar actionBar = getSupportActionBar();
+        actionBar.setCustomView(mActionBarView, lp);
+//        actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
+//        actionBar.setDisplayShowCustomEnabled(true);
+        actionBar.setDisplayHomeAsUpEnabled(true);
+
+
+//        actionBar.setIcon(getNumberDrawable());
+//        actionBar.setDisplayShowHomeEnabled(true);
+        actionBar.setDisplayShowTitleEnabled(true);
+    }
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_check_saved);
+
+
+
+        if (savedInstanceState == null)
+        {
+
+
+            String function_name = getIntent().getStringExtra("function_name");
+            if(function_name.equals("Saved Detail"))
+            {
+               f = new SavedDetailFragment();
+//                ToolsFragment f = new ToolsFragment();
+//                Bundle b = new Bundle();
+//                b.putBoolean("Login", true);
+//                favorites.setArguments(b);
+                getSupportFragmentManager().beginTransaction()
+                        .add(R.id.container, f).commit();
+            }
+            else if (function_name.equals("Saved Search"))
+            {
+                f = new SavedSearchFragment();
+//                Bundle b = new Bundle();
+//                b.putBoolean("Login", true);
+//                history.setArguments(b);
+                getSupportFragmentManager().beginTransaction()
+                        .add(R.id.container, f).commit();
+            }
+            else if (function_name.equals("Saved Documents"))
+            {
+                f = new SavedDocumentsFragment();
+//                Bundle b = new Bundle();
+//                b.putBoolean("Login", true);
+//                history.setArguments(b);
+                getSupportFragmentManager().beginTransaction()
+                        .add(R.id.container, f).commit();
+            }
+
+
+        }
+        setCustomActionBar();
+    }
+}

+ 374 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/saved/SavedDetailFragment.java

@@ -0,0 +1,374 @@
+package com.usai.apex.saved;
+
+import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
+import android.os.Bundle;
+import android.text.format.DateFormat;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import com.usai.apex.ApexTrackingApplication;
+import com.usai.apex.R;
+import com.usai.apex.swipemenulistview.BaseSwipListAdapter;
+import com.usai.apex.swipemenulistview.SwipeMenu;
+import com.usai.apex.swipemenulistview.SwipeMenuCreator;
+import com.usai.apex.swipemenulistview.SwipeMenuItem;
+import com.usai.apex.swipemenulistview.SwipeMenuListView;
+import com.usai.util.commonUtil;
+import com.usai.util.dbUtil;
+
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class SavedDetailFragment extends AMListFragment
+{
+
+	SearchResult	searchresult	= new SearchResult();
+	BaseAdapter		adapter			= null;
+	private int		pointX, pointY, endX, endY;
+	private int		position, newpos;
+	private Button	curDel_btn;
+
+
+	public void clear_result()
+	{
+		searchresult.getData().clear();
+	}
+	public void reload_adapter()
+	{
+		adapter.notifyDataSetChanged();
+	}
+	@Override
+	public void onActivityCreated(Bundle savedInstanceState)
+	{
+		super.onActivityCreated(savedInstanceState);
+		adapter = new FavoritesAdapter(searchresult, getActivity());
+
+//		getListView().setOnTouchListener(this);
+		setListAdapter(adapter);
+		// this.getListView().setBackgroundColor(Color.WHITE);
+
+		// step 1. create a MenuCreator
+		SwipeMenuCreator creator = new SwipeMenuCreator() {
+
+			@Override
+			public void create(SwipeMenu menu) {
+
+				// create "delete" item
+				SwipeMenuItem deleteItem = new SwipeMenuItem(mContext);
+				// set item background
+				deleteItem.setBackground(new ColorDrawable(Color.rgb(0xF9,0x3F, 0x25)));
+				// set item width
+				deleteItem.setWidth(dp2px(90));
+				// set a icon
+				deleteItem.setTitle("Delete");
+				// set item title fontsize
+				deleteItem.setTitleSize(18);
+				// set item title font color
+				deleteItem.setTitleColor(Color.WHITE);
+				// add to menu
+				menu.addMenuItem(deleteItem);
+			}
+		};
+		// set creator
+		mSwipeMenuListView.setMenuCreator(creator);
+
+		// step 2. listener item click event
+		mSwipeMenuListView.setOnMenuItemClickListener(new SwipeMenuListView.OnMenuItemClickListener() {
+			@Override
+			public boolean onMenuItemClick(int position, SwipeMenu menu, int index) {
+
+
+				switch (index) {
+					case 0:
+						// delete
+						SQLiteDatabase db = dbUtil.OpenDB(getActivity(),
+								null, false);
+						db.execSQL("delete from favorites where _id="
+								+ (Long) searchresult.getData()
+								.get(position).get("_id"));
+
+						dbUtil.CloseDB(db);
+						searchresult.getData().remove(position);
+						adapter.notifyDataSetChanged();
+
+						break;
+				}
+				return false;
+			}
+		});
+
+		// set SwipeListener
+		mSwipeMenuListView.setOnSwipeListener(new SwipeMenuListView.OnSwipeListener() {
+
+			@Override
+			public void onSwipeStart(int position) {
+				// swipe start
+			}
+
+			@Override
+			public void onSwipeEnd(int position) {
+				// swipe end
+			}
+		});
+
+		// set MenuStateChangeListener
+		mSwipeMenuListView.setOnMenuStateChangeListener(new SwipeMenuListView.OnMenuStateChangeListener() {
+			@Override
+			public void onMenuOpen(int position) {
+			}
+
+			@Override
+			public void onMenuClose(int position) {
+			}
+		});
+	}
+
+	@Override
+	public void onListItemClick(ListView l, View v, int position, long id)
+	{
+
+		Intent intent = new Intent();
+		// SQLiteDatabase db = dbUtil.OpenDB(getActivity(), null, false);
+		// Cursor c = db.query("favorites", new String[]
+		// {"params"},"_id="+searchresult.getData().get(position).get("_id"),null,
+		// null, null, null);
+		// if(c.moveToNext())
+		// {
+		String uri = (String) searchresult.getData().get(position)
+				.get("params");
+		try
+		{
+			intent = Intent.parseUri(uri, 0);
+
+			startActivity(intent);
+		}
+		catch (URISyntaxException e)
+		{
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+
+
+
+	}
+
+	private class FavoritesAdapter extends BaseSwipListAdapter
+	{
+		private LayoutInflater	mInflater;	// 动态布局映射
+											// private SearchResult result;
+
+		class Holder {
+			TextView message,time;
+			ImageView icon;
+
+			Holder(View cell) {
+				message = (TextView) cell.findViewById(R.id.tv_title);// 找某个控件
+				time = (TextView) cell.findViewById(R.id.tv_detail);
+				icon = (ImageView)cell.findViewById(R.id.iv_thumb);
+				cell.setTag(this);
+			}
+
+		}
+
+		// private Context context;
+		// private int i = 0;
+		public FavoritesAdapter(SearchResult result, Context context)
+		{
+			// this.result = result;
+			this.mInflater = LayoutInflater.from(context);
+			SQLiteDatabase db = dbUtil.OpenDB(getActivity(), null, false);
+			Cursor cursor = db.query("favorites", new String[] { "_id",
+					"create_time", "name", "params","module_name" }, "user='"
+					+ ApexTrackingApplication.get_user() + "'", null, null,
+					null, "_id desc", null);
+
+			result.add_records(cursor);
+			dbUtil.CloseCursor(cursor);
+			dbUtil.CloseDB(db);
+			// this.result = result;
+			// // this.context = context;
+			// this.mInflater = LayoutInflater.from(context);
+		}
+
+		Holder holder = null;
+		@Override
+		public View getView(int position, View convertView, ViewGroup parent)
+		{
+			// TODO Auto-generated method stub
+			if (convertView == null) {
+				convertView = mInflater.inflate(R.layout.saved_cell, null);// 根据布局文件实例化view
+				holder = new Holder(convertView);
+			} else {
+				holder = (Holder) convertView.getTag();
+			}
+
+
+			String module_name = (String) searchresult.getData().get(position).get("module_name");
+			int rid= commonUtil.iconName2Rid(getActivity(),module_name);
+
+			holder.message.setText(searchresult.getData().get(position).get("name")
+					.toString());// 给该控件设置数据(数据从集合类中来)
+			holder.time.setText(DateFormat.format(
+					getString(R.string.time_format),
+					(Long) searchresult.getData().get(position)
+							.get("create_time")));
+			holder.icon.setImageResource(rid);
+
+
+			return convertView;
+		}
+
+		@Override
+		public int getCount()
+		{
+			return searchresult.get_count();
+		}
+
+		@Override
+		public Object getItem(int position)
+		{
+			// TODO Auto-generated method stub
+			return searchresult.getData().get(position);
+		}
+
+		@Override
+		public long getItemId(int position)
+		{
+			// TODO Auto-generated method stub
+			return position;
+		}
+
+		@Override
+		public boolean getSwipEnableByPosition(int position) {
+			return true;
+		}
+	}
+
+	class SearchResult
+	{
+		List<Map<String, Object>>	datalist	= new ArrayList<Map<String, Object>>();
+
+		public int get_count()
+		{
+			return datalist.size();
+		}
+
+		public void add_records(Cursor c)
+		{
+			while (c.moveToNext())
+			{
+				long _id = c.getInt(0);
+				long create_time = c.getLong(1);
+				String name = c.getString(2);
+				String params = c.getString(3);
+				String module_name = c.getString(4);
+				Map<String, Object> map = new HashMap<String, Object>();
+				map.put("_id", _id);
+
+				map.put("create_time", create_time);
+				map.put("name", name);
+
+				map.put("params", params);
+				map.put("module_name", module_name);
+
+				datalist.add(map);
+			}
+
+		}
+
+		public List<Map<String, Object>> getData()
+		{
+
+			return datalist;
+		}
+	}
+
+//	@Override
+//	public boolean onTouch(View v, MotionEvent event)
+//	{
+//		switch (event.getAction())
+//		{
+//			case MotionEvent.ACTION_DOWN:
+//				System.out.println("====>>>>>>>>>>>>>>ACTION_DOWN"
+//						+ MotionEvent.ACTION_DOWN);
+//				// 手指按下,计算焦点位于ListView的那个条目
+//				pointX = (int) event.getX();
+//				pointY = (int) event.getY();
+//				// 备注1
+//				position = getListView().pointToPosition(pointX, pointY);
+//				if (curDel_btn != null)
+//				{
+//					curDel_btn.setVisibility(View.GONE);
+//				}
+//				break;
+//			case MotionEvent.ACTION_MOVE:
+//
+//				break;
+//			case MotionEvent.ACTION_UP:
+//				System.out.println("====>>>>>>>>>>>>>>ACTION_UP"
+//						+ MotionEvent.ACTION_UP);
+//				endX = (int) event.getX();
+//				endY = (int) event.getY();
+//				newpos = getListView().pointToPosition(endX, endY);
+//				// 原本想着加上这个条件(newpos==position)是不是更精确些,
+//				// 经过实践发现,其实我们在滑动listView的列表的时候有时候更渴望有滑动就ok
+//				if (Math.abs(endX - pointX) > 100 && newpos == position
+//						&& Math.abs(endY - pointY) < 100)
+//				{
+//					// 获取到ListView第一个可见条目的position
+//					int firstVisiblePosition = getListView()
+//							.getFirstVisiblePosition();
+//
+//					// --------------备注2
+//					View view = getListView().getChildAt(
+//							position - firstVisiblePosition);
+//					Button delbtn = (Button) view.findViewById(R.id.btn_del);
+//					delbtn.setVisibility(View.VISIBLE);
+//					curDel_btn = delbtn;
+//					delbtn.setOnClickListener(new View.OnClickListener()
+//					{
+//
+//						@Override
+//						public void onClick(View v)
+//						{
+//							// TODO Auto-generated method stub
+//
+//							SQLiteDatabase db = dbUtil.OpenDB(getActivity(),
+//									null, false);
+//							db.execSQL("delete from favorites where _id="
+//									+ (Long) searchresult.getData()
+//											.get(position).get("_id"));
+//							Log.d("sql delete" + position,
+//									"delete from push_message where _id="
+//											+ (Long) searchresult.getData()
+//													.get(position).get("_id"));
+//
+//							dbUtil.CloseDB(db);
+//							searchresult.getData().remove(position);
+//							adapter.notifyDataSetChanged();
+//						}
+//					});
+//
+//				}
+//				break;
+//
+//			default:
+//				break;
+//		}
+//		return false;
+//	}
+}

+ 490 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/saved/SavedDocumentsFragment.java

@@ -0,0 +1,490 @@
+package com.usai.apex.saved;
+
+
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Environment;
+import android.support.v4.app.Fragment;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import com.usai.apex.R;
+import com.usai.apex.pdf.PDFPreviewActivity;
+import com.usai.apex.swipemenulistview.BaseSwipListAdapter;
+import com.usai.apex.swipemenulistview.SwipeMenu;
+import com.usai.apex.swipemenulistview.SwipeMenuCreator;
+import com.usai.apex.swipemenulistview.SwipeMenuItem;
+import com.usai.apex.swipemenulistview.SwipeMenuListView;
+import com.usai.util.commonUtil;
+
+import java.io.File;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A simple {@link Fragment} subclass.
+ */
+public class SavedDocumentsFragment extends AMListFragment/* implements View.OnTouchListener*/ {
+    class FileComparator2 implements Comparator<File> {
+
+        @Override
+        public int compare(File file1, File file2) {
+            if (file1.lastModified() < file2.lastModified()) {
+                return 1;// 最后修改的文件在前
+            } else {
+                return -1;
+            }
+        }
+    }
+    private class DocumentsAdapter extends BaseSwipListAdapter
+    {
+
+        class Holder {
+            TextView message,time;
+            ImageView iv,icon;
+
+
+            Holder(View cell) {
+                message = (TextView) cell.findViewById(R.id.tv_title);// 找某个控件
+                time = (TextView) cell.findViewById(R.id.tv_detail);
+                iv = (ImageView)cell.findViewById(R.id.iv_share);
+                icon = (ImageView)cell.findViewById(R.id.iv_thumb);
+                cell.setTag(this);
+            }
+
+        }
+
+        @Override
+        public int getCount() {
+            return mList.size();
+        }
+
+        @Override
+        public Object getItem(int i) {
+            return mList.get(i);
+        }
+
+        @Override
+        public long getItemId(int i) {
+            return i;
+        }
+
+        @Override
+        public boolean getSwipEnableByPosition(int position) {
+            return true;
+        }
+
+        //		private LayoutInflater	mInflater;
+        @Override
+        public View getView( int position, View convertView, ViewGroup parent)
+        {
+
+            Holder holder = null;
+            if (convertView == null) {
+                convertView = LayoutInflater.from(mContext).inflate(R.layout.saved_doc, null);// 根据布局文件实例化view
+                holder = new Holder(convertView);
+            } else {
+                holder = (Holder) convertView.getTag();
+            }
+            // TODO Auto-generated method stub
+//			convertView = mInflater.inflate(R.layout.announcement_item, null);// 根据布局文件实例化view
+
+//            ImageView iv = (ImageView)convertView.findViewById(R.id.iv_share);
+
+            int rid = (int)mList.get(position).get("img");
+
+            holder.icon.setImageResource(rid);
+            holder.message.setText((String)mList.get(position).get("title"));
+            holder.time.setText((String)mList.get(position).get("lastmodify"));
+
+
+            holder.iv.setTag( (String) mList.get(position).get("title"));
+            holder.iv.setOnClickListener(new View.OnClickListener()
+            {
+
+                @Override
+                public void onClick(View v)
+                {
+
+                    if(false)
+                    {
+                        Intent intent = new Intent(Intent.ACTION_SEND); // 启动分享发送的属性
+                        intent.setType("text/plain"); // 分享发送的数据类型
+                        intent.putExtra(Intent.EXTRA_TEXT, "email test"); // 分享的内容
+                        startActivity(Intent.createChooser(intent,"abcdefg!!!!!!!"));// 目标应用选择对话框的标题
+                    }
+                    else
+
+                    {
+                        Intent share = new Intent(Intent.ACTION_SEND);
+                        String filename = (String) v.getTag();
+                        share.putExtra(Intent.EXTRA_STREAM,
+                                Uri.fromFile(new File(Environment.getExternalStorageDirectory().getPath()+"/Apex Mobile/"+filename)));
+                        String[] token = filename.split("\\.");
+                        String ext = token[token.length-1];
+                        share.setType("application/"+ext);//此处可发送多种文件
+                        share.putExtra(Intent.EXTRA_TEXT, "test content text");   //附带的说明信息
+                        share.putExtra(Intent.EXTRA_SUBJECT, "test subject");
+                        share.putExtra(Intent.EXTRA_EMAIL, new String[]{"isbcd@hotmail.com","isbcd.zhangrui@gmail.com"});
+                        share.putExtra(Intent.EXTRA_CC, new String[]{"ray.zhang@united-cn.net"});
+                        startActivity(Intent.createChooser(share,getString(R.string.str_sendto)));
+                    }
+
+
+                }
+            });
+//			TextView title = (TextView) convertView.findViewById(R.id.tv_title);// 找某个控件
+//			title.setText(result.getData().get(position).get("title")
+//					.toString());// 给该控件设置数据(数据从集合类中来)
+//			TextView content = (TextView) convertView
+//					.findViewById(R.id.tv_content);
+//			content.setText(result.getData().get(position).get("content")
+//					.toString());
+//			if (result.getData().get(position).get("image").toString().length() > 0)
+//			{
+//				byte[] gzipBuff = Base64.decode(result.getData().get(position)
+//						.get("image").toString(), 0);
+//
+//				ByteArrayInputStream memstream = new ByteArrayInputStream(
+//						gzipBuff, 0, gzipBuff.length);
+//
+//				ByteArrayOutputStream baos = new ByteArrayOutputStream(
+//						gzipBuff.length);
+//				ImageView iv_thumb = (ImageView) convertView
+//						.findViewById(R.id.iv_thumb);
+//				try
+//				{
+//					baos.write(gzipBuff);
+//
+//					Bitmap bmp = BitmapFactory.decodeStream(memstream);
+//
+//					// ImageView image = new ImageView(this);
+//
+//					iv_thumb.setImageBitmap(bmp);
+//				}
+//				catch (IOException e)
+//				{
+//					// TODO Auto-generated catch block
+//					e.printStackTrace();
+//				}
+//			}
+//			// img.setBackgroundResource((Integer)jObject.get("img"));
+
+            return convertView;
+        }
+        public DocumentsAdapter(Context context)
+        {
+
+
+
+//			this.mInflater = LayoutInflater.from(context);
+            // TODO Auto-generated constructor stub
+        }
+
+    }
+    public static final String FILETYPE ="pdf";
+    public SavedDocumentsFragment() {
+        // Required empty public constructor
+    }
+
+    private ArrayList<Map<String, Object>> getData()
+    {
+        ArrayList<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
+
+
+
+        if(commonUtil.localdirExist())
+        {
+            File path = new File(Environment.getExternalStorageDirectory().getPath()+"/Apex Mobile");
+            //返回文件夹中有的数据
+            File[] files = path.listFiles();
+            //先判断下有没有权限,如果没有权限的话,就不执行了
+            if(null == files)
+                return list;
+
+            List<File> fileList = new ArrayList<File>();
+//            String path = FileUtils.IMAGE_PATH;//文件夹路径
+//            File file = new File(path);
+//            if (file.exists() && file.isDirectory()) {
+//                File[] files = file.listFiles();
+            for (int i = 0; i < files.length; i++) {
+                    fileList.add(files[i]);
+                }
+            Collections.sort(fileList, new FileComparator2());
+
+
+
+
+            for(int i = 0; i < fileList.size(); i++)
+            {
+//				String filePath = files[i].getAbsolutePath();
+                String fileName = fileList.get(i).getName();
+//                files[i].get
+                String[] token = fileName.split("\\.");
+                String ext = token[token.length-1];
+                if(!FILETYPE.contains(ext))
+                    continue;
+
+                Map<String, Object> map = new HashMap<String, Object>();
+                map.put("title", fileName);
+                map.put("ext", ext);
+                if(ext.toLowerCase().equals("pdf"))
+                    map.put("img", R.drawable.ic_pdf128);
+                else
+                    map.put("img", R.drawable.ic_file128);
+                list.add(map);
+
+
+                long time = fileList.get(i).lastModified();//返回文件最后修改时间,是以个long型毫秒数
+                String ctime = new SimpleDateFormat("MM/dd/yyyy hh:mm:ss").format(new Date(time));
+
+                map.put("lastmodify", ctime);
+
+                Log.d("file info", "last modify " + ctime);
+
+//                files[i]
+
+            }
+        }
+        return list;
+    }
+//    @Override
+//    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+//                             Bundle savedInstanceState) {
+//
+//
+//
+//        TextView textView = new TextView(getActivity());
+//        textView.setText(R.string.hello_blank_fragment);
+//        return textView;
+//    }
+
+
+    @Override
+    public void onListItemClick(ListView l, View v, int position, long id)
+    {
+
+        String filename = (String) getData().get(position).get("title");
+        String file=new File(Environment
+                .getExternalStorageDirectory().getPath()
+                + "/Apex Mobile/"
+                + filename).getAbsolutePath();
+
+        Intent myIntent = new Intent();
+        myIntent = new Intent(getActivity(), PDFPreviewActivity.class);
+
+        myIntent.putExtra("file",file);
+        myIntent.putExtra("iscache",false);
+        startActivity(myIntent);
+
+        /*
+        Log.d("FragmentList", "Item clicked: " + id);
+        String filename = (String) getData().get(position).get("title");
+        Intent intent = new Intent("android.intent.action.VIEW");
+
+        intent.addCategory("android.intent.category.DEFAULT");
+
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+        Uri uri = Uri.fromFile(new File(Environment
+                .getExternalStorageDirectory().getPath()
+                + "/Apex Mobile/"
+                + filename));
+
+        intent.setDataAndType(uri, "application/"+(String) getData().get(position).get("ext"));
+//	    startActivity(intent);
+        startActivity(Intent.createChooser(intent,getString(R.string.str_openfile)));
+//
+*/
+//		Intent intent = new Intent();
+//		if(title.equals("Search documents online"))
+//		{
+//			intent.setClass(this, SearchListActivity.class);
+//
+//			intent.putExtra("function_name", "Download Document");
+//			intent.putExtra("title", "Document Search");
+//
+//		}
+//		else if(title.equals("View download documents"))
+//		{
+//			intent.setClass(this, AnnouncementActivity.class);
+//			intent.putExtra("module_name", "Announcements");
+//		}
+//
+//
+//		startActivity(intent);
+
+    }
+
+    private ArrayList<Map<String, Object>> mList;
+    private DocumentsAdapter mAdapter;
+
+    @Override
+    public void onActivityCreated(Bundle savedInstanceState)
+    {
+        super.onActivityCreated(savedInstanceState);
+//        adapter = new SavedDetailFragment.FavoritesAdapter(searchresult, getActivity());
+//
+//        getListView().setOnTouchListener(this);
+//        setListAdapter(adapter);
+
+
+        mList = getData();
+//        SimpleAdapter adapter = new DocumentsAdapter(getActivity(),
+//                getData(), R.layout.saved_doc, new String[] { "title",
+//                "img","lastmodify" }, new int[] { R.id.tv_msg, R.id.iv_icon,R.id.tv_detail });
+        mAdapter = new DocumentsAdapter(mContext);
+        setListAdapter(mAdapter);
+        getListView().setBackgroundColor(Color.WHITE);
+        // this.getListView().setBackgroundColor(Color.WHITE);
+
+        // step 1. create a MenuCreator
+        SwipeMenuCreator creator = new SwipeMenuCreator() {
+
+            @Override
+            public void create(SwipeMenu menu) {
+
+                // create "delete" item
+                SwipeMenuItem deleteItem = new SwipeMenuItem(mContext);
+                // set item background
+                deleteItem.setBackground(new ColorDrawable(Color.rgb(0xF9,0x3F, 0x25)));
+                // set item width
+                deleteItem.setWidth(dp2px(90));
+                // set a icon
+                deleteItem.setTitle("Delete");
+                // set item title fontsize
+                deleteItem.setTitleSize(18);
+                // set item title font color
+                deleteItem.setTitleColor(Color.WHITE);
+                // add to menu
+                menu.addMenuItem(deleteItem);
+            }
+        };
+        // set creator
+        mSwipeMenuListView.setMenuCreator(creator);
+
+        // step 2. listener item click event
+        mSwipeMenuListView.setOnMenuItemClickListener(new SwipeMenuListView.OnMenuItemClickListener() {
+            @Override
+            public boolean onMenuItemClick(int position, SwipeMenu menu, int index) {
+
+
+                switch (index) {
+                    case 0:
+                        // delete
+                        String filename = (String) getData().get(position).get("title");
+
+                        File file = new File(Environment
+                                .getExternalStorageDirectory().getPath()
+                                + "/Apex Mobile/"
+                                + filename);
+                        if (file != null && file.exists()) {
+                            file.delete();
+                        }
+
+                        File emailFile = new File(Environment
+                                .getExternalStorageDirectory().getPath()
+                                + "/Apex Mobile/"
+                                + filename + ".email");
+                        if (emailFile != null && emailFile.exists()) {
+                            emailFile.delete();
+                        }
+
+                        mList.remove(position);
+                        mAdapter.notifyDataSetChanged();
+
+                        break;
+                }
+                return false;
+            }
+        });
+
+        // set SwipeListener
+        mSwipeMenuListView.setOnSwipeListener(new SwipeMenuListView.OnSwipeListener() {
+
+            @Override
+            public void onSwipeStart(int position) {
+                // swipe start
+            }
+
+            @Override
+            public void onSwipeEnd(int position) {
+                // swipe end
+            }
+        });
+
+        // set MenuStateChangeListener
+        mSwipeMenuListView.setOnMenuStateChangeListener(new SwipeMenuListView.OnMenuStateChangeListener() {
+            @Override
+            public void onMenuOpen(int position) {
+            }
+
+            @Override
+            public void onMenuClose(int position) {
+            }
+        });
+
+    }
+//
+//    @Override
+//    public boolean onTouch(View v, MotionEvent event) {
+//        return false;
+//    }
+
+    public void clear() {
+
+//        int count = mList.size();
+//        for (int i = count - 1; i >= 0; i--) {
+//            String filename = (String) getData().get(i).get("title");
+//
+//            File file = new File(Environment
+//                    .getExternalStorageDirectory().getPath()
+//                    + "/Apex Mobile/"
+//                    + filename);
+//            if (file != null && file.exists()) {
+//                file.delete();
+//            }
+//            mList.remove(i);
+//        }
+//        mAdapter.notifyDataSetChanged();
+
+
+        File dir = new File(Environment.getExternalStorageDirectory().getPath()+ "/Apex Mobile/");
+        deleteFile(dir);
+        mList.clear();
+        mAdapter.notifyDataSetChanged();
+    }
+
+    private void deleteFile(File deleteFile) {
+
+        if (deleteFile != null && deleteFile.isDirectory()) {
+
+            File[] files = deleteFile.listFiles();
+            for (int i = 0; i < files.length; i++) {
+
+                File file = files[i];
+                if (file.isDirectory()) {
+                    deleteFile(file);
+                }
+
+                file.delete();
+
+            }
+        }
+    }
+}

+ 399 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/saved/SavedSearchFragment.java

@@ -0,0 +1,399 @@
+package com.usai.apex.saved;
+
+import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.text.format.DateFormat;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import com.usai.apex.ApexTrackingApplication;
+import com.usai.apex.R;
+import com.usai.apex.swipemenulistview.BaseSwipListAdapter;
+import com.usai.apex.swipemenulistview.SwipeMenu;
+import com.usai.apex.swipemenulistview.SwipeMenuCreator;
+import com.usai.apex.swipemenulistview.SwipeMenuItem;
+import com.usai.apex.swipemenulistview.SwipeMenuListView;
+import com.usai.util.commonUtil;
+import com.usai.util.dbUtil;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+public class SavedSearchFragment extends AMListFragment
+{
+	SearchResult	searchresult	= new SearchResult();
+	BaseAdapter		adapter			= null;
+	private int		pointX, pointY, endX, endY;
+	private int		position, newpos;
+	private Button	curDel_btn;
+	public void clear_result()
+	{
+		searchresult.getData().clear();
+	}
+	public void reload_adapter()
+	{
+		adapter.notifyDataSetChanged();
+	}
+	@Override
+	public void onActivityCreated(Bundle savedInstanceState)
+	{
+		super.onActivityCreated(savedInstanceState);
+		adapter = new HistoryAdapter(searchresult, getActivity());
+
+//		getListView().setOnTouchListener(this);
+		setListAdapter(adapter);
+//		this.getListView().setBackgroundColor(Color.WHITE);
+
+
+		// step 1. create a MenuCreator
+		SwipeMenuCreator creator = new SwipeMenuCreator() {
+
+			@Override
+			public void create(SwipeMenu menu) {
+
+				// create "delete" item
+				SwipeMenuItem deleteItem = new SwipeMenuItem(mContext);
+				// set item background
+				deleteItem.setBackground(new ColorDrawable(Color.rgb(0xF9,0x3F, 0x25)));
+				// set item width
+				deleteItem.setWidth(dp2px(90));
+				// set a icon
+				deleteItem.setTitle("Delete");
+				// set item title fontsize
+				deleteItem.setTitleSize(18);
+				// set item title font color
+				deleteItem.setTitleColor(Color.WHITE);
+				// add to menu
+				menu.addMenuItem(deleteItem);
+			}
+		};
+		// set creator
+		mSwipeMenuListView.setMenuCreator(creator);
+
+		// step 2. listener item click event
+		mSwipeMenuListView.setOnMenuItemClickListener(new SwipeMenuListView.OnMenuItemClickListener() {
+			@Override
+			public boolean onMenuItemClick(int position, SwipeMenu menu, int index) {
+
+
+				switch (index) {
+					case 0:
+						// delete
+						SQLiteDatabase db = dbUtil.OpenDB(getActivity(), null, false);
+							db.execSQL("delete from history where _id=" + (Long) searchresult.getData().get(position).get("_id"));
+							dbUtil.CloseDB(db);
+							searchresult.getData().remove(position);
+							adapter.notifyDataSetChanged();
+
+						break;
+				}
+				return false;
+			}
+		});
+
+		// set SwipeListener
+		mSwipeMenuListView.setOnSwipeListener(new SwipeMenuListView.OnSwipeListener() {
+
+			@Override
+			public void onSwipeStart(int position) {
+				// swipe start
+			}
+
+			@Override
+			public void onSwipeEnd(int position) {
+				// swipe end
+			}
+		});
+
+		// set MenuStateChangeListener
+		mSwipeMenuListView.setOnMenuStateChangeListener(new SwipeMenuListView.OnMenuStateChangeListener() {
+			@Override
+			public void onMenuOpen(int position) {
+			}
+
+			@Override
+			public void onMenuClose(int position) {
+			}
+		});
+	}
+
+	@Override
+	public void onListItemClick(ListView l, View v, int position, long id)
+	{
+
+		Intent intent = new Intent();
+		String uri = (String) searchresult.getData().get(position).get("params");
+		String searchParms = (String) searchresult.getData().get(position).get("criterion");
+		try
+		{
+//			Bundle bundle = new Bundle();
+			intent = Intent.parseUri(uri, 0);
+			Bundle parms = new Bundle();
+//			parms.writeToParcel(parcel, flags)
+			JSONObject obj = new JSONObject(searchParms);
+			Iterator<?> it = obj.keys();
+			while (it.hasNext())
+			{
+
+				String key = (String) it.next();
+				parms.putString(key, obj.getString(key));
+
+//					obj.put(key, searchParms.get(key).toString());
+
+
+
+			}
+//			intent.putExtra("searchParms", parms);
+////			obj.toString();
+//
+//			intent.putExtra("columns",
+//					dbUtil.get_fields(ApexTrackingApplication.get_user(), (String) searchresult.getData().get(position).get("module_name")));
+
+			parms.putString("columns",dbUtil.get_fields(ApexTrackingApplication.get_user(), (String) searchresult.getData().get(position).get("module_name")));
+			intent.putExtra("query_params",parms);
+
+			startActivity(intent);
+		}
+		catch (URISyntaxException e)
+		{
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		catch (JSONException e)
+		{
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+
+		
+
+	}
+	
+	private class HistoryAdapter extends BaseSwipListAdapter
+	{
+		private LayoutInflater	mInflater;	// 动态布局映射
+											// private SearchResult result;
+
+		class Holder {
+			TextView message,time;
+			ImageView icon;
+
+			Holder(View cell) {
+				message = (TextView) cell.findViewById(R.id.tv_title);// 找某个控件
+				time = (TextView) cell.findViewById(R.id.tv_detail);
+				icon = (ImageView)cell.findViewById(R.id.iv_thumb);
+				cell.setTag(this);
+			}
+
+		}
+		// private Context context;
+		// private int i = 0;
+		public HistoryAdapter(SearchResult result, Context context)
+		{
+			// this.result = result;
+			this.mInflater = LayoutInflater.from(context);
+			SQLiteDatabase db = dbUtil
+					.OpenDB(getActivity(), null, false);
+			Cursor cursor = db.query("history",
+					new String[] { "_id", "create_time", "criterion",
+							"params","module_name" ,"name"}, "user='"
+							+ ApexTrackingApplication.get_user() + "'", null,
+					null, null, "_id desc", null);
+
+			result.add_records(cursor);
+			dbUtil.CloseCursor(cursor);
+			dbUtil.CloseDB(db);
+			// this.result = result;
+			// // this.context = context;
+			// this.mInflater = LayoutInflater.from(context);
+		}
+
+		@Override
+		public View getView(int position, View convertView, ViewGroup parent)
+		{
+			// TODO Auto-generated method stub
+			Holder holder = null;
+			if (convertView == null) {
+				convertView = mInflater.inflate(R.layout.saved_cell, null);// 根据布局文件实例化view
+				holder = new Holder(convertView);
+			} else {
+				holder = (Holder) convertView.getTag();
+			}
+
+
+			String name = (String) searchresult.getData().get(position).get("name");
+			if(TextUtils.isEmpty(name))
+			{
+				name = "";
+			}
+
+			String module_name = (String) searchresult.getData().get(position).get("module_name");
+			int rid=commonUtil.iconName2Rid(getActivity(),module_name);
+
+			holder.message.setText(name);// 给该控件设置数据(数据从集合类中来)
+			holder.time.setText(DateFormat.format(getString(R.string.time_format),(Long) searchresult.getData().get(position).get("create_time")));
+			holder.icon.setImageResource(rid);
+
+			return convertView;
+		}
+
+		@Override
+		public int getCount()
+		{
+			return searchresult.get_count();
+		}
+
+		@Override
+		public Object getItem(int position)
+		{
+			// TODO Auto-generated method stub
+			return searchresult.getData().get(position);
+		}
+
+		@Override
+		public long getItemId(int position)
+		{
+			// TODO Auto-generated method stub
+			return position;
+		}
+
+		@Override
+		public boolean getSwipEnableByPosition(int position) {
+			return true;
+		}
+	}
+	class SearchResult
+	{
+		List<Map<String, Object>>	datalist	= new ArrayList<Map<String, Object>>();
+
+		public int get_count()
+		{
+			return datalist.size();
+		}
+
+		public void add_records(Cursor c)
+		{
+			while (c.moveToNext())
+			{
+				long _id = c.getInt(0);
+				long create_time = c.getLong(1);
+				String criterion = c.getString(2);
+				String params = c.getString(3);
+				String module_name = c.getString(4);
+				String name = c.getString(5);
+				Map<String, Object> map = new HashMap<String, Object>();
+				map.put("_id", _id);
+				
+				map.put("create_time", create_time);
+				map.put("criterion", criterion);
+				
+				map.put("params", params);
+				map.put("module_name", module_name);
+				map.put("name", name);
+
+				datalist.add(map);
+			}
+
+		}
+
+		public List<Map<String, Object>> getData()
+		{
+
+			return datalist;
+		}
+	}
+
+//	@Override
+//	public boolean onTouch(View v, MotionEvent event)
+//	{
+//		switch (event.getAction())
+//		{
+//			case MotionEvent.ACTION_DOWN:
+//				System.out.println("====>>>>>>>>>>>>>>ACTION_DOWN"
+//						+ MotionEvent.ACTION_DOWN);
+//				// 手指按下,计算焦点位于ListView的那个条目
+//				pointX = (int) event.getX();
+//				pointY = (int) event.getY();
+//				// 备注1
+//				position = getListView().pointToPosition(pointX, pointY);
+//				if (curDel_btn != null)
+//				{
+//					curDel_btn.setVisibility(View.GONE);
+//				}
+//				break;
+//			case MotionEvent.ACTION_MOVE:
+//
+//				break;
+//			case MotionEvent.ACTION_UP:
+//				System.out.println("====>>>>>>>>>>>>>>ACTION_UP"
+//						+ MotionEvent.ACTION_UP);
+//				endX = (int) event.getX();
+//				endY = (int) event.getY();
+//				newpos = getListView().pointToPosition(endX, endY);
+//				// 原本想着加上这个条件(newpos==position)是不是更精确些,
+//				// 经过实践发现,其实我们在滑动listView的列表的时候有时候更渴望有滑动就ok
+//				if (Math.abs(endX - pointX) > 100 && newpos == position
+//						&& Math.abs(endY - pointY) < 100)
+//				{
+//					// 获取到ListView第一个可见条目的position
+//					int firstVisiblePosition = getListView()
+//							.getFirstVisiblePosition();
+//
+//					// --------------备注2
+//					View view = getListView().getChildAt(
+//							position - firstVisiblePosition);
+//					Button delbtn = (Button) view.findViewById(R.id.btn_del);
+//					delbtn.setVisibility(View.VISIBLE);
+//					curDel_btn = delbtn;
+//					delbtn.setOnClickListener(new View.OnClickListener()
+//					{
+//
+//						@Override
+//						public void onClick(View v)
+//						{
+//							// TODO Auto-generated method stub
+//
+//							SQLiteDatabase db = dbUtil.OpenDB(
+//									getActivity(), null, false);
+//							db.execSQL("delete from history where _id="
+//									+ (Long) searchresult.getData()
+//											.get(position).get("_id"));
+//							Log.d("sql delete" + position,
+//									"delete from push_message where _id="
+//											+ (Long) searchresult.getData()
+//													.get(position).get("_id"));
+//
+//							dbUtil.CloseDB(db);
+//							searchresult.getData().remove(position);
+//							adapter.notifyDataSetChanged();
+//						}
+//					});
+//
+//				}
+//				break;
+//
+//			default:
+//				break;
+//		}
+//		return false;
+//	}
+}

+ 41 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/swipemenulistview/BaseSwipListAdapter.java

@@ -0,0 +1,41 @@
+/*
+* The MIT License (MIT)
+*
+* Copyright (c) 2015 nimengbo
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all
+* copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+* SOFTWARE.
+*/
+package com.usai.apex.swipemenulistview;
+
+import android.widget.BaseAdapter;
+
+/**
+ * Created by Abner on 15/11/20.
+ * Email nimengbo@gmail.com
+ * github https://github.com/nimengbo
+ */
+public abstract class BaseSwipListAdapter extends BaseAdapter {
+
+    public boolean getSwipEnableByPosition(int position){
+        return true;
+    }
+
+
+
+}

+ 53 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/swipemenulistview/SwipeMenu.java

@@ -0,0 +1,53 @@
+package com.usai.apex.swipemenulistview;
+
+import android.content.Context;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 
+ * @author baoyz
+ * @date 2014-8-23
+ * 
+ */
+public class SwipeMenu {
+
+	private Context mContext;
+	private List<SwipeMenuItem> mItems;
+	private int mViewType;
+
+	public SwipeMenu(Context context) {
+		mContext = context;
+		mItems = new ArrayList<SwipeMenuItem>();
+	}
+
+	public Context getContext() {
+		return mContext;
+	}
+
+	public void addMenuItem(SwipeMenuItem item) {
+		mItems.add(item);
+	}
+
+	public void removeMenuItem(SwipeMenuItem item) {
+		mItems.remove(item);
+	}
+
+	public List<SwipeMenuItem> getMenuItems() {
+		return mItems;
+	}
+
+	public SwipeMenuItem getMenuItem(int index) {
+		return mItems.get(index);
+	}
+
+	public int getViewType() {
+		return mViewType;
+	}
+
+	public void setViewType(int viewType) {
+		this.mViewType = viewType;
+	}
+
+}

+ 149 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/swipemenulistview/SwipeMenuAdapter.java

@@ -0,0 +1,149 @@
+package com.usai.apex.swipemenulistview;
+
+import android.content.Context;
+import android.database.DataSetObserver;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ListAdapter;
+import android.widget.WrapperListAdapter;
+
+/**
+ * 
+ * @author baoyz
+ * @date 2014-8-24
+ * 
+ */
+public class SwipeMenuAdapter implements WrapperListAdapter,
+        SwipeMenuView.OnSwipeItemClickListener {
+
+    private ListAdapter mAdapter;
+    private Context mContext;
+    private SwipeMenuListView.OnMenuItemClickListener onMenuItemClickListener;
+
+    public SwipeMenuAdapter(Context context, ListAdapter adapter) {
+        mAdapter = adapter;
+        mContext = context;
+    }
+
+    @Override
+    public int getCount() {
+        return mAdapter.getCount();
+    }
+
+    @Override
+    public Object getItem(int position) {
+        return mAdapter.getItem(position);
+    }
+
+    @Override
+    public long getItemId(int position) {
+        return mAdapter.getItemId(position);
+    }
+
+    @Override
+    public View getView(int position, View convertView, ViewGroup parent) {
+        SwipeMenuLayout layout = null;
+        if (convertView == null) {
+            View contentView = mAdapter.getView(position, convertView, parent);
+            SwipeMenu menu = new SwipeMenu(mContext);
+            menu.setViewType(getItemViewType(position));
+            createMenu(menu);
+            SwipeMenuView menuView = new SwipeMenuView(menu,
+                    (SwipeMenuListView) parent);
+            menuView.setOnSwipeItemClickListener(this);
+            SwipeMenuListView listView = (SwipeMenuListView) parent;
+            layout = new SwipeMenuLayout(contentView, menuView,
+                    listView.getCloseInterpolator(),
+                    listView.getOpenInterpolator());
+            layout.setPosition(position);
+        } else {
+            layout = (SwipeMenuLayout) convertView;
+            layout.closeMenu();
+            layout.setPosition(position);
+            View view = mAdapter.getView(position, layout.getContentView(),
+                    parent);
+        }
+        layout.closeMenu();
+        if (mAdapter instanceof BaseSwipListAdapter) {
+            boolean swipEnable = (((BaseSwipListAdapter) mAdapter).getSwipEnableByPosition(position));
+            layout.setSwipEnable(swipEnable);
+        }
+        return layout;
+    }
+
+    public void createMenu(SwipeMenu menu) {
+        // Test Code
+        SwipeMenuItem item = new SwipeMenuItem(mContext);
+        item.setTitle("Item 1");
+        item.setBackground(new ColorDrawable(Color.GRAY));
+        item.setWidth(300);
+        menu.addMenuItem(item);
+
+        item = new SwipeMenuItem(mContext);
+        item.setTitle("Item 2");
+        item.setBackground(new ColorDrawable(Color.RED));
+        item.setWidth(300);
+        menu.addMenuItem(item);
+    }
+
+    @Override
+    public void onItemClick(SwipeMenuView view, SwipeMenu menu, int index) {
+        if (onMenuItemClickListener != null) {
+            onMenuItemClickListener.onMenuItemClick(view.getPosition(), menu,
+                    index);
+        }
+    }
+
+    public void setOnSwipeItemClickListener(
+            SwipeMenuListView.OnMenuItemClickListener onMenuItemClickListener) {
+        this.onMenuItemClickListener = onMenuItemClickListener;
+    }
+
+    @Override
+    public void registerDataSetObserver(DataSetObserver observer) {
+        mAdapter.registerDataSetObserver(observer);
+    }
+
+    @Override
+    public void unregisterDataSetObserver(DataSetObserver observer) {
+        mAdapter.unregisterDataSetObserver(observer);
+    }
+
+    @Override
+    public boolean areAllItemsEnabled() {
+        return mAdapter.areAllItemsEnabled();
+    }
+
+    @Override
+    public boolean isEnabled(int position) {
+        return mAdapter.isEnabled(position);
+    }
+
+    @Override
+    public boolean hasStableIds() {
+        return mAdapter.hasStableIds();
+    }
+
+    @Override
+    public int getItemViewType(int position) {
+        return mAdapter.getItemViewType(position);
+    }
+
+    @Override
+    public int getViewTypeCount() {
+        return mAdapter.getViewTypeCount();
+    }
+
+    @Override
+    public boolean isEmpty() {
+        return mAdapter.isEmpty();
+    }
+
+    @Override
+    public ListAdapter getWrappedAdapter() {
+        return mAdapter;
+    }
+
+}

+ 13 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/swipemenulistview/SwipeMenuCreator.java

@@ -0,0 +1,13 @@
+package com.usai.apex.swipemenulistview;
+
+
+/**
+ * 
+ * @author baoyz
+ * @date 2014-8-24
+ *
+ */
+public interface SwipeMenuCreator {
+
+	void create(SwipeMenu menu);
+}

+ 96 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/swipemenulistview/SwipeMenuItem.java

@@ -0,0 +1,96 @@
+package com.usai.apex.swipemenulistview;
+
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+
+/**
+ * 
+ * @author baoyz
+ * @date 2014-8-23
+ * 
+ */
+public class SwipeMenuItem {
+
+	private int id;
+	private Context mContext;
+	private String title;
+	private Drawable icon;
+	private Drawable background;
+	private int titleColor;
+	private int titleSize;
+	private int width;
+
+	public SwipeMenuItem(Context context) {
+		mContext = context;
+	}
+
+	public int getId() {
+		return id;
+	}
+
+	public void setId(int id) {
+		this.id = id;
+	}
+
+	public int getTitleColor() {
+		return titleColor;
+	}
+
+	public int getTitleSize() {
+		return titleSize;
+	}
+
+	public void setTitleSize(int titleSize) {
+		this.titleSize = titleSize;
+	}
+
+	public void setTitleColor(int titleColor) {
+		this.titleColor = titleColor;
+	}
+
+	public String getTitle() {
+		return title;
+	}
+
+	public void setTitle(String title) {
+		this.title = title;
+	}
+
+	public void setTitle(int resId) {
+		setTitle(mContext.getString(resId));
+	}
+
+	public Drawable getIcon() {
+		return icon;
+	}
+
+	public void setIcon(Drawable icon) {
+		this.icon = icon;
+	}
+
+	public void setIcon(int resId) {
+		this.icon = mContext.getResources().getDrawable(resId);
+	}
+
+	public Drawable getBackground() {
+		return background;
+	}
+
+	public void setBackground(Drawable background) {
+		this.background = background;
+	}
+
+	public void setBackground(int resId) {
+		this.background = mContext.getResources().getDrawable(resId);
+	}
+
+	public int getWidth() {
+		return width;
+	}
+
+	public void setWidth(int width) {
+		this.width = width;
+	}
+
+}

+ 347 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/swipemenulistview/SwipeMenuLayout.java

@@ -0,0 +1,347 @@
+package com.usai.apex.swipemenulistview;
+
+import android.content.Context;
+import android.support.v4.view.GestureDetectorCompat;
+import android.support.v4.widget.ScrollerCompat;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.TypedValue;
+import android.view.GestureDetector.OnGestureListener;
+import android.view.GestureDetector.SimpleOnGestureListener;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.animation.Interpolator;
+import android.widget.AbsListView;
+import android.widget.FrameLayout;
+
+/**
+ * 
+ * @author baoyz
+ * @date 2014-8-23
+ * 
+ */
+public class SwipeMenuLayout extends FrameLayout {
+
+	private static final int CONTENT_VIEW_ID = 1;
+	private static final int MENU_VIEW_ID = 2;
+
+	private static final int STATE_CLOSE = 0;
+	private static final int STATE_OPEN = 1;
+
+	private int mSwipeDirection;
+
+	private View mContentView;
+	private SwipeMenuView mMenuView;
+	private int mDownX;
+	private int state = STATE_CLOSE;
+	private GestureDetectorCompat mGestureDetector;
+	private OnGestureListener mGestureListener;
+	private boolean isFling;
+	private int MIN_FLING = dp2px(15);
+	private int MAX_VELOCITYX = -dp2px(500);
+	private ScrollerCompat mOpenScroller;
+	private ScrollerCompat mCloseScroller;
+	private int mBaseX;
+	private int position;
+	private Interpolator mCloseInterpolator;
+	private Interpolator mOpenInterpolator;
+
+	private boolean mSwipEnable = true;
+
+	public SwipeMenuLayout(View contentView, SwipeMenuView menuView) {
+		this(contentView, menuView, null, null);
+	}
+
+	public SwipeMenuLayout(View contentView, SwipeMenuView menuView,
+                           Interpolator closeInterpolator, Interpolator openInterpolator) {
+		super(contentView.getContext());
+		mCloseInterpolator = closeInterpolator;
+		mOpenInterpolator = openInterpolator;
+		mContentView = contentView;
+		mMenuView = menuView;
+		mMenuView.setLayout(this);
+		init();
+	}
+
+	// private SwipeMenuLayout(Context context, AttributeSet attrs, int
+	// defStyle) {
+	// super(context, attrs, defStyle);
+	// }
+
+	private SwipeMenuLayout(Context context, AttributeSet attrs) {
+		super(context, attrs);
+	}
+
+	private SwipeMenuLayout(Context context) {
+		super(context);
+	}
+
+	public int getPosition() {
+		return position;
+	}
+
+	public void setPosition(int position) {
+		this.position = position;
+		mMenuView.setPosition(position);
+	}
+
+	public void setSwipeDirection(int swipeDirection) {
+		mSwipeDirection = swipeDirection;
+	}
+
+	private void init() {
+		setLayoutParams(new AbsListView.LayoutParams(LayoutParams.MATCH_PARENT,
+				LayoutParams.WRAP_CONTENT));
+		mGestureListener = new SimpleOnGestureListener() {
+			@Override
+			public boolean onDown(MotionEvent e) {
+				isFling = false;
+				return true;
+			}
+
+			@Override
+			public boolean onFling(MotionEvent e1, MotionEvent e2,
+                                   float velocityX, float velocityY) {
+				// TODO
+				if (Math.abs(e1.getX() - e2.getX()) > MIN_FLING
+						&& velocityX < MAX_VELOCITYX) {
+					isFling = true;
+				}
+				// Log.i("byz", MAX_VELOCITYX + ", velocityX = " + velocityX);
+				return super.onFling(e1, e2, velocityX, velocityY);
+			}
+		};
+		mGestureDetector = new GestureDetectorCompat(getContext(),
+				mGestureListener);
+
+		// mScroller = ScrollerCompat.create(getContext(), new
+		// BounceInterpolator());
+		if (mCloseInterpolator != null) {
+			mCloseScroller = ScrollerCompat.create(getContext(),
+					mCloseInterpolator);
+		} else {
+			mCloseScroller = ScrollerCompat.create(getContext());
+		}
+		if (mOpenInterpolator != null) {
+			mOpenScroller = ScrollerCompat.create(getContext(),
+					mOpenInterpolator);
+		} else {
+			mOpenScroller = ScrollerCompat.create(getContext());
+		}
+
+		LayoutParams contentParams = new LayoutParams(
+				LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
+		mContentView.setLayoutParams(contentParams);
+		if ((int)mContentView.getId() < 1) {
+			mContentView.setId(CONTENT_VIEW_ID);
+		}
+
+		mMenuView.setId(MENU_VIEW_ID);
+		mMenuView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
+				LayoutParams.WRAP_CONTENT));
+
+		addView(mContentView);
+		addView(mMenuView);
+
+		// if (mContentView.getBackground() == null) {
+		// mContentView.setBackgroundColor(Color.WHITE);
+		// }
+
+		// in android 2.x, MenuView height is MATCH_PARENT is not work.
+		// getViewTreeObserver().addOnGlobalLayoutListener(
+		// new OnGlobalLayoutListener() {
+		// @Override
+		// public void onGlobalLayout() {
+		// setMenuHeight(mContentView.getHeight());
+		// // getViewTreeObserver()
+		// // .removeGlobalOnLayoutListener(this);
+		// }
+		// });
+
+	}
+
+	@Override
+	protected void onAttachedToWindow() {
+		super.onAttachedToWindow();
+	}
+
+	@Override
+	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+		super.onSizeChanged(w, h, oldw, oldh);
+	}
+
+	public boolean onSwipe(MotionEvent event) {
+		mGestureDetector.onTouchEvent(event);
+		switch (event.getAction()) {
+		case MotionEvent.ACTION_DOWN:
+			mDownX = (int) event.getX();
+			isFling = false;
+			break;
+		case MotionEvent.ACTION_MOVE:
+			// Log.i("byz", "downX = " + mDownX + ", moveX = " + event.getX());
+			int dis = (int) (mDownX - event.getX());
+			if (state == STATE_OPEN) {
+				dis += mMenuView.getWidth()*mSwipeDirection;;
+			}
+			swipe(dis);
+			break;
+		case MotionEvent.ACTION_UP:
+			if ((isFling || Math.abs(mDownX - event.getX()) > (mMenuView.getWidth() / 2)) &&
+					Math.signum(mDownX - event.getX()) == mSwipeDirection) {
+				// open
+				smoothOpenMenu();
+			} else {
+				// close
+				smoothCloseMenu();
+				return false;
+			}
+			break;
+		}
+		return true;
+	}
+
+	public boolean isOpen() {
+		return state == STATE_OPEN;
+	}
+
+	@Override
+	public boolean onTouchEvent(MotionEvent event) {
+		return super.onTouchEvent(event);
+	}
+
+	private void swipe(int dis) {
+		if(!mSwipEnable){
+			return ;
+		}
+		if (Math.signum(dis) != mSwipeDirection) {
+			dis = 0;
+		} else if (Math.abs(dis) > mMenuView.getWidth()) {
+			dis = mMenuView.getWidth()*mSwipeDirection;
+		}
+
+		mContentView.layout(-dis, mContentView.getTop(),
+				mContentView.getWidth() -dis, getMeasuredHeight());
+
+		if (mSwipeDirection == SwipeMenuListView.DIRECTION_LEFT) {
+
+			mMenuView.layout(mContentView.getWidth() - dis, mMenuView.getTop(),
+					mContentView.getWidth() + mMenuView.getWidth() - dis,
+					mMenuView.getBottom());
+		} else {
+			mMenuView.layout(-mMenuView.getWidth() - dis, mMenuView.getTop(),
+					- dis, mMenuView.getBottom());
+		}
+	}
+
+	@Override
+	public void computeScroll() {
+		if (state == STATE_OPEN) {
+			if (mOpenScroller.computeScrollOffset()) {
+				swipe(mOpenScroller.getCurrX()*mSwipeDirection);
+				postInvalidate();
+			}
+		} else {
+			if (mCloseScroller.computeScrollOffset()) {
+				swipe((mBaseX - mCloseScroller.getCurrX())*mSwipeDirection);
+				postInvalidate();
+			}
+		}
+	}
+
+	public void smoothCloseMenu() {
+		state = STATE_CLOSE;
+		if (mSwipeDirection == SwipeMenuListView.DIRECTION_LEFT) {
+			mBaseX = -mContentView.getLeft();
+			mCloseScroller.startScroll(0, 0, mMenuView.getWidth(), 0, 350);
+		} else {
+			mBaseX = mMenuView.getRight();
+			mCloseScroller.startScroll(0, 0, mMenuView.getWidth(), 0, 350);
+		}
+		postInvalidate();
+	}
+
+	public void smoothOpenMenu() {
+		if(!mSwipEnable){
+			return ;
+		}
+		state = STATE_OPEN;
+		if (mSwipeDirection == SwipeMenuListView.DIRECTION_LEFT) {
+			mOpenScroller.startScroll(-mContentView.getLeft(), 0, mMenuView.getWidth(), 0, 350);
+		} else {
+			mOpenScroller.startScroll(mContentView.getLeft(), 0, mMenuView.getWidth(), 0, 350);
+		}
+		postInvalidate();
+	}
+
+	public void closeMenu() {
+		if (mCloseScroller.computeScrollOffset()) {
+			mCloseScroller.abortAnimation();
+		}
+		if (state == STATE_OPEN) {
+			state = STATE_CLOSE;
+			swipe(0);
+		}
+	}
+
+	public void openMenu() {
+		if(!mSwipEnable){
+			return ;
+		}
+		if (state == STATE_CLOSE) {
+			state = STATE_OPEN;
+			swipe(mMenuView.getWidth() * mSwipeDirection);
+		}
+	}
+
+	public View getContentView() {
+		return mContentView;
+	}
+
+	public SwipeMenuView getMenuView() {
+		return mMenuView;
+	}
+
+	private int dp2px(int dp) {
+		return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,
+				getContext().getResources().getDisplayMetrics());
+	}
+
+	@Override
+	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+		mMenuView.measure(MeasureSpec.makeMeasureSpec(0,
+				MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(
+				getMeasuredHeight(), MeasureSpec.EXACTLY));
+	}
+
+	@Override
+	protected void onLayout(boolean changed, int l, int t, int r, int b) {
+		mContentView.layout(0, 0, getMeasuredWidth(),
+				mContentView.getMeasuredHeight());
+		if (mSwipeDirection == SwipeMenuListView.DIRECTION_LEFT) {
+			mMenuView.layout(getMeasuredWidth(), 0,
+					getMeasuredWidth() + mMenuView.getMeasuredWidth(),
+					mContentView.getMeasuredHeight());
+		} else {
+			mMenuView.layout(-mMenuView.getMeasuredWidth(), 0,
+					0, mContentView.getMeasuredHeight());
+		}
+	}
+
+	public void setMenuHeight(int measuredHeight) {
+		Log.i("byz", "pos = " + position + ", height = " + measuredHeight);
+		LayoutParams params = (LayoutParams) mMenuView.getLayoutParams();
+		if (params.height != measuredHeight) {
+			params.height = measuredHeight;
+			mMenuView.setLayoutParams(mMenuView.getLayoutParams());
+		}
+	}
+
+	public void setSwipEnable(boolean swipEnable){
+		mSwipEnable = swipEnable;
+	}
+
+	public boolean getSwipEnable(){
+		return mSwipEnable;
+	}
+}

+ 339 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/swipemenulistview/SwipeMenuListView.java

@@ -0,0 +1,339 @@
+package com.usai.apex.swipemenulistview;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.util.TypedValue;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.animation.Interpolator;
+import android.widget.ListAdapter;
+import android.widget.ListView;
+
+/**
+ * @author baoyz
+ * @date 2014-8-18
+ */
+public class SwipeMenuListView extends ListView {
+
+    private static final int TOUCH_STATE_NONE = 0;
+    private static final int TOUCH_STATE_X = 1;
+    private static final int TOUCH_STATE_Y = 2;
+
+    public static final int DIRECTION_LEFT = 1;
+    public static final int DIRECTION_RIGHT = -1;
+    private int mDirection = 1;//swipe from right to left by default
+
+    private int MAX_Y = 5;
+    private int MAX_X = 3;
+    private float mDownX;
+    private float mDownY;
+    private int mTouchState;
+    private int mTouchPosition;
+    private SwipeMenuLayout mTouchView;
+    private OnSwipeListener mOnSwipeListener;
+
+    private SwipeMenuCreator mMenuCreator;
+    private OnMenuItemClickListener mOnMenuItemClickListener;
+    private OnMenuStateChangeListener mOnMenuStateChangeListener;
+    private Interpolator mCloseInterpolator;
+    private Interpolator mOpenInterpolator;
+
+    public SwipeMenuListView(Context context) {
+        super(context);
+        init();
+    }
+
+    public SwipeMenuListView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+        init();
+    }
+
+    public SwipeMenuListView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        init();
+    }
+
+    private void init() {
+        MAX_X = dp2px(MAX_X);
+        MAX_Y = dp2px(MAX_Y);
+        mTouchState = TOUCH_STATE_NONE;
+    }
+
+    @Override
+    public void setAdapter(ListAdapter adapter) {
+        super.setAdapter(new SwipeMenuAdapter(getContext(), adapter) {
+            @Override
+            public void createMenu(SwipeMenu menu) {
+                if (mMenuCreator != null) {
+                    mMenuCreator.create(menu);
+                }
+            }
+
+            @Override
+            public void onItemClick(SwipeMenuView view, SwipeMenu menu,
+                                    int index) {
+                boolean flag = false;
+                if (mOnMenuItemClickListener != null) {
+                    flag = mOnMenuItemClickListener.onMenuItemClick(
+                            view.getPosition(), menu, index);
+                }
+                if (mTouchView != null && !flag) {
+                    mTouchView.smoothCloseMenu();
+                }
+            }
+        });
+    }
+
+    public void setCloseInterpolator(Interpolator interpolator) {
+        mCloseInterpolator = interpolator;
+    }
+
+    public void setOpenInterpolator(Interpolator interpolator) {
+        mOpenInterpolator = interpolator;
+    }
+
+    public Interpolator getOpenInterpolator() {
+        return mOpenInterpolator;
+    }
+
+    public Interpolator getCloseInterpolator() {
+        return mCloseInterpolator;
+    }
+
+    @Override
+    public boolean onInterceptTouchEvent(MotionEvent ev) {
+        //在拦截处处理,在滑动设置了点击事件的地方也能swip,点击时又不能影响原来的点击事件
+        int action = ev.getAction();
+        switch (action) {
+            case MotionEvent.ACTION_DOWN:
+                mDownX = ev.getX();
+                mDownY = ev.getY();
+                boolean handled = super.onInterceptTouchEvent(ev);
+                mTouchState = TOUCH_STATE_NONE;
+                mTouchPosition = pointToPosition((int) ev.getX(), (int) ev.getY());
+                View view = getChildAt(mTouchPosition - getFirstVisiblePosition());
+
+                //只在空的时候赋值 以免每次触摸都赋值,会有多个open状态
+                if (view instanceof SwipeMenuLayout) {
+                    //如果有打开了 就拦截.
+                    if (mTouchView != null && mTouchView.isOpen() && !inRangeOfView(mTouchView.getMenuView(), ev)) {
+                        return true;
+                    }
+                    mTouchView = (SwipeMenuLayout) view;
+                    mTouchView.setSwipeDirection(mDirection);
+                }
+                //如果摸在另外个view
+                if (mTouchView != null && mTouchView.isOpen() && view != mTouchView) {
+                    handled = true;
+                }
+
+                if (mTouchView != null) {
+                    mTouchView.onSwipe(ev);
+                }
+                return handled;
+            case MotionEvent.ACTION_MOVE:
+                float dy = Math.abs((ev.getY() - mDownY));
+                float dx = Math.abs((ev.getX() - mDownX));
+                if (Math.abs(dy) > MAX_Y || Math.abs(dx) > MAX_X) {
+                    //每次拦截的down都把触摸状态设置成了TOUCH_STATE_NONE 只有返回true才会走onTouchEvent 所以写在这里就够了
+                    if (mTouchState == TOUCH_STATE_NONE) {
+                        if (Math.abs(dy) > MAX_Y) {
+                            mTouchState = TOUCH_STATE_Y;
+                        } else if (dx > MAX_X) {
+                            mTouchState = TOUCH_STATE_X;
+                            if (mOnSwipeListener != null) {
+                                mOnSwipeListener.onSwipeStart(mTouchPosition);
+                            }
+                        }
+                    }
+                    return true;
+                }
+        }
+        return super.onInterceptTouchEvent(ev);
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent ev) {
+        if (ev.getAction() != MotionEvent.ACTION_DOWN && mTouchView == null)
+            return super.onTouchEvent(ev);
+        int action = ev.getAction();
+        switch (action) {
+            case MotionEvent.ACTION_DOWN:
+                int oldPos = mTouchPosition;
+                mDownX = ev.getX();
+                mDownY = ev.getY();
+                mTouchState = TOUCH_STATE_NONE;
+
+                mTouchPosition = pointToPosition((int) ev.getX(), (int) ev.getY());
+
+                if (mTouchPosition == oldPos && mTouchView != null
+                        && mTouchView.isOpen()) {
+                    mTouchState = TOUCH_STATE_X;
+                    mTouchView.onSwipe(ev);
+                    return true;
+                }
+
+                View view = getChildAt(mTouchPosition - getFirstVisiblePosition());
+
+                if (mTouchView != null && mTouchView.isOpen()) {
+                    mTouchView.smoothCloseMenu();
+                    mTouchView = null;
+                    // return super.onTouchEvent(ev);
+                    // try to cancel the touch event
+                    MotionEvent cancelEvent = MotionEvent.obtain(ev);
+                    cancelEvent.setAction(MotionEvent.ACTION_CANCEL);
+                    onTouchEvent(cancelEvent);
+                    if (mOnMenuStateChangeListener != null) {
+                        mOnMenuStateChangeListener.onMenuClose(oldPos);
+                    }
+                    return true;
+                }
+                if (view instanceof SwipeMenuLayout) {
+                    mTouchView = (SwipeMenuLayout) view;
+                    mTouchView.setSwipeDirection(mDirection);
+                }
+                if (mTouchView != null) {
+                    mTouchView.onSwipe(ev);
+                }
+                break;
+            case MotionEvent.ACTION_MOVE:
+                //有些可能有header,要减去header再判断
+                mTouchPosition = pointToPosition((int) ev.getX(), (int) ev.getY()) - getHeaderViewsCount();
+                //如果滑动了一下没完全展现,就收回去,这时候mTouchView已经赋值,再滑动另外一个不可以swip的view
+                //会导致mTouchView swip 。 所以要用位置判断是否滑动的是一个view
+                if (!mTouchView.getSwipEnable() || mTouchPosition != mTouchView.getPosition()) {
+                    break;
+                }
+                float dy = Math.abs((ev.getY() - mDownY));
+                float dx = Math.abs((ev.getX() - mDownX));
+                if (mTouchState == TOUCH_STATE_X) {
+                    if (mTouchView != null) {
+                        mTouchView.onSwipe(ev);
+                    }
+                    getSelector().setState(new int[]{0});
+                    ev.setAction(MotionEvent.ACTION_CANCEL);
+                    super.onTouchEvent(ev);
+                    return true;
+                } else if (mTouchState == TOUCH_STATE_NONE) {
+                    if (Math.abs(dy) > MAX_Y) {
+                        mTouchState = TOUCH_STATE_Y;
+                    } else if (dx > MAX_X) {
+                        mTouchState = TOUCH_STATE_X;
+                        if (mOnSwipeListener != null) {
+                            mOnSwipeListener.onSwipeStart(mTouchPosition);
+                        }
+                    }
+                }
+                break;
+            case MotionEvent.ACTION_UP:
+                if (mTouchState == TOUCH_STATE_X) {
+                    if (mTouchView != null) {
+                        boolean isBeforeOpen = mTouchView.isOpen();
+                        mTouchView.onSwipe(ev);
+                        boolean isAfterOpen = mTouchView.isOpen();
+                        if (isBeforeOpen != isAfterOpen && mOnMenuStateChangeListener != null) {
+                            if (isAfterOpen) {
+                                mOnMenuStateChangeListener.onMenuOpen(mTouchPosition);
+                            } else {
+                                mOnMenuStateChangeListener.onMenuClose(mTouchPosition);
+                            }
+                        }
+                        if (!isAfterOpen) {
+                            mTouchPosition = -1;
+                            mTouchView = null;
+                        }
+                    }
+                    if (mOnSwipeListener != null) {
+                        mOnSwipeListener.onSwipeEnd(mTouchPosition);
+                    }
+                    ev.setAction(MotionEvent.ACTION_CANCEL);
+                    super.onTouchEvent(ev);
+                    return true;
+                }
+                break;
+        }
+        return super.onTouchEvent(ev);
+    }
+
+    public void smoothOpenMenu(int position) {
+        if (position >= getFirstVisiblePosition()
+                && position <= getLastVisiblePosition()) {
+            View view = getChildAt(position - getFirstVisiblePosition());
+            if (view instanceof SwipeMenuLayout) {
+                mTouchPosition = position;
+                if (mTouchView != null && mTouchView.isOpen()) {
+                    mTouchView.smoothCloseMenu();
+                }
+                mTouchView = (SwipeMenuLayout) view;
+                mTouchView.setSwipeDirection(mDirection);
+                mTouchView.smoothOpenMenu();
+            }
+        }
+    }
+
+    public void smoothCloseMenu(){
+        if (mTouchView != null && mTouchView.isOpen()) {
+            mTouchView.smoothCloseMenu();
+        }
+    }
+
+    private int dp2px(int dp) {
+        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,
+                getContext().getResources().getDisplayMetrics());
+    }
+
+    public void setMenuCreator(SwipeMenuCreator menuCreator) {
+        this.mMenuCreator = menuCreator;
+    }
+
+    public void setOnMenuItemClickListener(
+            OnMenuItemClickListener onMenuItemClickListener) {
+        this.mOnMenuItemClickListener = onMenuItemClickListener;
+    }
+
+    public void setOnSwipeListener(OnSwipeListener onSwipeListener) {
+        this.mOnSwipeListener = onSwipeListener;
+    }
+
+    public void setOnMenuStateChangeListener(OnMenuStateChangeListener onMenuStateChangeListener) {
+        mOnMenuStateChangeListener = onMenuStateChangeListener;
+    }
+
+    public static interface OnMenuItemClickListener {
+        boolean onMenuItemClick(int position, SwipeMenu menu, int index);
+    }
+
+    public static interface OnSwipeListener {
+        void onSwipeStart(int position);
+
+        void onSwipeEnd(int position);
+    }
+
+    public static interface OnMenuStateChangeListener {
+        void onMenuOpen(int position);
+
+        void onMenuClose(int position);
+    }
+
+    public void setSwipeDirection(int direction) {
+        mDirection = direction;
+    }
+
+    /**
+     * 判断点击事件是否在某个view内
+     *
+     * @param view
+     * @param ev
+     * @return
+     */
+    public static boolean inRangeOfView(View view, MotionEvent ev) {
+        int[] location = new int[2];
+        view.getLocationOnScreen(location);
+        int x = location[0];
+        int y = location[1];
+        if (ev.getRawX() < x || ev.getRawX() > (x + view.getWidth()) || ev.getRawY() < y || ev.getRawY() > (y + view.getHeight())) {
+            return false;
+        }
+        return true;
+    }
+}

+ 104 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/apex/swipemenulistview/SwipeMenuView.java

@@ -0,0 +1,104 @@
+package com.usai.apex.swipemenulistview;
+
+import android.text.TextUtils;
+import android.view.Gravity;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import java.util.List;
+
+/**
+ * 
+ * @author baoyz
+ * @date 2014-8-23
+ * 
+ */
+public class SwipeMenuView extends LinearLayout implements OnClickListener {
+
+	private SwipeMenuListView mListView;
+	private SwipeMenuLayout mLayout;
+	private SwipeMenu mMenu;
+	private OnSwipeItemClickListener onItemClickListener;
+	private int position;
+
+	public int getPosition() {
+		return position;
+	}
+
+	public void setPosition(int position) {
+		this.position = position;
+	}
+
+	public SwipeMenuView(SwipeMenu menu, SwipeMenuListView listView) {
+		super(menu.getContext());
+		mListView = listView;
+		mMenu = menu;
+		List<SwipeMenuItem> items = menu.getMenuItems();
+		int id = 0;
+		for (SwipeMenuItem item : items) {
+			addItem(item, id++);
+		}
+	}
+
+	private void addItem(SwipeMenuItem item, int id) {
+		LayoutParams params = new LayoutParams(item.getWidth(),
+				LayoutParams.MATCH_PARENT);
+		LinearLayout parent = new LinearLayout(getContext());
+		parent.setId(id);
+		parent.setGravity(Gravity.CENTER);
+		parent.setOrientation(LinearLayout.VERTICAL);
+		parent.setLayoutParams(params);
+		parent.setBackgroundDrawable(item.getBackground());
+		parent.setOnClickListener(this);
+		addView(parent);
+
+		if (item.getIcon() != null) {
+			parent.addView(createIcon(item));
+		}
+		if (!TextUtils.isEmpty(item.getTitle())) {
+			parent.addView(createTitle(item));
+		}
+
+	}
+
+	private ImageView createIcon(SwipeMenuItem item) {
+		ImageView iv = new ImageView(getContext());
+		iv.setImageDrawable(item.getIcon());
+		return iv;
+	}
+
+	private TextView createTitle(SwipeMenuItem item) {
+		TextView tv = new TextView(getContext());
+		tv.setText(item.getTitle());
+		tv.setGravity(Gravity.CENTER);
+		tv.setTextSize(item.getTitleSize());
+		tv.setTextColor(item.getTitleColor());
+		return tv;
+	}
+
+	@Override
+	public void onClick(View v) {
+		if (onItemClickListener != null && mLayout.isOpen()) {
+			onItemClickListener.onItemClick(this, mMenu, v.getId());
+		}
+	}
+
+	public OnSwipeItemClickListener getOnSwipeItemClickListener() {
+		return onItemClickListener;
+	}
+
+	public void setOnSwipeItemClickListener(OnSwipeItemClickListener onItemClickListener) {
+		this.onItemClickListener = onItemClickListener;
+	}
+
+	public void setLayout(SwipeMenuLayout mLayout) {
+		this.mLayout = mLayout;
+	}
+
+	public static interface OnSwipeItemClickListener {
+		void onItemClick(SwipeMenuView view, SwipeMenu menu, int index);
+	}
+}

+ 242 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/util/AES.java

@@ -0,0 +1,242 @@
+package com.usai.util;
+
+import android.util.Base64;
+import android.util.Log;
+
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Security;
+import java.util.Arrays;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+
+import static android.content.ContentValues.TAG;
+
+/**
+ * Created by ray on 07/06/2017.
+ * AES128 算法
+ *
+ * CBC 模式
+ *
+ * PKCS7Padding 填充模式
+ *
+ * CBC模式需要添加一个参数iv
+ *
+ * 介于java 不支持PKCS7Padding,只支持PKCS5Padding 但是PKCS7Padding 和 PKCS5Padding 没有什么区别
+ * 要实现在java端用PKCS7Padding填充,需要用到bouncycastle组件来实现
+ */
+
+public class AES {
+    // 算法名称
+    final static String KEY_ALGORITHM = "AES";
+    // 加解密算法/模式/填充方式
+    final static String algorithmStr = "AES/CBC/PKCS7Padding";
+    //
+//    private Key key;
+//    private Cipher cipher;
+//    boolean isInited = false;
+
+    static byte[] iv = new byte[16];//{ 0x30, 0x31, 0x30, 0x32, 0x30, 0x33, 0x30, 0x34, 0x30, 0x35, 0x30, 0x36, 0x30, 0x37, 0x30, 0x38 };
+//    private static void init(byte[] keyBytes) {
+//
+//        // 如果密钥不足16位,那么就补足.  这个if 中的内容很重要
+//        int base = 16;
+//        if (keyBytes.length % base != 0) {
+//            int groups = keyBytes.length / base + (keyBytes.length % base != 0 ? 1 : 0);
+//            byte[] temp = new byte[groups * base];
+//            Arrays.fill(temp, (byte) 0);
+//            System.arraycopy(keyBytes, 0, temp, 0, keyBytes.length);
+//            keyBytes = temp;
+//        }
+//        // 初始化
+//        Security.addProvider(new BouncyCastleProvider());
+//        // 转化成JAVA的密钥格式
+//        key = new SecretKeySpec(keyBytes, KEY_ALGORITHM);
+//        try {
+//            // 初始化cipher
+//            cipher = Cipher.getInstance(algorithmStr, "BC");
+//        } catch (NoSuchAlgorithmException e) {
+//            // TODO Auto-generated catch block
+//            e.printStackTrace();
+//        } catch (NoSuchPaddingException e) {
+//            // TODO Auto-generated catch block
+//            e.printStackTrace();
+//        } catch (NoSuchProviderException e) {
+//            // TODO Auto-generated catch block
+//            e.printStackTrace();
+//        }
+//    }
+
+    private static String toHex(byte[] buf)
+    {
+        if (buf == null)
+            return "";
+        StringBuffer result = new StringBuffer(2 * buf.length);
+        for (int i = 0; i < buf.length; i++)
+        {
+            appendHex(result, buf[i]);
+        }
+        return result.toString();
+    }
+    private static void appendHex(StringBuffer sb, byte b)
+    {
+        sb.append(HEX.charAt((b >> 4) & 0x0f)).append(HEX.charAt(b & 0x0f));
+    }
+    private final static String HEX = "0123456789ABCDEF";
+
+    public static String encrypt(String key, String content)
+    {
+        byte[] result=encrypt(content.getBytes(),key.getBytes());
+        Log.d(TAG, "encrypt: "+toHex(result));
+        return Base64.encodeToString(result, Base64.DEFAULT);
+    }
+
+    public static String decrypt(String key, String content)
+    {
+        byte[] buffer = Base64.decode(content, Base64.DEFAULT);
+
+        byte[] result = decrypt(buffer,key.getBytes());
+
+        return new String(result);
+    }
+
+    /**
+     * 加密方法
+     *
+     * @param content
+     *            要加密的字符串
+     * @param keyBytes
+     *            加密密钥
+     * @return
+     */
+    private static byte[] encrypt(byte[] content, byte[] keyBytes) {
+        byte[] encryptedText = null;
+//        init(keyBytes);
+
+     Key key;
+     Cipher cipher;
+        // 如果密钥不足16位,那么就补足.  这个if 中的内容很重要
+        int base = 16;
+        if (keyBytes.length % base != 0) {
+            int groups = keyBytes.length / base + (keyBytes.length % base != 0 ? 1 : 0);
+            byte[] temp = new byte[groups * base];
+            Arrays.fill(temp, (byte) 0);
+            System.arraycopy(keyBytes, 0, temp, 0, keyBytes.length);
+            keyBytes = temp;
+        }
+        // 初始化
+        Security.addProvider(new BouncyCastleProvider());
+        // 转化成JAVA的密钥格式
+        key = new SecretKeySpec(keyBytes, KEY_ALGORITHM);
+        try {
+            // 初始化cipher
+            cipher = Cipher.getInstance(algorithmStr, "BC");
+
+
+            cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
+            encryptedText = cipher.doFinal(content);
+
+        } catch (NoSuchAlgorithmException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (NoSuchPaddingException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (NoSuchProviderException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (BadPaddingException e) {
+            e.printStackTrace();
+        } catch (InvalidKeyException e) {
+            e.printStackTrace();
+        } catch (IllegalBlockSizeException e) {
+            e.printStackTrace();
+        } catch (InvalidAlgorithmParameterException e) {
+            e.printStackTrace();
+        }
+
+
+//        System.out.println("IV:" + new String(iv));
+//        try {
+//
+//        } catch (Exception e) {
+//            // TODO Auto-generated catch block
+//            e.printStackTrace();
+//        }
+        return encryptedText;
+    }
+    /**
+     * 解密方法
+     *
+     * @param encryptedData
+     *            要解密的字符串
+     * @param keyBytes
+     *            解密密钥
+     * @return
+     */
+    private static byte[] decrypt(byte[] encryptedData, byte[] keyBytes) {
+        byte[] encryptedText = null;
+//        init(keyBytes);
+
+        Key key;
+        Cipher cipher;
+                // 如果密钥不足16位,那么就补足.  这个if 中的内容很重要
+        int base = 16;
+        if (keyBytes.length % base != 0) {
+            int groups = keyBytes.length / base + (keyBytes.length % base != 0 ? 1 : 0);
+            byte[] temp = new byte[groups * base];
+            Arrays.fill(temp, (byte) 0);
+            System.arraycopy(keyBytes, 0, temp, 0, keyBytes.length);
+            keyBytes = temp;
+        }
+        // 初始化
+        Security.addProvider(new BouncyCastleProvider());
+        // 转化成JAVA的密钥格式
+        key = new SecretKeySpec(keyBytes, KEY_ALGORITHM);
+        try {
+            // 初始化cipher
+            cipher = Cipher.getInstance(algorithmStr, "BC");
+            cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
+            encryptedText = cipher.doFinal(encryptedData);
+        } catch (NoSuchAlgorithmException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (NoSuchPaddingException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (NoSuchProviderException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (BadPaddingException e) {
+            e.printStackTrace();
+        } catch (InvalidKeyException e) {
+            e.printStackTrace();
+        } catch (IllegalBlockSizeException e) {
+            e.printStackTrace();
+        } catch (InvalidAlgorithmParameterException e) {
+            e.printStackTrace();
+        }
+
+//        System.out.println("IV:" + new String(iv));
+//        try {
+//
+//        } catch (Exception e) {
+//            // TODO Auto-generated catch block
+//            e.printStackTrace();
+//        }
+
+        return encryptedText;
+    }
+
+
+}

+ 1904 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/util/Network.java

@@ -0,0 +1,1904 @@
+package com.usai.util;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
+import java.net.HttpURLConnection;
+import java.net.Socket;
+import java.net.URL;
+import java.net.URLEncoder;
+import java.net.UnknownHostException;
+import java.security.KeyManagementException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.UnrecoverableKeyException;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.HttpVersion;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.conn.ClientConnectionManager;
+import org.apache.http.conn.ConnectTimeoutException;
+import org.apache.http.conn.scheme.PlainSocketFactory;
+import org.apache.http.conn.scheme.Scheme;
+import org.apache.http.conn.scheme.SchemeRegistry;
+import org.apache.http.conn.ssl.SSLSocketFactory;
+import org.apache.http.entity.mime.HttpMultipartMode;
+import org.apache.http.entity.mime.MultipartEntity;
+import org.apache.http.entity.mime.content.StringBody;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
+import org.apache.http.params.BasicHttpParams;
+import org.apache.http.params.HttpConnectionParams;
+import org.apache.http.params.HttpParams;
+import org.apache.http.params.HttpProtocolParams;
+import org.apache.http.protocol.HTTP;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import com.usai.apex.ApexTrackingApplication;
+import com.usai.apex.CustomizeFieldsActivity.fieldedit;
+import com.usai.apex.R;
+
+import android.content.Context;
+import android.content.SharedPreferences.Editor;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteStatement;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.os.Bundle;
+import android.os.Environment;
+import android.text.TextUtils;
+import android.util.Log;
+
+public class Network
+{
+	public static final int		BEHAVIOR_SEARCH					= 0;
+	public static final int		BEHAVIOR_RESULT					= 1;
+
+	private static final int	REQUEST_TIMEOUT					= 30 * 1000;										// request
+																													// time
+																													// out
+																													// 20
+																													// secs
+	private static final int	SO_TIMEOUT						= 30 * 1000;										// so
+																													// time
+																													// out
+																													// 20
+																													// secs;
+	public static int			AP_USER_AUTH					= 1;
+	public static int			AP_USER_NOT_AUTH				= 2;
+	public static int			AP_USER_NOT_EXIST				= 3;
+	public static int			AP_SESSION_EXPIRED				= 4;
+
+	public static int			AP_MESSAGE_NEW					= 5;
+	public static int			AP_MESSAGE_NONE					= 6;
+	//
+	public static final int		RESULT_FALSE					= 0;
+	public static final int		RESULT_TRUE						= 2;
+	public static final int		RESULT_NET_ERROR				= -3;
+	public static final int		RESULT_NET_NOTAVAILABLE			= -4;
+	public static final int		RESULT_ERROR					= -5;
+	public static final int		RESULT_LOCALFILE_ERROR			= -7;
+	public static final int		RESULT_USERAUTH_ERROR			= -9;
+	public static final int		RESULT_UPDATE_USERAUTH_ERROR	= -11;
+	public static final int		RESULT_SESSION_EXPIRED			= -13;
+	public static final int		RESULT_VER_LOW					= -15;
+
+
+	//release
+	public static String		URL_HOME						= "https://ra.apexshipping.com/main_new.php";
+	public static String		URL_HISTORY						= "https://ra.apexshipping.com/main_new.php";
+	public static String		URL_KPI							= "https://ra.apexshipping.com/main_new.php";
+	public static String		URL_UPDATE_AUTH					= "https://ra.apexshipping.com/main_new.php";
+	public static String		URL_REQUEST_COUNT				= "https://ra.apexshipping.com/main_new.php";
+	public static String		URL_REQUEST_RECORDS				= "https://ra.apexshipping.com/main_new.php";
+	public static String		URL_RETRIEVE_PASS				= "https://ra.apexshipping.com/main_new.php";
+	public static String		URL_ANNOUNCEMENTS				= "https://ra.apexshipping.com/mobile_news.php";
+	public static String		URL_NEWS						= "https://ra.apexshipping.com/mobile_news.php";
+	public static String		URL_LOCATIONS					= "https://ra.apexshipping.com/mobile_news.php";
+	public static String		URL_PUSH						= "https://ra.apexshipping.com/main_new.php";
+	public static String		URL_LOG							= "https://ra.apexshipping.com/mobile_news.php";
+	public static String		URL_SEND_COMM_EMAIL				= "https://ra.apexshipping.com/main_new.php";
+	public static String		URL_CHECK_UPDATE				= "https://ra.apexshipping.com/main_new.php";
+
+
+//
+////debug
+//	public static String		URL_HOME				= "http://192.168.0.155/Online/Online/main_new.php";
+//	public static String		URL_HISTORY				= "http://192.168.0.155/Online/Online/main_new.php";
+//
+//	public static String		URL_UPDATE_AUTH					= "http://192.168.0.155/Online/Online/login.php";
+//	public static String		URL_REQUEST_COUNT				= "http://192.168.0.155/Online/Online/main_new.php";
+//	public static String		URL_REQUEST_RECORDS				= "http://192.168.0.155/Online/Online/main_new.php";
+//	public static String		URL_RETRIEVE_PASS				= "http://192.168.0.155/Online/Online/main_new.php";
+//	public static String		URL_ANNOUNCEMENTS				= "http://192.168.0.155/Online/Online/mobile_news.php";
+//	public static String		URL_NEWS						= "http://192.168.0.155/Online/Online/mobile_news.php";
+//	public static String		URL_LOCATIONS					= "http://192.168.0.155/Online/Online/mobile_news.php";
+//	public static String		URL_PUSH						= "http://192.168.0.155/Online/Online/main_new.php";
+//	public static String		URL_LOG						= "http://192.168.0.155/Online/Online/mobile_news.php";
+//
+
+
+	
+
+	private static HttpClient getNewHttpClient()
+	{
+		try
+		{
+			KeyStore trustStore = KeyStore.getInstance(KeyStore
+					.getDefaultType());
+			trustStore.load(null, null);
+
+			SSLSocketFactory sf = new SSLSocketFactoryEx(trustStore);
+			sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
+
+			HttpParams params = new BasicHttpParams();
+			HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
+			HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
+			HttpConnectionParams.setConnectionTimeout(params, REQUEST_TIMEOUT);
+			HttpConnectionParams.setSoTimeout(params, SO_TIMEOUT);
+			SchemeRegistry registry = new SchemeRegistry();
+			registry.register(new Scheme("http", PlainSocketFactory
+					.getSocketFactory(), 80));
+			registry.register(new Scheme("https", sf, 443));
+
+			ClientConnectionManager ccm = new ThreadSafeClientConnManager(
+					params, registry);
+
+			return new DefaultHttpClient(ccm, params);
+		}
+		catch (Exception e)
+		{
+			return new DefaultHttpClient();
+		}
+	}
+
+	public static String get_marketnews(String id, int limit)
+	{
+		String TAG = "net_dbg@get_marketnews";
+
+		if (!Network.NetworkIsAvailable())
+		{
+			Log.d(TAG, "network not available!");
+			return null; // network not available
+		}
+
+		Bundle parms = new Bundle();
+		parms.putString("module_name", "Market News");
+		parms.putString("action_type", "search");
+		parms.putString("id", id + "");
+		parms.putString("limit", limit + "");
+		String jstr = getJson(Network.URL_NEWS, parms);
+		if (jstr == null || jstr.length() <= 0)
+		{
+			Log.d(TAG, "json is wrong");
+			return null;
+		}
+		return jstr;
+
+	}
+
+	public static String get_servicelocation()
+	{
+		String TAG = "net_dbg@get_servicelocation";
+
+		if (!Network.NetworkIsAvailable())
+		{
+			Log.d(TAG, "network not available!");
+			return null; // network not available
+		}
+
+		Bundle parms = new Bundle();
+		parms.putString("module_name", "Location");
+		parms.putString("action_type", "search");
+		// parms.putString("id", id+"");
+		parms.putString("limit", "999");
+		String jstr = getJson(Network.URL_LOCATIONS, parms);
+		if (jstr == null || jstr.length() <= 0)
+		{
+			Log.d(TAG, "json is wrong");
+			return null;
+		}
+		return jstr;
+
+	}
+
+	public static String get_announcements(String id, int limit)
+	{
+		String TAG = "net_dbg@get_announcements";
+
+		if (!Network.NetworkIsAvailable())
+		{
+			Log.d(TAG, "network not available!");
+			return null; // network not available
+		}
+
+		Bundle parms = new Bundle();
+		parms.putString("module_name", "Announcements");
+		parms.putString("action_type", "search");
+		parms.putString("id", id);
+		parms.putString("limit", limit + "");
+		String jstr = getJson(Network.URL_ANNOUNCEMENTS, parms);
+		if (jstr == null || jstr.length() <= 0)
+		{
+			Log.d(TAG, "json is wrong");
+			return null;
+		}
+		return jstr;
+
+	}
+
+	public static int change_pass(String oldpass, String newpass, String user)
+	{
+		String TAG = "net_dbg@change_pass";
+		Log.d(TAG, "old:" + oldpass + ";new:" + newpass);
+		if (!Network.NetworkIsAvailable())
+		{
+			Log.d(TAG, "network not available!");
+			return Network.RESULT_NET_NOTAVAILABLE; // network not available
+		}
+		Bundle parms = new Bundle();
+		parms.putString("user", user);
+		parms.putString("oldpass", oldpass);
+		parms.putString("newpass", newpass);
+		parms.putString("module_name", "Change Password");
+//		parms.putString("sessionid", ApexTrackingApplication.get_sessionid());
+		parms.putString("action", "handset_search");
+		String jstr = getJson(Network.URL_RETRIEVE_PASS, parms);
+		/*
+		 * error occur while get authorization info from server. include can not
+		 * reach server , wrong parms ,server get wrong , etc.
+		 */
+		if (jstr == null || jstr.length() <= 0)
+		{
+			Log.d(TAG, "json is wrong");
+			return Network.RESULT_NET_ERROR;
+		}
+		JSONObject jsobj;
+
+		try
+		{
+			jsobj = new JSONObject(jstr);
+			if (jsobj.length() > 0)
+			{
+				int iresult = jsobj.getInt("result");
+				if (iresult == Network.AP_SESSION_EXPIRED)
+				{
+					Log.e(TAG, "AP_SESSION_EXPIRED");
+					Network.get_Auth(user, oldpass);
+					jstr = getJson(Network.URL_RETRIEVE_PASS, parms);
+					jsobj = new JSONObject(jstr);
+					iresult = jsobj.getInt("result");
+				}
+				if (iresult != Network.AP_USER_AUTH)
+				{
+					// user not authorized return
+					Log.d(TAG,
+							"USER NOT AUTHORIZED CODE="
+									+ jsobj.getInt("result"));
+					return RESULT_FALSE;
+				}
+				else
+				{
+
+					return RESULT_TRUE;
+				}
+			}
+			return RESULT_NET_ERROR;
+		}
+		catch (JSONException e)
+		{
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+
+		return RESULT_NET_ERROR;
+	}
+
+	public static int retrieve_pass(String user, String email)
+	{
+		String TAG = "net_dbg@retrieve_pass";
+		Log.d(TAG, "u:" + user + ";e:" + email);
+		if (!Network.NetworkIsAvailable())
+		{
+			Log.d(TAG, "network not available!");
+			return Network.RESULT_NET_NOTAVAILABLE; // network not available
+		}
+		Bundle parms = new Bundle();
+		parms.putString("user", user);
+		parms.putString("email", email);
+		parms.putString("module_name", "Retrieve Password");
+		parms.putString("action", "handset_search");
+		String jstr = getJson(Network.URL_RETRIEVE_PASS, parms);
+		/*
+		 * error occur while get authorization info from server. include can not
+		 * reach server , wrong parms ,server get wrong , etc.
+		 */
+		if (jstr == null || jstr.length() <= 0)
+		{
+			Log.d(TAG, "json is wrong");
+			return Network.RESULT_NET_ERROR;
+		}
+		JSONObject jsobj;
+
+		// array = new JSONArray(json);
+		try
+		{
+			jsobj = new JSONObject(jstr);
+			if (jsobj.length() > 0)
+			{
+				int iresult = jsobj.getInt("result");
+
+				if (iresult != Network.AP_USER_AUTH)
+				{
+					// user not authorized return
+					Log.d(TAG,
+							"USER NOT AUTHORIZED CODE="
+									+ jsobj.getInt("result"));
+					return RESULT_FALSE;
+				}
+				return RESULT_TRUE;
+
+			}
+			return RESULT_NET_ERROR;
+		}
+		catch (JSONException e)
+		{
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+
+		return RESULT_NET_ERROR;
+	}
+
+	public static void prepare_addtional_params(Bundle params) {
+		if (params == null) {
+			params = new Bundle();
+		}
+
+		String user = ApexTrackingApplication.get_user();
+		if (user != null && params.getString("user") == null) {
+			params.putString("user",user);
+		}
+
+		String pwd = ApexTrackingApplication.get_pass();
+		if (pwd != null && params.getString("pwd") == null) {
+			params.putString("pwd",pwd);
+		}
+
+	}
+
+	public static String getJson(String url, Bundle parms)
+	{
+		String TAG = "net_dbg@GetJson";
+		Log.d(TAG, "entry");
+
+		prepare_addtional_params(parms);
+//		parms.putString("sessionid", ApexTrackingApplication.get_sessionid());
+
+		// if (true)
+		// return fakegetJson(url);
+		try
+		{
+			// BasicHttpParams httpParams = new BasicHttpParams();
+			// HttpConnectionParams.setConnectionTimeout(httpParams,
+			// REQUEST_TIMEOUT);
+			// HttpConnectionParams.setSoTimeout(httpParams, SO_TIMEOUT);
+			HttpClient client = getNewHttpClient();// new
+													// DefaultHttpClient(httpParams);
+			HttpPost post = new HttpPost(url);
+			MultipartEntity reqEntity = new MultipartEntity(
+					HttpMultipartMode.BROWSER_COMPATIBLE);
+
+			Set<String> keys = parms.keySet();
+			Log.d(TAG, "================parms============");
+			for (String key : keys)
+			{
+				if (key.contains("_file"))
+				{
+					;
+				}
+				else
+					reqEntity.addPart(key, new StringBody(parms.get(key)
+							.toString()));
+				Log.d(TAG, "key=" + key + "    val="
+						+ parms.get(key).toString());
+			}
+			Log.d(TAG, "================parms============");
+
+			post.setEntity(reqEntity);
+			HttpResponse response = client.execute(post);
+			int statucode = response.getStatusLine().getStatusCode();
+			if (statucode == HttpStatus.SC_OK)
+			{
+				HttpEntity resEntity = response.getEntity();
+				if (resEntity != null)
+				{
+					Log.d(TAG,
+							"Response: content len==>"
+									+ resEntity.getContentLength());
+					InputStream is = resEntity.getContent();
+					try
+					{
+
+						BufferedReader br = new BufferedReader(
+								new InputStreamReader(is, "utf-8"), 8);
+						StringBuilder sb = new StringBuilder();
+						String line = null;
+						while ((line = br.readLine()) != null)
+						{
+							sb.append(line + "\n");
+						}
+
+						Log.d(TAG, "Response: content begin");
+						Log.d(TAG, sb.toString());
+						Log.d(TAG, "Response: content end");
+
+						if (sb.length() <= 0)
+						{
+
+							return null;
+						}
+						return sb.toString();
+
+					}
+					catch (Exception e)
+					{
+						Log.e(TAG, e.toString());
+						return null;
+						// TODO: handle exception
+					}
+					finally
+					{
+						is.close();
+
+					}
+
+				}
+				else
+				{
+					/*
+					 * resEntity is null
+					 */
+					Log.d(TAG, "RESPONSE ENTITY IS NULL");
+					return null;
+				}
+
+			}
+			else
+			{
+				/*
+				 * Http error; out put error code;
+				 */
+				Log.d(TAG, "HTTP " + statucode);
+
+				HttpEntity resEntity = response.getEntity();
+				if (resEntity != null)
+				{
+
+					InputStream is = resEntity.getContent();
+					try
+					{
+
+						BufferedReader br = new BufferedReader(
+								new InputStreamReader(is, "utf-8"), 8);
+						StringBuilder sb = new StringBuilder();
+						String line = null;
+						while ((line = br.readLine()) != null)
+						{
+							sb.append(line + "\n");
+						}
+
+						Log.d(TAG, "Response: content begin");
+						Log.d(TAG, sb.toString());
+						Log.d(TAG, "Response: content end");
+						return null;
+					}
+					catch (Exception e)
+					{
+						Log.e(TAG, e.toString());
+						return null;
+						// TODO: handle exception
+					}
+					finally
+					{
+						is.close();
+
+					}
+
+				}
+				else
+				{
+					/*
+					 * resEntity is null
+					 */
+					Log.e(TAG, "RESPONSE ENTITY IS NULL");
+					return null;
+				}
+			}
+
+		}
+		catch (ConnectTimeoutException e)
+		{
+			Log.d(TAG, "request time out");
+			return null;
+
+		}
+		catch (Exception e)
+		{
+			Log.d(TAG, e.toString());
+			return null;
+		}
+
+	}
+
+	public static int get_recordcount(Bundle parms)
+	{
+		String TAG = "net_dbg@get_recordcount";
+
+		parms.putString("action", "handset_search_count");
+//		parms.putString("sessionid", ApexTrackingApplication.get_sessionid());
+//		Log.d(TAG, "sessionid=" + ApexTrackingApplication.get_sessionid());
+		String jstr = getJson(Network.URL_REQUEST_COUNT, parms);
+		if (jstr == null || jstr.length() <= 0)
+		{
+			Log.d(TAG, "json is wrong");
+			return Network.RESULT_NET_ERROR;
+		}
+		JSONObject jsobj;
+
+		// array = new JSONArray(json);
+		try
+		{
+			jsobj = new JSONObject(jstr);
+			if (jsobj.length() > 0)
+			{
+				int iresult = jsobj.getInt("result");
+				if (iresult == Network.AP_SESSION_EXPIRED)
+				{
+					Log.e(TAG, "AP_SESSION_EXPIRED");
+					String user, pass;
+					user = ApexTrackingApplication.get_user();
+					pass = ApexTrackingApplication.get_pass();
+					Network.get_Auth(user, pass);
+					jstr = getJson(Network.URL_REQUEST_COUNT, parms);
+					jsobj = new JSONObject(jstr);
+					iresult = jsobj.getInt("result");
+				}
+				if (iresult != Network.AP_USER_AUTH)
+				{
+					// session expired
+					Log.d(TAG,
+							"USER NOT AUTHORIZED CODE="
+									+ jsobj.getInt("result"));
+					return RESULT_SESSION_EXPIRED;
+					// if (get_Auth(name, password) == RESULT_TRUE)
+					// {
+					// return get_recordcount(name, password, parms);
+					//
+					// }
+					// else
+					// {
+					//
+					// Log.d(TAG,
+					// "USER NOT AUTHORIZED CODE="
+					// + jsobj.getInt("result"));
+					// return RESULT_SESSION_EXPIRED;
+					// }
+				}
+				else
+				{
+					ApexTrackingApplication.SetAuthorizeStatus(true);
+					return jsobj.getInt("count");
+				}
+			}
+			else
+			{
+				Log.d(TAG, "json is wrong");
+				return Network.RESULT_NET_ERROR;
+			}
+		}
+		catch (JSONException e)
+		{
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+
+		return RESULT_ERROR;
+	}
+
+	public static String get_records(String name, String password, Bundle parms)
+	{
+		String TAG = "net_dbg@get_records";
+		// parms.putString("user", name);
+		// parms.putString("password", password);
+		// if (!Network.NetworkIsAvailable())
+		// {
+		// Log.d(TAG, "network not available!");
+		// return "Network.RESULT_NET_NOTAVAILABLE"; // network not available
+		// }
+		parms.putString("action", "handset_search");
+//		parms.putString("sessionid", ApexTrackingApplication.get_sessionid());
+		String jstr = getJson(Network.URL_REQUEST_RECORDS, parms);
+		if (jstr == null || jstr.length() <= 0)
+		{
+			Log.d(TAG, "json is wrong");
+			return null;
+		}
+		JSONObject jsobj;
+		//
+		// array = new JSONArray(json);
+		try
+		{
+			jsobj = new JSONObject(jstr);
+			if (jsobj.length() > 0)
+			{
+				int iresult = jsobj.getInt("result");
+				if (iresult == Network.AP_SESSION_EXPIRED)
+				{
+					Log.e(TAG, "AP_SESSION_EXPIRED");
+					String user, pass;
+					user = ApexTrackingApplication.get_user();
+					pass = ApexTrackingApplication.get_pass();
+					Network.get_Auth(user, pass);
+					jstr = getJson(Network.URL_REQUEST_RECORDS, parms);
+					jsobj = new JSONObject(jstr);
+					iresult = jsobj.getInt("result");
+				}
+				if (iresult != Network.AP_USER_AUTH)
+				{
+					// session expired
+					Log.d(TAG,
+							"USER NOT AUTHORIZED CODE="
+									+ jsobj.getInt("result"));
+					return null;
+					// if (get_Auth(name, password) == RESULT_TRUE)
+					// {
+					// return get_records(name, password, parms);
+					//
+					// }
+					// else
+					// {
+					//
+					// Log.d(TAG,
+					// "USER NOT AUTHORIZED CODE="
+					// + jsobj.getInt("result"));
+					// return null;
+					// }
+				}
+				else
+				{
+					ApexTrackingApplication.SetAuthorizeStatus(true);
+					return jstr;
+				}
+			}
+			else
+			{
+				Log.d(TAG, "json is wrong");
+				return null;
+			}
+		}
+		catch (JSONException e)
+		{
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		return null;
+
+		// return RESULT_ERROR;
+	}
+
+	public static String get_push(String e_id, String s_id, int limit,
+			int offset)
+	{
+		String TAG = "net_dbg@get_push";
+		Bundle parms = new Bundle();
+		parms.putString("action", "handset_search");
+		parms.putString("e_id", e_id);
+		parms.putString("s_id", s_id);
+		parms.putString("limit", limit + "");
+		parms.putString("offset", offset + "");
+		parms.putString("action_type", "detail");
+		parms.putString("module_name", "Pull Message");
+		parms.putString("uuid", commonUtil.getDUID());
+//		String sessionid = ApexTrackingApplication.get_sessionid();
+		// if (TextUtils.isEmpty(sessionid))
+		// {
+		//
+		// Log.d(TAG, "no sessionid return!");
+		// return null;
+		//
+		// }
+		String user = ApexTrackingApplication.get_user();
+		// if (TextUtils.isEmpty(user))
+		// {
+		//
+		// Log.d(TAG, "no user name return!");
+		// return null;
+		//
+		// }
+//		parms.putString("sessionid", sessionid);
+		parms.putString("user", user);
+		// SQLiteDatabase db =
+		// dbUtil.OpenDB(ApexTrackingApplication.get_instance(), null, false);
+		// Cursor cursor = db.query("push_message", new String[] {"MAX(e_id)"},
+		// "user = '"+ApexTrackingApplication.get_user()+"'", null, null, null,
+		// null, null);
+		// if (cursor.moveToNext())
+		// {
+		// String maxid = cursor.getString(0);
+		// if(!TextUtils.isEmpty(maxid))
+		// parms.putString("id", maxid);
+		// }
+		// dbUtil.CloseCursor(cursor);
+		// dbUtil.CloseDB(db);
+
+		String jstr = getJson(Network.URL_PUSH, parms);
+		if (jstr == null || jstr.length() <= 0)
+		{
+			Log.d(TAG, "json is wrong");
+			return null;
+		}
+		JSONObject jsobj;
+		//
+		// array = new JSONArray(json);
+		try
+		{
+			jsobj = new JSONObject(jstr);
+			if (jsobj.length() > 0)
+			{
+				int iresult = jsobj.getInt("result");
+				if (iresult == Network.AP_SESSION_EXPIRED)
+				{
+					Log.e(TAG, "AP_SESSION_EXPIRED");
+					String pass;
+
+					pass = ApexTrackingApplication.get_pass();
+					Network.get_Auth(user, pass);
+					jstr = getJson(Network.URL_REQUEST_RECORDS, parms);
+					jsobj = new JSONObject(jstr);
+					iresult = jsobj.getInt("result");
+				}
+				if (iresult != Network.AP_MESSAGE_NEW)
+				{
+					// session expired
+					Log.d(TAG,
+							"DOSE NOT GET NEW MESSAGE CODE="
+									+ jsobj.getInt("result"));
+					return null;
+					// if (get_Auth(name, password) == RESULT_TRUE)
+					// {
+					// return get_records(name, password, parms);
+					//
+					// }
+					// else
+					// {
+					//
+					// Log.d(TAG,
+					// "USER NOT AUTHORIZED CODE="
+					// + jsobj.getInt("result"));
+					// return null;
+					// }
+				}
+				else
+				{
+					return jstr;
+				}
+			}
+			else
+			{
+				Log.d(TAG, "json is wrong");
+				return null;
+			}
+		}
+		catch (JSONException e)
+		{
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		return null;
+
+		// return RESULT_ERROR;
+	}
+
+	public static String check_push()
+	{
+	    if(true)
+	        return null;
+		String TAG = "net_dbg@check_push";
+		Bundle parms = new Bundle();
+		parms.putString("action", "handset_search");
+		parms.putString("module_name", "Pull Message");
+		parms.putString("uuid", commonUtil.getDUID());
+//		String sessionid = ApexTrackingApplication.get_sessionid();
+		// if (TextUtils.isEmpty(sessionid))
+		// {
+		//
+		// Log.d(TAG, "no sessionid return!");
+		// return null;
+		//
+		// }
+		String user = ApexTrackingApplication.get_user();
+		if (TextUtils.isEmpty(user))
+		{
+
+			Log.d(TAG, "no user name return!");
+			return null;
+
+		}
+		// parms.putString("sessionid", sessionid);
+		parms.putString("user", user);
+		SQLiteDatabase db = dbUtil.OpenDB(
+				ApexTrackingApplication.get_instance(), null, false);
+		Cursor cursor = db.query("push_message", new String[] { "MAX(e_id)" },
+				"user = '" + ApexTrackingApplication.get_user() + "'", null,
+				null, null, null, null);
+		if (cursor.moveToNext())
+		{
+			String maxid = cursor.getString(0);
+			if (!TextUtils.isEmpty(maxid))
+				parms.putString("id", maxid);
+		}
+		dbUtil.CloseCursor(cursor);
+		dbUtil.CloseDB(db);
+
+		String jstr = getJson(Network.URL_PUSH, parms);
+		if (jstr == null || jstr.length() <= 0)
+		{
+			Log.d(TAG, "json is wrong");
+			return null;
+		}
+		JSONObject jsobj;
+		//
+		// array = new JSONArray(json);
+		try
+		{
+			jsobj = new JSONObject(jstr);
+			if (jsobj.length() > 0)
+			{
+				int iresult = jsobj.getInt("result");
+				if (iresult == Network.AP_SESSION_EXPIRED)
+				{
+					Log.e(TAG, "AP_SESSION_EXPIRED");
+					String pass;
+
+					pass = ApexTrackingApplication.get_pass();
+					Network.get_Auth(user, pass);
+					jstr = getJson(Network.URL_PUSH, parms);
+					jsobj = new JSONObject(jstr);
+					iresult = jsobj.getInt("result");
+				}
+				if (iresult != Network.AP_MESSAGE_NEW)
+				{
+					// session expired
+					Log.d(TAG,
+							"DOSE NOT GET NEW MESSAGE CODE="
+									+ jsobj.getInt("result"));
+					return null;
+					// if (get_Auth(name, password) == RESULT_TRUE)
+					// {
+					// return get_records(name, password, parms);
+					//
+					// }
+					// else
+					// {
+					//
+					// Log.d(TAG,
+					// "USER NOT AUTHORIZED CODE="
+					// + jsobj.getInt("result"));
+					// return null;
+					// }
+				}
+				else
+				{
+					return jstr;
+				}
+			}
+			else
+			{
+				Log.d(TAG, "json is wrong");
+				return null;
+			}
+		}
+		catch (JSONException e)
+		{
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		return null;
+
+		// return RESULT_ERROR;
+	}
+
+	public static String get_detail(Bundle parms)
+	{
+		String TAG = "net_dbg@get_detail";
+		parms.putString("action", "handset_search");
+
+		String actionType = parms.getString("action_type");
+		if (actionType != null && actionType.equals("Detail")) {
+		    parms.putBoolean("request_communication",true);
+        } else if(actionType != null && (actionType.equals("Tracing") || actionType.equals("Tracking"))) {
+			parms.putBoolean("request_location",true);
+		}
+
+//		parms.putString("sessionid", ApexTrackingApplication.get_sessionid());
+		String jstr = getJson(Network.URL_REQUEST_RECORDS, parms);
+		if (jstr == null || jstr.length() <= 0)
+		{
+			Log.d(TAG, "json is wrong");
+			return null;
+		}
+		JSONObject jsobj;
+		//
+		// array = new JSONArray(json);
+		try
+		{
+			jsobj = new JSONObject(jstr);
+			if (jsobj.length() > 0)
+			{
+				int iresult = jsobj.getInt("result");
+				if (iresult == Network.AP_SESSION_EXPIRED)
+				{
+					Log.e(TAG, "AP_SESSION_EXPIRED");
+					String user, pass;
+					user = ApexTrackingApplication.get_user();
+					pass = ApexTrackingApplication.get_pass();
+					Network.get_Auth(user, pass);
+					jstr = getJson(Network.URL_REQUEST_RECORDS, parms);
+					jsobj = new JSONObject(jstr);
+					iresult = jsobj.getInt("result");
+				}
+				if (iresult != Network.AP_USER_AUTH)
+				{
+					// session expired
+					Log.d(TAG,
+							"USER NOT AUTHORIZED CODE="
+									+ jsobj.getInt("result"));
+					return null;
+					// if (get_Auth(name, password) == RESULT_TRUE)
+					// {
+					// return get_records(name, password, parms);
+					//
+					// }
+					// else
+					// {
+					//
+					// Log.d(TAG,
+					// "USER NOT AUTHORIZED CODE="
+					// + jsobj.getInt("result"));
+					// return null;
+					// }
+				}
+				else
+				{
+					ApexTrackingApplication.SetAuthorizeStatus(true);
+					return jstr;
+				}
+			}
+			else
+			{
+				Log.d(TAG, "json is wrong");
+				return null;
+			}
+		}
+		catch (JSONException e)
+		{
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		return null;
+
+		// return RESULT_ERROR;
+	}
+
+	public static int get_Auth(String name, String password)
+	{
+
+		String TAG = "net_dbg@get_Auth";
+		Log.d(TAG, "u:" + name + ";p:" + password);
+		if (!Network.NetworkIsAvailable())
+		{
+			Log.d(TAG, "network not available!");
+			return Network.RESULT_NET_NOTAVAILABLE; // network not available
+		}
+		Bundle parms = new Bundle();
+		parms.putString("user", name);
+		parms.putString("password", password);
+		parms.putString("action", "handset_login");
+		int ver = ApexTrackingApplication
+				.get_instance()
+				.getSharedPreferences(name + "_Apex_auth", Context.MODE_PRIVATE)
+				.getInt("AuthInfoVer", 0);
+		parms.putString("auth_ver", ver + "");
+		String jstr = getJson(Network.URL_UPDATE_AUTH, parms);
+		/*
+		 * error occur while get authorization info from server. include can not
+		 * reach server , wrong parms ,server get wrong , etc.
+		 */
+		if (jstr == null || jstr.length() <= 0)
+		{
+			Log.d(TAG, "json is wrong");
+			return Network.RESULT_NET_ERROR;
+		}
+
+		return parse_authinfo(jstr, name, password, parms);
+	}
+
+	private static int parse_authinfo(String json, String user, String pass, Bundle parms)
+	{
+		String TAG = "net_dbg@parse_authinfo";
+		Log.d(TAG, json);
+		// JSONArray array;
+		JSONObject jsobj;
+		SQLiteDatabase db = null;
+		try
+
+		{
+
+			// array = new JSONArray(json);
+			jsobj = new JSONObject(json);
+			if (jsobj.length() > 0)
+			{
+				// JSONObject objresult = jsobj.get.getJSONObject(0);// result
+				// the
+				// server result
+				// ;
+				if (jsobj.getInt("result") != Network.AP_USER_AUTH)
+				{
+					ApexTrackingApplication.logout();
+					// user not authorized return
+					Log.d(TAG,
+							"USER NOT AUTHORIZED CODE="
+									+ jsobj.getInt("result"));
+					return RESULT_FALSE;
+				}
+
+				JSONObject objheader = jsobj.getJSONObject("header");
+				String required_ver = objheader.getString("client_ver");
+				//String ver = objheader.getString("ver");
+				String current_ver = ApexTrackingApplication.get_instance()
+						.getPackageManager().getPackageInfo("com.usai.apex", 0).versionName;
+				if (current_ver.compareTo(required_ver) < 0)
+					return RESULT_VER_LOW;
+				// JSONObject objsessionid = jsobj.getJSONObject(1); // session
+				// id
+				// on
+				// server;
+				// ApexTrackingApplication.put_sessionid(objheader
+				// .getString("sessionid"));
+				// ApexTrackingApplication.put_user(user);
+				// ApexTrackingApplication.put_password(pass);
+				// ApexTrackingApplication.put_authorization(true);
+				ApexTrackingApplication.login(null,
+						user, pass);
+//				Log.d(TAG, "sessionid=" + objheader.getString("sessionid"));
+				// JSONObject objupdate = array.getJSONObject(3); // whether
+				// need
+				// update ;
+				if (objheader.getBoolean("update") == false)
+				{
+					// no update on the server;
+					return RESULT_TRUE;
+				}
+				// JSONObject objver = array.getJSONObject(4); // new version
+				// get
+				// from server;
+
+				Editor editor = ApexTrackingApplication
+						.get_instance()
+						.getSharedPreferences(user + "_Apex_auth",
+								Context.MODE_PRIVATE).edit();
+
+				editor.putInt("AuthInfoVer", objheader.getInt("ver"));
+				JSONObject objfuncs = jsobj.getJSONObject("functions");
+				Iterator<?> it = objfuncs.keys();
+				db = dbUtil.OpenDB(ApexTrackingApplication.get_instance(),
+						null, true);
+				String sql = "insert into fields_info(name,aname,field_type,function_name,behavior,priority,show,user) values(?,?,?,?,?,?,?,?)";
+				String sql1 = "insert into actions_info(name,function_name,user,priority) values(?,?,?,?)";
+
+				SQLiteStatement stat = db.compileStatement(sql);
+				SQLiteStatement stat1 = db.compileStatement(sql1);
+
+				db.beginTransaction();
+				db.execSQL("update fields_info set abandon = 1 where user ='"
+						+ user + "'");
+				db.execSQL("update actions_info set abandon = 1 where user ='"
+						+ user + "'");
+
+				String field_name, field_type, alias_name;
+				while (it.hasNext()) // loop for each function
+				{
+					String func_name = (String) it.next();
+
+					// Set<String> funset = new HashSet<String>();
+					JSONObject objfun = objfuncs.getJSONObject(func_name);
+					int behavior, priority = 999;
+					int show = 1;
+					JSONObject objbehavior = objfun.getJSONObject("search");
+					Iterator<?> itbehavior = objbehavior.keys();
+					behavior = BEHAVIOR_SEARCH;
+					while (itbehavior.hasNext()) // loop for search fields in
+													// certain function
+					{
+						String field = (String) itbehavior.next();
+						JSONObject field_info = objbehavior
+								.getJSONObject(field);
+						field_name = field_info.getString("name");
+						field_type = field_info.getString("type");
+						alias_name = field_info.getString("alias");
+						priority = field_info.getInt("priority");
+						if (priority == 999)
+							show = 0;
+						else
+							show = 1;
+						int id = dbUtil.get_recordid(db, "fields_info",
+								"name='" + field_name + "' and behavior="
+										+ behavior + " and function_name='"
+										+ func_name + "' and user='" + user
+										+ "'");
+						if (id >= 0) // record exist;
+						{
+							db.execSQL("update fields_info set abandon = 0 where _id ="
+									+ id);
+						}
+						else
+						{
+							stat.bindString(1, field_name);
+							stat.bindString(2, alias_name);
+							stat.bindString(3, field_type);
+							stat.bindString(4, func_name);
+							stat.bindLong(5, behavior);
+							stat.bindLong(6, priority);
+							stat.bindLong(7, show);
+							stat.bindString(8, user);
+							stat.executeInsert();
+						}
+					}
+
+					objbehavior = objfun.getJSONObject("result");
+					Iterator<?> itresult = objbehavior.keys();
+					behavior = BEHAVIOR_RESULT;
+					while (itresult.hasNext()) // loop for result fields in
+												// certain function
+					{
+						String field = (String) itresult.next();
+						JSONObject field_info = objbehavior
+								.getJSONObject(field);
+						field_name = field_info.getString("name");
+						field_type = field_info.getString("type");
+						alias_name = field_info.getString("alias");
+						priority = field_info.getInt("priority");
+						if (priority == 999)
+							show = 0;
+						else
+							show = 1;
+						int id = dbUtil.get_recordid(db, "fields_info",
+								"name='" + field_name + "' and behavior="
+										+ behavior + " and function_name='"
+										+ func_name + "' and user='" + user
+										+ "'");
+						if (id >= 0) // record exist;
+						{
+							db.execSQL("update fields_info set abandon = 0 where _id ="
+									+ id);
+						}
+						else
+						{
+							stat.bindString(1, field_name);
+							stat.bindString(2, alias_name);
+							stat.bindString(3, field_type);
+							stat.bindString(4, func_name);
+							stat.bindLong(5, behavior);
+							stat.bindLong(6, priority);
+							stat.bindLong(7, show);
+							stat.bindString(8, user);
+							stat.executeInsert();
+						}
+					}
+
+					// objfun.has("actions")
+					objbehavior = objfun.getJSONObject("actions");
+					Iterator<?> itactions = objbehavior.keys();
+					// behavior = BEHAVIOR_RESULT;
+					while (itactions.hasNext()) // loop for result fields in
+												// certain function
+					{
+						String actionname = (String) itactions.next();
+						int action_priority = objbehavior.getInt(actionname);
+
+						int id = dbUtil.get_recordid(db, "actions_info",
+								"name='" + actionname + "' and function_name='"
+										+ func_name + "' and user='" + user
+										+ "'");
+						if (id >= 0) // record exist;
+						{
+							db.execSQL("update actions_info set abandon = 0 , priority="
+									+ action_priority + " where _id =" + id);
+						}
+						else
+						{
+							stat1.bindString(1, actionname);
+							stat1.bindString(2, func_name);
+							stat1.bindString(3, user);
+							stat1.bindLong(4, action_priority);
+							stat1.executeInsert();
+
+						}
+					}
+				}
+				db.execSQL("delete from fields_info where abandon = 1");
+				db.execSQL("delete from actions_info where abandon = 1");
+				db.setTransactionSuccessful();
+				db.endTransaction();
+				editor.commit();
+				return RESULT_TRUE;
+			}
+			Log.d(TAG, "json is wrong");
+			return RESULT_USERAUTH_ERROR;
+		}
+		catch (JSONException e1)
+		{
+			// TODO Auto-generated catch block
+			ApexTrackingApplication.logout();
+			
+			
+			parms.putString("module_name", "Log");
+			parms.putString("action_type", "save");
+			parms.putString("return", json);
+			
+			String jstr = getJson(Network.URL_LOG, parms);
+			
+			e1.printStackTrace();
+			Log.d(TAG, "json is wrong");
+		}
+		catch (NameNotFoundException e)
+		{
+			// TODO Auto-generated catch block
+			
+			ApexTrackingApplication.logout();
+			
+			
+			parms.putString("module_name", "Log");
+			parms.putString("action_type", "save");
+			parms.putString("return", json);
+			String jstr = getJson(Network.URL_LOG, parms);
+			e.printStackTrace();
+		}
+		finally
+		{
+			dbUtil.CloseDB(db);
+		}
+
+		// try
+		// {
+		// m_RemoteVerCode = Integer
+		// .parseInt(obj.getString("verCode"));
+		// m_RemoteVerName = obj.getString("verName");
+		// m_NewVerUrl = obj.getString("URL");
+		// }
+		// catch (Exception e)
+		// {
+		// m_RemoteVerCode = -1;
+		// m_RemoteVerName = "";
+		// m_NewVerUrl = "";
+		// dbgUtil.Log(Log.INFO,TAG, "download failed json file wrong!");
+		// return false;
+		// }
+		Log.d(TAG, "json is wrong");
+		return RESULT_USERAUTH_ERROR;
+	}
+
+	// private void writeData(JSONObject allData)
+	// {
+	//
+	// File file = new File(Environment.getExternalStorageDirectory()
+	// .toString() + File.separator + "live.txt");
+	// if (!file.exists())
+	// {
+	// try
+	// {
+	// file.createNewFile();
+	// }
+	// catch (IOException e)
+	// {
+	// e.printStackTrace();
+	// }
+	// }
+	// FileOutputStream fos;
+	// OutputStreamWriter osw = null;
+	// try
+	// {
+	// fos = new FileOutputStream(file);
+	//
+	// osw = new OutputStreamWriter(fos, "UTF-8");
+	// osw.write(allData.toString());
+	// osw.flush();
+	// }
+	// catch (FileNotFoundException e)
+	// {
+	// e.printStackTrace();
+	// }
+	// catch (UnsupportedEncodingException e)
+	// {
+	// e.printStackTrace();
+	// }
+	// catch (IOException e)
+	// {
+	// e.printStackTrace();
+	// }
+	// finally
+	// {
+	// if (osw != null)
+	// {
+	// try
+	// {
+	// osw.close();
+	// }
+	// catch (IOException e)
+	// {
+	// e.printStackTrace();
+	// }
+	// }
+	// }
+	// }
+
+	public static boolean NetworkIsAvailable()// Context context)
+	{
+		String TAG = "net_dbg@CheckNetwork";
+		ConnectivityManager connManager = (ConnectivityManager) ApexTrackingApplication
+				.get_instance().getSystemService(Context.CONNECTIVITY_SERVICE);
+		// .getSystemService(Context.CONNECTIVITY_SERVICE);
+
+		NetworkInfo networkInfo = connManager.getActiveNetworkInfo();
+		if (networkInfo == null)
+		{
+			Log.d(TAG, "can not get Active NetworkInfo!");
+			// dbgUtil.Log(Log.DEBUG, "Current Network info",
+			// "can not get Active NetworkInfo!");
+			return false;
+		}
+		NetworkInfo.State netState = networkInfo.getState();
+		if (netState != NetworkInfo.State.CONNECTED)
+		{
+			Log.d(TAG, "not Connected!State=" + netState);
+			// dbgUtil.Log(Log.DEBUG, "Current Network info",
+			// "not Connected!State=" + netState);
+			return false;
+		}
+		// int iconntype = -1;
+		// iconntype = networkInfo.getType();
+
+		// boolean bUseMobileNetwork = context.getSharedPreferences(
+		// "PhoneAsstPref", 0).getBoolean("UseMobileNetwork", false);
+		//
+		// if (bUseMobileNetwork == false
+		// && iconntype != ConnectivityManager.TYPE_WIFI && iconntype != 9/*
+		// earthnet */)
+		// {
+		// Log.d(TAG,);
+		// dbgUtil.Log(Log.DEBUG, "Current Network info",
+		// "not allowed!Connection type=" + networkInfo.getTypeName());
+		// return false;
+		// }
+		boolean bavailable = networkInfo.isAvailable();
+		String strtype = networkInfo.getTypeName();
+
+		Log.d(TAG, " type = " + strtype + " abailable = " + bavailable
+				+ " state " + netState);
+		// dbgUtil.Log(Log.INFO, "Current Network info", " type = " + strtype
+		// + " abailable = " + bavailable + " state " + netState);
+		return bavailable;
+	}
+
+//	public static class SSLSocketFactoryEx extends SSLSocketFactory
+//	{
+//
+//		SSLContext	sslContext	= SSLContext.getInstance("TLS");
+//
+//		public SSLSocketFactoryEx(KeyStore truststore)
+//				throws NoSuchAlgorithmException, KeyManagementException,
+//				KeyStoreException, UnrecoverableKeyException
+//		{
+//			super(truststore);
+//
+//			TrustManager tm = new X509TrustManager()
+//			{
+//				public java.security.cert.X509Certificate[] getAcceptedIssuers()
+//				{
+//					return null;
+//				}
+//
+//				@Override
+//				public void checkClientTrusted(
+//						java.security.cert.X509Certificate[] chain,
+//						String authType)
+//						throws java.security.cert.CertificateException
+//				{
+//				}
+//
+////				@Override
+////				public void checkServerTrusted(
+////						java.security.cert.X509Certificate[] chain,
+////						String authType)
+////						throws java.security.cert.CertificateException
+////				{
+////				}
+////				@Override
+////				public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws java.security.cert.CertificateException {
+////	                try {
+////	                    chain[0].checkValidity();
+////	                } catch (java.security.cert.CertificateExpiredException e) {
+////	                   // Logger.e(TAG, "CertificateExpiredException");
+////	                    throw new java.security.cert.CertificateException("CertificateExpiredException");
+////	                } catch (java.security.cert.CertificateNotYetValidException e) {
+////	                    //Logger.e(TAG, "CertificateNotYetValidException");
+////	                    throw new java.security.cert.CertificateException("CertificateNotYetValidException");
+////	                }
+////	            }@Override
+////				public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws java.security.cert.CertificateException {
+////	                try {
+////	                    chain[0].checkValidity();
+////	                } catch (java.security.cert.CertificateExpiredException e) {
+////	                   // Logger.e(TAG, "CertificateExpiredException");
+////	                    throw new java.security.cert.CertificateException("CertificateExpiredException");
+////	                } catch (java.security.cert.CertificateNotYetValidException e) {
+////	                    //Logger.e(TAG, "CertificateNotYetValidException");
+////	                    throw new java.security.cert.CertificateException("CertificateNotYetValidException");
+////	                }
+////	            }
+//			};
+//			sslContext.init(null, new TrustManager[] { tm }, null);
+//		}
+//
+//		@Override
+//		public Socket createSocket(Socket socket, String host, int port,
+//				boolean autoClose) throws IOException, UnknownHostException
+//		{
+//			return sslContext.getSocketFactory().createSocket(socket, host,
+//					port, autoClose);
+//		}
+//
+//		@Override
+//		public Socket createSocket() throws IOException
+//		{
+//			return sslContext.getSocketFactory().createSocket();
+//		}
+//	}
+
+	public static class SSLSocketFactoryEx extends SSLSocketFactory
+	{
+
+		SSLContext	sslContext	= SSLContext.getInstance("TLS");
+
+		public SSLSocketFactoryEx(KeyStore truststore)
+				throws NoSuchAlgorithmException, KeyManagementException,
+				KeyStoreException, UnrecoverableKeyException
+		{
+			super(truststore);
+
+			TrustManager tm = new X509TrustManager()
+			{
+				public java.security.cert.X509Certificate[] getAcceptedIssuers()
+				{
+					return null;
+				}
+
+				@Override
+				public void checkClientTrusted(
+						java.security.cert.X509Certificate[] chain,
+						String authType)
+						throws java.security.cert.CertificateException
+				{
+				}
+
+				//				@Override
+//				public void checkServerTrusted(
+//						java.security.cert.X509Certificate[] chain,
+//						String authType)
+//						throws java.security.cert.CertificateException
+//				{
+//				}
+				@Override
+				public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws java.security.cert.CertificateException {
+					try {
+						chain[0].checkValidity();
+					} catch (java.security.cert.CertificateExpiredException e) {
+						// Logger.e(TAG, "CertificateExpiredException");
+						throw new java.security.cert.CertificateException("CertificateExpiredException");
+					} catch (java.security.cert.CertificateNotYetValidException e) {
+						//Logger.e(TAG, "CertificateNotYetValidException");
+						throw new java.security.cert.CertificateException("CertificateNotYetValidException");
+					}
+				}
+			};
+			sslContext.init(null, new TrustManager[] { tm }, null);
+		}
+
+		@Override
+		public Socket createSocket(Socket socket, String host, int port,
+								   boolean autoClose) throws IOException, UnknownHostException
+		{
+			return sslContext.getSocketFactory().createSocket(socket, host,
+					port, autoClose);
+		}
+
+		@Override
+		public Socket createSocket() throws IOException
+		{
+			return sslContext.getSocketFactory().createSocket();
+		}
+	}
+	private static String createPostParameters(Bundle parms) throws UnsupportedEncodingException {
+		StringBuilder result = new StringBuilder();
+		boolean first = true;
+		for(String key : parms.keySet()){
+			if (first)
+				first = false;
+			else
+				result.append("&");
+
+			result.append(URLEncoder.encode(key, "UTF-8"));
+			result.append("=");
+			result.append(URLEncoder.encode(parms.get(key).toString(), "UTF-8"));
+		}
+
+		return result.toString();
+	}
+
+	//读取响应头
+	public static JSONObject getResponseHeader(HttpURLConnection conn) {
+		Map<String, List<String>> responseHeaderMap = conn.getHeaderFields();
+		int size = responseHeaderMap.size();
+		try {
+			JSONObject responseHeader = new JSONObject();
+			for(int i = 0; i < size; i++){
+				String responseHeaderKey = conn.getHeaderFieldKey(i);
+				String responseHeaderValue = conn.getHeaderField(i);
+				if (responseHeaderKey != null && !responseHeaderKey.isEmpty() && responseHeaderValue != null) {
+					responseHeader.put(responseHeaderKey,responseHeaderValue);
+				}
+			}
+			return responseHeader;
+		} catch (JSONException e) {
+			e.printStackTrace();
+			return null;
+		}
+	}
+
+	public static String getResponsesuggestedFilename(JSONObject response) {
+
+		if (response == null) {
+			return null;
+		}
+
+		try {
+			String key = "Content-Disposition";
+			String content_disposition = response.getString(key);
+			if (content_disposition != null) {
+				String[] components = content_disposition.split(";");
+				if (components[1] != null) {
+					String fileName = components[1].split("=")[1];
+					fileName = fileName.replace("\"","");
+					return fileName;
+				}
+			}
+
+		} catch (JSONException e) {
+			e.printStackTrace();
+		}
+
+
+		return null;
+	}
+
+	public static File downloadFile(Bundle params, String download_url,String dir) {
+
+		if (params == null) {
+			params = new Bundle();
+		}
+
+		prepare_addtional_params(params);
+		HttpURLConnection connection = null;
+
+		File returnFile = null;
+		try {
+
+			String fileName = UUID.randomUUID().toString();
+			if (dir == null) {
+				dir = Environment.getExternalStorageDirectory() + File.separator + "download";
+			}
+
+			if (RAUtil.isFileExist(fileName,dir)) {
+				returnFile = new File(dir + File.separator + fileName);
+			} else {
+				// 创建一个URL对象
+				URL url=new URL(download_url);
+				// 创建一个HTTP链接
+				connection=(HttpURLConnection)url.openConnection();
+				connection.setRequestMethod("POST");
+
+				// 拼参数
+				if (params != null && params.keySet().size() > 0) {
+					OutputStream os = connection.getOutputStream();
+					BufferedWriter writer = new BufferedWriter(
+							new OutputStreamWriter(os, "UTF-8"));
+					writer.write(createPostParameters(params));
+
+					writer.flush();
+					writer.close();
+					os.close();
+				}
+
+				// 获取响应
+				JSONObject responseHeader = getResponseHeader(connection);
+				String suggestedFileName = getResponsesuggestedFilename(responseHeader);
+				Log.d("Download", "download_query: " + suggestedFileName);
+				if (suggestedFileName != null && !suggestedFileName.isEmpty()) {
+					fileName = suggestedFileName;
+				}
+
+				// 使用IO流获取数据
+				InputStream inputStream=connection.getInputStream();
+				// 写文件
+				File downloadFile = RAUtil.write2SDFromInput(fileName,dir,inputStream);
+
+				if (downloadFile == null) {
+					returnFile = null;
+				} else {
+					returnFile = downloadFile;
+				}
+			}
+
+		} catch (IOException e) {
+			e.printStackTrace();
+		} finally {
+			if (connection != null) {
+				connection.disconnect();
+			}
+		}
+
+
+
+		return returnFile;
+	}
+
+	public static File download_query(String download_url,String path) {
+
+		return downloadFile(null,download_url,path);
+	}
+
+	public  static JSONObject query(Bundle params) {
+
+		params.putString("action","handset_search");
+
+		String jstr = getJson(Network.URL_REQUEST_COUNT, params);
+		try {
+
+			if (jstr == null || jstr.length() <= 0)
+			{
+				JSONObject resultJson = new JSONObject();
+				resultJson.put("err_msg","Net Error. Cannot connect to server for now. Please retry later.");
+				resultJson.put("result",RESULT_NET_ERROR);
+				return resultJson;
+			}
+
+			JSONObject jsobj = new JSONObject(jstr);
+			return jsobj;
+
+		} catch (JSONException e) {
+			e.printStackTrace();
+		}
+
+		return null;
+	}
+
+
+	public static JSONObject request_home() {
+
+		Bundle params = new Bundle();
+		params.putString("action","hand_new_home_list");
+		params.putBoolean("request_location",true);
+		boolean personMode = ApexTrackingApplication.get_instance().getPersonMode();
+		if (personMode) {
+			params.putString("personal_mode","true");
+		} else {
+			params.putString("personal_mode","false");
+		}
+
+		String jstr = getJson(URL_HOME,params);
+		Log.d("Network", "request_home: " + jstr);
+		try {
+
+			if (jstr == null || jstr.length() <= 0)
+			{
+				JSONObject resultJson = new JSONObject();
+				resultJson.put("err_msg","Net Error. Cannot connect to server for now. Please retry later.");
+				resultJson.put("result",RESULT_NET_ERROR);
+				return resultJson;
+			}
+
+			JSONObject jsobj = new JSONObject(jstr);
+			return jsobj;
+
+		} catch (JSONException e) {
+			e.printStackTrace();
+		}
+
+		return null;
+	}
+
+	public static JSONObject request_KPI() {
+
+		Bundle params = new Bundle();
+		params.putString("action","hand_new_kpi");
+
+		boolean personMode = ApexTrackingApplication.get_instance().getPersonMode();
+		if (personMode) {
+			params.putString("personal_mode","true");
+		} else {
+			params.putString("personal_mode","false");
+		}
+
+		String jstr = getJson(URL_KPI,params);
+		Log.d("Network", "request_kpi: " + jstr);
+		try {
+
+			if (jstr == null || jstr.length() <= 0)
+			{
+				JSONObject resultJson = new JSONObject();
+				resultJson.put("err_msg","Net Error. Cannot connect to server for now. Please retry later.");
+				resultJson.put("result",RESULT_NET_ERROR);
+				return resultJson;
+			}
+
+			JSONObject jsobj = new JSONObject(jstr);
+			return jsobj;
+
+		} catch (JSONException e) {
+			e.printStackTrace();
+		}
+
+		return null;
+	}
+
+	public static JSONObject request_history(Bundle params) {
+
+		if (params == null) {
+			params = new Bundle();
+		}
+		params.putString("action","hand_new_home_list_all");
+
+		boolean personMode = ApexTrackingApplication.get_instance().getPersonMode();
+		if (personMode) {
+			params.putString("personal_mode","true");
+		} else {
+			params.putString("personal_mode","false");
+		}
+
+		String jstr = getJson(URL_HISTORY,params);
+		Log.d("Network", "request_home: " + jstr);
+		try {
+
+			if (jstr == null || jstr.length() <= 0)
+			{
+				JSONObject resultJson = new JSONObject();
+				resultJson.put("err_msg","Net Error. Cannot connect to server for now. Please retry later.");
+				resultJson.put("result",RESULT_NET_ERROR);
+				return resultJson;
+			}
+
+			JSONObject jsobj = new JSONObject(jstr);
+			return jsobj;
+
+		} catch (JSONException e) {
+			e.printStackTrace();
+		}
+
+		return null;
+	}
+
+	public static JSONObject sendEmail(String email,String cc, String serialNo) {
+
+		Bundle params = new Bundle();
+		if (email == null) {
+			email = "";
+		}
+		if (serialNo == null) {
+			serialNo = "";
+		}
+
+		params.putString("msg",email);
+		params.putString("action","handset_search");
+		params.putString("action_type","save_communication_email");
+		params.putString("serial_no",serialNo);
+
+		if (cc != null) {
+			params.putString("cc",cc);
+		}
+		String jstr = getJson(URL_SEND_COMM_EMAIL,params);
+
+		return handleResponse(jstr);
+	}
+
+	private static JSONObject handleResponse(String jstr) {
+
+		try {
+
+			if (jstr == null || jstr.length() <= 0)
+			{
+				JSONObject resultJson = new JSONObject();
+				resultJson.put("err_msg","Net Error. Cannot connect to server for now. Please retry later.");
+				resultJson.put("result",RESULT_NET_ERROR);
+				return resultJson;
+			}
+
+			JSONObject jsobj = new JSONObject(jstr);
+			return jsobj;
+
+		} catch (JSONException e) {
+			e.printStackTrace();
+		}
+
+		return null;
+
+	}
+
+	public static String checkUpdate(Context context) {
+
+		if (context == null) {
+			return null;
+		}
+		String  ver_name = null;
+		int ver_code = -1;
+		try {
+			// ---get the package info---
+			PackageManager pm = context.getPackageManager();
+			PackageInfo pi = pm.getPackageInfo(context.getPackageName(), 0);
+			ver_name = pi.versionName;
+			ver_code = pi.versionCode;
+
+		} catch (Exception e) {
+			Log.e("VersionInfo", "Exception", e);
+		}
+
+		if (ver_name == null || ver_name.length() <= 0) {
+			return null;
+		}
+
+		Bundle params = new Bundle();
+		params.putString("ver",ver_name);
+		params.putString("action","current_ver");
+
+		String jsonStr = getJson(URL_CHECK_UPDATE,params);
+
+//		String jsonStr = "{\"ver\":\"2.2.1.180519\",\"url\":\"http://192.168.0.130/Apex Mobile.apk\"}";
+
+		return jsonStr;
+	}
+
+}

+ 849 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/util/RAUtil.java

@@ -0,0 +1,849 @@
+package com.usai.util;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Matrix;
+import android.media.ExifInterface;
+import android.media.MediaScannerConnection;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Environment;
+import android.support.v4.app.ActivityCompat;
+import android.support.v4.content.FileProvider;
+import android.support.v4.content.PermissionChecker;
+import android.util.Log;
+import android.webkit.MimeTypeMap;
+
+import com.usai.apex.ApexTrackingApplication;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.lang.reflect.Array;
+import java.nio.channels.FileChannel;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Created by ray on 27/06/2017.
+ */
+
+
+public class RAUtil {
+    public static final int MY_PERMISSIONS_REQUEST= 1;
+//    public static void checkPermissions1(Activity activity, String[] permissions)
+//    {
+//        Log.d("_RAIMAGE", "checkPermissions1:==================================== ");
+//        for(String permission : permissions) {
+//            boolean bshow=ActivityCompat.shouldShowRequestPermissionRationale(activity,permission);
+//            boolean granted= ContextCompat.checkSelfPermission(activity,
+//                    Manifest.permission.ACCESS_FINE_LOCATION)
+//                    == PackageManager.PERMISSION_GRANTED;
+//            boolean pc = PermissionChecker.checkSelfPermission(activity,permission)==PermissionChecker.PERMISSION_GRANTED;
+//            Log.d("_RAIMAGE", "checkPermissions1: "+permission+"  SHOW  "+bshow+"  granted  "+granted +","+pc);
+//        }
+//        Log.d("_RAIMAGE", "checkPermissions1:==================================== ");
+//    }
+    public static boolean isNumeric(String str){
+        for (int i = 0; i < str.length(); i++){
+            System.out.println(str.charAt(i));
+            if (!Character.isDigit(str.charAt(i))){
+                return false;
+            }
+        }
+        return true;
+    }
+    public static Boolean checkPermissions(Activity activity, String[] permissions)
+    {
+        if (Build.VERSION.SDK_INT >= 23)
+        {
+            return checkPermissions_23(activity,permissions);
+        }
+        else
+        {
+            return false;
+//            return checkPermissions_23(activity,permissions);
+        }
+    }
+
+    public static Boolean checkPermissions_23(String[] permissions)
+    {
+        Log.d("_RAIMAGE", "checkPermissions23:==================================== ");
+        ArrayList<String> request_list = new ArrayList<String>();
+        Context context = ApexTrackingApplication.getInstance().getApplicationContext();
+        for(String permission : permissions) {
+
+            boolean pc = PermissionChecker.checkSelfPermission(context,permission)== PermissionChecker.PERMISSION_GRANTED;
+            if(!pc)
+                return false;
+        }
+        Log.d("_RAIMAGE", "checkPermissions23:==================================== ");
+
+
+
+        return true;
+
+    }
+
+    public static void updateGallery(String filename)//filename是我们的文件全名,包括后缀哦
+    {
+
+        Context context = ApexTrackingApplication.getInstance().getApplicationContext();
+        MediaScannerConnection.scanFile(context,
+                new String[] { filename }, null,
+                new MediaScannerConnection.OnScanCompletedListener() {
+                    public void onScanCompleted(String path, Uri uri) {
+                        Log.i("ExternalStorage", "Scanned " + path + ":");
+                        Log.i("ExternalStorage", "-> uri=" + uri);
+                    }
+                });
+    }
+
+    public static Boolean checkPermissions_23(Activity activity, String[] permissions)
+    {
+        Log.d("_RAIMAGE", "checkPermissions23:==================================== ");
+        ArrayList<String> request_list = new ArrayList<String>();
+        for(String permission : permissions) {
+            boolean bshow= ActivityCompat.shouldShowRequestPermissionRationale(activity,permission);
+//            boolean granted= ContextCompat.checkSelfPermission(activity,
+//                    Manifest.permission.ACCESS_FINE_LOCATION)
+//                    == PackageManager.PERMISSION_GRANTED;
+            boolean pc = PermissionChecker.checkSelfPermission(activity,permission)== PermissionChecker.PERMISSION_GRANTED;
+//            Log.d("_RAIMAGE", "checkPermissions23: "+permission+"  SHOW  "+bshow+"  granted  "+granted +","+pc);
+
+            if(!pc)
+                request_list.add(permission);
+        }
+        Log.d("_RAIMAGE", "checkPermissions23:==================================== ");
+
+
+        if(request_list.isEmpty())
+            return false;
+        ActivityCompat.requestPermissions(activity,
+                request_list.toArray(new String[0]),
+                MY_PERMISSIONS_REQUEST);
+
+
+        return true;
+
+    }
+    public static Boolean checkPermissions_24(Activity activity, String[] permissions)
+    {
+
+
+
+
+//        ArrayList<String> request_list = new ArrayList<String>();
+//        for(String permission : permissions) {
+//
+//
+////            boolean bshow=ActivityCompat.shouldShowRequestPermissionRationale(activity,permission);
+////
+////
+////            AppOpsManager appOpsManager = (AppOpsManager) activity.getSystemService(Context.APP_OPS_SERVICE);
+////            String opsName = AppOpsManager.permissionToOp(permission);
+////            if (opsName == null) {
+////                return true;
+////            }
+////            int opsMode = appOpsManager.checkOpNoThrow(opsName, Process.myUid(), activity.getPackageName());
+//////            return opsMode == AppOpsManager.MODE_ALLOWED;
+//
+//
+////            if (ContextCompat.checkSelfPermission(activity,
+////                    Manifest.permission.ACCESS_FINE_LOCATION)
+////                    != PackageManager.PERMISSION_GRANTED||opsMode != AppOpsManager.MODE_ALLOWED)
+//
+//                request_list.add(permission);
+//
+//        }
+
+//        File logfile = new File(Environment.getExternalStorageDirectory()
+//                .getPath() + "/redant/pop/" + "debug" + ".log");
+//
+//        // int mode = Application.MODE_APPEND;
+//        if (!logfile.exists())
+//        {
+//            // mode = Application.MODE_PRIVATE;
+//            try
+//            {
+//                logfile.createNewFile();
+//            }
+//            catch (IOException e)
+//            {
+//                // TODO Auto-generated catch block
+//                e.printStackTrace();
+//
+//            }
+//        }
+        if(permissions.length==0)
+            return true;
+        ActivityCompat.requestPermissions(activity,
+                permissions,
+                MY_PERMISSIONS_REQUEST);
+
+
+        return true;
+
+//
+//        if (ContextCompat.checkSelfPermission(activity,
+//                Manifest.permission.ACCESS_FINE_LOCATION)
+//                != PackageManager.PERMISSION_GRANTED)
+//        {
+//
+//
+////            if (ActivityCompat.shouldShowRequestPermissionRationale(activity,
+////                    permission))
+////            {
+////                return false;
+////            }
+////            else
+//            {
+//                ActivityCompat.requestPermissions(activity,
+//                        new String[]{permission},
+//                        MY_PERMISSIONS_REQUEST);
+//                return true;
+//            }
+//        } else
+//        {
+//           return true;
+//        }
+//        if(true)
+//        return true;
+        // 调用Context的checkCallingOrSelfPermission来检查权限
+
+//        Activity activity1 = (Activity) activity;
+//        if(activity==null)
+//            return false;
+//        if (PackageManager.PERMISSION_GRANTED!= context.checkCallingOrSelfPermission(permission)) {
+//
+////            String[] tmp = permission.split("\\.");
+////            String permission_name = tmp[tmp.length - 1];
+////            permission_name = permission_name.replace("_"," ");
+////
+////
+////            new AlertDialog.Builder(context)
+////                    .setTitle("Warning")
+////                    .setMessage("RA Image need " + permission_name.toLowerCase() + " permission")
+////                    .setPositiveButton("OK", null)
+////                    .show();
+////
+////            return false;
+//
+//
+//             if (ActivityCompat.shouldShowRequestPermissionRationale(activity,
+//                    permission)) {
+//
+//                Log.d("_RAIMAGE", "checkPermission: shouldShowRequestPermissionRationale TRUE   " + permission);
+//                // Show an expanation to the user *asynchronously* -- don't block
+//                // this thread waiting for the user's response! After the user
+//                // sees the explanation, try again to request the permission.
+//
+//            } else {
+//
+//                // No explanation needed, we can request the permission.
+//
+//
+//                Log.d("_RAIMAGE", "checkPermission: shouldShowRequestPermissionRationale false   "+ permission);
+//                ActivityCompat.requestPermissions(activity,
+//                        new String[]{permission},
+//                        123);
+//
+//                // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
+//                // app-defined int constant. The callback method gets the
+//                // result of the request.
+//            }
+//
+//        }
+//        return true;
+    }
+
+    public static String lastPathComponent(String path){
+
+        int start=path.lastIndexOf("/");
+        int end=path.lastIndexOf(".");
+        if(start!=-1 && end!=-1){
+            return path.substring(start+1,end);
+        }else{
+            return null;
+        }
+
+    }
+
+    public static File routeBitmap(File sourceFile, String file_name)
+    {
+        /**
+         * 获取图片的旋转角度,有些系统把拍照的图片旋转了,有的没有旋转
+         */
+        int degree = RAUtil.readPictureDegree(sourceFile.getAbsolutePath());
+
+        BitmapFactory.Options opts=new BitmapFactory.Options();//获取缩略图显示到屏幕上
+        opts.inSampleSize=1;
+        Bitmap cbitmap= BitmapFactory.decodeFile(sourceFile.getAbsolutePath(),opts);
+
+        /**
+         * 把图片旋转为正的方向
+         */
+        Bitmap newbitmap = RAUtil.rotaingImageView(degree, cbitmap);
+
+        //sourceFile.get
+        String routedPath = "";
+        if(file_name==null) {
+            String path = sourceFile.getPath();
+
+            routedPath=path.replace(".jpg", "_routed.jpg");
+        }
+        else
+        {
+            String path = sourceFile.getParent();
+            routedPath = path+"/"+file_name;
+        }
+        File routedFile = new File(routedPath);
+        try {
+
+            FileOutputStream outputStream = new FileOutputStream(routedFile);
+            newbitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
+
+            outputStream.flush();
+            outputStream.close();
+
+            String filepath = sourceFile.getAbsolutePath();
+            sourceFile.delete();
+            RAUtil.updateGallery(filepath);
+//				scaleFile.renameTo(new File(path));
+            return routedFile;
+
+        } catch (IOException e) {
+            e.printStackTrace();
+            return null;
+        }
+
+    }
+    /**
+     * 读取图片属性:旋转的角度
+     * @param path 图片绝对路径
+     * @return degree旋转的角度
+     */
+    public static int readPictureDegree(String path) {
+        int degree  = 0;
+        try {
+            ExifInterface exifInterface = new ExifInterface(path);
+            int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
+            switch (orientation) {
+                case ExifInterface.ORIENTATION_ROTATE_90:
+                    degree = 90;
+                    break;
+                case ExifInterface.ORIENTATION_ROTATE_180:
+                    degree = 180;
+                    break;
+                case ExifInterface.ORIENTATION_ROTATE_270:
+                    degree = 270;
+                    break;
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return degree;
+    }
+    /*
+     * 旋转图片
+     * @param angle
+     * @param bitmap
+     * @return Bitmap
+     */
+    public static Bitmap rotaingImageView(int angle , Bitmap bitmap) {
+        //旋转图片 动作
+        Matrix matrix = new Matrix();;
+        matrix.postRotate(angle);
+        System.out.println("angle2=" + angle);
+        // 创建新的图片
+        Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0,
+                bitmap.getWidth(), bitmap.getHeight(), matrix, true);
+        return resizedBitmap;
+    }
+    public static JSONObject Bundle2Json(Bundle bundle)
+    {
+        JSONObject json = new JSONObject();
+        Set<String> keys = bundle.keySet();
+        for (String key : keys) {
+            try {
+                Log.d("", "Bundle2Json: key:"+key+"  val: "+wrap(bundle.get(key)));
+                 json.put(key, wrap(bundle.get(key))); //see edit below
+//                json.put(key, JSONObject.wrap(bundle.get(key)));
+            } catch(JSONException e) {
+                //Handle exception here
+            }
+        }
+        return json;
+    }
+
+    private static Object wrap(Object o) {
+        if (o == null) {
+            return JSONObject.NULL;
+        }
+        if (o instanceof JSONArray || o instanceof JSONObject) {
+            return o;
+        }
+        if (o.equals(JSONObject.NULL)) {
+            return o;
+        }
+        try {
+            if (o instanceof Bundle)
+            {
+                return Bundle2Json((Bundle) o);
+
+            }
+            if (o instanceof Collection) {
+                return new JSONArray((Collection) o);
+            } else if (o.getClass().isArray()) {
+                return toJSONArray(o);
+            }
+            if (o instanceof Map) {
+                return new JSONObject((Map) o);
+            }
+            if (o instanceof Boolean ||
+                    o instanceof Byte ||
+                    o instanceof Character ||
+                    o instanceof Double ||
+                    o instanceof Float ||
+                    o instanceof Integer ||
+                    o instanceof Long ||
+                    o instanceof Short ||
+                    o instanceof String) {
+                return o;
+            }
+            if (o.getClass().getPackage().getName().startsWith("java.")) {
+                return o.toString();
+            }
+        } catch (Exception ignored) {
+        }
+        return null;
+    }
+
+    private static JSONArray toJSONArray(Object array) throws JSONException {
+        JSONArray result = new JSONArray();
+        if (!array.getClass().isArray()) {
+            throw new JSONException("Not a primitive array: " + array.getClass());
+        }
+        final int length = Array.getLength(array);
+        for (int i = 0; i < length; ++i) {
+            result.put(wrap(Array.get(array, i)));
+        }
+        return result;
+    }
+    public static Bundle Json2Bundle(JSONObject s) {
+        Bundle bundle = new Bundle();
+
+        for (Iterator<String> it = s.keys(); it.hasNext(); ) {
+            String key = it.next();
+            try {
+                Object o = s.get(key);
+
+
+
+                if (o == null) {
+                    continue;
+                }
+                else if ( o instanceof JSONObject) {
+                    bundle.putBundle(key,Json2Bundle((JSONObject) o));
+                }
+                else if(o instanceof JSONArray)
+                {
+                    throw new JSONException("Json2Bundle does not support Json array: " + o.getClass());// bundle.putarr
+                }
+                else if (o.equals(JSONObject.NULL)) {
+                    continue;
+                }
+                else if (o instanceof Boolean)
+                {
+                    bundle.putBoolean(key,((Boolean) o).booleanValue());
+                }
+                else if(o instanceof Byte)
+                {
+                    bundle.putByte(key, ((Byte) o).byteValue());
+                }
+                else if(o instanceof Character)
+                {
+                    bundle.putChar(key, ((Character) o).charValue());
+                }
+                else if(o instanceof Double)
+                {
+                    bundle.putDouble(key, ((Double) o).doubleValue());
+                }
+                else if(o instanceof Float)
+                {
+                    bundle.putFloat(key, ((Float) o).floatValue());
+                }
+                else if(o instanceof Integer)
+                {
+                    bundle.putInt(key, ((Integer) o).intValue());
+                }
+                else if(o instanceof Long)
+                {
+                    bundle.putLong(key, ((Long) o).longValue());
+                }
+                else if(o instanceof Short)
+                {
+                    bundle.putShort(key, ((Short) o).shortValue());
+                }
+                else if(o instanceof String)
+                {
+                    bundle.putString(key, o.toString());
+                }
+
+//                ArrayList<Parcelable> a = new ArrayList<>();
+//                a.add("");
+//                a.add(1);
+//                bundle.putParcelableArrayList("arr", a);
+
+
+
+            } catch (JSONException e) {
+                e.printStackTrace();
+            }
+        }
+        return bundle;
+    }
+    public static Bundle Json2Bundle1(JSONObject s) {
+        Bundle bundle = new Bundle();
+
+        for (Iterator<String> it = s.keys(); it.hasNext(); ) {
+            String key = it.next();
+            JSONArray arr = s.optJSONArray(key);
+            Double num = s.optDouble(key);
+//            Integer i = s.optInt(key);
+            String str = s.optString(key);
+            JSONObject obj = s.optJSONObject(key);
+            if (arr != null && arr.length() <= 0)
+            {
+                bundle.putStringArray(key, new String[]{});
+            }
+
+            else if (arr != null && !Double.isNaN(arr.optDouble(0))) {
+                double[] newarr = new double[arr.length()];
+                for (int i=0; i<arr.length(); i++)
+                    newarr[i] = arr.optDouble(i);
+                bundle.putDoubleArray(key, newarr);
+            }
+
+            else if (arr != null && arr.optString(0) != null) {
+                String[] newarr = new String[arr.length()];
+                for (int i=0; i<arr.length(); i++)
+                    newarr[i] = arr.optString(i);
+                bundle.putStringArray(key, newarr);
+            }
+
+
+            else if (obj != null)
+            {
+                Bundle b=Json2Bundle(obj);
+                bundle.putBundle(key, b);
+            }
+
+            else if (!num.isNaN())
+                bundle.putDouble(key, num);
+
+            else if (str != null)
+                bundle.putString(key, str);
+
+            else
+                System.err.println("unable to transform json to bundle " + key);
+        }
+        return bundle;
+    }
+//    public static Bundle Json2Bundle(JSONObject jsonObject) throws JSONException {
+//        Bundle bundle = new Bundle();
+//        Iterator iter = jsonObject.keys();
+//        while(iter.hasNext()){
+//            String key = (String)iter.next();
+//            String value = jsonObject.getString(key);
+//            bundle.putString(key,value);
+//        }
+//        return bundle;
+//    }
+
+    public static JSONArray jsonObject2KVArray(JSONObject object, boolean trim) {
+
+        if (object == null) {
+            return null;
+        }
+
+        try {
+            JSONArray ret = new JSONArray();
+            Iterator<String> iterator = object.keys();
+
+            while (iterator.hasNext()) {
+
+                JSONObject kv = new JSONObject();
+
+                String key = iterator.next();
+                Object value = object.get(key);
+
+                kv.put("key",key);
+                if (trim) {
+                    if (value == null) {
+                        continue;
+                    }
+                    String val = value.toString();
+                    if (val.length() == 0) {
+                        continue;
+                    }
+                }
+
+                kv.put("value",value);
+                ret.put(kv);
+
+            }
+
+            return ret;
+
+        } catch (JSONException e) {
+            e.printStackTrace();
+            return null;
+        }
+
+    }
+
+    public static String getApplicationName(Context context) {
+
+        PackageManager packageManager = null;
+        ApplicationInfo applicationInfo = null;
+        try {
+            packageManager = context.getPackageManager();
+            applicationInfo = packageManager.getApplicationInfo(context.getPackageName(), 0);
+        } catch (PackageManager.NameNotFoundException e) {
+            applicationInfo = null;
+        }
+        String applicationName = (String) packageManager.getApplicationLabel(applicationInfo);
+        return applicationName;
+    }
+
+    public static String SDCardRoot() {
+        return Environment.getExternalStorageDirectory()+File.separator;
+    }
+
+    public static File createSDDir(String dir)throws IOException{
+        File dirFile=new File(SDCardRoot()+dir);
+        dirFile.mkdir();//mkdir()只能创建一层文件目录,mkdirs()可以创建多层文件目录
+        return dirFile;
+    }
+
+    //在SD卡上创建文件
+    public static File createFileInSDCard(String fileName,String dir) throws IOException {
+        File file=new File(SDCardRoot()+dir+File.separator+fileName);
+        file.createNewFile();
+        return file;
+    }
+
+    public static boolean isFileExist(String fileName,String dir){
+        File file=new File(SDCardRoot()+dir+File.separator+fileName);
+        return file.exists();
+    }
+
+    public static File createFileInDir(String fileName,String dir) throws IOException {
+        File file=new File(dir+File.separator+fileName);
+        file.createNewFile();
+        return file;
+    }
+
+    //将一个InoutStream里面的数据写入到SD卡中
+    public static File write2SDFromInput(String fileName,String dir,InputStream input){
+        File file=null;
+        OutputStream output=null;
+        try {
+//            //创建目录
+//            createSDDir(dir);
+            //创建文件
+            file=createFileInDir(fileName,dir);
+            //写数据流
+            output=new FileOutputStream(file);
+            byte buffer[]=new byte[4*1024];//每次存4K
+            int temp;
+            //写入数据
+            while((temp=input.read(buffer))!=-1){
+                output.write(buffer,0,temp);
+            }
+            output.flush();
+        } catch (Exception e) {
+            System.out.println("写数据异常:"+e);
+        }
+        finally{
+            try {
+                output.close();
+            } catch (Exception e2) {
+                System.out.println(e2);
+            }
+        }
+        return file;
+    }
+
+    public static String getMimeType(String filePath) {
+        String ext = MimeTypeMap.getFileExtensionFromUrl(filePath);
+        String mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(ext);
+        if (mime == null || mime.isEmpty()) {
+            mime = "text/plain";
+        }
+        return mime;
+    }
+
+    /**
+     * 复制单个文件
+     * @param oldPath String 原文件路径 如:c:/fqf.txt
+     * @param newPath String 复制后路径 如:f:/fqf.txt
+     * @return boolean
+     */
+    public static boolean copyFile(String oldPath, String newPath) {
+        try {
+            int bytesum = 0;
+            int byteread = 0;
+            File oldfile = new File(oldPath);
+            if (oldfile.exists()) { //文件存在时
+                InputStream inStream = new FileInputStream(oldPath); //读入原文件
+                FileOutputStream fs = new FileOutputStream(newPath);
+                byte[] buffer = new byte[4*1024];
+                int length;
+                while ( (byteread = inStream.read(buffer)) != -1) {
+                    bytesum += byteread; //字节数 文件大小
+                    System.out.println(bytesum);
+                    fs.write(buffer, 0, byteread);
+                }
+                inStream.close();
+            }
+        }
+        catch (Exception e) {
+            System.out.println("复制单个文件操作出错");
+            e.printStackTrace();
+            return false;
+
+        }
+        return true;
+
+    }
+    public static void openFile(Context context,File file) {
+
+        if (context == null || file == null || !file.exists()) {
+            return;
+        }
+
+        Uri uri = null;
+        String type = RAUtil.getMimeType(file.getPath());
+
+        // type "application/pdf"
+        Intent intent = new Intent(Intent.ACTION_VIEW);
+
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+
+            // "com.usai.apex.fileprovider"即是在Manifest文件中配置的authorities
+            uri = FileProvider.getUriForFile(context, "com.usai.apex.fileprovider", file);
+            // 给目标应用一个临时授权
+            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+        } else {
+            uri = Uri.fromFile(file);
+        }
+
+        intent.setDataAndType(uri, type);
+
+        if (context.getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY) != null) {
+            // someone knows how to handle this mime type with this scheme, don't download.
+            try {
+                context.startActivity(intent);
+                return;
+            } catch (Exception ex) {
+                Log.d("Open File", "activity not found for " + type + " over " + uri, ex);
+            }
+
+        } else {
+            Log.d("Open File", "openFileAtPath: " + "No App " + uri);
+            try {
+                shareFile(context,uri,type);
+            } catch (Exception e) {
+                Log.e("Show Dialog Error", "openFileAtPath: ", e);
+            }
+        }
+
+    }
+
+    public static void shareFile(Context context,Uri uri, String type) {
+
+        Intent shareIntent = new Intent();
+        shareIntent.setAction(Intent.ACTION_SEND);
+        shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
+        shareIntent.setType(type);
+        context.startActivity(Intent.createChooser(shareIntent, "Share"));
+    }
+
+    public static void writeJson(String json, String filePath) {
+
+        Writer writer = null;
+        try {
+
+            OutputStream out = new FileOutputStream(new File(filePath));
+            writer = new OutputStreamWriter(out);
+            writer.write(json);
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            if (writer != null) {
+                try {
+                    writer.close();
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+
+    }
+
+    public static String readJson(String filePath) {
+        BufferedReader reader = null;
+        StringBuilder jsonString = null;
+        try {
+            InputStream in = new FileInputStream(new File(filePath));
+            reader = new BufferedReader(new InputStreamReader(in));
+            jsonString = new StringBuilder();
+            String line = null;
+            while ((line = reader.readLine()) != null) {
+                jsonString.append(line);
+            }
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            if (reader != null) {
+                try {
+                    reader.close();
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        if (jsonString != null) {
+            return jsonString.toString();
+        } else {
+            return null;
+        }
+    }
+
+}

+ 96 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/util/SqlOpenHelper.java

@@ -0,0 +1,96 @@
+package com.usai.util;
+
+//import android.R.array;
+import java.util.ArrayList;
+
+import android.content.Context;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteDatabase.CursorFactory;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.util.Log;
+
+public class SqlOpenHelper extends SQLiteOpenHelper
+{
+
+	private ArrayList<String>	initSQL	= new ArrayList<String>();
+
+	public void addInitSQL(String sql)
+	{
+		initSQL.add(sql);
+
+	}
+
+	public int get_RecordCount(String tablename)
+	{
+		return 0;
+
+	}
+
+	public SQLiteDatabase OpenDB(boolean writable)
+	{
+		if (writable)
+			return getWritableDatabase();
+		else
+			return getReadableDatabase();
+	}
+
+	private void initDB(SQLiteDatabase db)
+	{
+		for (int i = 0; i < initSQL.size(); i++)
+		{
+			db.execSQL(initSQL.get(i));
+		}
+
+	}
+
+	public SqlOpenHelper(Context context, String name, CursorFactory factory,
+			int version)
+	{
+		super(context, name, factory, version);
+		// TODO Auto-generated constructor stub
+	}
+
+	@Override
+	public void onCreate(SQLiteDatabase db)
+	{
+		// TODO Auto-generated method stub
+		initDB(db);
+
+	}
+
+	@Override
+	public void onOpen(SQLiteDatabase db)
+	{
+		// TODO Auto-generated method stub
+		super.onOpen(db);
+	}
+
+	@Override
+	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
+	{
+		Log.d("DB upgrade", "from " + oldVersion + " to " + newVersion);
+
+		if (newVersion == 2)
+		{
+			db.execSQL("CREATE TABLE push_message ("
+					+ "_id INTEGER PRIMARY KEY," + "s_id VARCHAR(20),"
+					+ "e_id VARCHAR(20)," + "msgcount INTEGER,"
+					+ "message VARCHAR(20)," + "h_time timestamp,"
+					+ "create_time timestamp," + "user VARCHAR(20),"
+					+ "read BOOLEAN)");
+			db.execSQL("CREATE TABLE favorites (" + "_id INTEGER PRIMARY KEY,"
+					+ "name VARCHAR(20)," + "params VARCHAR(20),"
+					+ "action VARCHAR(20)," + "module_name VARCHAR(20),"
+					+ "detail_id VARCHAR(20)," + "action_type VARCHAR(20),"
+					+ "create_time timestamp," + "user VARCHAR(20))");
+			db.execSQL("CREATE TABLE history (" + "_id INTEGER PRIMARY KEY,"
+					+ "name VARCHAR(20)," + "params VARCHAR(20),"
+					+ "action VARCHAR(20)," + "module_name VARCHAR(20),"
+					+ "criterion VARCHAR(20)," + "create_time timestamp,"
+					+ "user VARCHAR(20))");
+			db.execSQL("ALTER TABLE search_history ADD level INTEGER");
+		}
+
+	}
+
+}

+ 211 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/util/commonUtil.java

@@ -0,0 +1,211 @@
+package com.usai.util;
+
+import java.io.File;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.UUID;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import com.usai.apex.ApexTrackingApplication;
+import com.usai.apex.R;
+
+import android.Manifest;
+import android.app.Activity;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.graphics.drawable.Drawable;
+import android.os.Build;
+import android.os.Environment;
+import android.support.v4.app.ActivityCompat;
+import android.support.v4.content.PermissionChecker;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+import android.util.Log;
+
+
+public class commonUtil {
+    public static final int MY_PERMISSIONS_REQUEST = 1;
+    private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);
+
+
+
+
+    public static int dp2px(Context context, float dipValue)
+
+    {
+
+        float m=context.getResources().getDisplayMetrics().density ;
+
+        return (int)(dipValue * m + 0.5f) ;
+
+    }
+
+    public static int sp2px(Context context, float spValue) {
+        float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
+        return (int) (spValue * fontScale + 0.5f);
+    }
+
+    public static int px2dp(Context context, float pxValue)
+
+    {
+
+        float m=context.getResources().getDisplayMetrics().density ;
+
+        return (int)(pxValue / m + 0.5f) ;
+
+    }
+
+
+    public static Boolean checkPermissions(Activity activity, String[] permissions) {
+        if (Build.VERSION.SDK_INT >= 23) {
+            return checkPermissions_23(activity, permissions);
+        } else {
+            return false;
+//            return checkPermissions_23(activity,permissions);
+        }
+    }
+
+    public static Boolean checkPermissions_23(Activity activity, String[] permissions) {
+        Log.d("_APEXMOBILE", "checkPermissions23:==================================== ");
+        ArrayList<String> request_list = new ArrayList<String>();
+        for (String permission : permissions) {
+            boolean bshow = ActivityCompat.shouldShowRequestPermissionRationale(activity, permission);
+//            boolean granted= ContextCompat.checkSelfPermission(activity,
+//                    Manifest.permission.ACCESS_FINE_LOCATION)
+//                    == PackageManager.PERMISSION_GRANTED;
+            boolean pc = PermissionChecker.checkSelfPermission(activity, permission) == PermissionChecker.PERMISSION_GRANTED;
+//            Log.d("_RAIMAGE", "checkPermissions23: "+permission+"  SHOW  "+bshow+"  granted  "+granted +","+pc);
+
+            if (!pc)
+                request_list.add(permission);
+        }
+        Log.d("_APEXMOBILE", "checkPermissions23:==================================== ");
+
+
+        if (request_list.isEmpty())
+            return false;
+        ActivityCompat.requestPermissions(activity,
+                request_list.toArray(new String[0]),
+                MY_PERMISSIONS_REQUEST);
+
+
+        return true;
+
+    }
+//	public static Boolean checkPermissions_24(Activity activity, String[] permissions)
+//	{
+//
+//
+//		if(permissions.length==0)
+//			return true;
+//		ActivityCompat.requestPermissions(activity,
+//				permissions,
+//				MY_PERMISSIONS_REQUEST);
+//
+//
+//		return true;
+//
+//
+//	}
+//
+//	public static Boolean checkPermissions_23(String[] permissions)
+//	{
+//		Log.d("_RAIMAGE", "checkPermissions23:==================================== ");
+//		ArrayList<String> request_list = new ArrayList<String>();
+//		Context context = ApexTrackingApplication.getInstance().getApplicationContext();
+//		for(String permission : permissions) {
+//
+//			boolean pc = PermissionChecker.checkSelfPermission(context,permission)==PermissionChecker.PERMISSION_GRANTED;
+//			if(!pc)
+//				return false;
+//		}
+//		Log.d("_RAIMAGE", "checkPermissions23:==================================== ");
+//
+//
+//
+//		return true;
+//
+//	}
+
+    public static int iconName2Rid(Context context,String name) {
+
+        if (context == null) {
+            context = ApexTrackingApplication.get_instance();
+        }
+
+        if (context == null || TextUtils.isEmpty(name)) {
+            Log.d("null icon", "iconName2Rid context: "+(context==null)+" name isnull: "+(name == null) );
+
+            return R.drawable.ic_launcher_new;
+        }
+        if(name.equals("Ocean Booking")|| name.equals("Booking Detail"))
+            name = "mode_booking";
+        if(name.equals("Ocean B/L info.")||name.equals("B/L info. Detail"))
+            name = "mode_bl";
+        if(name.equals("Container detail")||name.equals("Container Detail"))
+            name = "mode_container";
+        if(name.equals("Download Document"))
+            name = "mode_document";
+        if(name.equals("Cargo Tracking"))
+            name = "mode_cargo_tracking";
+
+        int iconid = context.getResources().getIdentifier(name, "drawable", context.getPackageName());
+
+        return iconid;
+    }
+
+    public static boolean localdirExist() {
+
+        File folder = new File(Environment.getExternalStorageDirectory().getPath() + "/Apex Mobile");
+        return (folder.exists() && folder.isDirectory()) ? true : folder.mkdirs();
+    }
+
+    /**
+     * Generate a value suitable for use in {@link #setId(int)}.
+     * This value will not collide with ID values generated at build time by aapt for R.id.
+     *
+     * @return a generated ID value
+     */
+    public static int generateViewId() {
+        for (; ; ) {
+            final int result = sNextGeneratedId.get();
+            // aapt-generated IDs have the high byte nonzero; clamp to the range under that.
+            int newValue = result + 1;
+            if (newValue > 0x00FFFFFF) newValue = 1; // Roll over to 1, not 0.
+            if (sNextGeneratedId.compareAndSet(result, newValue)) {
+                return result;
+            }
+        }
+    }
+
+    public static String getDUID() {
+        final TelephonyManager tm = (TelephonyManager) ApexTrackingApplication.get_instance().getBaseContext().getSystemService(Context.TELEPHONY_SERVICE);
+        final String tmDevice, tmSerial, androidId;
+        String uniqueId;
+        try {
+            if (ActivityCompat.checkSelfPermission(ApexTrackingApplication.get_instance(), Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
+                // TODO: Consider calling
+                //    ActivityCompat#requestPermissions
+                // here to request the missing permissions, and then overriding
+                //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
+                //                                          int[] grantResults)
+                // to handle the case where the user grants the permission. See the documentation
+                // for ActivityCompat#requestPermissions for more details.
+                return null;
+            }
+            tmDevice = "" + tm.getDeviceId();
+            tmSerial = "" + tm.getSimSerialNumber();
+            androidId = "" + android.provider.Settings.Secure.getString(ApexTrackingApplication.get_instance().getContentResolver(),android.provider.Settings.Secure.ANDROID_ID);
+            UUID deviceUuid = new UUID(androidId.hashCode(), ((long)tmDevice.hashCode() << 32) | tmSerial.hashCode());
+            uniqueId = deviceUuid.toString();
+            Log.d("debug","uuid="+uniqueId);
+
+        }
+        catch(Exception e)
+        {
+            uniqueId= null;
+        }
+        return uniqueId;
+
+		 }
+}

+ 384 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/util/dbUtil.java

@@ -0,0 +1,384 @@
+package com.usai.util;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteDatabase.CursorFactory;
+import android.database.sqlite.SQLiteException;
+import android.net.Uri;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.usai.apex.ApexTrackingApplication;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class dbUtil
+{
+
+	private static final String[]	FIELD_ID	= { "_id" };
+
+	public static boolean isContentExist(Context context, Uri uri, String where)
+	{
+		boolean ret;
+		Cursor cursor = context.getContentResolver().query(uri, null, where,
+				null, null);
+		dbgUtil.dbgCursorInfo(cursor, context);
+		if (cursor.moveToNext())
+			ret = true;
+		else
+			ret = false;
+
+		dbUtil.CloseCursor(cursor);
+		return ret;
+	}
+
+	public static void CloseDB(SQLiteDatabase db)
+	{
+		if (db == null)
+			return;
+		if (db.isOpen() == false)
+			return;
+		db.close();
+		return;
+
+	}
+
+	public static void CloseCursor(Cursor c)
+	{
+		if (c == null)
+			return;
+		if (c.isClosed())
+			return;
+		c.close();
+		return;
+
+	}
+
+	public static SQLiteDatabase OpenDB(Context context, CursorFactory factory,
+			boolean writable)
+	{
+
+		SqlOpenHelper dbHelper = new SqlOpenHelper(context, "apex.db", factory,
+				2);
+		dbHelper.addInitSQL("create table users (" + "_id INTEGER PRIMARY KEY,"
+				+ "name varchar(20)," + "pass varchar(20))");
+
+		// dbHelper.addInitSQL("create table scan_records ("
+		// + "_id INTEGER PRIMARY KEY," + "submit BOOLEAN DEFAULT (0),"
+		// + "picker VARCHAR(20)," + "pid varchar(20))");
+
+		/*
+		 * 
+		 * name : field name aname: alias name for display field_type:
+		 * int,bool,varchar... function_name: Ocean Booking , Ocean B/L Info.,
+		 * ... behavior: search / result priority: display order show: whether
+		 * show this field abandon: true/false , uses for update auth_info user:
+		 * record owner
+		 */
+		dbHelper.addInitSQL("CREATE TABLE fields_info ("
+				+ "_id INTEGER PRIMARY KEY," + "name VARCHAR(20),"
+				+ "aname VARCHAR(20)," + "field_type INTEGER,"
+				+ "function_name VARCHAR(20)," + "behavior INTEGER,"
+				+ "priority INTEGER," + "show BOOLEAN," + "abandon BOOLEAN,"
+				+ "user VARCHAR(20))");
+
+		dbHelper.addInitSQL("CREATE TABLE actions_info ("
+				+ "_id INTEGER PRIMARY KEY," + "name VARCHAR(20),"
+				+ "function_name VARCHAR(20)," + "priority INTEGER,"
+				+ "abandon BOOLEAN," + "user VARCHAR(20))");
+
+		dbHelper.addInitSQL("CREATE TABLE search_history ("
+				+ "_id INTEGER PRIMARY KEY," + "h_val VARCHAR(20),"
+				+ "h_field VARCHAR(20)," + "level INTEGER,"
+				+ "h_time TIMESTAMP default (datetime('now', 'localtime')),"
+				+ "user VARCHAR(20))");
+
+		// new table must create in onupgrade function too;
+
+		dbHelper.addInitSQL("CREATE TABLE push_message ("
+				+ "_id INTEGER PRIMARY KEY," + "s_id VARCHAR(20),"
+				+ "e_id VARCHAR(20)," + "msgcount INTEGER,"
+				+ "message VARCHAR(20)," + "h_time timestamp,"
+				+ "create_time timestamp," + "user VARCHAR(20),"
+				+ "read BOOLEAN)");
+
+		dbHelper.addInitSQL("CREATE TABLE favorites ("
+				+ "_id INTEGER PRIMARY KEY," + "name VARCHAR(20),"
+				+ "params VARCHAR(20)," + "action VARCHAR(20),"
+				+ "module_name VARCHAR(20)," + "detail_id VARCHAR(20),"
+				+ "action_type VARCHAR(20)," + "create_time timestamp,"
+				+ "user VARCHAR(20))");
+		dbHelper.addInitSQL("CREATE TABLE history ("
+				+ "_id INTEGER PRIMARY KEY," + "name VARCHAR(20),"
+				+ "params VARCHAR(20)," + "action VARCHAR(20),"
+				+ "module_name VARCHAR(20)," + "criterion VARCHAR(20),"
+				+ "create_time timestamp," + "user VARCHAR(20))");
+		// dbHelper.addInitSQL("create table pics (" +
+		// "_id INTEGER PRIMARY KEY,"
+		// + "picker varchar(20)," + "err_code INTEGER ,"
+		// + "pid varchar(20)," + "local_path varchar(256))");
+
+		SQLiteDatabase db = dbHelper.OpenDB(writable);
+		return db;
+	}
+
+	public static void removeRecords(SQLiteDatabase db, String table,
+			String whereclause)
+	{
+		db.execSQL("delete from " + table + " where " + whereclause);
+	}
+
+	public static long addRecordsFromCursor(SQLiteDatabase db,
+			String tablename, Cursor source, String[] from, String[] to,
+			boolean dumpPrimaryKey, boolean dumpOneRecord)
+	{
+		int ret = -1;
+		ContentValues cv = new ContentValues();
+
+		if (from == null)
+			from = source.getColumnNames();
+
+		if (to == null)
+			to = source.getColumnNames();
+
+		if (from.length != to.length)
+			return ret;
+
+		while (source.moveToNext())
+		{
+
+			for (int i = 0; i < from.length; i++)
+			{
+				if (from[i].equals("_id"))
+				{
+					if (dumpPrimaryKey)
+						cv.put(to[i], source.getInt(i));
+				}
+				else
+				{
+					cv.put(to[i], source.getString(i));
+				}
+
+			}
+			db.insert(tablename, null, cv);
+
+			if (dumpOneRecord)
+				break;
+		}
+
+		ret = 1;
+		return ret;
+
+	}
+
+	// public static long addRecord(SQLiteDatabase db, String table,
+	// ContentValues record)
+	// {
+	// long ret = -1;
+	// try
+	// {
+	// ret = db.insert(table, null, record);
+	// }
+	// catch (SQLiteException e)
+	// {
+	// dbgUtil.Log(Log.ERROR,"sql_err", e.toString());
+	//
+	// }
+	// return ret;
+	// }
+
+	public static boolean isTableEmpty(SQLiteDatabase db, String table)
+	{
+		boolean ret = true;
+
+		Cursor cursor = null;
+		try
+		{
+
+			cursor = db.query(table, FIELD_ID, null, null, null, null, null,
+					"1");
+			if (cursor.moveToNext())
+			{
+				// cursor.close();
+				ret = false;
+			}
+			else
+				ret = true;
+		}
+		catch (SQLiteException e)
+		{
+			Log.e("sql_err", e.toString());
+		}
+		finally
+		{
+			dbUtil.CloseCursor(cursor);
+		}
+		return ret;
+	}
+
+	public static boolean isRecordExist(SQLiteDatabase db, String table,
+			String where)
+	{
+		boolean ret = false;
+		Cursor cursor = null;
+		try
+		{
+
+			cursor = db.query(table, FIELD_ID, where, null, null, null, null,
+					null);
+			if (cursor.moveToNext())
+				ret = true;
+			else
+				ret = false;
+		}
+		catch (SQLiteException e)
+		{
+			Log.e("sql_err", e.toString());
+
+		}
+		finally
+		{
+
+			dbUtil.CloseCursor(cursor);
+		}
+		return ret;
+
+	}
+
+	public static String get_fields(String user, String module)
+	{
+		SQLiteDatabase db = OpenDB(ApexTrackingApplication.get_instance()
+				.getApplicationContext(), null, false);
+		Cursor cursor = db.query("fields_info", new String[] { "name" },
+				"function_name='" + module + "' and user='" + user
+						+ "' and behavior=" + Network.BEHAVIOR_RESULT + " and show=1", null,
+				null, null, "priority , aname", null);
+		String ret = "";
+		while (cursor.moveToNext())
+		{
+			ret += cursor.getString(0);
+			ret += ",";
+
+		}
+		ret = ret.substring(0, ret.length() - 1);
+		CloseCursor(cursor);
+		CloseDB(db);
+		return ret;
+	}
+
+	public static void cleanhistory()
+	{
+		SQLiteDatabase db = OpenDB(ApexTrackingApplication.get_instance()
+				.getApplicationContext(), null, true);
+		db.execSQL("delete from search_history where julianday('now', 'localtime')-julianday(h_time, 'localtime')>30");
+		CloseDB(db);
+	}
+
+	public static void savehistory(String field, String value)
+	{
+		if (TextUtils.isEmpty(value))
+			return;
+
+		SQLiteDatabase db = OpenDB(ApexTrackingApplication.get_instance()
+				.getApplicationContext(), null, true);
+		int _id = get_recordid(db, "search_history", "user = '"
+				+ ApexTrackingApplication.get_user() + "' and h_field='"
+				+ field + "' and h_val='" + value + "'");
+
+		if (_id >= 0)
+		{
+			String sql = "update search_history set h_time = datetime('now', 'localtime') where _id = "
+					+ _id;
+			db.execSQL(sql);
+		}
+		else
+		{
+			String sql = "insert into search_history(user,h_field,h_val) values('"
+					+ ApexTrackingApplication.get_user()
+					+ "','"
+					+ field
+					+ "','" + value + "')";
+			db.execSQL(sql);
+		}
+
+		CloseDB(db);
+		// return ret;
+	}
+
+	public static List<String> get_searchhistory(String field)
+	{
+		List<String> ret = new ArrayList<String>();
+		SQLiteDatabase db = OpenDB(ApexTrackingApplication.get_instance()
+				.getApplicationContext(), null, false);
+		Cursor cursor = db.query(
+				"search_history",
+				new String[] { "h_val" },
+				"h_field='" + field + "' and user='"
+						+ ApexTrackingApplication.get_user() + "'", null, null,
+				null, "h_time desc", null);
+
+		while (cursor.moveToNext())
+		{
+			ret.add(cursor.getString(0));
+
+		}
+
+		CloseCursor(cursor);
+		CloseDB(db);
+		return ret;
+	}
+
+	public static int get_count(SQLiteDatabase db, String table, String where)
+	{
+		int ret = 0;
+		Cursor cursor = db.query(table, new String[] { "count(*)" }, where,
+				null, null, null, null, null);
+		if (cursor.moveToNext())
+		{
+			ret = cursor.getInt(0);
+		}
+
+		dbUtil.CloseCursor(cursor);
+		return ret;
+	}
+
+	public static int get_recordid(SQLiteDatabase db, String table, String where)
+	{
+		return get_recordid(db, table, where, null);
+	}
+
+	public static int get_recordid(SQLiteDatabase db, String table,
+			String where, String Orderby)
+	{
+		int ret = -1;
+		Cursor cursor = null;
+		try
+		{
+
+			cursor = db.query(table, FIELD_ID, where, null, null, null,
+					Orderby, null);
+			if (cursor.moveToNext())
+				ret = cursor.getInt(0);
+			else
+				ret = -1;
+		}
+		catch (SQLiteException e)
+		{
+			Log.e("sql_err", e.toString());
+
+		}
+		finally
+		{
+
+			dbUtil.CloseCursor(cursor);
+		}
+		return ret;
+
+	}
+
+	// if(isTableEmpty(db,"block_records"))
+
+}

+ 119 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/util/dbgUtil.java

@@ -0,0 +1,119 @@
+package com.usai.util;
+
+import android.content.Context;
+import android.database.Cursor;
+import android.util.Log;
+
+public class dbgUtil
+{
+//	static boolean ENABLE_DEBUG = true;
+//	static boolean ENABLE_SQL_DEBUG = true;
+//	final int DEBUG_LEVEL_NONE = 8;
+//	static int DEBUG_LEVEL = Log.VERBOSE;
+
+	// private static boolean m_dbgFlag = true;
+	/*
+	 * public dbgUtil(Context context) {
+	 * 
+	 * m_dbgFlag = Boolean.parseBoolean(context.getString(R.string.flag_debug));
+	 * 
+	 * }
+	 * 
+	 * public dbgUtil(Context context) { m_dbgFlag =
+	 * Boolean.parseBoolean(context.getString(R.string.flag_debug)); return
+	 * this; }
+	 */
+	public static void Logd(String tag,String msg)
+	{
+		String pos = getTracePos();
+		Log.d(tag,msg+pos);
+	}
+//	public static void Log(int type, String tag, String msg)
+//	{
+////		if (ENABLE_DEBUG == false)
+////			return;
+////		if (type < DEBUG_LEVEL)
+////			return;
+//		String pos= getTracePos();
+//		switch (type)
+//		{
+//			case Log.ASSERT:
+//				Log.wtf(tag, msg+pos);
+//				break;
+//			case Log.DEBUG:
+//				Log.d(tag, msg+pos);
+//				break;
+//			case Log.ERROR:
+//				Log.e(tag, msg+pos);
+//				break;
+//			case Log.INFO:
+//				Log.i(tag, msg+pos);
+//				break;
+//			case Log.VERBOSE:
+//				Log.v(tag, msg+pos);
+//				break;
+//			case Log.WARN:
+//				Log.w(tag, msg+pos);
+//				break;
+//			default:
+//				Log.wtf("dbgUtil", "LOG TYPE ERROR!"+pos);
+//				break;
+//		}
+//
+//	}
+
+	private static String getTracePos()
+	{
+		// StackTraceElement[] elements =
+		// Thread.currentThread().getStackTrace();
+		StackTraceElement element = Thread.currentThread().getStackTrace()[4];
+		
+		return " at " + element.getClassName() + "." + element.getMethodName()
+				+ "("+element.getFileName()+":" + element.getLineNumber()+")" ;
+	}
+
+	public static void dbgCursorInfo(Cursor cursor, Context context/*
+																	 * , String
+																	 * TracePos
+																	 */)
+	{
+//		if (ENABLE_SQL_DEBUG == false)
+//			return;
+
+		// ----------------------debug cursor-----------------------------------
+		Log.d("sql_dbg@dbgCursorInfo", getTracePos() + "Cursor size:	" + cursor.getCount()
+				+ ";	columns count:	" + cursor.getColumnCount() + ";");
+//		dbgUtil.Log(Log.DEBUG,"sql_dbg", getTracePos() + "Cursor size:	" + cursor.getCount()
+//				+ ";	columns count:	" + cursor.getColumnCount() + ";");
+		for (int i = 0; i < cursor.getColumnCount(); i++)
+		{
+			Log.d("sql_dbg@dbgCursorInfo","column idx:	" + i + ";		column name:	"
+					+ cursor.getColumnName(i) + ";");
+//			dbgUtil.Log(Log.DEBUG,"sql_dbg",
+//					"column idx:	" + i + ";		column name:	"
+//							+ cursor.getColumnName(i) + ";");
+		}
+		// ----------------------debug cursor-----------------------------------
+
+	}
+	// public static void dbgCursorMoreInfo(Cursor cursor /*, String TracePos*/)
+	// {
+	// if(Boolean.parseBoolean(context.getString(R.string.flag_debug))==false)
+	// return;
+	//
+	//
+	// //----------------------debug cursor-----------------------------------
+	// dbgUtil.Log(Log.DEBUG,"sql_dbg",Log.getStackTraceString(new Throwable())
+	// +"Cursor size:	"+cursor.getCount()
+	// +";	columns count:	"+cursor.getColumnCount()
+	// +";");
+	// for (int i =0;i<cursor.getColumnCount();i++)
+	// {
+	// dbgUtil.Log(Log.DEBUG,"sql_dbg","column idx:	"+i
+	// +";		column name:	"+cursor.getColumnName(i)
+	// +";");
+	// }
+	// //----------------------debug cursor-----------------------------------
+	//
+	// }
+}

+ 8 - 0
ApexDrivers/apexmobile/src/main/java/com/usai/util/package-info.java

@@ -0,0 +1,8 @@
+/**
+ * 
+ */
+/**
+ * @author Ray
+ *
+ */
+package com.usai.util;

Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff