Bladeren bron

no message

master
呆鵝 5 jaren geleden
commit
cada616d1d
100 gewijzigde bestanden met toevoegingen van 2671 en 0 verwijderingen
  1. +14
    -0
      .gitignore
  2. +116
    -0
      .idea/codeStyles/Project.xml
  3. +21
    -0
      .idea/gradle.xml
  4. +25
    -0
      .idea/jarRepositories.xml
  5. +9
    -0
      .idea/misc.xml
  6. +12
    -0
      .idea/runConfigurations.xml
  7. +1
    -0
      app/.gitignore
  8. +48
    -0
      app/build.gradle
  9. BIN
      app/libs/gasdk.aar
  10. +21
    -0
      app/proguard-rules.pro
  11. +1
    -0
      app/release/output.json
  12. +38
    -0
      app/src/androidTest/java/tw/com/altob/goodpk/ExampleInstrumentedTest.java
  13. +71
    -0
      app/src/main/AndroidManifest.xml
  14. +24
    -0
      app/src/main/java/tw/com/altob/goodpk/Activity/CarLockActivity.java
  15. +25
    -0
      app/src/main/java/tw/com/altob/goodpk/Activity/CarSecurityActivity.java
  16. +25
    -0
      app/src/main/java/tw/com/altob/goodpk/Activity/HelpActivity.java
  17. +24
    -0
      app/src/main/java/tw/com/altob/goodpk/Activity/HomeActivity.java
  18. +25
    -0
      app/src/main/java/tw/com/altob/goodpk/Activity/InquireCarActivity.java
  19. +49
    -0
      app/src/main/java/tw/com/altob/goodpk/Activity/MainActivity.java
  20. +24
    -0
      app/src/main/java/tw/com/altob/goodpk/Activity/PWActivity.java
  21. +25
    -0
      app/src/main/java/tw/com/altob/goodpk/Activity/PaymentActivity.java
  22. +37
    -0
      app/src/main/java/tw/com/altob/goodpk/Api/BaseApi.java
  23. +46
    -0
      app/src/main/java/tw/com/altob/goodpk/Api/GoodPkApi.java
  24. +26
    -0
      app/src/main/java/tw/com/altob/goodpk/Bean/CS.java
  25. +68
    -0
      app/src/main/java/tw/com/altob/goodpk/Bean/CW.java
  26. +204
    -0
      app/src/main/java/tw/com/altob/goodpk/Fragment/CarLockFragment.java
  27. +146
    -0
      app/src/main/java/tw/com/altob/goodpk/Fragment/CarSecurityFragment.java
  28. +89
    -0
      app/src/main/java/tw/com/altob/goodpk/Fragment/HelpFragment.java
  29. +196
    -0
      app/src/main/java/tw/com/altob/goodpk/Fragment/HomeFragment.java
  30. +171
    -0
      app/src/main/java/tw/com/altob/goodpk/Fragment/InquireCarFragment.java
  31. +17
    -0
      app/src/main/java/tw/com/altob/goodpk/Fragment/MainFragment.java
  32. +124
    -0
      app/src/main/java/tw/com/altob/goodpk/Fragment/PWFragment.java
  33. +39
    -0
      app/src/main/java/tw/com/altob/goodpk/Fragment/PaymentFragment.java
  34. +43
    -0
      app/src/main/java/tw/com/altob/goodpk/Loader/ApiLoaderCallback.java
  35. +40
    -0
      app/src/main/java/tw/com/altob/goodpk/Loader/ChengePWLoader.java
  36. +50
    -0
      app/src/main/java/tw/com/altob/goodpk/Loader/GetCarSecurityLoader.java
  37. +44
    -0
      app/src/main/java/tw/com/altob/goodpk/Loader/GetCarWhereLoader.java
  38. +18
    -0
      app/src/main/java/tw/com/altob/goodpk/Parser/BaseApiParser.java
  39. +11
    -0
      app/src/main/java/tw/com/altob/goodpk/Parser/BaseParser.java
  40. +11
    -0
      app/src/main/java/tw/com/altob/goodpk/Parser/CarSecurityParser.java
  41. +11
    -0
      app/src/main/java/tw/com/altob/goodpk/Parser/CarWhereParser.java
  42. +46
    -0
      app/src/main/java/tw/com/altob/goodpk/Parser/DataParser.java
  43. +103
    -0
      app/src/main/java/tw/com/altob/goodpk/Util/CommonIntent.java
  44. +149
    -0
      app/src/main/java/tw/com/altob/goodpk/Util/CryptionUtil.java
  45. +12
    -0
      app/src/main/java/tw/com/altob/goodpk/Util/ExtraKey.java
  46. +6
    -0
      app/src/main/java/tw/com/altob/goodpk/Util/PermissionCode.java
  47. +53
    -0
      app/src/main/java/tw/com/altob/goodpk/Util/PermissionUtil.java
  48. +113
    -0
      app/src/main/java/tw/com/altob/goodpk/Util/PrefsUtil.java
  49. +194
    -0
      app/src/main/java/tw/com/altob/goodpk/Util/ScreenShot.java
  50. +6
    -0
      app/src/main/res/anim/right_in.xml
  51. BIN
      app/src/main/res/drawable-hdpi/bg_home.jpg
  52. BIN
      app/src/main/res/drawable-hdpi/bg_landingpage.jpg
  53. BIN
      app/src/main/res/drawable-hdpi/bg_page.jpg
  54. BIN
      app/src/main/res/drawable-hdpi/bg_password_02.png
  55. BIN
      app/src/main/res/drawable-hdpi/btn_aboutus.png
  56. BIN
      app/src/main/res/drawable-hdpi/btn_area.png
  57. BIN
      app/src/main/res/drawable-hdpi/btn_bg_voice.png
  58. BIN
      app/src/main/res/drawable-hdpi/btn_bg_voice_down.png
  59. BIN
      app/src/main/res/drawable-hdpi/btn_main_icon_01.png
  60. BIN
      app/src/main/res/drawable-hdpi/btn_main_icon_02.png
  61. BIN
      app/src/main/res/drawable-hdpi/btn_main_icon_03.png
  62. BIN
      app/src/main/res/drawable-hdpi/btn_main_icon_04.png
  63. BIN
      app/src/main/res/drawable-hdpi/btn_main_icon_05.png
  64. BIN
      app/src/main/res/drawable-hdpi/btn_main_icon_06.png
  65. BIN
      app/src/main/res/drawable-hdpi/btn_main_icon_07.png
  66. BIN
      app/src/main/res/drawable-hdpi/btn_site.png
  67. BIN
      app/src/main/res/drawable-hdpi/custom.png
  68. BIN
      app/src/main/res/drawable-hdpi/ic_dialog_close_dark.png
  69. BIN
      app/src/main/res/drawable-hdpi/ic_dialog_close_light.png
  70. BIN
      app/src/main/res/drawable-hdpi/icon_btn_back.png
  71. BIN
      app/src/main/res/drawable-hdpi/icon_btn_close.png
  72. BIN
      app/src/main/res/drawable-hdpi/icon_btn_home.png
  73. BIN
      app/src/main/res/drawable-hdpi/icon_btn_lock.png
  74. BIN
      app/src/main/res/drawable-hdpi/icon_btn_menu.png
  75. BIN
      app/src/main/res/drawable-hdpi/icon_btn_nav.png
  76. BIN
      app/src/main/res/drawable-hdpi/icon_btn_phone.png
  77. BIN
      app/src/main/res/drawable-hdpi/icon_btn_right.png
  78. BIN
      app/src/main/res/drawable-hdpi/icon_btn_unlock.png
  79. BIN
      app/src/main/res/drawable-hdpi/icon_home_location.png
  80. BIN
      app/src/main/res/drawable-hdpi/icon_home_nav_friendly.png
  81. BIN
      app/src/main/res/drawable-hdpi/icon_home_nav_guide.png
  82. BIN
      app/src/main/res/drawable-hdpi/icon_home_nav_info.png
  83. BIN
      app/src/main/res/drawable-hdpi/icon_home_nav_map.png
  84. BIN
      app/src/main/res/drawable-hdpi/icon_home_nav_member.png
  85. BIN
      app/src/main/res/drawable-hdpi/icon_home_nav_metro.png
  86. BIN
      app/src/main/res/drawable-hdpi/icon_home_nav_opa.png
  87. BIN
      app/src/main/res/drawable-hdpi/icon_home_nav_payment.png
  88. BIN
      app/src/main/res/drawable-hdpi/icon_home_nav_search.png
  89. BIN
      app/src/main/res/drawable-hdpi/icon_home_nav_sos.png
  90. BIN
      app/src/main/res/drawable-hdpi/icon_home_nav_user.png
  91. BIN
      app/src/main/res/drawable-hdpi/icon_info_map.png
  92. BIN
      app/src/main/res/drawable-hdpi/icon_input_keyboard.png
  93. BIN
      app/src/main/res/drawable-hdpi/icon_input_list.png
  94. BIN
      app/src/main/res/drawable-hdpi/icon_input_pen.png
  95. BIN
      app/src/main/res/drawable-hdpi/icon_input_target.png
  96. BIN
      app/src/main/res/drawable-hdpi/icon_location_title.png
  97. BIN
      app/src/main/res/drawable-hdpi/page_help_sos.png
  98. BIN
      app/src/main/res/drawable-hdpi/page_info_board_bg.9.png
  99. BIN
      app/src/main/res/drawable-hdpi/page_info_board_bg2.9.png
  100. BIN
      app/src/main/res/drawable-hdpi/page_security_off.png

+ 14
- 0
.gitignore Bestand weergeven

@@ -0,0 +1,14 @@
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild
.cxx

+ 116
- 0
.idea/codeStyles/Project.xml Bestand weergeven

@@ -0,0 +1,116 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<codeStyleSettings language="XML">
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
</indentOptions>
<arrangement>
<rules>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:android</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:id</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>style</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>ANDROID_ATTRIBUTE_ORDER</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>.*</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
</rules>
</arrangement>
</codeStyleSettings>
</code_scheme>
</component>

+ 21
- 0
.idea/gradle.xml Bestand weergeven

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="delegatedBuild" value="false" />
<option name="testRunner" value="PLATFORM" />
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
<option name="resolveModulePerSourceSet" value="false" />
</GradleProjectSettings>
</option>
</component>
</project>

+ 25
- 0
.idea/jarRepositories.xml Bestand weergeven

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
<remote-repository>
<option name="id" value="BintrayJCenter" />
<option name="name" value="BintrayJCenter" />
<option name="url" value="https://jcenter.bintray.com/" />
</remote-repository>
<remote-repository>
<option name="id" value="Google" />
<option name="name" value="Google" />
<option name="url" value="https://dl.google.com/dl/android/maven2/" />
</remote-repository>
</component>
</project>

+ 9
- 0
.idea/misc.xml Bestand weergeven

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>

+ 12
- 0
.idea/runConfigurations.xml Bestand weergeven

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
</set>
</option>
</component>
</project>

+ 1
- 0
app/.gitignore Bestand weergeven

@@ -0,0 +1 @@
/build

+ 48
- 0
app/build.gradle Bestand weergeven

@@ -0,0 +1,48 @@
apply plugin: 'com.android.application'

android {
compileSdkVersion 29
buildToolsVersion "29.0.2"
defaultConfig {
applicationId "tw.com.altob.goodpk.carin"
minSdkVersion 21
targetSdkVersion 29
versionCode 6
versionName "1.5"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

buildTypes {

debug {

buildConfigField "String", "API_URL", "\"https://cloudservice.altob.com.tw/LockCarSerivce/api/JumpApi\""
}

release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
buildConfigField "String", "API_URL", "\"https://cloudservice.altob.com.tw/LockCarSerivce/api/JumpApi\""
}
}
}

dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation fileTree(dir: 'libs', include: ['*.aar'])

implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
implementation 'com.google.android.material:material:1.0.0'
implementation "androidx.loader:loader:1.1.0"

//插件
implementation 'com.google.code.gson:gson:2.8.1'
implementation 'com.android.support:multidex:1.0.2'
implementation 'com.orhanobut:logger:1.8'
implementation "com.squareup.okhttp3:okhttp:4.7.2"

}

BIN
app/libs/gasdk.aar Bestand weergeven


+ 21
- 0
app/proguard-rules.pro Bestand weergeven

@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

# 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 *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

+ 1
- 0
app/release/output.json Bestand weergeven

@@ -0,0 +1 @@
[{"outputType":{"type":"APK"},"apkData":{"type":"MAIN","splits":[],"versionCode":6,"versionName":"1.5","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release"},"path":"app-release.apk","properties":{}}]

+ 38
- 0
app/src/androidTest/java/tw/com/altob/goodpk/ExampleInstrumentedTest.java Bestand weergeven

@@ -0,0 +1,38 @@
package tw.com.altob.goodpk;

import android.content.Context;

import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;

import org.junit.Test;
import org.junit.runner.RunWith;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.net.URL;
import java.net.URLConnection;

import tw.com.altob.goodpk.Util.PrefsUtil;

import static org.junit.Assert.*;

/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() {
// Context of the app under test.
//Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();

//assertEquals("tw.com.altob.goodpk", appContext.getPackageName());
//String a = PrefsUtil.md5("ABC1234");
//System.out.println(a);

}
}

+ 71
- 0
app/src/main/AndroidManifest.xml Bestand weergeven

@@ -0,0 +1,71 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="tw.com.altob.goodpk">

<!--使用到的權限-->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@drawable/ic_launcher"
android:supportsRtl="true"
android:theme="@style/AppTheme"
android:usesCleartextTraffic="true">
<activity android:name=".Activity.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<activity
android:name=".Activity.HomeActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:launchMode="singleTask"
android:screenOrientation="portrait"/>

<activity
android:name=".Activity.CarSecurityActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:launchMode="singleTask"
android:screenOrientation="portrait"/>

<activity
android:name=".Activity.InquireCarActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:windowSoftInputMode="adjustPan|stateHidden"
android:launchMode="singleTask"
android:screenOrientation="portrait"/>

<activity
android:name=".Activity.HelpActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:launchMode="singleTask"
android:screenOrientation="portrait"/>

<activity
android:name=".Activity.PaymentActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:launchMode="singleTask"
android:screenOrientation="portrait"/>

<activity
android:name=".Activity.PWActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:launchMode="singleTask"
android:screenOrientation="portrait"/>

<activity
android:name=".Activity.CarLockActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:launchMode="singleTask"
android:screenOrientation="portrait"/>

</application>

</manifest>

+ 24
- 0
app/src/main/java/tw/com/altob/goodpk/Activity/CarLockActivity.java Bestand weergeven

@@ -0,0 +1,24 @@
package tw.com.altob.goodpk.Activity;

import android.os.Bundle;

import androidx.fragment.app.Fragment;

import com.ga.sdk.activity.BaseActivity;

import tw.com.altob.goodpk.Fragment.CarLockFragment;

public class CarLockActivity extends BaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

this.createToolbarLayout();
this.setTitle("會員防竊首頁");
}

@Override
protected Fragment newFragment() {
return new CarLockFragment();
}
}

+ 25
- 0
app/src/main/java/tw/com/altob/goodpk/Activity/CarSecurityActivity.java Bestand weergeven

@@ -0,0 +1,25 @@
package tw.com.altob.goodpk.Activity;

import android.os.Bundle;

import androidx.fragment.app.Fragment;

import com.ga.sdk.activity.BaseActivity;

import tw.com.altob.goodpk.Fragment.CarSecurityFragment;

public class CarSecurityActivity extends BaseActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

this.createToolbarLayout();
this.setTitle("會員防竊車");
}

@Override
protected Fragment newFragment() {
return new CarSecurityFragment();
}
}

+ 25
- 0
app/src/main/java/tw/com/altob/goodpk/Activity/HelpActivity.java Bestand weergeven

@@ -0,0 +1,25 @@
package tw.com.altob.goodpk.Activity;

import android.os.Bundle;

import androidx.fragment.app.Fragment;

import com.ga.sdk.activity.BaseActivity;

import tw.com.altob.goodpk.Fragment.HelpFragment;

public class HelpActivity extends BaseActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

this.createToolbarLayout();
this.setTitle("緊急協助");
}

@Override
protected Fragment newFragment() {
return new HelpFragment();
}
}

+ 24
- 0
app/src/main/java/tw/com/altob/goodpk/Activity/HomeActivity.java Bestand weergeven

@@ -0,0 +1,24 @@
package tw.com.altob.goodpk.Activity;


import android.os.Bundle;
import androidx.fragment.app.Fragment;

import com.ga.sdk.activity.BaseActivity;

import tw.com.altob.goodpk.Fragment.HomeFragment;

public class HomeActivity extends BaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

this.createFrameLayout();
}

@Override
protected Fragment newFragment() {
return new HomeFragment();
}

}

+ 25
- 0
app/src/main/java/tw/com/altob/goodpk/Activity/InquireCarActivity.java Bestand weergeven

@@ -0,0 +1,25 @@
package tw.com.altob.goodpk.Activity;

import android.os.Bundle;

import androidx.fragment.app.Fragment;

import com.ga.sdk.activity.BaseActivity;

import tw.com.altob.goodpk.Fragment.InquireCarFragment;

public class InquireCarActivity extends BaseActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

this.createToolbarLayout();
this.setTitle("停車位置查詢");
}

@Override
protected Fragment newFragment() {
return new InquireCarFragment();
}
}

+ 49
- 0
app/src/main/java/tw/com/altob/goodpk/Activity/MainActivity.java Bestand weergeven

@@ -0,0 +1,49 @@
package tw.com.altob.goodpk.Activity;

import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;

import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;

import com.ga.sdk.activity.BaseActivity;

import tw.com.altob.goodpk.Fragment.MainFragment;
import tw.com.altob.goodpk.R;
import tw.com.altob.goodpk.Util.CommonIntent;
import tw.com.altob.goodpk.Util.PrefsUtil;

public class MainActivity extends BaseActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

//存token(定值)
PrefsUtil.setAccountData(MainActivity.this, "9a406a82bd551e6ef8e845f42f788af4");
this.createFrameLayout();
this.nextActivity();
}

@Override
protected Fragment newFragment() {
return new MainFragment();
}

private void nextActivity() {
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
Intent intent;

intent = CommonIntent.createHomeActivity(MainActivity.this);

startActivity(intent);
overridePendingTransition(R.anim.right_in,0);
finish();
}
}, 2000);
}
}

+ 24
- 0
app/src/main/java/tw/com/altob/goodpk/Activity/PWActivity.java Bestand weergeven

@@ -0,0 +1,24 @@
package tw.com.altob.goodpk.Activity;

import android.os.Bundle;

import androidx.fragment.app.Fragment;

import com.ga.sdk.activity.BaseActivity;

import tw.com.altob.goodpk.Fragment.PWFragment;

public class PWActivity extends BaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

this.createToolbarLayout();
this.setTitle("修改密碼");
}

@Override
protected Fragment newFragment() {
return new PWFragment();
}
}

+ 25
- 0
app/src/main/java/tw/com/altob/goodpk/Activity/PaymentActivity.java Bestand weergeven

@@ -0,0 +1,25 @@
package tw.com.altob.goodpk.Activity;

import android.os.Bundle;

import androidx.fragment.app.Fragment;

import com.ga.sdk.activity.BaseActivity;

import tw.com.altob.goodpk.Fragment.PaymentFragment;

public class PaymentActivity extends BaseActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

this.createToolbarLayout();
this.setTitle("線上繳費");
}

@Override
protected Fragment newFragment() {
return new PaymentFragment();
}
}

+ 37
- 0
app/src/main/java/tw/com/altob/goodpk/Api/BaseApi.java Bestand weergeven

@@ -0,0 +1,37 @@
package tw.com.altob.goodpk.Api;

import android.content.Context;
import android.text.TextUtils;

import com.ga.sdk.api.AbstractBaseApi;

import java.util.HashMap;
import java.util.Map;

import tw.com.altob.goodpk.BuildConfig;
import tw.com.altob.goodpk.Util.PrefsUtil;

public class BaseApi extends AbstractBaseApi {

@Override
protected Map<String, String> getHeader() {
Map<String, String> headers = null;

if (!TextUtils.isEmpty(this.accessToken)) {
headers = new HashMap<>();
headers.put("Authorization", "Bearer " + this.accessToken);
}

return headers;
}

@Override
protected String getAccessToken(Context context) {
return PrefsUtil.getAccessToken(context);
}

@Override
protected String toUrl(String path) {
return BuildConfig.API_URL + path;
}
}

+ 46
- 0
app/src/main/java/tw/com/altob/goodpk/Api/GoodPkApi.java Bestand weergeven

@@ -0,0 +1,46 @@
package tw.com.altob.goodpk.Api;

import com.ga.sdk.api.Params;

import tw.com.altob.goodpk.Util.CryptionUtil;

public class GoodPkApi extends BaseApi {

//鎖車
private static final String CARSECURITY = "/CARSECURITY?acct=%1$s&pwd=%2$s&status=%3$s&key=%4$s&station=%5$s";

//改密碼
private static final String CHANGEPW = "/change_pwd_40808/%1$s/%2$s/%3$s/%4$s";

//尋車
private static final String CARWHERE = "/CARWHERE?carNo=%1$s";

/*鎖車
使用者車號
使用者密碼
加密後資料
狀態(0.解鎖 1.鎖車 2.查詢)
*/
public String getCarSecurity(String acct, String pwd, String status, String key, String station)
throws Exception {
Params params = new Params();

String Nacct = CryptionUtil.aesEncryptBase64(acct, "Altob");
Nacct = Nacct.replace("\n", "");
return this.doGet( String.format(CARSECURITY, Nacct, pwd, status, key, station), params.getMap());
}

public String changePwd(String acct, String pwd, String npwd, String key)
throws Exception {
Params params = new Params();

return this.doGet( String.format(CHANGEPW, acct, pwd, npwd, key), params.getMap());
}

public String getCarWhere(String carNo)
throws Exception {
Params params = new Params();

return this.doGet( String.format(CARWHERE, CryptionUtil.aesEncryptBase64(carNo, "Altob")), params.getMap());
}
}

+ 26
- 0
app/src/main/java/tw/com/altob/goodpk/Bean/CS.java Bestand weergeven

@@ -0,0 +1,26 @@
package tw.com.altob.goodpk.Bean;

import com.google.gson.annotations.SerializedName;

import java.io.Serializable;

public class CS implements Serializable {

@SerializedName("result_code")
private String result_code;

@SerializedName("result_msg")
private String result_msg;

public String getResult_code() {
return result_code;
}

public String getResult_msg() {
return result_msg;
}

public void setResult_code(String result_code) {
this.result_code = result_code;
}
}

+ 68
- 0
app/src/main/java/tw/com/altob/goodpk/Bean/CW.java Bestand weergeven

@@ -0,0 +1,68 @@
package tw.com.altob.goodpk.Bean;

import com.google.gson.annotations.SerializedName;

import java.io.Serializable;

public class CW implements Serializable {

@SerializedName("num")
private String num;

@SerializedName("in_time")
private String in_time;

@SerializedName("station_no")
private String station_no;

@SerializedName("station_name")
private String station_name;

@SerializedName("image_url")
private String image_url;

@SerializedName("image_url2")
private String image_url2;

@SerializedName("location_no")
private String location_no;

@SerializedName("result_code")
private String result_code;

public String getNum() {
return num;
}

public String getIn_time() {
return in_time;
}

public String getStation_no() {
return station_no;
}

public String getStation_name() {
return station_name;
}

public String getImage_url() {
return image_url;
}

public String getImage_url2() {
return image_url2;
}

public String getLocation_no() {
return location_no;
}

public String getResult_code() {
return result_code;
}

public void setResult_code(String result_code) {
this.result_code = result_code;
}
}

+ 204
- 0
app/src/main/java/tw/com/altob/goodpk/Fragment/CarLockFragment.java Bestand weergeven

@@ -0,0 +1,204 @@
package tw.com.altob.goodpk.Fragment;

import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;
import androidx.loader.content.Loader;

import com.ga.sdk.api.ApiResult;

import tw.com.altob.goodpk.Bean.CS;
import tw.com.altob.goodpk.Loader.ApiLoaderCallback;
import tw.com.altob.goodpk.Loader.GetCarSecurityLoader;
import tw.com.altob.goodpk.R;
import tw.com.altob.goodpk.Util.CommonIntent;
import tw.com.altob.goodpk.Util.ExtraKey;
import tw.com.altob.goodpk.Util.PrefsUtil;

public class CarLockFragment extends Fragment {

private String mAcct,mPwd, msg, mkey, mStatus, station;

private Button lockBtn, unlockBtn, ChangeBtn;
private ImageView carImg, carImg2;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

this.mAcct = this.getArguments().getString(ExtraKey.ID);
this.mPwd = this.getArguments().getString(ExtraKey.DATA);
this.msg = this.getArguments().getString(ExtraKey.OPTION);
this.station = this.getArguments().getString(ExtraKey.LOCATION);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View contentView = inflater.inflate(R.layout.activity_car_lock, container, false);

this.lockBtn = (Button) contentView.findViewById(R.id.lockBtn);
this.unlockBtn = (Button) contentView.findViewById(R.id.unlockBtn);
//this.ChangeBtn = (Button) contentView.findViewById(R.id.ChangeBtn);
this.carImg = (ImageView) contentView.findViewById(R.id.carImg);
this.carImg2 = (ImageView) contentView.findViewById(R.id.carImg2);

return contentView;
}

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);

if(msg.contains("unlocked")){
carImg2.setVisibility(View.INVISIBLE);
carImg.setVisibility(View.VISIBLE);
unlockBtn.setEnabled(false);
lockBtn.setEnabled(true);
}else{
carImg2.setVisibility(View.VISIBLE);
carImg.setVisibility(View.INVISIBLE);
unlockBtn.setEnabled(true);
lockBtn.setEnabled(false);
}

this.lockBtn.setOnClickListener( this.onLockBtnClickListener);
this.unlockBtn.setOnClickListener( this.onUnlockBtnClickListener);
//this.ChangeBtn.setOnClickListener( this.onChangeBtnClickListener);
}

//鎖車
private Button.OnClickListener onLockBtnClickListener = new Button.OnClickListener() {
@Override
public void onClick(View v) {
mStatus = "1";
mkey = PrefsUtil.md5((mAcct + "i" + mPwd + "iii" + mStatus));
ApiLoaderCallback.startApiLoader(getActivity(), setLockLoaderCallback);
}
};

//解鎖
private Button.OnClickListener onUnlockBtnClickListener = new Button.OnClickListener() {
@Override
public void onClick(View v) {
mStatus = "0";
mkey = PrefsUtil.md5((mAcct + "i" + mPwd + "iii" + mStatus));
ApiLoaderCallback.startApiLoader(getActivity(), setUnLockLoaderCallback);
}
};

//改密碼
private Button.OnClickListener onChangeBtnClickListener = new Button.OnClickListener() {
@Override
public void onClick(View v) {
//跳修改密碼頁面
Intent intent = new Intent();
intent = CommonIntent.createChangePWActivity(getActivity());
startActivity(intent);
getActivity().overridePendingTransition(R.anim.right_in,0);
}
};

private void showAlert(int titleID, int contentID){
AlertDialog.Builder dialog = new AlertDialog.Builder( getActivity());
dialog.setTitle( getString( titleID));
dialog.setMessage( getString( contentID));

dialog.setNegativeButton( "確認",new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
// TODO Auto-generated method stub
}

});


dialog.show();
}

//鎖車
private ApiLoaderCallback<CS> setLockLoaderCallback = new ApiLoaderCallback<CS>() {

@Override
public Loader<ApiResult<CS>> onCreateLoader(int id, Bundle args) {

return new GetCarSecurityLoader( getActivity(), mAcct, mPwd, mStatus, mkey, station);
}

@Override
protected void onStatusOk(CS data) {
//Log.d("test", "onStatusOk: " + data.getResult_code());
//Log.d("test", "onStatusOk: " + data.getResult_msg());
if(data.getResult_code().contains("OK")){
Toast.makeText( getContext(), getString(R.string.action_lock), Toast.LENGTH_SHORT).show();
carImg2.setVisibility(View.VISIBLE);
carImg.setVisibility(View.INVISIBLE);
unlockBtn.setEnabled(true);
lockBtn.setEnabled(false);
}else{
if(data.getResult_code().contains("-99")){
int title = R.string.action_ca_error;
int content = R.string.action_ca_error_lock;
showAlert( title, content);
}else{
int title = R.string.action_error;
int content = R.string.action_error_lock;
showAlert( title, content);
}

}
}

@Override
protected void onPreLoadFinished() {

}
};

//解鎖
private ApiLoaderCallback<CS> setUnLockLoaderCallback = new ApiLoaderCallback<CS>() {

@Override
public Loader<ApiResult<CS>> onCreateLoader(int id, Bundle args) {

return new GetCarSecurityLoader( getActivity(), mAcct, mPwd, mStatus, mkey, station);
}

@Override
protected void onStatusOk(CS data) {
//Log.d("test", "onStatusOk: " + data.getResult_code());
//Log.d("test", "onStatusOk: " + data.getResult_msg());
if(data.getResult_code().contains("OK")){
Toast.makeText( getContext(), getString(R.string.action_unlock), Toast.LENGTH_SHORT).show();
carImg2.setVisibility(View.INVISIBLE);
carImg.setVisibility(View.VISIBLE);
unlockBtn.setEnabled(false);
lockBtn.setEnabled(true);
}else{
if(data.getResult_code().contains("-99")){
int title = R.string.action_ca_error;
int content = R.string.action_ca_error_lock;
showAlert( title, content);
}else{
int title = R.string.action_error;
int content = R.string.action_error_lock;
showAlert( title, content);
}
}
}

@Override
protected void onPreLoadFinished() {

}
};
}

+ 146
- 0
app/src/main/java/tw/com/altob/goodpk/Fragment/CarSecurityFragment.java Bestand weergeven

@@ -0,0 +1,146 @@
package tw.com.altob.goodpk.Fragment;

import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;
import androidx.loader.content.Loader;

import com.ga.sdk.api.ApiResult;

import tw.com.altob.goodpk.Bean.CS;
import tw.com.altob.goodpk.Loader.ApiLoaderCallback;
import tw.com.altob.goodpk.Loader.GetCarSecurityLoader;
import tw.com.altob.goodpk.R;
import tw.com.altob.goodpk.Util.CommonIntent;
import tw.com.altob.goodpk.Util.ExtraKey;
import tw.com.altob.goodpk.Util.PrefsUtil;

public class CarSecurityFragment extends Fragment {

private Button LoginBtn,ChangeBtn;
private EditText AcctText,PwText;

private String mAcct, mPwd, mStatus , mkey, station;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
station = this.getArguments().getString(ExtraKey.DATA);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View contentView = inflater.inflate(R.layout.activity_car_security, container, false);

this.LoginBtn = (Button) contentView.findViewById(R.id.LoginBtn);
//this.ChangeBtn = (Button) contentView.findViewById(R.id.ChangeBtn);
this.AcctText = (EditText) contentView.findViewById(R.id.AcctText);
this.PwText = (EditText) contentView.findViewById(R.id.PwText);

return contentView;
}

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);

this.LoginBtn.setOnClickListener( this.onLoginBtnClickListener);
//this.ChangeBtn.setOnClickListener( this.onChangeBtnClickListener);
}

private Button.OnClickListener onLoginBtnClickListener = new Button.OnClickListener() {
@Override
public void onClick(View v) {
if(AcctText.getText().length() >0 && PwText.getText().length() >0){
//API
mAcct = AcctText.getText().toString();
mPwd = PrefsUtil.md5(PwText.getText().toString());
mStatus = "2";
//Log.d("test", "onClick: " + (mAcct + "i" + mPwd + "iii" + mStatus));
mkey = PrefsUtil.md5((mAcct + "i" + mPwd + "iii" + mStatus));
ApiLoaderCallback.startApiLoader(getActivity(), getCarSecurityLoaderCallback);
}else{
int title = R.string.action_error;
int content = R.string.action_error_content;
showAlert( title, content);
}
}
};

private Button.OnClickListener onChangeBtnClickListener = new Button.OnClickListener() {
@Override
public void onClick(View v) {
//跳修改密碼頁面
Intent intent = new Intent();
intent = CommonIntent.createChangePWActivity(getActivity());
startActivity(intent);
getActivity().overridePendingTransition(R.anim.right_in,0);
}
};

private void showAlert(int titleID, int contentID){
AlertDialog.Builder dialog = new AlertDialog.Builder( getActivity());
dialog.setTitle( getString( titleID));
dialog.setMessage( getString( contentID));

dialog.setNegativeButton( "確認",new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
// TODO Auto-generated method stub
}

});


dialog.show();
}

//查詢鎖車狀態
private ApiLoaderCallback<CS> getCarSecurityLoaderCallback = new ApiLoaderCallback<CS>() {

@Override
public Loader<ApiResult<CS>> onCreateLoader(int id, Bundle args) {

return new GetCarSecurityLoader( getActivity(), mAcct, mPwd, mStatus, mkey, station);
}

@Override
protected void onStatusOk(CS data) {
//Log.d("test", "onStatusOk: " + data.getResult_code());
//Log.d("test", "onStatusOk: " + data.getResult_msg());
if(data.getResult_code().contains("-99")){
int title = R.string.action_ca_error;
int content = R.string.action_ca_error_lock;
showAlert( title, content);
}

if(data.getResult_code().contains("FAIL") || data.getResult_code().contains("fail")){
int title = R.string.action_error;
int content = R.string.action_error_car_security;
showAlert( title, content);
}else{
Toast.makeText( getContext(), getString(R.string.action_login), Toast.LENGTH_SHORT).show();
//登入成功,轉至控制畫面
Intent intent = new Intent();
intent = CommonIntent.createCarLockActivity(getActivity(), mAcct, mPwd, data.getResult_msg(), station);
startActivity(intent);
getActivity().overridePendingTransition(R.anim.right_in,0);
}
}

@Override
protected void onPreLoadFinished() {

}
};
}

+ 89
- 0
app/src/main/java/tw/com/altob/goodpk/Fragment/HelpFragment.java Bestand weergeven

@@ -0,0 +1,89 @@
package tw.com.altob.goodpk.Fragment;

import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;

import tw.com.altob.goodpk.R;
import tw.com.altob.goodpk.Util.PermissionCode;
import tw.com.altob.goodpk.Util.PermissionUtil;

public class HelpFragment extends Fragment {

private Button callOutBtn;
private String phoneNum = "0229647078";

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View contentView = inflater.inflate(R.layout.activity_help, container, false);

this.callOutBtn = (Button) contentView.findViewById(R.id.callOutBtn);

return contentView;
}

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);

this.callOutBtn.setOnClickListener( this.onCallOutBtnClickListener);
}

private Button.OnClickListener onCallOutBtnClickListener = new Button.OnClickListener() {
@Override
public void onClick(View v) {
int title = R.string.action_import;
int content = R.string.action_import_content;
showAlert( title, content);
}
};

//權限回調
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {

if (requestCode == PermissionCode.PERMISSION_PHONE) {
if (PermissionUtil.checkPhonePermission(this.getActivity())) {
callPhone(phoneNum);
} else{
Toast.makeText( getContext(),getString(R.string.about_callphone_error), Toast.LENGTH_SHORT).show();
}
}
}

private void callPhone(String phoneNum) {

Intent intent = new Intent(Intent.ACTION_CALL);
Uri data = Uri.parse("tel:" + phoneNum);
intent.setData(data);
startActivity(intent);
}

private void showAlert(int titleID, int contentID){
AlertDialog.Builder dialog = new AlertDialog.Builder( getActivity());
dialog.setTitle( getString( titleID));
dialog.setMessage( getString( contentID));

dialog.setNegativeButton( "確認",new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
// TODO Auto-generated method stub
PermissionUtil.requestPhonePermissions(HelpFragment.this, PermissionCode.PERMISSION_PHONE);
}

});


dialog.show();
}
}

+ 196
- 0
app/src/main/java/tw/com/altob/goodpk/Fragment/HomeFragment.java Bestand weergeven

@@ -0,0 +1,196 @@
package tw.com.altob.goodpk.Fragment;

import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;

import java.util.List;

import tw.com.altob.goodpk.R;
import tw.com.altob.goodpk.Util.CommonIntent;
import tw.com.altob.goodpk.Util.PermissionCode;
import tw.com.altob.goodpk.Util.PermissionUtil;
import tw.com.altob.goodpk.Util.PrefsUtil;
import tw.com.altob.goodpk.Util.ScreenShot;

public class HomeFragment extends Fragment {


private LinearLayout stationBtn;
private TextView stationView;
private ImageButton b1, b2, b3, b4;
private ScreenShot mScreenShot;
private final String[] stationTitle = {"市民廣場","新體","二重公園","金城","澳底"};
private String[] stationCode = {"40808", "12143", "40806", "12117", "12145"};
private String station;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View contentView = inflater.inflate(R.layout.activity_home, container, false);

this.b1 = (ImageButton) contentView.findViewById(R.id.imageButton);
this.b2 = (ImageButton) contentView.findViewById(R.id.imageButton2);
this.b3 = (ImageButton) contentView.findViewById(R.id.imageButton3);
this.b4 = (ImageButton) contentView.findViewById(R.id.imageButton4);

this.stationBtn = (LinearLayout) contentView.findViewById(R.id.stationBtn);
this.stationView = (TextView) contentView.findViewById(R.id.stationView);

return contentView;
}

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);

if(PrefsUtil.getFirst( getActivity())){
showAlert();
}else{
PermissionUtil.requestResPermissions(HomeFragment.this, PermissionCode.READ_EXTERNAL_STORAGE);
}

this.b1.setTag(0);
this.b2.setTag(1);
this.b3.setTag(2);
this.b4.setTag(3);

this.b1.setOnClickListener( this.onBtnClickListener);
this.b2.setOnClickListener( this.onBtnClickListener);
this.b3.setOnClickListener( this.onBtnClickListener);
this.b4.setOnClickListener( this.onBtnClickListener);
this.stationBtn.setOnClickListener( this.stationLayoutOnClickListener);
}

private View.OnClickListener stationLayoutOnClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
showListDialog();
}
};

private void showListDialog(){
AlertDialog.Builder dialog_list = new AlertDialog.Builder(getContext());
dialog_list.setTitle( getString(R.string.action_station));
dialog_list.setItems( stationTitle, new DialogInterface.OnClickListener(){
@Override
//只要你在onClick處理事件內,使用which參數,就可以知道按下陣列裡的哪一個了
public void onClick(DialogInterface dialog, int which) {
//Log.d("test", "onClick: " + which);
stationView.setText(getText(R.string.action_station) + " : " + stationTitle[which]);
station = stationCode[which];
}
});

dialog_list.setNeutralButton( "取消",new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
}
});

dialog_list.show();
}

private Button.OnClickListener onBtnClickListener = new Button.OnClickListener() {
@Override
public void onClick(View v) {

Intent intent = new Intent();
if(station == null){
Toast.makeText(getContext(), "請先選擇場站", Toast.LENGTH_LONG).show();
}else{
switch ((int)v.getTag()){
case 0:
intent = CommonIntent.createInquireCarActivity(getActivity());
startActivity(intent);
getActivity().overridePendingTransition(R.anim.right_in,0);
break;
case 1:
intent = CommonIntent.createCarSecurityActivity(getActivity(), station);
startActivity(intent);
getActivity().overridePendingTransition(R.anim.right_in,0);
break;
case 2:
intent = CommonIntent.createHelpActivity(getActivity());
startActivity(intent);
getActivity().overridePendingTransition(R.anim.right_in,0);
break;
case 3:
intent = CommonIntent.createPaymentActivity(getActivity());
startActivity(intent);
getActivity().overridePendingTransition(R.anim.right_in,0);
break;
}
}
}
};

private void showAlert(){
AlertDialog.Builder dialog = new AlertDialog.Builder( getActivity());
dialog.setTitle( getString( R.string.main_alert_title));
dialog.setMessage( getString( R.string.main_alert_content));
dialog.setNeutralButton( getString(R.string.main_alert_btn2),new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
// TODO Auto-generated method stub
getActivity().finish();
}

});
dialog.setNegativeButton( getString(R.string.main_alert_btn),new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
// TODO Auto-generated method stub
PrefsUtil.saveFirst( getActivity());
PermissionUtil.requestResPermissions(HomeFragment.this, PermissionCode.READ_EXTERNAL_STORAGE);
}

});


dialog.show();
}

//權限回調
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {

if (requestCode == PermissionCode.READ_EXTERNAL_STORAGE) {
if (PermissionUtil.checkResPermission(this.getActivity())) {
//啟動截圖監聽
mScreenShot = ScreenShot.getInstance();
handelSystemScreenShot();
} else{
Toast.makeText( getContext(),getString(R.string.about_res_error), Toast.LENGTH_SHORT).show();
}
}
}


private void handelSystemScreenShot() {
mScreenShot.register(getActivity(), new ScreenShot.CallbackListener() {
@Override
public void onShot(String path) {
//Log.d("test", " shot : " + path);
Toast.makeText( getContext(),getString(R.string.about_res), Toast.LENGTH_SHORT).show();
}
});
}
}

+ 171
- 0
app/src/main/java/tw/com/altob/goodpk/Fragment/InquireCarFragment.java Bestand weergeven

@@ -0,0 +1,171 @@
package tw.com.altob.goodpk.Fragment;

import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;
import androidx.loader.content.Loader;

import com.ga.sdk.api.ApiResult;

import java.io.InputStream;

import tw.com.altob.goodpk.Bean.CW;
import tw.com.altob.goodpk.Loader.ApiLoaderCallback;
import tw.com.altob.goodpk.Loader.GetCarWhereLoader;
import tw.com.altob.goodpk.R;

public class InquireCarFragment extends Fragment {

private Button OKBtn;
private EditText CarNoText;
private TextView stationName,inTime;
private ImageView carWhereImg;
private LinearLayout stationInfo, stationInfo2;

private String carNo;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View contentView = inflater.inflate(R.layout.activity_inquire_car, container, false);

this.OKBtn = (Button) contentView.findViewById(R.id.OKBtn);
this.CarNoText = (EditText) contentView.findViewById(R.id.carNoText);
this.stationName = (TextView) contentView.findViewById(R.id.stationName);
this.inTime = (TextView) contentView.findViewById(R.id.inTime);
this.carWhereImg = (ImageView) contentView.findViewById(R.id.carWhereImg);
this.stationInfo = (LinearLayout) contentView.findViewById(R.id.stationInfo);
this.stationInfo2 = (LinearLayout) contentView.findViewById(R.id.stationIfo2);

return contentView;
}

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);

this.OKBtn.setOnClickListener( this.onOKBtnClickListener);
}

private Button.OnClickListener onOKBtnClickListener = new Button.OnClickListener() {
@Override
public void onClick(View v) {
if(CarNoText.getText().length() >0){
//API
carNo = CarNoText.getText().toString();
ApiLoaderCallback.startApiLoader(getActivity(), getCarWhereLoaderCallback);
}else{
int title = R.string.action_error;
int content = R.string.action_error_content_carno;
showAlert( title, content);
}
}
};

private void showAlert(int titleID, int contentID){
AlertDialog.Builder dialog = new AlertDialog.Builder( getActivity());
dialog.setTitle( getString( titleID));
dialog.setMessage( getString( contentID));

dialog.setNegativeButton( "確認",new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
// TODO Auto-generated method stub
}

});


dialog.show();
}

//查詢鎖車狀態
private ApiLoaderCallback<CW> getCarWhereLoaderCallback = new ApiLoaderCallback<CW>() {

@Override
public Loader<ApiResult<CW>> onCreateLoader(int id, Bundle args) {

return new GetCarWhereLoader( getActivity(), carNo);
}

@Override
protected void onStatusOk(CW data) {
//Log.d("test", "onStatusOk: " + data.getResult_code());
//Log.d("test", "onStatusOk: " + data.getNum());
//Log.d("test", "onStatusOk: " + data.getImage_url());

if(data.getResult_code().contains("OK")){
stationInfo.setVisibility(View.VISIBLE);
stationInfo2.setVisibility(View.VISIBLE);
carWhereImg.setVisibility(View.VISIBLE);

stationName.setText(data.getStation_name());
inTime.setText(data.getIn_time());

if(data.getImage_url2() != null && !data.getImage_url2().isEmpty()){
new DownloadImageTask(carWhereImg).execute(data.getImage_url2());
}else{
new DownloadImageTask(carWhereImg).execute(data.getImage_url());
}


}else{
if(data.getResult_code().contains("-99")){
int title = R.string.action_ca_error;
int content = R.string.action_ca_error_lock;
showAlert( title, content);
}else{

int title = R.string.action_error;
int content = R.string.action_error_lock;
showAlert( title, content);
}
}
}

@Override
protected void onPreLoadFinished() {

}
};

private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
ImageView bmImage;

public DownloadImageTask(ImageView bmImage) {
this.bmImage = bmImage;
}

protected Bitmap doInBackground(String... urls) {
String urldisplay = urls[0];
Bitmap mIcon11 = null;
try {
InputStream in = new java.net.URL(urldisplay).openStream();
mIcon11 = BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return mIcon11;
}

protected void onPostExecute(Bitmap result) {
bmImage.setImageBitmap(result);
}
}
}

+ 17
- 0
app/src/main/java/tw/com/altob/goodpk/Fragment/MainFragment.java Bestand weergeven

@@ -0,0 +1,17 @@
package tw.com.altob.goodpk.Fragment;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.fragment.app.Fragment;

import tw.com.altob.goodpk.R;

public class MainFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.activity_main, container, false);
}
}

+ 124
- 0
app/src/main/java/tw/com/altob/goodpk/Fragment/PWFragment.java Bestand weergeven

@@ -0,0 +1,124 @@
package tw.com.altob.goodpk.Fragment;

import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;
import androidx.loader.content.Loader;

import com.ga.sdk.api.ApiResult;

import tw.com.altob.goodpk.Bean.CS;
import tw.com.altob.goodpk.Loader.ApiLoaderCallback;
import tw.com.altob.goodpk.Loader.ChengePWLoader;
import tw.com.altob.goodpk.Loader.GetCarSecurityLoader;
import tw.com.altob.goodpk.R;
import tw.com.altob.goodpk.Util.CommonIntent;
import tw.com.altob.goodpk.Util.PrefsUtil;

public class PWFragment extends Fragment {

private Button DoneBtn;
private EditText AcctText,PwText, nPwText;

private String mAcct, mPwd, mNPwd , mkey;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View contentView = inflater.inflate(R.layout.activity_change_pw, container, false);

this.DoneBtn = (Button) contentView.findViewById(R.id.DoneBtn);
this.AcctText = (EditText) contentView.findViewById(R.id.AcctText);
this.PwText = (EditText) contentView.findViewById(R.id.PwText);
this.nPwText = (EditText) contentView.findViewById(R.id.nPwText);

return contentView;
}

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);

this.DoneBtn.setOnClickListener( this.onLoginBtnClickListener);
}

private Button.OnClickListener onLoginBtnClickListener = new Button.OnClickListener() {
@Override
public void onClick(View v) {
if(AcctText.getText().length() >0 && PwText.getText().length() >0 && nPwText.getText().length() > 0){
//API
mAcct = AcctText.getText().toString();
mPwd = PwText.getText().toString();
mNPwd = nPwText.getText().toString();
//Log.d("test", "onClick: " + (mAcct + "i" + mPwd + "iii" + mNPwd));
mkey = PrefsUtil.md5((mAcct + "i" + mPwd + "iii" + mNPwd));

ApiLoaderCallback.startApiLoader(getActivity(), getChengePWLoaderCallback);
}else{
int title = R.string.action_error;
int content = R.string.action_error_content2;
showAlert( title, content);
}
}
};

private void showAlert(int titleID, int contentID){
AlertDialog.Builder dialog = new AlertDialog.Builder( getActivity());
dialog.setTitle( getString( titleID));
dialog.setMessage( getString( contentID));

dialog.setNegativeButton( "確認",new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
// TODO Auto-generated method stub
}

});


dialog.show();
}

//查詢鎖車狀態
private ApiLoaderCallback<CS> getChengePWLoaderCallback = new ApiLoaderCallback<CS>() {

@Override
public Loader<ApiResult<CS>> onCreateLoader(int id, Bundle args) {

return new ChengePWLoader( getActivity(), mAcct, mPwd, mNPwd, mkey);
}

@Override
protected void onStatusOk(CS data) {
//Log.d("test", "onStatusOk: " + data.getResult_code());
//Log.d("test", "onStatusOk: " + data.getResult_msg());

if(data.getResult_code().contains("OK")){
Toast.makeText( getContext(), getString(R.string.action_change), Toast.LENGTH_SHORT).show();
getActivity().finish();
}else{
Toast.makeText( getContext(), getString(R.string.action_error_lock), Toast.LENGTH_SHORT).show();
}
}

@Override
protected void onPreLoadFinished() {

}
};
}

+ 39
- 0
app/src/main/java/tw/com/altob/goodpk/Fragment/PaymentFragment.java Bestand weergeven

@@ -0,0 +1,39 @@
package tw.com.altob.goodpk.Fragment;

import android.os.Build;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;

import androidx.fragment.app.Fragment;

import tw.com.altob.goodpk.R;

public class PaymentFragment extends Fragment {

private WebView webView;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View contentView = inflater.inflate(R.layout.activity_payment, container, false);
this.webView = (WebView) contentView.findViewById(R.id.WebView);
return contentView;
}

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);

WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
if (Build.VERSION.SDK_INT >= 21) {
webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}
webView.setWebViewClient(new WebViewClient());
webView.loadUrl( getString(R.string.payment_url));
}
}

+ 43
- 0
app/src/main/java/tw/com/altob/goodpk/Loader/ApiLoaderCallback.java Bestand weergeven

@@ -0,0 +1,43 @@
package tw.com.altob.goodpk.Loader;

import android.content.Context;

import com.ga.sdk.api.ApiResult;
import com.ga.sdk.loader.AbstractApiLoaderCallback;
import com.orhanobut.logger.Logger;

import org.json.JSONException;

import tw.com.altob.goodpk.Parser.BaseApiParser;
import tw.com.altob.goodpk.Util.PrefsUtil;

public abstract class ApiLoaderCallback<T> extends AbstractApiLoaderCallback<T> {

@Override
protected String toErrorMessage(ApiResult apiResult) {

String message;
try {
message = BaseApiParser.getMessage(apiResult.getError().getBody());
} catch (JSONException e) {
int status = apiResult.getError().getStatus();
String reason = apiResult.getError().getReason();

message = "[" + status + "] " + reason;
}

return message;
}

@Override
protected void handleForbidden(Context context) {
try {
PrefsUtil.clearData(context);
//DBUtil.cleanData(context);
} catch (Exception e) {
Logger.e(e, e.getMessage());
}
}


}

+ 40
- 0
app/src/main/java/tw/com/altob/goodpk/Loader/ChengePWLoader.java Bestand weergeven

@@ -0,0 +1,40 @@
package tw.com.altob.goodpk.Loader;

import android.content.Context;

import androidx.annotation.NonNull;

import com.ga.sdk.loader.BaseAsyncTaskLoader;

import tw.com.altob.goodpk.Api.GoodPkApi;
import tw.com.altob.goodpk.Bean.CS;
import tw.com.altob.goodpk.Parser.CarSecurityParser;

public class ChengePWLoader extends BaseAsyncTaskLoader<CS> {

private String Acct, Pwd, NPwd, Key;
private Context mContext;

public ChengePWLoader(@NonNull Context context, String mAcct, String mPwd, String mNPwd, String mkey) {
super(context);

this.mContext = context;
this.Acct = mAcct;
this.Pwd = mPwd;
this.NPwd = mNPwd;
this.Key = mkey;
}

@Override
protected String action() throws Exception {
GoodPkApi api = new GoodPkApi().withAccessToken(this.mContext);
return api.changePwd(this.Acct, this.Pwd, this.NPwd, this.Key);
}

@Override
protected CS parseData(String s) throws Exception {
CarSecurityParser parser = new CarSecurityParser();

return parser.toData(s);
}
}

+ 50
- 0
app/src/main/java/tw/com/altob/goodpk/Loader/GetCarSecurityLoader.java Bestand weergeven

@@ -0,0 +1,50 @@
package tw.com.altob.goodpk.Loader;

import android.content.Context;
import android.widget.Switch;

import androidx.annotation.NonNull;

import com.ga.sdk.loader.BaseAsyncTaskLoader;

import tw.com.altob.goodpk.Api.GoodPkApi;
import tw.com.altob.goodpk.Bean.CS;
import tw.com.altob.goodpk.Bean.CW;
import tw.com.altob.goodpk.Parser.CarSecurityParser;

public class GetCarSecurityLoader extends BaseAsyncTaskLoader<CS> {

private String Acct, Pwd, Status, Key, station;
private Context mContext;

public GetCarSecurityLoader(@NonNull Context context, String mAcct, String mPwd, String mStatus, String mkey, String station) {
super(context);

this.mContext = context;
this.Acct = mAcct;
this.Pwd = mPwd;
this.Status = mStatus;
this.Key = mkey;
this.station = station;
}

@Override
protected String action() throws Exception {
GoodPkApi api = new GoodPkApi().withAccessToken(this.mContext);
return api.getCarSecurity(this.Acct, this.Pwd, this.Status, this.Key, this.station);
}

@Override
protected CS parseData(String s) throws Exception {
CarSecurityParser parser = new CarSecurityParser();

//憑證錯誤
if(s.contains("Certificate pinning failure!")){
CS cs = new CS();
cs.setResult_code("-99");
return cs;
}else{
return parser.toData(s);
}
}
}

+ 44
- 0
app/src/main/java/tw/com/altob/goodpk/Loader/GetCarWhereLoader.java Bestand weergeven

@@ -0,0 +1,44 @@
package tw.com.altob.goodpk.Loader;

import android.content.Context;

import androidx.annotation.NonNull;

import com.ga.sdk.loader.BaseAsyncTaskLoader;

import tw.com.altob.goodpk.Api.GoodPkApi;
import tw.com.altob.goodpk.Bean.CW;
import tw.com.altob.goodpk.Parser.CarWhereParser;

public class GetCarWhereLoader extends BaseAsyncTaskLoader<CW> {

private String mCarNo;
private Context mContext;

public GetCarWhereLoader(@NonNull Context context, String carNo) {
super(context);

this.mContext = context;
this.mCarNo = carNo;
}

@Override
protected String action() throws Exception {
GoodPkApi api = new GoodPkApi().withAccessToken(this.mContext);
return api.getCarWhere(this.mCarNo);
}

@Override
protected CW parseData(String s) throws Exception {
CarWhereParser parser = new CarWhereParser();

//憑證錯誤
if(s.contains("Certificate pinning failure!")){
CW cw = new CW();
cw.setResult_code("-99");
return cw;
}else{
return parser.toData(s);
}
}
}

+ 18
- 0
app/src/main/java/tw/com/altob/goodpk/Parser/BaseApiParser.java Bestand weergeven

@@ -0,0 +1,18 @@
package tw.com.altob.goodpk.Parser;

import com.ga.sdk.parser.BaseParser;

import org.json.JSONException;
import org.json.JSONObject;

public class BaseApiParser extends BaseParser {
public static String getMessage(String jsonString) throws JSONException {
return getString(jsonString, "message");
}

private static String getString(String jsonString, String key) throws JSONException {
JSONObject json = new JSONObject(jsonString);

return getString(json, key);
}
}

+ 11
- 0
app/src/main/java/tw/com/altob/goodpk/Parser/BaseParser.java Bestand weergeven

@@ -0,0 +1,11 @@
package tw.com.altob.goodpk.Parser;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class BaseParser {
protected static Gson gson() {
return new GsonBuilder().create();
}

}

+ 11
- 0
app/src/main/java/tw/com/altob/goodpk/Parser/CarSecurityParser.java Bestand weergeven

@@ -0,0 +1,11 @@
package tw.com.altob.goodpk.Parser;

import tw.com.altob.goodpk.Bean.CS;

public class CarSecurityParser extends DataParser<CS> {

@Override
protected Class<CS> getType() {
return CS.class;
}
}

+ 11
- 0
app/src/main/java/tw/com/altob/goodpk/Parser/CarWhereParser.java Bestand weergeven

@@ -0,0 +1,11 @@
package tw.com.altob.goodpk.Parser;

import tw.com.altob.goodpk.Bean.CW;

public class CarWhereParser extends DataParser<CW> {

@Override
protected Class<CW> getType() {
return CW.class;
}
}

+ 46
- 0
app/src/main/java/tw/com/altob/goodpk/Parser/DataParser.java Bestand weergeven

@@ -0,0 +1,46 @@
package tw.com.altob.goodpk.Parser;

import android.text.TextUtils;

import com.google.gson.Gson;
import com.google.gson.JsonParseException;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;

public abstract class DataParser<T> extends BaseParser {
protected Gson gson;

public DataParser() {
this.gson = gson();
}

public T toData(String json) throws JsonParseException {
return this.gson.fromJson(json, getType());
}

public List<T> toList(String json) throws JsonParseException {
List<T> list = new ArrayList<>();


if (!TextUtils.isEmpty(json)) {
Object[] array = (Object[]) Array.newInstance(getType(), 1);
array = this.gson.fromJson(json, array.getClass());

for (Object object : array) {
@SuppressWarnings("unchecked")
T t = (T) object;
list.add(t);
}
}

return list;
}

public String toJson(T t) throws JsonParseException {
return this.gson.toJson(t);
}

protected abstract Class<T> getType();
}

+ 103
- 0
app/src/main/java/tw/com/altob/goodpk/Util/CommonIntent.java Bestand weergeven

@@ -0,0 +1,103 @@
package tw.com.altob.goodpk.Util;

import android.content.Context;
import android.content.Intent;

import androidx.annotation.NonNull;

import tw.com.altob.goodpk.Activity.CarLockActivity;
import tw.com.altob.goodpk.Activity.CarSecurityActivity;
import tw.com.altob.goodpk.Activity.HomeActivity;
import tw.com.altob.goodpk.Activity.InquireCarActivity;
import tw.com.altob.goodpk.Activity.HelpActivity;
import tw.com.altob.goodpk.Activity.PWActivity;
import tw.com.altob.goodpk.Activity.PaymentActivity;

public class CommonIntent {

@NonNull
public static Intent createHomeActivity(@NonNull Context context) {
return createHomeActivity(context, -1);
}

@NonNull
public static Intent createHomeActivity(@NonNull Context context, int index) {
return createHomeActivity(context, index, false);
}

@NonNull
public static Intent createHomeActivity(@NonNull Context context, boolean option) {
return createHomeActivity(context, -1, option);
}

@NonNull
private static Intent createHomeActivity(@NonNull Context context, int index, boolean option) {
Intent intent = new Intent(context, HomeActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

if (index >= 0) {
intent.putExtra(ExtraKey.ID, index);
}

if (option) {
intent.putExtra(ExtraKey.OPTION, true);
}

return intent;
}


@NonNull
public static Intent createHelpActivity(@NonNull Context context) {

Intent intent = new Intent(context, HelpActivity.class);

return intent;
}


@NonNull
public static Intent createInquireCarActivity(@NonNull Context context) {

Intent intent = new Intent(context, InquireCarActivity.class);

return intent;
}


@NonNull
public static Intent createCarSecurityActivity(@NonNull Context context, String station) {

Intent intent = new Intent(context, CarSecurityActivity.class);
intent.putExtra(ExtraKey.DATA, station);
return intent;
}

@NonNull
public static Intent createPaymentActivity(@NonNull Context context) {

Intent intent = new Intent(context, PaymentActivity.class);

return intent;
}

@NonNull
public static Intent createChangePWActivity(@NonNull Context context) {

Intent intent = new Intent(context, PWActivity.class);

return intent;
}

@NonNull
public static Intent createCarLockActivity(@NonNull Context context, String acct, String pwd, String msg, String station) {

Intent intent = new Intent(context, CarLockActivity.class);
intent.putExtra(ExtraKey.ID, acct);
intent.putExtra(ExtraKey.DATA, pwd);
intent.putExtra(ExtraKey.OPTION, msg);
intent.putExtra(ExtraKey.LOCATION, station);
return intent;
}
}

+ 149
- 0
app/src/main/java/tw/com/altob/goodpk/Util/CryptionUtil.java Bestand weergeven

@@ -0,0 +1,149 @@
package tw.com.altob.goodpk.Util;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import android.util.Base64;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class CryptionUtil {

//AES解密
public static String aesDecryptBase64(String carNo, String CryptoKey){

byte[] key = new byte[32];
byte[] iv = new byte[16];
String decKey = "";
String decString = "";

decKey = sha256encrypt(CryptoKey).substring(0, 10);
byte[] sha = sha384encrypt(decKey);

System.arraycopy(sha, 0, key, 0, 32);
System.arraycopy(sha, 32, iv, 0, 16);

try {
decString = decrypt(carNo, key, iv);
} catch (Exception e) {
e.printStackTrace();
}

return decString;
}

//AES加密
public static String aesEncryptBase64(String carNo, String CryptoKey){

byte[] key = new byte[32];
byte[] iv = new byte[16];
String encKey = "";
String encString = "";

encKey = sha256encrypt(CryptoKey).substring(0, 10);
byte[] sha = sha384encrypt(encKey);

System.arraycopy(sha, 0, key, 0, 32);
System.arraycopy(sha, 32, iv, 0, 16);

try {
encString = encrypt(carNo, key, iv);
} catch (Exception e) {
e.printStackTrace();
}

return encString;
}

//SHA384加密
private static byte[] sha384encrypt(String input){

MessageDigest objSHA = null;

try {
objSHA = MessageDigest.getInstance("SHA-384");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}

byte[] bytSHA = objSHA.digest(input.getBytes());

return bytSHA;
}

//SHA256加密
public static String sha256encrypt(String input){

MessageDigest md = null;
String strDes = null;
String encName = null;

byte[] bt = input.getBytes();
try {
encName = "SHA-256";
md = MessageDigest.getInstance(encName);
md.update(bt);
strDes = bytes2Hex(md.digest()); // to HexString

} catch (NoSuchAlgorithmException e) {
return null;
}
return strDes;
}

private static String bytes2Hex(byte[] bts) {
String des = "";
String tmp = null;
for (int i = 0; i < bts.length; i++) {
tmp = (Integer.toHexString(bts[i] & 0xFF));
if (tmp.length() == 1) {
des += "0";
}
des += tmp;
}
return des;
}

private static String decrypt(String sSrc, byte[] key, byte[] ivs) throws Exception {
try {

byte[] raw = key;

SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

IvParameterSpec iv = new IvParameterSpec(ivs);

cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);

byte[] encrypted1 = Base64.decode(sSrc, Base64.DEFAULT);// 先用base64解密
byte[] original = cipher.doFinal(encrypted1);

String originalString = new String(original, "utf-8");

return originalString;
} catch (Exception ex) {
return null;
}
}

private static String encrypt(String sSrc, byte[] key, byte[] ivs) throws Exception {

SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

IvParameterSpec iv = new IvParameterSpec(ivs);

cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);

byte[] p = sSrc.getBytes("UTF-8");
byte[] result = cipher.doFinal(p);

String encoded = new String(Base64.encode(result, Base64.DEFAULT), "utf-8");

return encoded;
}
}

+ 12
- 0
app/src/main/java/tw/com/altob/goodpk/Util/ExtraKey.java Bestand weergeven

@@ -0,0 +1,12 @@
package tw.com.altob.goodpk.Util;

public class ExtraKey {

public static final String LOCATION = "location";
public static final String LAT = "lat";
public static final String LON = "lon";
public static final String DATA = "data";
public static final String OPTION = "option";
public static final String TOKEN = "token";
public static final String ID = "id";
}

+ 6
- 0
app/src/main/java/tw/com/altob/goodpk/Util/PermissionCode.java Bestand weergeven

@@ -0,0 +1,6 @@
package tw.com.altob.goodpk.Util;

public class PermissionCode {
public static final int PERMISSION_PHONE = 112;
public static final int READ_EXTERNAL_STORAGE = 113;
}

+ 53
- 0
app/src/main/java/tw/com/altob/goodpk/Util/PermissionUtil.java Bestand weergeven

@@ -0,0 +1,53 @@
package tw.com.altob.goodpk.Util;

import android.content.Context;

import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;

public class PermissionUtil {
private static final String[] PHONE_PERMISSIONS = new String[]{"android.permission.CALL_PHONE"};
private static final String[] READ_EXTERNAL_STORAGE = new String[]{"android.permission.READ_EXTERNAL_STORAGE"};

public static boolean checkPhonePermission(@NonNull Context context) {
return checkPermissions(context, PHONE_PERMISSIONS);
}

public static void requestPhonePermissions(@NonNull Fragment fragment, int requestCode) {
requestPermissions(fragment, requestCode, PHONE_PERMISSIONS);
}

protected static void requestPermissions(@NonNull Fragment fragment, int requestCode, String[] permissions) {
fragment.requestPermissions(permissions, requestCode);
}

public static boolean checkResPermission(@NonNull Context context) {
return checkPermissions(context, READ_EXTERNAL_STORAGE);
}

public static void requestResPermissions(@NonNull Fragment fragment, int requestCode) {
requestPermissions(fragment, requestCode, READ_EXTERNAL_STORAGE);
}


protected static boolean checkPermissions(@NonNull Context context, String[]... permissionsArray) {
String[][] var2 = permissionsArray;
int var3 = permissionsArray.length;

for(int var4 = 0; var4 < var3; ++var4) {
String[] permissions = var2[var4];
String[] var6 = permissions;
int var7 = permissions.length;

for(int var8 = 0; var8 < var7; ++var8) {
String permission = var6[var8];
if (ContextCompat.checkSelfPermission(context, permission) != 0) {
return false;
}
}
}

return true;
}
}

+ 113
- 0
app/src/main/java/tw/com/altob/goodpk/Util/PrefsUtil.java Bestand weergeven

@@ -0,0 +1,113 @@
package tw.com.altob.goodpk.Util;

import android.content.Context;
import android.content.SharedPreferences;
import android.text.TextUtils;

import androidx.annotation.NonNull;

import com.ga.sdk.util.CryptoUtil;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class PrefsUtil {

private static final String PREF_ACCOUNT = "account";
private static final String PREF_MESSAGE = "message";
private static final String PREF_STICKER = "sticker";
private static final String KEY_ACCESS_TOKEN = "accessToken";
private static final String PREF_ADDCARLIST = "AddCar";
private static final String FIRST = "isFirst";

private static final byte[] seed = "Alobot".getBytes();

public static void clearData(@NonNull Context context) {
String[] prefs = {PREF_ACCOUNT, PREF_MESSAGE, PREF_STICKER};

for (String pref : prefs) {
SharedPreferences preferences = context.getSharedPreferences(
pref, Context.MODE_PRIVATE);

SharedPreferences.Editor editor = preferences.edit();

editor.clear();
editor.apply();
}

}

public static String getAccessToken(@NonNull Context context) {
SharedPreferences preferences = context.getSharedPreferences(
PREF_ACCOUNT, Context.MODE_PRIVATE);
String accessToken = preferences.getString(KEY_ACCESS_TOKEN, "");

try {
if (!TextUtils.isEmpty(accessToken)) {
accessToken = CryptoUtil.decrypt(accessToken, seed);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
return accessToken;
}

public static String md5(String string) {
if (TextUtils.isEmpty(string)) {
return "";
}
MessageDigest md5 = null;
try {
md5 = MessageDigest.getInstance("MD5");
byte[] bytes = md5.digest(string.getBytes());
String result = "";
for (byte b : bytes) {
String temp = Integer.toHexString(b & 0xff);
if (temp.length() == 1) {
temp = "0" + temp;
}
result += temp;
}
return result;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return "";
}

public static boolean getFirst(@NonNull Context context){
SharedPreferences settings;
settings = context.getSharedPreferences(PREF_ADDCARLIST, Context.MODE_PRIVATE);

if( settings.getString(FIRST, null) == null){
return true;
}else{
return false;
}
}

public static void saveFirst(@NonNull Context context){
SharedPreferences settings;
SharedPreferences.Editor editor;

settings = context.getSharedPreferences(PREF_ADDCARLIST, Context.MODE_PRIVATE);
editor = settings.edit();
editor.putString(FIRST, "true");

editor.commit();
}

public static void setAccountData(@NonNull Context context, String token) {
SharedPreferences preferences = context.getSharedPreferences(
PREF_ACCOUNT, Context.MODE_PRIVATE);

SharedPreferences.Editor editor = preferences.edit();
try {
editor.putString(KEY_ACCESS_TOKEN, CryptoUtil.encrypt(token, seed));

editor.apply();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}

+ 194
- 0
app/src/main/java/tw/com/altob/goodpk/Util/ScreenShot.java Bestand weergeven

@@ -0,0 +1,194 @@
package tw.com.altob.goodpk.Util;

import android.content.ContentResolver;
import android.content.Context;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Handler;
import android.os.HandlerThread;
import android.provider.MediaStore;
import android.util.Log;


public class ScreenShot {
private static final String TAG = "ScreenShot";
private static final String[] MEDIA_PROJECTIONS = {
MediaStore.Images.ImageColumns.DATA,
MediaStore.Images.ImageColumns.DATE_TAKEN,
MediaStore.Images.ImageColumns.DATE_ADDED
};

/**
* 截屏依据中的路径判断关键字
*/
private static final String[] KEYWORDS = {
"screenshot", "screen_shot", "screen-shot", "screen shot", "screencapture",
"screen_capture", "screen-capture", "screen capture", "screencap", "screen_cap",
"screen-cap", "screen cap"
};

private ContentResolver mContentResolver;
private CallbackListener mCallbackListener;
private MediaContentObserver mInternalObserver;
private MediaContentObserver mExternalObserver;
private static ScreenShot mInstance;

private ScreenShot() {
}

/**
* 获取 ScreenShot 对象
*
* @return ScreenShot对象
*/
public static ScreenShot getInstance() {
if (mInstance == null) {
synchronized (ScreenShot.class) {
mInstance = new ScreenShot();
}
}
return mInstance;
}

/**
* 注册
*
* @param context 上下文
* @param callbackListener 回调监听
*/
public void register(Context context, CallbackListener callbackListener) {
mContentResolver = context.getContentResolver();
mCallbackListener = callbackListener;

HandlerThread handlerThread = new HandlerThread(TAG);
handlerThread.start();
Handler handler = new Handler(handlerThread.getLooper());

mInternalObserver = new MediaContentObserver(MediaStore.Images.Media.INTERNAL_CONTENT_URI, handler);
mExternalObserver = new MediaContentObserver(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, handler);

mContentResolver.registerContentObserver(MediaStore.Images.Media.INTERNAL_CONTENT_URI,
false, mInternalObserver);
mContentResolver.registerContentObserver(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
false, mExternalObserver);
}

/**
* 注销
*/
public void unregister() {
if (mContentResolver != null) {
mContentResolver.unregisterContentObserver(mInternalObserver);
mContentResolver.unregisterContentObserver(mExternalObserver);
}
}

private void handleMediaContentChange(Uri uri) {
Cursor cursor = null;
try {
// 数据改变时,查询数据库中最后加入的一条数据
cursor = mContentResolver.query(uri, MEDIA_PROJECTIONS, null, null,
MediaStore.Images.ImageColumns.DATE_ADDED + " desc limit 1");
if (cursor == null) {
return;
}
if (!cursor.moveToFirst()) {
return;
}
int dataIndex = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
int dateAddedIndex = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATE_ADDED);
// 处理获取到的第一行数据
handleMediaRowData(cursor.getString(dataIndex), cursor.getLong(dateAddedIndex));
} catch (Exception e) {
e.printStackTrace();
} finally {
if (cursor != null && !cursor.isClosed()) {
cursor.close();
}
}
}

/**
* 处理监听到的资源
*/
private void handleMediaRowData(String path, long dateAdded) {
long duration = 0;
long step = 100;

// 发现个别手机会自己修改截图文件夹的文件,截屏功能会误以为是用户在截屏操作,进行捕获,所以加了一个时间判断
if (!isTimeValid(dateAdded)) {
//Log.d(TAG, "图片插入时间大于1秒,不是截屏");
return;
}

// 设置最大等待时间为500ms,因为魅族的部分手机保存截图有延迟
while (!checkScreenShot(path) && duration <= 500) {
try {
duration += step;
Thread.sleep(step);
} catch (Exception e) {
e.printStackTrace();
}
}

if (checkScreenShot(path)) {
if (mCallbackListener != null) {
mCallbackListener.onShot(path);
}
}
}

/**
* 判断时间是否合格,图片插入时间小于1秒才有效
*/
private boolean isTimeValid(long dateAdded) {
return Math.abs(System.currentTimeMillis() / 1000 - dateAdded) <= 1;
}

private boolean checkScreenShot(String path) {
if (path == null) {
return false;
}
path = path.toLowerCase();
for (String keyword : KEYWORDS) {
if (path.contains(keyword)) {
return true;
}
}
return false;
}

/**
* 媒体内容观察者
*/
private class MediaContentObserver extends ContentObserver {
private Uri mUri;

MediaContentObserver(Uri uri, Handler handler) {
super(handler);
mUri = uri;
}

@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
//Log.d("ScreenShot", "图片数据库发生变化:" + selfChange);
handleMediaContentChange(mUri);
}
}

/**
* 回调监听器
*/
public interface CallbackListener {
/**
* 截屏
*
* @param path 图片路径
*/
void onShot(String path);
}

}


+ 6
- 0
app/src/main/res/anim/right_in.xml Bestand weergeven

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXDelta="100%"
android:toXDelta="0"
android:duration="300">
</translate>

BIN
app/src/main/res/drawable-hdpi/bg_home.jpg Bestand weergeven

Before After
Width: 540  |  Height: 960  |  Size: 94KB

BIN
app/src/main/res/drawable-hdpi/bg_landingpage.jpg Bestand weergeven

Before After
Width: 540  |  Height: 960  |  Size: 166KB

BIN
app/src/main/res/drawable-hdpi/bg_page.jpg Bestand weergeven

Before After
Width: 540  |  Height: 960  |  Size: 293KB

BIN
app/src/main/res/drawable-hdpi/bg_password_02.png Bestand weergeven

Before After
Width: 540  |  Height: 960  |  Size: 7.0KB

BIN
app/src/main/res/drawable-hdpi/btn_aboutus.png Bestand weergeven

Before After
Width: 90  |  Height: 63  |  Size: 5.9KB

BIN
app/src/main/res/drawable-hdpi/btn_area.png Bestand weergeven

Before After
Width: 95  |  Height: 95  |  Size: 5.5KB

BIN
app/src/main/res/drawable-hdpi/btn_bg_voice.png Bestand weergeven

Before After
Width: 90  |  Height: 90  |  Size: 5.3KB

BIN
app/src/main/res/drawable-hdpi/btn_bg_voice_down.png Bestand weergeven

Before After
Width: 90  |  Height: 90  |  Size: 2.8KB

BIN
app/src/main/res/drawable-hdpi/btn_main_icon_01.png Bestand weergeven

Before After
Width: 75  |  Height: 75  |  Size: 690B

BIN
app/src/main/res/drawable-hdpi/btn_main_icon_02.png Bestand weergeven

Before After
Width: 75  |  Height: 75  |  Size: 992B

BIN
app/src/main/res/drawable-hdpi/btn_main_icon_03.png Bestand weergeven

Before After
Width: 75  |  Height: 75  |  Size: 838B

BIN
app/src/main/res/drawable-hdpi/btn_main_icon_04.png Bestand weergeven

Before After
Width: 75  |  Height: 75  |  Size: 1.0KB

BIN
app/src/main/res/drawable-hdpi/btn_main_icon_05.png Bestand weergeven

Before After
Width: 75  |  Height: 75  |  Size: 957B

BIN
app/src/main/res/drawable-hdpi/btn_main_icon_06.png Bestand weergeven

Before After
Width: 75  |  Height: 75  |  Size: 3.0KB

BIN
app/src/main/res/drawable-hdpi/btn_main_icon_07.png Bestand weergeven

Before After
Width: 60  |  Height: 60  |  Size: 4.5KB

BIN
app/src/main/res/drawable-hdpi/btn_site.png Bestand weergeven

Before After
Width: 95  |  Height: 95  |  Size: 6.9KB

BIN
app/src/main/res/drawable-hdpi/custom.png Bestand weergeven

Before After
Width: 45  |  Height: 45  |  Size: 1.9KB

BIN
app/src/main/res/drawable-hdpi/ic_dialog_close_dark.png Bestand weergeven

Before After
Width: 36  |  Height: 36  |  Size: 206B

BIN
app/src/main/res/drawable-hdpi/ic_dialog_close_light.png Bestand weergeven

Before After
Width: 36  |  Height: 36  |  Size: 207B

BIN
app/src/main/res/drawable-hdpi/icon_btn_back.png Bestand weergeven

Before After
Width: 33  |  Height: 33  |  Size: 234B

BIN
app/src/main/res/drawable-hdpi/icon_btn_close.png Bestand weergeven

Before After
Width: 33  |  Height: 33  |  Size: 213B

BIN
app/src/main/res/drawable-hdpi/icon_btn_home.png Bestand weergeven

Before After
Width: 33  |  Height: 33  |  Size: 421B

BIN
app/src/main/res/drawable-hdpi/icon_btn_lock.png Bestand weergeven

Before After
Width: 33  |  Height: 33  |  Size: 413B

BIN
app/src/main/res/drawable-hdpi/icon_btn_menu.png Bestand weergeven

Before After
Width: 33  |  Height: 33  |  Size: 202B

BIN
app/src/main/res/drawable-hdpi/icon_btn_nav.png Bestand weergeven

Before After
Width: 33  |  Height: 33  |  Size: 473B

BIN
app/src/main/res/drawable-hdpi/icon_btn_phone.png Bestand weergeven

Before After
Width: 33  |  Height: 33  |  Size: 416B

BIN
app/src/main/res/drawable-hdpi/icon_btn_right.png Bestand weergeven

Before After
Width: 33  |  Height: 33  |  Size: 182B

BIN
app/src/main/res/drawable-hdpi/icon_btn_unlock.png Bestand weergeven

Before After
Width: 33  |  Height: 33  |  Size: 423B

BIN
app/src/main/res/drawable-hdpi/icon_home_location.png Bestand weergeven

Before After
Width: 24  |  Height: 24  |  Size: 769B

BIN
app/src/main/res/drawable-hdpi/icon_home_nav_friendly.png Bestand weergeven

Before After
Width: 60  |  Height: 60  |  Size: 2.2KB

BIN
app/src/main/res/drawable-hdpi/icon_home_nav_guide.png Bestand weergeven

Before After
Width: 60  |  Height: 60  |  Size: 2.1KB

BIN
app/src/main/res/drawable-hdpi/icon_home_nav_info.png Bestand weergeven

Before After
Width: 60  |  Height: 60  |  Size: 1.9KB

BIN
app/src/main/res/drawable-hdpi/icon_home_nav_map.png Bestand weergeven

Before After
Width: 60  |  Height: 60  |  Size: 2.5KB

BIN
app/src/main/res/drawable-hdpi/icon_home_nav_member.png Bestand weergeven

Before After
Width: 60  |  Height: 60  |  Size: 1.6KB

BIN
app/src/main/res/drawable-hdpi/icon_home_nav_metro.png Bestand weergeven

Before After
Width: 60  |  Height: 60  |  Size: 4.5KB

BIN
app/src/main/res/drawable-hdpi/icon_home_nav_opa.png Bestand weergeven

Before After
Width: 60  |  Height: 60  |  Size: 1.1KB

BIN
app/src/main/res/drawable-hdpi/icon_home_nav_payment.png Bestand weergeven

Before After
Width: 60  |  Height: 60  |  Size: 2.2KB

BIN
app/src/main/res/drawable-hdpi/icon_home_nav_search.png Bestand weergeven

Before After
Width: 60  |  Height: 60  |  Size: 1.5KB

BIN
app/src/main/res/drawable-hdpi/icon_home_nav_sos.png Bestand weergeven

Before After
Width: 60  |  Height: 60  |  Size: 1.6KB

BIN
app/src/main/res/drawable-hdpi/icon_home_nav_user.png Bestand weergeven

Before After
Width: 60  |  Height: 60  |  Size: 1.6KB

BIN
app/src/main/res/drawable-hdpi/icon_info_map.png Bestand weergeven

Before After
Width: 48  |  Height: 48  |  Size: 1.9KB

BIN
app/src/main/res/drawable-hdpi/icon_input_keyboard.png Bestand weergeven

Before After
Width: 27  |  Height: 27  |  Size: 606B

BIN
app/src/main/res/drawable-hdpi/icon_input_list.png Bestand weergeven

Before After
Width: 27  |  Height: 27  |  Size: 581B

BIN
app/src/main/res/drawable-hdpi/icon_input_pen.png Bestand weergeven

Before After
Width: 27  |  Height: 27  |  Size: 572B

BIN
app/src/main/res/drawable-hdpi/icon_input_target.png Bestand weergeven

Before After
Width: 27  |  Height: 27  |  Size: 793B

BIN
app/src/main/res/drawable-hdpi/icon_location_title.png Bestand weergeven

Before After
Width: 33  |  Height: 33  |  Size: 1.1KB

BIN
app/src/main/res/drawable-hdpi/page_help_sos.png Bestand weergeven

Before After
Width: 378  |  Height: 402  |  Size: 26KB

BIN
app/src/main/res/drawable-hdpi/page_info_board_bg.9.png Bestand weergeven

Before After
Width: 494  |  Height: 192  |  Size: 3.4KB

BIN
app/src/main/res/drawable-hdpi/page_info_board_bg2.9.png Bestand weergeven

Before After
Width: 470  |  Height: 272  |  Size: 1.6KB

BIN
app/src/main/res/drawable-hdpi/page_security_off.png Bestand weergeven

Before After
Width: 254  |  Height: 300  |  Size: 30KB

Some files were not shown because too many files changed in this diff

Laden…
Annuleren
Opslaan