@ -0,0 +1,6 @@
|
||||
.gradle |
||||
/local.properties |
||||
/.idea/workspace.xml |
||||
/.idea/libraries |
||||
.DS_Store |
||||
/build |
@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<project version="4"> |
||||
<component name="CompilerConfiguration"> |
||||
<option name="DEFAULT_COMPILER" value="Javac" /> |
||||
<resourceExtensions /> |
||||
<wildcardResourcePatterns> |
||||
<entry name="!?*.java" /> |
||||
<entry name="!?*.form" /> |
||||
<entry name="!?*.class" /> |
||||
<entry name="!?*.groovy" /> |
||||
<entry name="!?*.scala" /> |
||||
<entry name="!?*.flex" /> |
||||
<entry name="!?*.kt" /> |
||||
<entry name="!?*.clj" /> |
||||
</wildcardResourcePatterns> |
||||
<annotationProcessing> |
||||
<profile default="true" name="Default" enabled="false"> |
||||
<processorPath useClasspath="true" /> |
||||
</profile> |
||||
</annotationProcessing> |
||||
</component> |
||||
</project> |
||||
|
@ -0,0 +1,3 @@
|
||||
<component name="CopyrightManager"> |
||||
<settings default="" /> |
||||
</component> |
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<project version="4"> |
||||
<component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" /> |
||||
</project> |
||||
|
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<project version="4"> |
||||
<component name="GradleSettings"> |
||||
<option name="linkedExternalProjectsSettings"> |
||||
<GradleProjectSettings> |
||||
<option name="distributionType" value="LOCAL" /> |
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" /> |
||||
<option name="gradleHome" value="$APPLICATION_HOME_DIR$/gradle/gradle-2.2.1" /> |
||||
<option name="modules"> |
||||
<set> |
||||
<option value="$PROJECT_DIR$" /> |
||||
<option value="$PROJECT_DIR$/app" /> |
||||
<option value="$PROJECT_DIR$/tesseract" /> |
||||
</set> |
||||
</option> |
||||
</GradleProjectSettings> |
||||
</option> |
||||
</component> |
||||
</project> |
||||
|
@ -0,0 +1,12 @@
|
||||
<component name="InspectionProjectProfileManager"> |
||||
<profile version="1.0" is_locked="false"> |
||||
<option name="myName" value="Project Default" /> |
||||
<option name="myLocal" value="false" /> |
||||
<inspection_tool class="AndroidLintInvalidId" enabled="false" level="ERROR" enabled_by_default="false" /> |
||||
<inspection_tool class="AndroidLintRtlHardcoded" enabled="false" level="WARNING" enabled_by_default="false" /> |
||||
<inspection_tool class="LoggerInitializedWithForeignClass" enabled="false" level="WARNING" enabled_by_default="false"> |
||||
<option name="loggerClassName" value="org.apache.log4j.Logger,org.slf4j.LoggerFactory,org.apache.commons.logging.LogFactory,java.util.logging.Logger" /> |
||||
<option name="loggerFactoryMethodName" value="getLogger,getLogger,getLog,getLogger" /> |
||||
</inspection_tool> |
||||
</profile> |
||||
</component> |
@ -0,0 +1,7 @@
|
||||
<component name="InspectionProjectProfileManager"> |
||||
<settings> |
||||
<option name="PROJECT_PROFILE" value="Project Default" /> |
||||
<option name="USE_PROJECT_PROFILE" value="true" /> |
||||
<version value="1.0" /> |
||||
</settings> |
||||
</component> |
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<project version="4"> |
||||
<component name="EntryPointsManager"> |
||||
<entry_points version="2.0" /> |
||||
</component> |
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK"> |
||||
<output url="file://$PROJECT_DIR$/build/classes" /> |
||||
</component> |
||||
</project> |
||||
|
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<project version="4"> |
||||
<component name="ProjectModuleManager"> |
||||
<modules> |
||||
<module fileurl="file://$PROJECT_DIR$/PointsPermis.iml" filepath="$PROJECT_DIR$/PointsPermis.iml" /> |
||||
<module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" /> |
||||
<module fileurl="file://$PROJECT_DIR$/tesseract/tesseract.iml" filepath="$PROJECT_DIR$/tesseract/tesseract.iml" /> |
||||
</modules> |
||||
</component> |
||||
</project> |
||||
|
@ -0,0 +1,5 @@
|
||||
<component name="DependencyValidationManager"> |
||||
<state> |
||||
<option name="SKIP_IMPORT_STATEMENTS" value="false" /> |
||||
</state> |
||||
</component> |
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<project version="4"> |
||||
<component name="VcsDirectoryMappings"> |
||||
<mapping directory="" vcs="" /> |
||||
</component> |
||||
</project> |
||||
|
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" type="JAVA_MODULE" version="4"> |
||||
<component name="FacetManager"> |
||||
<facet type="java-gradle" name="Java-Gradle"> |
||||
<configuration> |
||||
<option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" /> |
||||
</configuration> |
||||
</facet> |
||||
</component> |
||||
<component name="NewModuleRootManager" inherit-compiler-output="false"> |
||||
<output url="file://$MODULE_DIR$/build/classes/main" /> |
||||
<output-test url="file://$MODULE_DIR$/build/classes/test" /> |
||||
<exclude-output /> |
||||
<content url="file://$MODULE_DIR$"> |
||||
<excludeFolder url="file://$MODULE_DIR$/.gradle" /> |
||||
</content> |
||||
<orderEntry type="inheritedJdk" /> |
||||
<orderEntry type="sourceFolder" forTests="false" /> |
||||
</component> |
||||
</module> |
||||
|
@ -0,0 +1,92 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" type="JAVA_MODULE" version="4"> |
||||
<component name="FacetManager"> |
||||
<facet type="android-gradle" name="Android-Gradle"> |
||||
<configuration> |
||||
<option name="GRADLE_PROJECT_PATH" value=":app" /> |
||||
</configuration> |
||||
</facet> |
||||
<facet type="android" name="Android"> |
||||
<configuration> |
||||
<option name="SELECTED_BUILD_VARIANT" value="debug" /> |
||||
<option name="ASSEMBLE_TASK_NAME" value="assembleDebug" /> |
||||
<option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" /> |
||||
<option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugTest" /> |
||||
<option name="SOURCE_GEN_TASK_NAME" value="generateDebugSources" /> |
||||
<option name="TEST_SOURCE_GEN_TASK_NAME" value="generateDebugTestSources" /> |
||||
<option name="ALLOW_USER_CONFIGURATION" value="false" /> |
||||
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" /> |
||||
<option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" /> |
||||
<option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res" /> |
||||
<option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" /> |
||||
</configuration> |
||||
</facet> |
||||
</component> |
||||
<component name="NewModuleRootManager" inherit-compiler-output="false"> |
||||
<output url="file://$MODULE_DIR$/build/intermediates/classes/debug" /> |
||||
<exclude-output /> |
||||
<content url="file://$MODULE_DIR$"> |
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/debug" isTestSource="false" generated="true" /> |
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/debug" isTestSource="false" generated="true" /> |
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" /> |
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" /> |
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" /> |
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/debug" type="java-resource" /> |
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/test/debug" isTestSource="true" generated="true" /> |
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/test/debug" isTestSource="true" generated="true" /> |
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/test/debug" isTestSource="true" generated="true" /> |
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/test/debug" isTestSource="true" generated="true" /> |
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/test/debug" type="java-test-resource" /> |
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/test/debug" type="java-test-resource" /> |
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" /> |
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" /> |
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" /> |
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" /> |
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" /> |
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" /> |
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" /> |
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" /> |
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" /> |
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" /> |
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" /> |
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" /> |
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" /> |
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" /> |
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" /> |
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" /> |
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" /> |
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" /> |
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" /> |
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" /> |
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" /> |
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" /> |
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" /> |
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" /> |
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/coverage-instrumented-classes" /> |
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" /> |
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex" /> |
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex-cache" /> |
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" /> |
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/jacoco" /> |
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaResources" /> |
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/libs" /> |
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/lint" /> |
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" /> |
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/ndk" /> |
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" /> |
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/proguard" /> |
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" /> |
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" /> |
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" /> |
||||
<excludeFolder url="file://$MODULE_DIR$/build/outputs" /> |
||||
<excludeFolder url="file://$MODULE_DIR$/build/tmp" /> |
||||
</content> |
||||
<orderEntry type="jdk" jdkName="Android API 19 Platform" jdkType="Android SDK" /> |
||||
<orderEntry type="sourceFolder" forTests="false" /> |
||||
<orderEntry type="library" exported="" name="jsoup-1.8.1" level="project" /> |
||||
<orderEntry type="library" exported="" name="support-v4-21.0.3" level="project" /> |
||||
<orderEntry type="library" exported="" name="support-annotations-21.0.3" level="project" /> |
||||
<orderEntry type="module" module-name="tesseract" exported="" /> |
||||
</component> |
||||
</module> |
||||
|
@ -0,0 +1,32 @@
|
||||
apply plugin: 'com.android.application' |
||||
|
||||
android { |
||||
compileSdkVersion 19 |
||||
buildToolsVersion '21.1.2' |
||||
defaultConfig { |
||||
applicationId "fr.android.pointspermis" |
||||
minSdkVersion 14 |
||||
targetSdkVersion 19 |
||||
versionCode 1 |
||||
versionName "1.0" |
||||
} |
||||
buildTypes { |
||||
release { |
||||
minifyEnabled false |
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' |
||||
} |
||||
} |
||||
compileOptions { |
||||
sourceCompatibility JavaVersion.VERSION_1_7 |
||||
targetCompatibility JavaVersion.VERSION_1_7 |
||||
} |
||||
productFlavors { |
||||
} |
||||
} |
||||
|
||||
dependencies { |
||||
compile fileTree(include: ['*.jar'], dir: 'libs') |
||||
compile 'com.android.support:support-v4:21.0.3' |
||||
compile project(':tesseract') |
||||
compile files('libs/jsoup-1.8.1.jar') |
||||
} |
@ -0,0 +1,17 @@
|
||||
# Add project specific ProGuard rules here. |
||||
# By default, the flags in this file are appended to flags specified |
||||
# in /opt/android/sdk/tools/proguard/proguard-android.txt |
||||
# You can edit the include path and order by changing the proguardFiles |
||||
# directive in build.gradle. |
||||
# |
||||
# 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 *; |
||||
#} |
@ -0,0 +1,13 @@
|
||||
package fr.android.pointspermis; |
||||
|
||||
import android.app.Application; |
||||
import android.test.ApplicationTestCase; |
||||
|
||||
/** |
||||
* <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a> |
||||
*/ |
||||
public class ApplicationTest extends ApplicationTestCase<Application> { |
||||
public ApplicationTest() { |
||||
super(Application.class); |
||||
} |
||||
} |
@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" |
||||
package="fr.android.pointspermis" > |
||||
|
||||
<!-- permissions --> |
||||
<uses-permission android:name="android.permission.INTERNET"/> |
||||
|
||||
<application |
||||
android:allowBackup="true" |
||||
android:icon="@drawable/ic_launcher" |
||||
android:label="@string/app_name" |
||||
android:theme="@style/AppTheme" > |
||||
<activity |
||||
android:name=".MainActivity" |
||||
android:label="@string/app_name" |
||||
android:launchMode="singleTop" > |
||||
<intent-filter> |
||||
<action android:name="android.intent.action.MAIN" /> |
||||
<category android:name="android.intent.category.LAUNCHER" /> |
||||
</intent-filter> |
||||
</activity> |
||||
<activity |
||||
android:name=".settings.SettingsActivity" |
||||
android:label="@string/title_activity_settings" |
||||
android:parentActivityName=".MainActivity" > |
||||
<!-- The meta-data element is needed for versions lower than 4.1 --> |
||||
<meta-data |
||||
android:name="android.support.PARENT_ACTIVITY" |
||||
android:value=".MainActivity" /> |
||||
</activity> |
||||
</application> |
||||
|
||||
</manifest> |
@ -0,0 +1,16 @@
|
||||
0oO |
||||
lI1 |
||||
cCG |
||||
kK |
||||
pP |
||||
sS |
||||
uU |
||||
vV |
||||
wW |
||||
xX |
||||
yY |
||||
zZ |
||||
Ôó |
||||
Ùù |
||||
Ûû |
||||
Üü |
@ -0,0 +1,7 @@
|
||||
LeadPunc="'([{¡«¿’“ |
||||
TrailPunc=!"'),-.:;?]_}©®»‘” |
||||
NumLeadPunc=#(@[{.-<=>€ |
||||
NumTrailPunc=!%),.:;]_}°<=> |
||||
Operators=*+-/.:,()[]{}<>= |
||||
Digits=0123456789 |
||||
Alphas=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzÀÂÄÆÇÈÉÊËÎÏÔÙÛÜàâäæçèéêëîïñòóôùûüŒœŸfifl |
@ -0,0 +1,13 @@
|
||||
RecoWgt=0.7662 |
||||
SizeWgt=0.0898 |
||||
OODWgt=0.0400 |
||||
NumWgt=0.0513 |
||||
CharBigramsWgt=0.0464 |
||||
MaxSegPerChar=8 |
||||
BeamWidth=10 |
||||
ConvGridSize=48 |
||||
WordUnigramsWgt=0.005 |
||||
MaxWordAspectRatio=20.0000 |
||||
MinSpaceHeightRatio=0.5000 |
||||
MaxSpaceHeightRatio=0.6000 |
||||
HistWindWid=2 |
@ -0,0 +1,308 @@
|
||||
package fr.android.pointspermis; |
||||
|
||||
import android.app.Activity; |
||||
|
||||
import android.app.ActionBar; |
||||
import android.app.AlertDialog; |
||||
import android.app.Fragment; |
||||
import android.app.FragmentManager; |
||||
import android.content.Context; |
||||
import android.content.DialogInterface; |
||||
import android.content.Intent; |
||||
import android.content.SharedPreferences; |
||||
import android.os.Bundle; |
||||
import android.os.StrictMode; |
||||
import android.view.LayoutInflater; |
||||
import android.view.Menu; |
||||
import android.view.MenuItem; |
||||
import android.view.View; |
||||
import android.view.ViewGroup; |
||||
import android.support.v4.widget.DrawerLayout; |
||||
import android.widget.TextView; |
||||
|
||||
import java.io.File; |
||||
import java.util.List; |
||||
|
||||
import fr.android.pointspermis.captcha.Captcha; |
||||
import fr.android.pointspermis.settings.SettingsActivity; |
||||
import fr.android.pointspermis.tools.AssetsTools; |
||||
import fr.android.pointspermis.web.WebTask; |
||||
|
||||
|
||||
public class MainActivity extends Activity |
||||
implements NavigationDrawerFragment.NavigationDrawerCallbacks { |
||||
|
||||
private final Context context = this; |
||||
|
||||
private WebTask webform; |
||||
|
||||
private SharedPreferences prefs; |
||||
private SharedPreferences.Editor editor; |
||||
|
||||
private String solde; |
||||
private String username; |
||||
private String birthday; |
||||
|
||||
/** |
||||
* Fragment managing the behaviors, interactions and presentation of the navigation drawer. |
||||
*/ |
||||
private NavigationDrawerFragment mNavigationDrawerFragment; |
||||
|
||||
private PlaceholderFragment mPlaceholderFrament; |
||||
|
||||
/** |
||||
* Used to store the last screen title. For use in {@link #restoreActionBar()}. |
||||
*/ |
||||
private CharSequence mTitle; |
||||
|
||||
@Override |
||||
protected void onCreate(Bundle savedInstanceState) { |
||||
|
||||
// Routines
|
||||
super.onCreate(savedInstanceState); |
||||
setContentView(R.layout.activity_main); |
||||
|
||||
// Strict thread mode
|
||||
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); |
||||
StrictMode.setThreadPolicy(policy); |
||||
|
||||
// Copy tesseract data to app-specific internal storage (language stuff)
|
||||
copyTesseractData(); |
||||
|
||||
mNavigationDrawerFragment = (NavigationDrawerFragment) |
||||
getFragmentManager().findFragmentById(R.id.navigation_drawer); |
||||
mTitle = getTitle(); |
||||
|
||||
// Set up the drawer.
|
||||
mNavigationDrawerFragment.setUp( |
||||
R.id.navigation_drawer, |
||||
(DrawerLayout) findViewById(R.id.drawer_layout)); |
||||
|
||||
// Load prefs
|
||||
prefs = getSharedPreferences("fr.android.pointspermis", MODE_PRIVATE); |
||||
editor = prefs.edit(); |
||||
|
||||
// Try to get saved values
|
||||
solde = prefs.getString("solde", ""); |
||||
username = prefs.getString("username", ""); |
||||
birthday = prefs.getString("birthday", ""); |
||||
} |
||||
|
||||
public void copyTesseractData() { |
||||
|
||||
// Copy tesseract data to app-specific internal storage (language stuff)
|
||||
File filesDir = getFilesDir(); |
||||
if (!getFilesDir().canRead()) { getFilesDir().setReadable(true); } |
||||
if (!getFilesDir().canWrite()) { getFilesDir().setWritable(true); } |
||||
if (!getFilesDir().exists()) { getFilesDir().mkdir(); } |
||||
boolean dirExists = false; |
||||
for (String fod : getFilesDir().list()) { if (fod.contains(Captcha.TESSBASE_DIR)) { dirExists = true; break; } } |
||||
if (!dirExists && getFilesDir().getFreeSpace() < (31 * 1024 * 1024)) { |
||||
new AlertDialog.Builder(this) |
||||
.setTitle("Erreur fatale !") |
||||
.setMessage("Impossible de copier les données nécessaires au fonctionnement de l'application, "+ |
||||
"veuillez vous assurer de disposer d'au moins 30Mo d'espace de stockage interne disponible.") |
||||
.setCancelable(false) |
||||
.setPositiveButton("OK", new DialogInterface.OnClickListener() { |
||||
public void onClick(DialogInterface dialog, int id) { |
||||
MainActivity.this.finish(); |
||||
} |
||||
}) |
||||
.show(); |
||||
} |
||||
AssetsTools.copyFileOrDir(Captcha.TESSBASE_DIR, filesDir.getPath() + '/', getAssets()); |
||||
} |
||||
|
||||
@Override |
||||
public void onNavigationDrawerItemSelected(int position) { |
||||
// update the main content by replacing fragments
|
||||
FragmentManager fragmentManager = getFragmentManager(); |
||||
|
||||
mPlaceholderFrament = PlaceholderFragment.newInstance(position + 1); |
||||
|
||||
fragmentManager.beginTransaction().replace(R.id.container, mPlaceholderFrament).commit(); |
||||
} |
||||
|
||||
public void onSectionAttached(int number) { |
||||
switch (number) { |
||||
case 1: |
||||
mTitle = getString(R.string.title_home); |
||||
break; |
||||
case 2: |
||||
mTitle = getString(R.string.title_settings); |
||||
Intent i = new Intent(this, SettingsActivity.class); |
||||
startActivity(i); |
||||
break; |
||||
} |
||||
} |
||||
|
||||
public void restoreActionBar() { |
||||
ActionBar actionBar = getActionBar(); |
||||
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD); |
||||
actionBar.setDisplayShowTitleEnabled(true); |
||||
actionBar.setTitle(mTitle); |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public boolean onCreateOptionsMenu(Menu menu) { |
||||
if (!mNavigationDrawerFragment.isDrawerOpen()) { |
||||
// Only show items in the action bar relevant to this screen
|
||||
// if the drawer is not showing. Otherwise, let the drawer
|
||||
// decide what to show in the action bar.
|
||||
getMenuInflater().inflate(R.menu.main, menu); |
||||
restoreActionBar(); |
||||
return true; |
||||
} |
||||
return super.onCreateOptionsMenu(menu); |
||||
} |
||||
|
||||
@Override |
||||
public boolean onOptionsItemSelected(MenuItem item) { |
||||
// Handle action bar item clicks here. The action bar will
|
||||
// automatically handle clicks on the Home/Up button, so long
|
||||
// as you specify a parent activity in AndroidManifest.xml.
|
||||
int id = item.getItemId(); |
||||
|
||||
//noinspection SimplifiableIfStatement
|
||||
if (id == R.id.action_settings) { |
||||
Intent i = new Intent(this, SettingsActivity.class); |
||||
startActivity(i); |
||||
return true; |
||||
} |
||||
|
||||
if (item.getItemId() == R.id.action_refresh) { |
||||
|
||||
// Initialize and execute the WebForm async task
|
||||
webform = new WebTask(context, MainActivity.this); |
||||
webform.execute(prefs.getString(SettingsActivity.DOSSIER1_KEY, ""), |
||||
prefs.getString(SettingsActivity.DOSSIER2_KEY, ""), |
||||
prefs.getString(SettingsActivity.DOSSIER3_KEY, ""), |
||||
prefs.getString(SettingsActivity.CODE_KEY, "") |
||||
); |
||||
return true; |
||||
} |
||||
|
||||
if (item.getItemId() == R.id.action_quit) { |
||||
quit(); |
||||
} |
||||
|
||||
return super.onOptionsItemSelected(item); |
||||
} |
||||
|
||||
/** |
||||
* A placeholder fragment containing a simple view. |
||||
*/ |
||||
public static class PlaceholderFragment extends Fragment { |
||||
/** |
||||
* The fragment argument representing the section number for this |
||||
* fragment. |
||||
*/ |
||||
private static final String ARG_SECTION_NUMBER = "section_number"; |
||||
|
||||
private TextView textViewSolde; |
||||
private TextView textViewUserName; |
||||
private TextView textViewBirthday; |
||||
|
||||
/** |
||||
* Returns a new instance of this fragment for the given section |
||||
* number. |
||||
*/ |
||||
public static PlaceholderFragment newInstance(int sectionNumber) { |
||||
PlaceholderFragment fragment = new PlaceholderFragment(); |
||||
Bundle args = new Bundle(); |
||||
args.putInt(ARG_SECTION_NUMBER, sectionNumber); |
||||
fragment.setArguments(args); |
||||
return fragment; |
||||
} |
||||
|
||||
public PlaceholderFragment() { |
||||
} |
||||
|
||||
public void setInfos(List<String> infos) { |
||||
|
||||
// Show values
|
||||
textViewSolde.setText(infos.get(0)); |
||||
textViewSolde.invalidate(); |
||||
textViewUserName.setText(infos.get(1)); |
||||
textViewUserName.invalidate(); |
||||
textViewBirthday.setText(infos.get(2)); |
||||
textViewBirthday.invalidate(); |
||||
} |
||||
|
||||
@Override |
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, |
||||
Bundle savedInstanceState) { |
||||
View rootView = inflater.inflate(R.layout.fragment_main, container, false); |
||||
|
||||
textViewSolde = (TextView) rootView.findViewById(R.id.textViewSolde); |
||||
textViewUserName = (TextView) rootView.findViewById(R.id.textViewUserName); |
||||
textViewBirthday = (TextView) rootView.findViewById(R.id.textViewBirthday); |
||||
|
||||
return rootView; |
||||
} |
||||
|
||||
@Override |
||||
public void onAttach(Activity activity) { |
||||
super.onAttach(activity); |
||||
((MainActivity) activity).onSectionAttached( |
||||
getArguments().getInt(ARG_SECTION_NUMBER)); |
||||
} |
||||
} |
||||
|
||||
public void setInfos(List<String> infos) { |
||||
|
||||
// Set infos to the fragment
|
||||
mPlaceholderFrament.setInfos(infos); |
||||
} |
||||
|
||||
private void saveUserData() { |
||||
|
||||
editor.putString("solde", solde); |
||||
editor.putString("username", username); |
||||
editor.putString("birthday", birthday); |
||||
editor.commit(); |
||||
} |
||||
|
||||
public void quit() { |
||||
new AlertDialog.Builder(this) |
||||
.setMessage("Quitter ?") |
||||
.setCancelable(false) |
||||
.setPositiveButton("Oui", new DialogInterface.OnClickListener() { |
||||
public void onClick(DialogInterface dialog, int id) { |
||||
|
||||
// Save user data
|
||||
saveUserData(); |
||||
|
||||
// Terminate activity
|
||||
MainActivity.this.finish(); |
||||
} |
||||
}) |
||||
.setNegativeButton("Non", new DialogInterface.OnClickListener() { |
||||
public void onClick(DialogInterface dialog, int id) { |
||||
dialog.dismiss(); |
||||
} |
||||
}) |
||||
.show(); |
||||
} |
||||
|
||||
@Override |
||||
public void onBackPressed() { |
||||
quit(); |
||||
} |
||||
|
||||
@Override |
||||
public void onStop() { |
||||
super.onStop(); |
||||
} |
||||
|
||||
@Override |
||||
public void onResume() { |
||||
super.onResume(); |
||||
} |
||||
|
||||
@Override |
||||
public void onPause() { |
||||
super.onPause(); |
||||
} |
||||
} |
@ -0,0 +1,281 @@
|
||||
package fr.android.pointspermis; |
||||
|
||||
|
||||
import android.app.Activity; |
||||
import android.app.ActionBar; |
||||
import android.app.Fragment; |
||||
import android.support.v4.app.ActionBarDrawerToggle; |
||||
import android.support.v4.view.GravityCompat; |
||||
import android.support.v4.widget.DrawerLayout; |
||||
import android.content.SharedPreferences; |
||||
import android.content.res.Configuration; |
||||
import android.os.Bundle; |
||||
import android.preference.PreferenceManager; |
||||
import android.view.LayoutInflater; |
||||
import android.view.Menu; |
||||
import android.view.MenuInflater; |
||||
import android.view.MenuItem; |
||||
import android.view.View; |
||||
import android.view.ViewGroup; |
||||
import android.widget.AdapterView; |
||||
import android.widget.ArrayAdapter; |
||||
import android.widget.ListView; |
||||
import android.widget.Toast; |
||||
|
||||
/** |
||||
* Fragment used for managing interactions for and presentation of a navigation drawer. |
||||
* See the <a href="https://developer.android.com/design/patterns/navigation-drawer.html#Interaction"> |
||||
* design guidelines</a> for a complete explanation of the behaviors implemented here. |
||||
*/ |
||||
public class NavigationDrawerFragment extends Fragment { |
||||
|
||||
/** |
||||
* Remember the position of the selected item. |
||||
*/ |
||||
private static final String STATE_SELECTED_POSITION = "selected_navigation_drawer_position"; |
||||
|
||||
/** |
||||
* Per the design guidelines, you should show the drawer on launch until the user manually |
||||
* expands it. This shared preference tracks this. |
||||
*/ |
||||
private static final String PREF_USER_LEARNED_DRAWER = "navigation_drawer_learned"; |
||||
|
||||
/** |
||||
* A pointer to the current callbacks instance (the Activity). |
||||
*/ |
||||
private NavigationDrawerCallbacks mCallbacks; |
||||
|
||||
/** |
||||
* Helper component that ties the action bar to the navigation drawer. |
||||
*/ |
||||
private ActionBarDrawerToggle mDrawerToggle; |
||||
|
||||
private DrawerLayout mDrawerLayout; |
||||
private ListView mDrawerListView; |
||||
private View mFragmentContainerView; |
||||
|
||||
private int mCurrentSelectedPosition = 0; |
||||
private boolean mFromSavedInstanceState; |
||||
private boolean mUserLearnedDrawer; |
||||
|
||||
public NavigationDrawerFragment() { |
||||
} |
||||
|
||||
@Override |
||||
public void onCreate(Bundle savedInstanceState) { |
||||
super.onCreate(savedInstanceState); |
||||
|
||||
// Read in the flag indicating whether or not the user has demonstrated awareness of the
|
||||
// drawer. See PREF_USER_LEARNED_DRAWER for details.
|
||||
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getActivity()); |
||||
mUserLearnedDrawer = sp.getBoolean(PREF_USER_LEARNED_DRAWER, false); |
||||
|
||||
if (savedInstanceState != null) { |
||||
mCurrentSelectedPosition = savedInstanceState.getInt(STATE_SELECTED_POSITION); |
||||
mFromSavedInstanceState = true; |
||||
} |
||||
|
||||
// Select either the default item (0) or the last selected item.
|
||||
selectItem(mCurrentSelectedPosition); |
||||
} |
||||
|
||||
@Override |
||||
public void onActivityCreated(Bundle savedInstanceState) { |
||||
super.onActivityCreated(savedInstanceState); |
||||
// Indicate that this fragment would like to influence the set of actions in the action bar.
|
||||
setHasOptionsMenu(true); |
||||
} |
||||
|
||||
@Override |
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, |
||||
Bundle savedInstanceState) { |
||||
mDrawerListView = (ListView) inflater.inflate( |
||||
R.layout.fragment_navigation_drawer, container, false); |
||||
mDrawerListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { |
||||
@Override |
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) { |
||||
selectItem(position); |
||||
} |
||||
}); |
||||
mDrawerListView.setAdapter(new ArrayAdapter<String>( |
||||
getActionBar().getThemedContext(), |
||||
android.R.layout.simple_list_item_activated_1, |
||||
android.R.id.text1, |
||||
new String[]{ |
||||
getString(R.string.title_home), |
||||
getString(R.string.title_settings), |
||||
})); |
||||
mDrawerListView.setItemChecked(mCurrentSelectedPosition, true); |
||||
return mDrawerListView; |
||||
} |
||||
|
||||
public boolean isDrawerOpen() { |
||||
return mDrawerLayout != null && mDrawerLayout.isDrawerOpen(mFragmentContainerView); |
||||
} |
||||
|
||||
/** |
||||
* Users of this fragment must call this method to set up the navigation drawer interactions. |
||||
* |
||||
* @param fragmentId The android:id of this fragment in its activity's layout. |
||||
* @param drawerLayout The DrawerLayout containing this fragment's UI. |
||||
*/ |
||||
public void setUp(int fragmentId, DrawerLayout drawerLayout) { |
||||
mFragmentContainerView = getActivity().findViewById(fragmentId); |
||||
mDrawerLayout = drawerLayout; |
||||
|
||||
// set a custom shadow that overlays the main content when the drawer opens
|
||||
mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START); |
||||
// set up the drawer's list view with items and click listener
|
||||
|
||||
ActionBar actionBar = getActionBar(); |
||||
actionBar.setDisplayHomeAsUpEnabled(true); |
||||
actionBar.setHomeButtonEnabled(true); |
||||
|
||||
// ActionBarDrawerToggle ties together the the proper interactions
|
||||
// between the navigation drawer and the action bar app icon.
|
||||
mDrawerToggle = new ActionBarDrawerToggle( |
||||
getActivity(), /* host Activity */ |
||||
mDrawerLayout, /* DrawerLayout object */ |
||||
R.drawable.ic_drawer, /* nav drawer image to replace 'Up' caret */ |
||||
R.string.navigation_drawer_open, /* "open drawer" description for accessibility */ |
||||
R.string.navigation_drawer_close /* "close drawer" description for accessibility */ |
||||
) { |
||||
@Override |
||||
public void onDrawerClosed(View drawerView) { |
||||
super.onDrawerClosed(drawerView); |
||||
if (!isAdded()) { |
||||
return; |
||||
} |
||||
|
||||
getActivity().invalidateOptionsMenu(); // calls onPrepareOptionsMenu()
|
||||
} |
||||
|
||||
@Override |
||||
public void onDrawerOpened(View drawerView) { |
||||
super.onDrawerOpened(drawerView); |
||||
if (!isAdded()) { |
||||
return; |
||||
} |
||||
|
||||
if (!mUserLearnedDrawer) { |
||||
// The user manually opened the drawer; store this flag to prevent auto-showing
|
||||
// the navigation drawer automatically in the future.
|
||||
mUserLearnedDrawer = true; |
||||
SharedPreferences sp = PreferenceManager |
||||
.getDefaultSharedPreferences(getActivity()); |
||||
sp.edit().putBoolean(PREF_USER_LEARNED_DRAWER, true).apply(); |
||||
} |
||||
|
||||
getActivity().invalidateOptionsMenu(); // calls onPrepareOptionsMenu()
|
||||
} |
||||
}; |
||||
|
||||
// If the user hasn't 'learned' about the drawer, open it to introduce them to the drawer,
|
||||
// per the navigation drawer design guidelines.
|
||||
if (!mUserLearnedDrawer && !mFromSavedInstanceState) { |
||||
mDrawerLayout.openDrawer(mFragmentContainerView); |
||||
} |
||||
|
||||
// Defer code dependent on restoration of previous instance state.
|
||||
mDrawerLayout.post(new Runnable() { |
||||
@Override |
||||
public void run() { |
||||
mDrawerToggle.syncState(); |
||||
} |
||||
}); |
||||
|
||||
mDrawerLayout.setDrawerListener(mDrawerToggle); |
||||
} |
||||
|
||||
private void selectItem(int position) { |
||||
mCurrentSelectedPosition = position; |
||||
if (mDrawerListView != null) { |
||||
mDrawerListView.setItemChecked(position, true); |
||||
} |
||||
if (mDrawerLayout != null) { |
||||
mDrawerLayout.closeDrawer(mFragmentContainerView); |
||||
} |
||||
if (mCallbacks != null) { |
||||
mCallbacks.onNavigationDrawerItemSelected(position); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void onAttach(Activity activity) { |
||||
super.onAttach(activity); |
||||
try { |
||||
mCallbacks = (NavigationDrawerCallbacks) activity; |
||||
} catch (ClassCastException e) { |
||||
throw new ClassCastException("Activity must implement NavigationDrawerCallbacks."); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void onDetach() { |
||||
super.onDetach(); |
||||
mCallbacks = null; |
||||
} |
||||
|
||||
@Override |
||||
public void onSaveInstanceState(Bundle outState) { |
||||
super.onSaveInstanceState(outState); |
||||
outState.putInt(STATE_SELECTED_POSITION, mCurrentSelectedPosition); |
||||
} |
||||
|
||||
@Override |
||||
public void onConfigurationChanged(Configuration newConfig) { |
||||
super.onConfigurationChanged(newConfig); |
||||
// Forward the new configuration the drawer toggle component.
|
||||
mDrawerToggle.onConfigurationChanged(newConfig); |
||||
} |
||||
|
||||
@Override |
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { |
||||
// If the drawer is open, show the global app actions in the action bar. See also
|
||||
// showGlobalContextActionBar, which controls the top-left area of the action bar.
|
||||
if (mDrawerLayout != null && isDrawerOpen()) { |
||||
inflater.inflate(R.menu.global, menu); |
||||
showGlobalContextActionBar(); |
||||
} |
||||
super.onCreateOptionsMenu(menu, inflater); |
||||
} |
||||
|
||||
@Override |
||||
public boolean onOptionsItemSelected(MenuItem item) { |
||||
if (mDrawerToggle.onOptionsItemSelected(item)) { |
||||
return true; |
||||
} |
||||
/* |
||||
if (item.getItemId() == R.id.action_refresh) { |
||||
Toast.makeText(getActivity(), "Actualisation..", Toast.LENGTH_SHORT).show(); |
||||
return true; |
||||
} |
||||
*/ |
||||
return super.onOptionsItemSelected(item); |
||||
} |
||||
|
||||
/** |
||||
* Per the navigation drawer design guidelines, updates the action bar to show the global app |
||||
* 'context', rather than just what's in the current screen. |
||||
*/ |
||||
private void showGlobalContextActionBar() { |
||||
ActionBar actionBar = getActionBar(); |
||||
actionBar.setDisplayShowTitleEnabled(true); |
||||
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD); |
||||
actionBar.setTitle(R.string.app_name); |
||||
} |
||||
|
||||
private ActionBar getActionBar() { |
||||
return getActivity().getActionBar(); |
||||
} |
||||
|
||||
/** |
||||
* Callbacks interface that all activities using this fragment must implement. |
||||
*/ |
||||
public static interface NavigationDrawerCallbacks { |
||||
/** |
||||
* Called when an item in the navigation drawer is selected. |
||||
*/ |
||||
void onNavigationDrawerItemSelected(int position); |
||||
} |
||||
} |
@ -0,0 +1,50 @@
|
||||
package fr.android.pointspermis.captcha; |
||||
|
||||
import android.graphics.Bitmap; |
||||
import android.util.Log; |
||||
|
||||
import com.googlecode.tesseract.android.TessBaseAPI; |
||||
|
||||
/** |
||||
* Created by vins on 07/01/15. |
||||
*/ |
||||
public class Captcha { |
||||
|
||||
public static final String TESSBASE_DIR = "tesseract"; |
||||
public static final String DEFAULT_LANGUAGE = "fra"; |
||||
|
||||
private String dataDir; |
||||
|
||||
public Captcha(String dataDir) { |
||||
this.dataDir = dataDir; |
||||
} |
||||
|
||||
public String getCode(Bitmap img) { |
||||
|
||||
String code = null; |
||||
TessBaseAPI baseApi = null; |
||||
|
||||
try { |
||||
// Attempt to initialize the API.
|
||||
baseApi = new TessBaseAPI(); |
||||
|
||||
// Init the API
|
||||
baseApi.init(dataDir + "/" + TESSBASE_DIR, DEFAULT_LANGUAGE); |
||||
baseApi.setPageSegMode(TessBaseAPI.PageSegMode.PSM_SINGLE_LINE); |
||||
baseApi.setImage(img); |
||||
|
||||
// Get UTF8 decoding
|
||||
code = baseApi.getUTF8Text().replace(" ", ""); |
||||
//Log.d("DEBUG", "Code: " + code);
|
||||
|
||||
// Attempt to shut down the API.
|
||||
baseApi.end(); |
||||
} catch (Exception e) { |
||||
Log.e("ERROR", "Error during the captcha recognition process:" + e.getMessage()); |
||||
} |
||||
finally { |
||||
// Attempt to shut down the API and return the code.
|
||||
try {baseApi.end();}catch(Exception e){}finally{return code;} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,188 @@
|
||||
package fr.android.pointspermis.settings; |
||||
|
||||
import android.app.AlertDialog; |
||||
import android.content.Context; |
||||
import android.content.DialogInterface; |
||||
import android.content.SharedPreferences; |
||||
import android.preference.DialogPreference; |
||||
import android.util.AttributeSet; |
||||
import android.view.View; |
||||
import android.view.inputmethod.InputMethodManager; |
||||
import android.widget.EditText; |
||||
|
||||
import fr.android.pointspermis.R; |
||||
|
||||
/** |
||||
* Created by vins on 27/01/15. |
||||
*/ |
||||
public class DossierDialogPreference extends DialogPreference { |
||||
|
||||
private final DossierDialogPreference me = this; |
||||
private final Context context; |
||||
|
||||
private SharedPreferences prefs; |
||||
private SharedPreferences.Editor editor; |
||||
|
||||
private String dossier1, dossier2, dossier3; |
||||
private EditText editTextDossier1, editTextDossier2, editTextDossier3; |
||||
|
||||
|
||||
public DossierDialogPreference(Context context, AttributeSet attrs) { |
||||
|
||||
super(context,attrs); |
||||
this.context = context; |
||||
|
||||
prefs = context.getSharedPreferences("fr.android.pointspermis", Context.MODE_PRIVATE); |
||||
editor = prefs.edit(); |
||||
|
||||
// Try to get old saved values
|
||||
dossier1 = prefs.getString(context.getString(R.string.pref_key_dossier1), ""); |
||||
dossier2 = prefs.getString(context.getString(R.string.pref_key_dossier2), ""); |
||||
dossier3 = prefs.getString(context.getString(R.string.pref_key_dossier3), ""); |
||||
|
||||
// Update summary
|
||||
updateSummary(); |
||||
|
||||
// Default saving behaviour => useless
|
||||
//setPersistent(true);
|
||||
|
||||
// Set the custom layout
|
||||
setDialogLayoutResource(R.layout.dossier_dialog); |
||||
} |
||||
|
||||
public void updateSummary() { |
||||
setSummary(dossier1 + " " + dossier2 + " " + dossier3); |
||||
} |
||||
|
||||
public String getDossier1() { |
||||
return dossier1; |
||||
} |
||||
|
||||
public String getDossier2() { |
||||
return dossier2; |
||||
} |
||||
|
||||
public String getDossier3() { |
||||
return dossier3; |
||||
} |
||||
|
||||
@Override |
||||
protected void onPrepareDialogBuilder(AlertDialog.Builder builder) { |
||||
|
||||
builder.setTitle(R.string.pref_title_dossier); |
||||
builder.setPositiveButton(R.string.action_valid, new DialogInterface.OnClickListener() { |
||||
@Override |
||||
public void onClick(DialogInterface di, int i) { |
||||
|
||||
// Get parameters
|
||||
dossier1 = editTextDossier1.getText().toString(); |
||||
dossier2 = editTextDossier2.getText().toString(); |
||||
dossier3 = editTextDossier3.getText().toString(); |
||||
|
||||
// Update summary
|
||||
updateSummary(); |
||||
|
||||
// Save parameters
|
||||
editor.putString(context.getString(R.string.pref_key_dossier1), dossier1); |
||||
editor.putString(context.getString(R.string.pref_key_dossier2), dossier2); |
||||
editor.putString(context.getString(R.string.pref_key_dossier3), dossier3); |
||||
editor.putString(context.getString(R.string.pref_key_dossier), |
||||
dossier1 + " " + dossier2 + " " + dossier3); |
||||
editor.commit(); |
||||
|
||||
// Trigger the onPreferenceChange event
|
||||
getOnPreferenceChangeListener().onPreferenceChange(me, ""); |
||||
|
||||
di.dismiss(); |
||||
} |
||||
}); |
||||
builder.setNegativeButton(R.string.action_cancel, new DialogInterface.OnClickListener() { |
||||
@Override |
||||
public void onClick(DialogInterface di, int i) { |
||||
di.cancel(); |
||||
} |
||||
}); |
||||
|
||||
super.onPrepareDialogBuilder(builder); |
||||
} |
||||
|
||||
@Override |
||||
protected void onBindDialogView(View view) { |
||||
|
||||
// Trigger the onPreferenceChange event
|
||||
getOnPreferenceChangeListener().onPreferenceChange(me, ""); |
||||
|
||||
/** Set fixed EditText width, keyboard behaviour on focus and previous values ! **/ |
||||
|
||||
editTextDossier1 = (EditText)view.findViewById(R.id.editTextDossier1); |
||||
editTextDossier1.setMinWidth(editTextDossier1.getWidth()); |
||||
editTextDossier1.setMaxWidth(editTextDossier1.getWidth()); |
||||
editTextDossier1.setOnFocusChangeListener(new View.OnFocusChangeListener() { |
||||
public void onFocusChange(View v, boolean hasFocus) { |
||||
if (hasFocus) { |
||||
setImeVisibility(v, editTextDossier1, true); |
||||
}/* else { |
||||
setImeVisibility(v, editTextDossier1, false); |
||||
}*/ |
||||
} |
||||
}); |
||||
editTextDossier1.setText(dossier1); |
||||
|
||||
editTextDossier2 = (EditText)view.findViewById(R.id.editTextDossier2); |
||||
editTextDossier2.setMinWidth(editTextDossier2.getWidth()); |
||||
editTextDossier2.setMaxWidth(editTextDossier2.getWidth()); |
||||
editTextDossier2.setOnFocusChangeListener(new View.OnFocusChangeListener() { |
||||
public void onFocusChange(View v, boolean hasFocus) { |
||||
if (hasFocus) { |
||||
setImeVisibility(v, editTextDossier2, true); |
||||
}/* else { |
||||
setImeVisibility(v, editTextDossier2, false); |
||||
}*/ |
||||
} |
||||
}); |
||||
editTextDossier2.setText(dossier2); |
||||
|
||||
editTextDossier3 = (EditText)view.findViewById(R.id.editTextDossier3); |
||||
editTextDossier3.setMinWidth(editTextDossier3.getWidth()); |
||||
editTextDossier3.setMaxWidth(editTextDossier3.getWidth()); |
||||
editTextDossier3.setOnFocusChangeListener(new View.OnFocusChangeListener() { |
||||
public void onFocusChange(View v, boolean hasFocus) { |
||||
if (hasFocus) { |
||||
setImeVisibility(v, editTextDossier3, true); |
||||
}/* else { |
||||
setImeVisibility(v, editTextDossier3, false); |
||||
}*/ |
||||
} |
||||
}); |
||||
editTextDossier3.setText(dossier3); |
||||
|
||||
super.onBindDialogView(view); |
||||
} |
||||
|
||||
// Nice method to show/hide the virtual keyboard, extracted from the Google's 4.1 source code
|
||||
private void setImeVisibility(View v, final EditText editText, final boolean visible) { |
||||
|
||||
Runnable mShowImeRunnable = new Runnable() { |
||||
public void run() { |
||||
InputMethodManager imm = (InputMethodManager) getContext() |
||||
.getSystemService(Context.INPUT_METHOD_SERVICE); |
||||
|
||||
if (imm != null) { |
||||
imm.showSoftInput(editText, 0); |
||||
} |
||||
} |
||||
}; |
||||
|
||||
if (visible) { |
||||
v.post(mShowImeRunnable); |
||||
} else { |
||||
v.removeCallbacks(mShowImeRunnable); |
||||
InputMethodManager imm = (InputMethodManager) getContext() |
||||
.getSystemService(Context.INPUT_METHOD_SERVICE); |
||||
|
||||
if (imm != null) { |
||||
imm.hideSoftInputFromWindow(v.getWindowToken(), 0); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,362 @@
|
||||
package fr.android.pointspermis.settings; |
||||
|
||||
import android.annotation.TargetApi; |
||||
import android.content.Context; |
||||
import android.content.SharedPreferences; |
||||
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.PreferenceFragment; |
||||
import android.preference.PreferenceManager; |
||||
import android.support.v4.app.NavUtils; |
||||
import android.text.TextUtils; |
||||
import android.view.MenuItem; |
||||
|
||||
|
||||
import java.util.List; |
||||
|
||||
import fr.android.pointspermis.R; |
||||
|
||||
/** |
||||
* 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 { |
||||
|
||||
public static String DOSSIER_KEY; |
||||
public static String DOSSIER1_KEY; |
||||
public static String DOSSIER2_KEY; |
||||
public static String DOSSIER3_KEY; |
||||
public static String CODE_KEY; |
||||
public static String NOTIFICATION_KEY; |
||||
public static String FREQUENCY_KEY; |
||||
public static String RINGTONE_KEY; |
||||
public static String VIBRATE_KEY; |
||||
|
||||
/** |
||||
* 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; |
||||
|
||||
// Shared Prefs
|
||||
private SharedPreferences prefs; |
||||
private static SharedPreferences.Editor editor; |
||||
|
||||
|
||||
@Override |
||||
public void onCreate(Bundle savedInstanceState) { |
||||
super.onCreate(savedInstanceState); |
||||
|
||||
// Shared prefs
|
||||
prefs = getSharedPreferences("fr.android.pointspermis", MODE_PRIVATE); |
||||
editor = prefs.edit(); |
||||
|
||||
// Get the key name of settings elements
|
||||
DOSSIER_KEY = getString(R.string.pref_key_dossier); |
||||
DOSSIER1_KEY = getString(R.string.pref_key_dossier1); |
||||
DOSSIER2_KEY = getString(R.string.pref_key_dossier2); |
||||
DOSSIER3_KEY = getString(R.string.pref_key_dossier3); |
||||
CODE_KEY = getString(R.string.pref_key_code); |
||||
NOTIFICATION_KEY = getString(R.string.pref_key_enable_notifications); |
||||
FREQUENCY_KEY = getString(R.string.pref_key_sync_frequency); |
||||
RINGTONE_KEY = getString(R.string.pref_key_ringtone); |
||||
VIBRATE_KEY = getString(R.string.pref_key_vibrate); |
||||
} |
||||
|
||||
@Override |
||||
protected void onPostCreate(Bundle savedInstanceState) { |
||||
super.onPostCreate(savedInstanceState); |
||||
|
||||
// Add the 'go back' navigation button (top left)
|
||||
getActionBar().setDisplayHomeAsUpEnabled(true); |
||||
|
||||
// Show the settings
|
||||
setupSimplePreferencesScreen(); |
||||
} |
||||
|
||||
@Override |
||||
public boolean onOptionsItemSelected(MenuItem item) { |
||||
switch (item.getItemId()) { |
||||
// Respond to the action bar's Up/Home button
|
||||
case android.R.id.home: |
||||
NavUtils.navigateUpFromSameTask(this); |
||||
return true; |
||||
} |
||||
return super.onOptionsItemSelected(item); |
||||
} |
||||
|
||||
/** |
||||
* 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; |
||||
} |
||||
|
||||
// In the simplified UI, fragments are not used at all and we instead
|
||||
// use the older PreferenceActivity APIs.
|
||||
|
||||
// Add 'connection' preferences.
|
||||
addPreferencesFromResource(R.xml.pref_connection); |
||||
|
||||
// Add 'notifications' preferences, and a corresponding header.
|
||||
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.
|
||||
manageValueAndSummary(findPreference(DOSSIER_KEY)); |
||||
manageValueAndSummary(findPreference(CODE_KEY)); |
||||
manageValueAndSummary(findPreference(NOTIFICATION_KEY)); |
||||
manageValueAndSummary(findPreference(FREQUENCY_KEY)); |
||||
manageValueAndSummary(findPreference(RINGTONE_KEY)); |
||||
manageValueAndSummary(findPreference(VIBRATE_KEY)); |
||||
} |
||||
|
||||
/** |
||||
* A preference value change listener that updates the preference's summary |
||||
* to reflect its new value. |
||||
*/ |
||||
private static Preference.OnPreferenceChangeListener changeListener = new Preference.OnPreferenceChangeListener() { |
||||
@Override |
||||
public boolean onPreferenceChange(Preference preference, Object value) { |
||||
|
||||
if (preference.hasKey()) { |
||||
|
||||
String key = preference.getKey(); |
||||
|
||||
if (key.equals(DOSSIER_KEY)) { |
||||
|
||||
/* No need to save values or update the summary as this is already done in |
||||
* custom dialogPreference, but anyway we still do it .. |
||||
*/ |
||||
|
||||
// Update the summary
|
||||
((DossierDialogPreference) preference).updateSummary(); |
||||
|
||||
// Get and save the dossier number
|
||||
String dossier1 = ((DossierDialogPreference) preference).getDossier1(); |
||||
String dossier2 = ((DossierDialogPreference) preference).getDossier2(); |
||||
String dossier3 = ((DossierDialogPreference) preference).getDossier3(); |
||||
editor.putString(DOSSIER1_KEY, dossier1); |
||||
editor.putString(DOSSIER2_KEY, dossier2); |
||||
editor.putString(DOSSIER3_KEY, dossier3); |
||||
editor.putString(DOSSIER_KEY, dossier1 + " " + dossier2 + " " + dossier3); |
||||
} |
||||
if (key.equals(CODE_KEY)) { |
||||
|
||||
/* Do not change summary: code is private ! */ |
||||
|
||||
// Save the value
|
||||
editor.putString(key, value.toString()); |
||||
} |
||||
if (key.equals(NOTIFICATION_KEY)) { |
||||
|
||||
// For checkbox, just save the value
|
||||
editor.putBoolean(key, ((Boolean)value).booleanValue()); |
||||
} |
||||
if (key.equals(RINGTONE_KEY)) { |
||||
|
||||
// For ringtone preferences, look up the correct display value
|
||||
// using RingtoneManager.
|
||||
if (TextUtils.isEmpty(value.toString())) { |
||||
|
||||
// Empty values correspond to 'silent' (no ringtone).
|
||||
preference.setSummary(R.string.pref_ringtone_silent); |
||||
|
||||
// Save the empty value
|
||||
editor.putString(key, ""); |
||||
|
||||
} else { |
||||
Ringtone ringtone = RingtoneManager.getRingtone( |
||||
preference.getContext(), Uri.parse(value.toString())); |
||||
|
||||
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); |
||||
|
||||
// Save the value
|
||||
editor.putString(key, name); |
||||
} |
||||
} |
||||
} |
||||
if (key.equals(FREQUENCY_KEY)) { |
||||
|
||||
// For list preferences, look up the correct display value in
|
||||
// the preference's 'entries' list.
|
||||
ListPreference listPreference = (ListPreference) preference; |
||||
int index = listPreference.findIndexOfValue(value.toString()); |
||||
|
||||
// Set the summary to reflect the new value.
|
||||
preference.setSummary(listPreference.getEntries()[index]); |
||||
|
||||
// Save the value
|
||||
editor.putString(key, listPreference.getEntries()[index].toString()); |
||||
} |
||||
if (key.equals(VIBRATE_KEY)) { |
||||
|
||||
// For checkbox, just save the value
|
||||
editor.putBoolean(key, ((Boolean)value).booleanValue()); |
||||
} |
||||
|
||||
editor.commit(); |
||||
} |
||||
|
||||
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 #changeListener |
||||
*/ |
||||
private static void manageValueAndSummary(Preference preference) { |
||||
|
||||
// Set the listener to watch for value changes.
|
||||
preference.setOnPreferenceChangeListener(changeListener); |
||||
|
||||
String key = preference.getKey(); |
||||
|
||||
// Trigger the listener immediately with the preference's current value to
|
||||
// update summary on element we want
|
||||
|
||||
// /!\ not for dossier as it is self-managed neither code: not secure /!\
|
||||
|
||||
// Text parameters
|
||||
if (key.equals(RINGTONE_KEY) || key.equals(FREQUENCY_KEY)) { |
||||
|
||||
// Safe list default changes
|
||||
if (!PreferenceManager |
||||
.getDefaultSharedPreferences(preference.getContext()) |
||||
.getString(preference.getKey(), "").equals("") ) { |
||||
|
||||
changeListener.onPreferenceChange(preference, |
||||
PreferenceManager |
||||
.getDefaultSharedPreferences(preference.getContext()) |
||||
.getString(preference.getKey(), "") |
||||
); |
||||
} |
||||
} |
||||
|
||||
// Boolean parameters
|
||||
if (key.equals(NOTIFICATION_KEY) || (key.equals(VIBRATE_KEY))) { |
||||
changeListener.onPreferenceChange(preference, |
||||
PreferenceManager |
||||
.getDefaultSharedPreferences(preference.getContext()) |
||||
.getBoolean(preference.getKey(), false) |
||||
); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 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 ConnectionPreferenceFragment extends PreferenceFragment { |
||||
@Override |
||||
public void onCreate(Bundle savedInstanceState) { |
||||
super.onCreate(savedInstanceState); |
||||
addPreferencesFromResource(R.xml.pref_connection); |
||||
|
||||
// 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.
|
||||
manageValueAndSummary(findPreference(DOSSIER_KEY)); |
||||
manageValueAndSummary(findPreference(CODE_KEY)); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 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.
|
||||
manageValueAndSummary(findPreference(NOTIFICATION_KEY)); |
||||
manageValueAndSummary(findPreference(FREQUENCY_KEY)); |
||||
manageValueAndSummary(findPreference(RINGTONE_KEY)); |
||||
manageValueAndSummary(findPreference(VIBRATE_KEY)); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* {@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); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,93 @@
|
||||
package fr.android.pointspermis.tools; |
||||
|
||||
import android.content.res.AssetManager; |
||||
import android.graphics.Bitmap; |
||||
import android.graphics.BitmapFactory; |
||||
import android.util.Log; |
||||
|
||||
import java.io.*; |
||||
|
||||
/** |
||||
* Created by vins on 08/01/15. |
||||
*/ |
||||
public class AssetsTools { |
||||
|
||||
public static void copyFileOrDir(String path, String dest, AssetManager assetManager) { |
||||
|
||||
String assets[] = null; |
||||
try { |
||||
Log.i("INFO", "copyFileOrDir() " + path); |
||||
assets = assetManager.list(path); |
||||
if (assets.length == 0) { |
||||
copyFile(path, dest, assetManager); |
||||
} else { |
||||
String fullPath = dest + path; |
||||
File dir = new File(fullPath); |
||||
if (!dir.exists() && !path.startsWith("images") && !path.startsWith("sounds") && !path.startsWith("webkit")) |
||||
if (!dir.mkdirs()) |
||||
Log.i("INFO", "could not create dir "+fullPath); |
||||
for (int i = 0; i < assets.length; ++i) { |
||||
String p; |
||||
if (path.equals("")) |
||||
p = ""; |
||||
else |
||||
p = path + "/"; |
||||
|
||||
if (!path.startsWith("images") && !path.startsWith("sounds") && !path.startsWith("webkit")) |
||||
copyFileOrDir(p + assets[i], dest, assetManager); |
||||
} |
||||
} |
||||
} catch (IOException ex) { |
||||
Log.e("ERROR", "I/O Exception", ex); |
||||
} |
||||
} |
||||
|
||||
private static void copyFile(String filename, String dest, AssetManager assetManager) { |
||||
|
||||
InputStream in = null; |
||||
OutputStream out = null; |
||||
String newFileName = null; |
||||
try { |
||||
in = assetManager.open(filename); |
||||
if (filename.endsWith(".jpg")) // extension was added to avoid compression on APK file
|
||||
newFileName = dest + filename.substring(0, filename.length()-4); |
||||
else |
||||
newFileName = dest + filename; |
||||
|
||||
if (!new File(newFileName).exists()) { |
||||
Log.i("INFO", "copyFile() "+filename); |
||||
out = new FileOutputStream(newFileName); |
||||
byte[] buffer = new byte[1024]; |
||||
int read; |
||||
while ((read = in.read(buffer)) != -1) { |
||||
out.write(buffer, 0, read); |
||||
} |
||||
in.close(); |
||||
in = null; |
||||
out.flush(); |
||||
out.close(); |
||||
out = null; |
||||
} |
||||
else { |
||||
Log.i("INFO", filename + " already exists, skipping.."); |
||||
} |
||||
} catch (Exception e) { |
||||
Log.e("ERROR", "Exception in copyFile() of "+newFileName); |
||||
Log.e("ERROR", "Exception in copyFile() "+e.toString()); |
||||
} |
||||
} |
||||
|
||||
public static Bitmap getBitmapFromAsset(String filePath, AssetManager assetManager) { |
||||
|
||||
InputStream istr; |
||||
Bitmap bitmap = null; |
||||
try { |
||||
istr = assetManager.open(filePath); |
||||
bitmap = BitmapFactory.decodeStream(istr); |
||||
} catch (IOException e) { |
||||
Log.e("ERROR", "Unable to get bitmap '" + filePath + "' from assets"); |
||||
} |
||||
|
||||
return bitmap; |
||||
} |
||||
} |
@ -0,0 +1,99 @@
|
||||
package fr.android.pointspermis.web; |
||||
|
||||
import android.util.Log; |
||||
|
||||
import java.io.IOException; |
||||
import java.net.InetAddress; |
||||
import java.net.Socket; |
||||
import java.util.ArrayList; |
||||
import java.util.Arrays; |
||||
import java.util.List; |
||||
|
||||
import javax.net.ssl.HttpsURLConnection; |
||||
import javax.net.ssl.SSLContext; |
||||
import javax.net.ssl.SSLSocket; |
||||
import javax.net.ssl.SSLSocketFactory; |
||||
|
||||
/** |
||||
* Created by vins on 15/01/15. |
||||
*/ |
||||
public class CustomSSL { |
||||
|
||||
private static class CustomSSLSocket extends DelegateSSLSocket { |
||||
|
||||
private CustomSSLSocket(SSLSocket delegate) { |
||||
super(delegate); |
||||
} |
||||
|
||||
@Override |
||||
public void setEnabledProtocols(String[] protocols) { |
||||
if (protocols != null && protocols.length == 1 && "SSLv3".equals(protocols[0])) { |
||||
List<String> enabledProtocols = new ArrayList<>(Arrays.asList(delegate.getEnabledProtocols())); |
||||
if (enabledProtocols.size() > 1) { |
||||
enabledProtocols.remove("SSLv3"); |
||||
Log.d("DEBUG", "Removed SSLv3 from enabled protocols"); |
||||
} else { |
||||
Log.d("DEBUG", "SSL stuck with protocol available for " + String.valueOf(enabledProtocols)); |
||||
} |
||||
protocols = enabledProtocols.toArray(new String[enabledProtocols.size()]); |
||||
} |
||||
|
||||
super.setEnabledProtocols(protocols); |
||||
} |
||||
} |
||||
|
||||
public static class CustomSSLSocketFactory extends SSLSocketFactory { |
||||
|
||||
private final SSLSocketFactory delegate; |
||||
|
||||
public CustomSSLSocketFactory() { |
||||
this.delegate = HttpsURLConnection.getDefaultSSLSocketFactory(); |
||||
} |
||||
|
||||
public CustomSSLSocketFactory(SSLContext context) { this.delegate = context.getSocketFactory(); } |
||||
|
||||
@Override |
||||
public String[] getDefaultCipherSuites() { |
||||
return delegate.getDefaultCipherSuites(); |
||||
} |
||||
|
||||
@Override |
||||
public String[] getSupportedCipherSuites() { |
||||
return delegate.getSupportedCipherSuites(); |
||||
} |
||||
|
||||
private static Socket makeSocketSafe(Socket socket) { |
||||
if (socket instanceof SSLSocket) { |
||||
socket = new CustomSSLSocket((SSLSocket) socket); |
||||
// Enable all supported cipher
|
||||
((SSLSocket) socket).setEnabledCipherSuites(((SSLSocket) socket).getSupportedCipherSuites()); |
||||
} |
||||
return socket; |
||||
} |
||||
|
||||
@Override |
||||
public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException { |
||||
return makeSocketSafe(delegate.createSocket(s, host, port, autoClose)); |
||||
} |
||||
|
||||
@Override |
||||
public Socket createSocket(String host, int port) throws IOException { |
||||
return makeSocketSafe(delegate.createSocket(host, port)); |
||||
} |
||||
|
||||
@Override |
||||
public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException { |
||||
return makeSocketSafe(delegate.createSocket(host, port, localHost, localPort)); |
||||
} |
||||
|
||||
@Override |
||||
public Socket createSocket(InetAddress host, int port) throws IOException { |
||||
return makeSocketSafe(delegate.createSocket(host, port)); |
||||
} |
||||
|
||||
@Override |
||||
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException { |
||||
return makeSocketSafe(delegate.createSocket(address, port, localAddress, localPort)); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,331 @@
|
||||
package fr.android.pointspermis.web; |
||||
|
||||
import java.io.IOException; |
||||
import java.io.InputStream; |
||||
import java.io.OutputStream; |
||||
import java.net.InetAddress; |
||||
import java.net.SocketAddress; |
||||
import java.net.SocketException; |
||||
import java.nio.channels.SocketChannel; |
||||
|
||||
import javax.net.ssl.HandshakeCompletedListener; |
||||
import javax.net.ssl.SSLParameters; |
||||
import javax.net.ssl.SSLSession; |
||||
import javax.net.ssl.SSLSocket; |
||||
|
||||
/** |
||||
* Created by vins on 15/01/15. |
||||
*/ |
||||
public class DelegateSSLSocket extends SSLSocket { |
||||
|
||||
protected final SSLSocket delegate; |
||||
|
||||
DelegateSSLSocket(SSLSocket delegate) { |
||||
this.delegate = delegate; |
||||
} |
||||
|
||||
@Override |
||||
public String[] getSupportedCipherSuites() { |
||||
return delegate.getSupportedCipherSuites(); |
||||
} |
||||
|
||||
@Override |
||||
public String[] getEnabledCipherSuites() { |
||||
return delegate.getEnabledCipherSuites(); |
||||
} |
||||
|
||||
@Override |
||||
public void setEnabledCipherSuites(String[] suites) { |
||||
delegate.setEnabledCipherSuites(suites); |
||||
} |
||||
|
||||
@Override |
||||
public String[] getSupportedProtocols() { |
||||
return delegate.getSupportedProtocols(); |
||||
} |
||||
|
||||
@Override |
||||
public String[] getEnabledProtocols() { |
||||
return delegate.getEnabledProtocols(); |
||||
} |
||||
|
||||
@Override |
||||
public void setEnabledProtocols(String[] protocols) { |
||||
delegate.setEnabledProtocols(protocols); |
||||
} |
||||
|
||||
@Override |
||||
public SSLSession getSession() { |
||||
return delegate.getSession(); |
||||
} |
||||
|
||||
@Override |
||||
public void addHandshakeCompletedListener(HandshakeCompletedListener listener) { |
||||
delegate.addHandshakeCompletedListener(listener); |
||||
} |
||||
|
||||
@Override |
||||
public void removeHandshakeCompletedListener(HandshakeCompletedListener listener) { |
||||
delegate.removeHandshakeCompletedListener(listener); |
||||
} |
||||
|
||||
@Override |
||||
public void startHandshake() throws IOException { |
||||
delegate.startHandshake(); |
||||
} |
||||
|
||||
@Override |
||||
public void setUseClientMode(boolean mode) { |
||||
delegate.setUseClientMode(mode); |
||||
} |
||||
|
||||
@Override |
||||
public boolean getUseClientMode() { |
||||
return delegate.getUseClientMode(); |
||||
} |
||||
|
||||
@Override |
||||
public void setNeedClientAuth(boolean need) { |
||||
delegate.setNeedClientAuth(need); |
||||
} |
||||
|
||||
@Override |
||||
public void setWantClientAuth(boolean want) { |
||||
delegate.setWantClientAuth(want); |
||||
} |
||||
|
||||
@Override |
||||
public boolean getNeedClientAuth() { |
||||
return delegate.getNeedClientAuth(); |
||||
} |
||||
|
||||
@Override |
||||
public boolean getWantClientAuth() { |
||||
return delegate.getWantClientAuth(); |
||||
} |
||||
|
||||
@Override |
||||
public void setEnableSessionCreation(boolean flag) { |
||||
delegate.setEnableSessionCreation(flag); |
||||
} |
||||
|
||||
@Override |
||||
public boolean getEnableSessionCreation() { |
||||
return delegate.getEnableSessionCreation(); |
||||
} |
||||
|
||||
@Override |
||||
public void bind(SocketAddress localAddr) throws IOException { |
||||
delegate.bind(localAddr); |
||||
} |
||||
|
||||
@Override |
||||
public synchronized void close() throws IOException { |
||||
delegate.close(); |
||||
} |
||||
|
||||
@Override |
||||
public void connect(SocketAddress remoteAddr) throws IOException { |
||||
delegate.connect(remoteAddr); |
||||
} |
||||
|
||||
@Override |
||||
public void connect(SocketAddress remoteAddr, int timeout) throws IOException { |
||||
delegate.connect(remoteAddr, timeout); |
||||
} |
||||
|
||||
@Override |
||||
public SocketChannel getChannel() { |
||||
return delegate.getChannel(); |
||||
} |
||||
|
||||
@Override |
||||
public InetAddress getInetAddress() { |
||||
return delegate.getInetAddress(); |
||||
} |
||||
|
||||
@Override |
||||
public InputStream getInputStream() throws IOException { |
||||
return delegate.getInputStream(); |
||||
} |
||||
|
||||
@Override |
||||
public boolean getKeepAlive() throws SocketException { |
||||
return delegate.getKeepAlive(); |
||||
} |
||||
|
||||
@Override |
||||
public InetAddress getLocalAddress() { |
||||
return delegate.getLocalAddress(); |
||||
} |
||||
|
||||
@Override |
||||
public int getLocalPort() { |
||||
return delegate.getLocalPort(); |
||||
} |
||||
|
||||
@Override |
||||
public SocketAddress getLocalSocketAddress() { |
||||
return delegate.getLocalSocketAddress(); |
||||
} |
||||
|
||||
@Override |
||||
public boolean getOOBInline() throws SocketException { |
||||
return delegate.getOOBInline(); |
||||
} |
||||
|
||||
@Override |
||||
public OutputStream getOutputStream() throws IOException { |
||||
return delegate.getOutputStream(); |
||||
} |
||||
|
||||
@Override |
||||
public int getPort() { |
||||
return delegate.getPort(); |
||||
} |
||||
|
||||
@Override |
||||
public synchronized int getReceiveBufferSize() throws SocketException { |
||||
return delegate.getReceiveBufferSize(); |
||||
} |
||||
|
||||
@Override |
||||
public SocketAddress getRemoteSocketAddress() { |
||||
return delegate.getRemoteSocketAddress(); |
||||
} |
||||
|
||||
@Override |
||||
public boolean getReuseAddress() throws SocketException { |
||||
return delegate.getReuseAddress(); |
||||
} |
||||
|
||||
@Override |
||||
public synchronized int getSendBufferSize() throws SocketException { |
||||
return delegate.getSendBufferSize(); |
||||
} |
||||
|
||||
@Override |
||||
public int getSoLinger() throws SocketException { |
||||
return delegate.getSoLinger(); |
||||
} |
||||
|
||||
@Override |
||||
public synchronized int getSoTimeout() throws SocketException { |
||||
return delegate.getSoTimeout(); |
||||
} |
||||
|
||||
@Override |
||||
public boolean getTcpNoDelay() throws SocketException { |
||||
return delegate.getTcpNoDelay(); |
||||
} |
||||
|
||||
@Override |
||||
public int getTrafficClass() throws SocketException { |
||||
return delegate.getTrafficClass(); |
||||
} |
||||
|
||||
@Override |
||||
public boolean isBound() { |
||||
return delegate.isBound(); |
||||
} |
||||
|
||||
@Override |
||||
public boolean isClosed() { |
||||
return delegate.isClosed(); |
||||
} |
||||
|
||||
@Override |
||||
public boolean isConnected() { |
||||
return delegate.isConnected(); |
||||
} |
||||
|
||||
@Override |
||||
public boolean isInputShutdown() { |
||||
return delegate.isInputShutdown(); |
||||
} |
||||
|
||||
@Override |
||||
public boolean isOutputShutdown() { |
||||
return delegate.isOutputShutdown(); |
||||
} |
||||
|
||||
@Override |
||||
public void sendUrgentData(int value) throws IOException { |
||||
delegate.sendUrgentData(value); |
||||
} |
||||
|
||||
@Override |
||||
public void setKeepAlive(boolean keepAlive) throws SocketException { |
||||
delegate.setKeepAlive(keepAlive); |
||||
} |
||||
|
||||
@Override |
||||
public void setOOBInline(boolean oobinline) throws SocketException { |
||||
delegate.setOOBInline(oobinline); |
||||
} |
||||
|
||||
@Override |
||||
public void setPerformancePreferences(int connectionTime, int latency, int bandwidth) { |
||||
delegate.setPerformancePreferences(connectionTime, latency, bandwidth); |
||||
} |
||||
|
||||
@Override |
||||
public synchronized void setReceiveBufferSize(int size) throws SocketException { |
||||
delegate.setReceiveBufferSize(size); |
||||
} |
||||
|
||||
@Override |
||||
public void setReuseAddress(boolean reuse) throws SocketException { |
||||
delegate.setReuseAddress(reuse); |
||||
} |
||||
|
||||
@Override |
||||
public synchronized void setSendBufferSize(int size) throws SocketException { |
||||
delegate.setSendBufferSize(size); |
||||
} |
||||
|
||||
@Override |
||||
public void setSoLinger(boolean on, int timeout) throws SocketException { |
||||
delegate.setSoLinger(on, timeout); |
||||
} |
||||
|
||||
@Override |
||||
public synchronized void setSoTimeout(int timeout) throws SocketException { |
||||
delegate.setSoTimeout(timeout); |
||||
} |
||||
|
||||
@Override |
||||
public void setSSLParameters(SSLParameters p) { |
||||
delegate.setSSLParameters(p); |
||||
} |
||||
|
||||
@Override |
||||
public void setTcpNoDelay(boolean on) throws SocketException { |
||||
delegate.setTcpNoDelay(on); |
||||
} |
||||
|
||||
@Override |
||||
public void setTrafficClass(int value) throws SocketException { |
||||
delegate.setTrafficClass(value); |
||||
} |
||||
|
||||
@Override |
||||
public void shutdownInput() throws IOException { |
||||
delegate.shutdownInput(); |
||||
} |
||||
|
||||
@Override |
||||
public void shutdownOutput() throws IOException { |
||||
delegate.shutdownOutput(); |
||||
} |
||||
|
||||
@Override |
||||
public String toString() { |
||||
return delegate.toString(); |
||||
} |
||||
|
||||
@Override |
||||
public boolean equals(Object o) { |
||||
return delegate.equals(o); |
||||
} |
||||
} |
@ -0,0 +1,310 @@
|
||||
package fr.android.pointspermis.web; |
||||
|
||||
import android.graphics.Bitmap; |
||||
import android.graphics.BitmapFactory; |
||||
import android.util.Log; |
||||
import org.apache.http.util.ByteArrayBuffer; |
||||
import org.jsoup.Jsoup; |
||||
import org.jsoup.nodes.Document; |
||||
|
||||
import javax.net.ssl.*; |
||||
import java.io.*; |
||||
import java.net.*; |
||||
import java.security.KeyStore; |
||||
import java.security.KeyStoreException; |
||||
import java.security.NoSuchAlgorithmException; |
||||
import java.security.cert.Certificate; |
||||
import java.security.cert.CertificateException; |
||||
import java.security.cert.CertificateFactory; |
||||
import java.security.cert.X509Certificate; |
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* Created by vins on 08/01/15. |
||||
*/ |
||||
public class HTTPSConnect { |
||||
|
||||
private Certificate ca; |
||||
private HttpsURLConnection urlConnection; |
||||
private List<String> cookies; |
||||
|
||||
private static final int READ_TIMEOUT = 10000; |
||||
private static final int CONNECT_TIMEOUT = 15000; |
||||
private static final char PARAMETER_DELIMITER = '&'; |
||||
private static final char PARAMETER_EQUALS_CHAR = '='; |
||||
|
||||
public HTTPSConnect(InputStream certificate) throws Exception { |
||||
|
||||
// Init a list of cookies
|
||||
cookies = new ArrayList<String>(); |
||||
|
||||
// Load certificate
|
||||
try { |
||||
ca = loadCA(certificate); |
||||
} catch (Exception e) { |
||||
throw new Exception("Unable to load CA certificate: " + e.getMessage()); |
||||
} |
||||
|
||||
// Create and set custom SSLSocketFactory (which trust the ca) as the default one
|
||||
try { |
||||
HttpsURLConnection.setDefaultSSLSocketFactory(createSSLSocketFactory(ca)); |
||||
} catch (Exception e) { |
||||
throw new Exception("Unable to create custom SSLSocketFactory: " + e.getMessage()); |
||||
} |
||||
} |
||||
|
||||
private HttpsURLConnection openConnection(String u) throws Exception { |
||||
|
||||
URL url; |
||||
HttpsURLConnection urlConnection; |
||||
|
||||
url = new URL(u); |
||||
urlConnection = (HttpsURLConnection) url.openConnection(); |
||||
|
||||
// Get cookies
|
||||
if(cookies.isEmpty()) { |
||||
cookies = urlConnection.getHeaderFields().get("Set-Cookie"); |
||||
} |
||||
else { |
||||
// Reuse all previous cookies
|
||||
for (String cookie : cookies) { |
||||
urlConnection.addRequestProperty("Cookie", cookie.split(";", 2)[0]); |
||||
} |
||||
} |
||||
|
||||
// Set a custom SSL socket factory
|
||||
//urlConnection.setSSLSocketFactory(socketFactory);
|
||||
|
||||
/* Specify a custom hostname verifier |
||||
HostnameVerifier hostnameVerifier = new HostnameVerifier() { |
||||
@Override |
||||
public boolean verify(String hostname, SSLSession session) { |
||||
HostnameVerifier hv = |
||||
HttpsURLConnection.getDefaultHostnameVerifier(); |
||||
return hv.verify("tele7.interieur.gouv.fr", session); |
||||
} |
||||
}; |
||||
urlConnection.setHostnameVerifier(hostnameVerifier); |
||||
*/ |
||||
|
||||
// Set timeouts
|
||||
urlConnection.setReadTimeout(READ_TIMEOUT); |
||||
urlConnection.setConnectTimeout(CONNECT_TIMEOUT); |
||||
|
||||
return urlConnection; |
||||
} |
||||
|
||||
public void clear() { |
||||
if (urlConnection != null) { |
||||
urlConnection.disconnect(); |
||||
} |
||||
cookies = new ArrayList<String>(); |
||||
} |
||||
|
||||
public Certificate getCertificate() { |
||||
return ca; |
||||
} |
||||
|
||||
private InputStream getPage(String u) throws Exception { |
||||
|
||||
InputStream in; |
||||
urlConnection = openConnection(u); |
||||
|
||||
try { |
||||
in = urlConnection.getInputStream(); |
||||
} catch (IOException e) { |
||||
throw new Exception("Unable to get remote input stream from SSL connection: " + e.getMessage()); |
||||
} |
||||
|
||||
return in; |
||||
} |
||||
|
||||
public Document getHTML(String u) throws Exception { |
||||
|
||||
Document doc = null; |
||||
InputStream in = getPage(u); |
||||
|
||||
try { |
||||
doc = Jsoup.parse(in, null, ""); |
||||
} catch (IOException e) { |
||||
throw new Exception("Unable to parse InputStream html to create the JSoup Document: " + e.getMessage()); |
||||
} |
||||
|
||||
return doc; |
||||
} |
||||
|
||||
public Bitmap getImage(String u) throws Exception { |
||||
|
||||
Bitmap img = null; |
||||
InputStream in = getPage(u); |
||||
|
||||
BufferedInputStream bis = new BufferedInputStream(in, 8190); |
||||
|
||||
ByteArrayBuffer baf = new ByteArrayBuffer(50); |
||||
int current = 0; |
||||
while ((current = bis.read()) != -1) { |
||||
baf.append((byte)current); |
||||
} |
||||
byte[] imageData = baf.toByteArray(); |
||||
|
||||
img = BitmapFactory.decodeByteArray(imageData, 0, imageData.length); |
||||
|
||||
return img; |
||||
} |
||||
|
||||
public Document postData(String u, Map<String, String> urlParams) throws Exception { |
||||
|
||||
Document doc = null; |
||||
HttpsURLConnection urlConnection = openConnection(u); |
||||
String urlParameters = createQueryStringForParameters(urlParams); |
||||
//Log.d("DEBUG", "POST Request params: " + urlParameters);
|
||||
|
||||
try { |
||||
urlConnection.setRequestMethod("POST"); |
||||
urlConnection.setRequestProperty("Content-Type", |
||||
"application/x-www-form-urlencoded"); |
||||
|
||||
urlConnection.setRequestProperty("Content-Length", "" + |
||||
Integer.toString(urlParameters.getBytes().length)); |
||||
urlConnection.setRequestProperty("Content-Language", "fr-FR"); |
||||
|
||||
urlConnection.setUseCaches(false); |
||||
urlConnection.setDoInput(true); |
||||
urlConnection.setDoOutput(true); |
||||
} catch (Exception e) { |
||||
|
||||
e.printStackTrace(); |
||||
return null; |
||||
} |
||||
|
||||
//Send request
|
||||
try { |
||||
DataOutputStream wr = new DataOutputStream(urlConnection.getOutputStream()); |
||||
wr.writeBytes(urlParameters); |
||||
wr.flush(); |
||||
wr.close(); |
||||
} catch (Exception e) { |
||||
throw new Exception("Unable to send the POST request: " + e.getMessage()); |
||||
} |
||||
|
||||
//Get Response
|
||||
InputStream in = urlConnection.getInputStream(); |
||||
try { |
||||
doc = Jsoup.parse(in, null, ""); |
||||
} catch (IOException e) { |
||||
throw new Exception("Unable to parse InputStream html to create the JSoup Document: " + e.getMessage()); |
||||
} |
||||
|
||||
return doc; |
||||
} |
||||
|
||||
private Certificate loadCA(InputStream crt) throws Exception { |
||||
|
||||
Certificate ca; |
||||
CertificateFactory cf; |
||||
|
||||
// Create certificateFactory instance
|
||||
try { |
||||
cf = CertificateFactory.getInstance("X.509"); |
||||
} catch (CertificateException e) { |
||||
throw new Exception("Can not get a X.509 certificate instance: " + e.getMessage()); |
||||
} |
||||
|
||||
// Read and load the certificate
|
||||
InputStream caInput = new BufferedInputStream(crt); |
||||
try { |
||||
ca = cf.generateCertificate(caInput); |
||||
//Log.d("DEBUG", "ca=" + ((X509Certificate) ca).getSubjectDN());
|
||||
} catch (CertificateException e) { |
||||
throw new Exception("Unable to read the certificate X509: " + e.getMessage()); |
||||
} finally { |
||||
try { |
||||
caInput.close(); |
||||
} catch (IOException e) { |
||||
throw new Exception("Can not close the certificate file: " + e.getMessage()); |
||||
} |
||||
} |
||||
|
||||
return ca; |
||||
} |
||||
|
||||
private SSLSocketFactory createSSLSocketFactory(Certificate ca) throws Exception { |
||||
|
||||
SSLContext sslContext; |
||||
CustomSSL.CustomSSLSocketFactory socketFactory; |
||||
KeyStore keyStore; |
||||
TrustManagerFactory tmf; |
||||
|
||||
// Create a KeyStore containing our trusted CAs
|
||||
String keyStoreType = KeyStore.getDefaultType(); |
||||
|
||||
try { |
||||
keyStore = KeyStore.getInstance(keyStoreType); |
||||
} catch (KeyStoreException e) { |
||||
throw new Exception("Can not get KeyStore instance: " + e.getMessage()); |
||||
} |
||||
try { |
||||
keyStore.load(null, null); |
||||
} catch (Exception e) { |
||||
throw new Exception("Error during keystore loading: " + e.getMessage()); |
||||
} |
||||
try { |
||||
keyStore.setCertificateEntry("ca", ca); |
||||
} catch (KeyStoreException e) { |
||||
throw new Exception("Unable to read certificate entry 'ca': " + e.getMessage()); |
||||
} |
||||
|
||||
// Create a TrustManager that trusts the CAs in our KeyStore
|
||||
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); |
||||
try { |
||||
tmf = TrustManagerFactory.getInstance(tmfAlgorithm); |
||||
} catch (NoSuchAlgorithmException e) { |
||||
throw new Exception("Can not get TrustManager instance: " + e.getMessage()); |
||||
} |
||||
try { |
||||
tmf.init(keyStore); |
||||
} catch (KeyStoreException e) { |
||||
throw new Exception("Unable to openConnection keystore from trustmanager: " + e.getMessage()); |
||||
} |
||||
|
||||
// Init a new SSLContext (TLS)
|
||||
sslContext = SSLContext.getInstance("TLS"); |
||||
sslContext.init(null, tmf.getTrustManagers(), null); |
||||
|
||||
// Create the custom SSLSocketFactory
|
||||
socketFactory = new CustomSSL.CustomSSLSocketFactory(sslContext); |
||||
|
||||
return socketFactory; |
||||
} |
||||
|
||||
private String createQueryStringForParameters(Map<String, String> parameters) throws Exception { |
||||
|
||||
StringBuilder parametersAsQueryString = new StringBuilder(); |
||||
|
||||
if (parameters != null) { |
||||
boolean firstParameter = true; |
||||
|
||||
for (String parameterName : parameters.keySet()) { |
||||
|
||||
if (!firstParameter) { |
||||
parametersAsQueryString.append(PARAMETER_DELIMITER); |
||||
} |
||||
|
||||
try { |
||||
parametersAsQueryString |
||||
.append(URLEncoder.encode(parameterName, "UTF-8")) |
||||
.append(PARAMETER_EQUALS_CHAR) |
||||
.append(URLEncoder.encode(parameters.get(parameterName), "UTF-8")); |
||||
} catch (Exception e) { |
||||
throw new Exception("Error during parameters encoding: " + e.getMessage()); |
||||
} |
||||
|
||||
firstParameter = false; |
||||
} |
||||
} |
||||
|
||||
return parametersAsQueryString.toString(); |
||||
} |
||||
} |
@ -0,0 +1,286 @@
|
||||
package fr.android.pointspermis.web; |
||||
|
||||
import android.app.ProgressDialog; |
||||
import android.content.Context; |
||||
import android.graphics.Bitmap; |
||||
import android.os.AsyncTask; |
||||
import android.util.Log; |
||||
import android.widget.Toast; |
||||
import fr.android.pointspermis.MainActivity; |
||||
import fr.android.pointspermis.captcha.Captcha; |
||||
import fr.android.pointspermis.web.HTTPSConnect; |
||||
import org.jsoup.nodes.Document; |
||||
import org.jsoup.select.Elements; |
||||
|
||||
import java.util.*; |
||||
|
||||
/** |
||||
* Created by vins on 07/01/15. |
||||
*/ |
||||
public class WebTask extends AsyncTask<String, String, String> { |
||||
|
||||
private final int RETRY = 3; |
||||
private final int RETRY_CAPTCHA = 15; |
||||
|
||||
private final String IDENTIFICATION_URL = "https://tele7.interieur.gouv.fr/telepoints/identification.do"; |
||||
private final String CONSULTATION_URL = "https://tele7.interieur.gouv.fr/telepoints/consultation.do"; |
||||
private final String CAPTCHA_URL = "https://tele7.interieur.gouv.fr/telepoints/jcaptcha?id=n&rnd="; |
||||
private final String TOKEN_NAME = "org.apache.struts.taglib.html.TOKEN"; |
||||
private final String CERTIFICATE = "tele7.interieur.gouv.fr.cert"; |
||||
|
||||
private final Context context; |
||||
private MainActivity main; |
||||
private ProgressDialog pDialog; |
||||
private List<String> result; |
||||
|
||||
public WebTask(Context context, MainActivity main) { |
||||
this.context = context; |
||||
this.main = main; |
||||
|
||||
result = new ArrayList<>(); |
||||
|
||||
System.setProperty("https.protocols", "TLSv1"); |
||||
} |
||||
|
||||
@Override |
||||
protected String doInBackground(String... inputs) { |
||||
|
||||
int count = 0, captcha = 0; |
||||
List<String> infos = null; |
||||
|
||||
while (count < RETRY && captcha < RETRY_CAPTCHA) { |
||||
infos = getInfos(inputs[0], inputs[1], inputs[2], inputs[3]); |
||||
if (infos == null) { |
||||
// Return null only if a big problem happened
|
||||
return null; |
||||
} |
||||
if (infos.isEmpty()) { |
||||
// Same as previous
|
||||
return null; |
||||
} |
||||
if (infos.size() == 1) { |
||||
if (infos.get(infos.size()-1).equals("RETRY")) { |
||||
captcha++; count = 0; |
||||
continue; |
||||
} |
||||
if (infos.get(infos.size()-1).contains("ERROR")) { |
||||
count++; captcha = 0; |
||||
continue; |
||||
} |
||||
// Also a big problem (should never happen)
|
||||
return null; |
||||
} |
||||
if (infos.size() == 3) { |
||||
result.addAll(infos); |
||||
return "OK"; |
||||
} |
||||
} |
||||
|
||||
// Return the original error
|
||||
return infos.get(0); |
||||
} |
||||
|
||||
public List<String> getInfos(String code1, String code2, String code3, String pwd) { |
||||
|
||||
List<String> infos = new ArrayList<>(); |
||||
result.clear(); |
||||
|
||||
// Create and init a new connection
|
||||
HTTPSConnect connection; |
||||
try { |
||||
connection = new HTTPSConnect(main.getAssets().open(CERTIFICATE)); |
||||
} catch (Exception e) { |
||||
Log.e("ERROR", "Cannot Init HTTPSConnect: " + e.getMessage()); |
||||
return Collections.singletonList("ERROR INIT"); |
||||
} |
||||
|
||||
// Get the identification html page
|
||||
Document docId = null; |
||||
try { |
||||
docId = connection.getHTML(IDENTIFICATION_URL); |
||||
} catch (Exception e) { |
||||
Log.e("ERROR", "Document initialisation error: " + e.getMessage()); |
||||
return Collections.singletonList("ERROR GET"); |
||||
} |
||||
|
||||
// Parse HTML page and retrieve all needed infos
|
||||
String token = docId.body().getElementsByAttributeValue("name", TOKEN_NAME).attr("value"); |
||||
String dossier1_name = docId.body().getElementById("dossier1").attr("name"); |
||||
String dossier2_name = docId.body().getElementById("dossier2").attr("name"); |
||||
String dossier3_name = docId.body().getElementById("dossier3").attr("name"); |
||||
String code_name = docId.body().getElementsByAttributeValue("type", "password").attr("name"); |
||||
String captcha_name = docId.body().getElementsByAttributeValueContaining("name", "captcha_response").attr("name"); |
||||
|
||||
// Generate a random click position over the send button
|
||||
int xMin = 5, xMax = 138; |
||||
int yMin = 5, yMax = 21; |
||||
int x = new Random().nextInt((xMax - xMin) + 1) + xMin; |
||||
int y = new Random().nextInt((yMax - yMin) + 1) + yMin; |
||||
|
||||
// Get the captcha img
|
||||
Bitmap img = null; |
||||
try { |
||||
img = connection.getImage(CAPTCHA_URL + code_name.replace("value(", "").replace("code)", "")); |
||||
} catch (Exception e) { |
||||
Log.e("ERROR", "Image downloading error: " + e.getMessage()); |
||||
return Collections.singletonList("ERROR CAPTCHA"); |
||||
} |
||||
|
||||
// Decoding captcha
|
||||
Captcha captcha = new Captcha(context.getFilesDir().getPath()); |
||||
String code_captcha = captcha.getCode(img); |
||||
if (code_captcha == null) { |
||||
Log.e("ERROR", "Error while decoding captcha"); |
||||
return Collections.singletonList("ERROR OCR"); |
||||
} |
||||
|
||||
// Set request parameters
|
||||
Map<String, String> urlParams = new HashMap<>(); |
||||
urlParams.put("y", Integer.toString(y)); |
||||
urlParams.put("x", Integer.toString(x)); |
||||
urlParams.put(captcha_name, code_captcha); |
||||
urlParams.put(code_name, pwd); |
||||
urlParams.put(dossier3_name, code3); |
||||
urlParams.put(dossier2_name, code2); |
||||
urlParams.put(dossier1_name, code1); |
||||
urlParams.put(TOKEN_NAME, token); |
||||
|
||||
// Send the post request
|
||||
Document docCons = null; |
||||
try { |
||||
docCons = connection.postData(CONSULTATION_URL, urlParams); |
||||
} catch (Exception e) { |
||||
Log.e("ERROR", "POST request error: " + e.getMessage()); |
||||
return Collections.singletonList("ERROR POST"); |
||||
} |
||||
|
||||
// Clean connection cookies
|
||||
connection.clear(); |
||||
|
||||
// Get the solde
|
||||
Elements elts = docCons.getElementsContainingText("SUR UN CAPITAL DE"); |
||||
if (elts != null && !elts.isEmpty()) { |
||||
String solde = elts.get(elts.size()-1).html(); |
||||
solde = solde.substring(0, solde.indexOf(' ')) + " / " + |
||||
solde.substring(solde.lastIndexOf(" ")+1, solde.length()-1); |
||||
Log.i("INFO", "Solde: " + solde); |
||||
infos.add(solde); |
||||
|
||||
// Get the name
|
||||
elts = docCons.getElementsContainingText("Bonjour"); |
||||
if (elts != null && !elts.isEmpty()) { |
||||
String name = elts.get(elts.size()-1).html(); |
||||
name = name.replace("Bonjour, ", ""); |
||||
Log.i("INFO", "Name: " + name); |
||||
infos.add(name); |
||||
|
||||
// Get the birthday
|
||||
elts = docCons.getElementsContainingText("Date de Naissance"); |
||||
if (elts != null && !elts.isEmpty()) { |
||||
String birthday = elts.get(elts.size()-1).html(); |
||||
birthday = birthday.replace("Date de Naissance", "").replace(" ", "").replace(" ", ""); |
||||
Log.i("INFO", "Birthday: " + birthday); |
||||
infos.add(birthday); |
||||
} |
||||
} |
||||
} |
||||
if (infos.size() < 3) { |
||||
elts = docCons.getElementsByClass("rouge12b"); |
||||
if (!elts.isEmpty()) { |
||||
// CAPTCHA ERROR
|
||||
if (elts.get(elts.size()-1).html().contains("Le code de s")) { |
||||
Log.e("ERROR", "Wrong captcha !"); |
||||
return Collections.singletonList("RETRY"); |
||||
} else { // USER ERROR
|
||||
if (elts.get(elts.size()-1).html().contains("Ce dossier n'existe pas")) { |
||||
Log.e("ERROR", "Dossier num is unknown !"); |
||||
return Collections.singletonList("ERROR DOSSIER"); |
||||
} |
||||
if (elts.get(elts.size()-1).html().contains("ro de dossier est incorrect")) { |
||||
Log.e("ERROR", "Dossier num is invalid !"); |
||||
return Collections.singletonList("ERROR DOSSIER"); |
||||
} |
||||
if (elts.get(elts.size()-1).html().contains("Le code confidentiel est incorrect")) { |
||||
Log.e("ERROR", "Personal code is wrong !"); |
||||
return Collections.singletonList("ERROR CODE"); |
||||
} |
||||
Log.e("ERROR", "Unknown error when parsing the result page !"); |
||||
return Collections.singletonList("ERROR UNKNOWN"); |
||||
} |
||||
} |
||||
else { |
||||
Log.e("ERROR", "Unable to parse the result webpage as expected, something has changed !"); |
||||
return Collections.singletonList("ERROR PAGE"); |
||||
} |
||||
} |
||||
else { |
||||
return infos; |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
protected void onPreExecute() { |
||||
pDialog = ProgressDialog.show(context, null, "Connection..", true); |
||||
} |
||||
|
||||
@Override |
||||
protected void onPostExecute(String s) { |
||||
if(pDialog != null ){ |
||||
if(pDialog.isShowing()) { |
||||
pDialog.dismiss(); |
||||
pDialog = null; |
||||
} |
||||
} |
||||
|
||||
if(s != null) { |
||||
if (s.equals("OK")) { |
||||
main.setInfos(result); |
||||
} |
||||
if (s.equals("RETRY")) { |
||||
Toast.makeText(context, "Erreur: Une mise à jour de sécurité empêche la récupération des informations" + |
||||
", veuillez vérifier que l'application est à jour.", Toast.LENGTH_LONG).show(); |
||||
} |
||||
if (s.contains("ERROR")) { |
||||
if (s.contains("DOSSIER")) { |
||||
Toast.makeText(context, "Erreur: Votre numéro de dossier n'existe pas.", Toast.LENGTH_LONG).show(); |
||||
} |
||||
if (s.contains("CODE")) { |
||||
Toast.makeText(context, "Erreur: Votre code personnel est incorrect.", Toast.LENGTH_LONG).show(); |
||||
} |
||||
if (s.contains("INIT")) { |
||||
Toast.makeText(context, "Erreur: Un problème est survenu lors de la préparation de la connexion " + |
||||
"sécurisée au serveur.", Toast.LENGTH_LONG).show(); |
||||
} |
||||
if (s.contains("GET")) { |
||||
Toast.makeText(context, "Erreur: Impossible d'établir de connection, veuillez vérifier votre " + |
||||
"connectivité Internet.", Toast.LENGTH_LONG).show(); |
||||
} |
||||
if (s.contains("CAPTCHA")) { |
||||
Toast.makeText(context, "Erreur: Impossible de récupérer certains éléments, veuillez mettre à " + |
||||
"jour l'application.", Toast.LENGTH_LONG).show(); |
||||
} |
||||
if (s.contains("POST")) { |
||||
Toast.makeText(context, "Erreur: Un problème est survenu lors de l'envoi de la requête au " + |
||||
"serveur, veuillez mettre à jour l'application.", Toast.LENGTH_LONG).show(); |
||||
} |
||||
if (s.contains("OCR")) { |
||||
Toast.makeText(context, "Erreur: Un problème interne est survenu. Essayez de réinstaller " + |
||||
"l'application.", Toast.LENGTH_LONG).show(); |
||||
} |
||||
if (s.contains("PAGE")) { |
||||
Toast.makeText(context, "Erreur: Impossible de récupérer les données, veuillez mettre à jour " + |
||||
"l'application.", Toast.LENGTH_LONG).show(); |
||||
} |
||||
if (s.contains("UNKNOWN")) { |
||||
Toast.makeText(context, "Erreur: Une erreur inconnue est survenue, veuillez mettre à jour " + |
||||
"l'application.", Toast.LENGTH_LONG).show(); |
||||
} |
||||
} |
||||
return; |
||||
} |
||||
|
||||
Log.e("ERROR", "Unable to get result (onPostExecute) from WebForm"); |
||||
Toast.makeText(context, "Erreur: Une erreur fatale est survenue durant la récupération du solde, veuillez " + |
||||
"vérifier que l'application est à jour ou essayez de la réinstaller.", Toast.LENGTH_LONG).show(); |
||||
} |
||||
} |
@ -0,0 +1,3 @@
|
||||
set solib-search-path /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/obj/local/armeabi-v7a |
||||
source /opt/android/android-ndk-r10d/prebuilt/common/gdb/common.setup |
||||
directory /opt/android/android-ndk-r10d/platforms/android-8/arch-arm/usr/include /opt/android/android-ndk-r10d/sources/cxx-stl/gnu-libstdc++ /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_leptonica_android /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_leptonica_android/src/src /opt/android/android-ndk-r10d/sources/cxx-stl/gnu-libstdc++/4.8/include /opt/android/android-ndk-r10d/sources/cxx-stl/gnu-libstdc++/4.8/libs/armeabi-v7a/include /opt/android/android-ndk-r10d/sources/cxx-stl/gnu-libstdc++/4.8/include/backward /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_tesseract_android/src/api /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_tesseract_android/src/ccmain /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_tesseract_android/src/ccstruct /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_tesseract_android/src/ccutil /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_tesseract_android/src/classify /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_tesseract_android/src/cube /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_tesseract_android/src/cutil /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_tesseract_android/src/dict /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_tesseract_android/src/opencl /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_tesseract_android/src/neural_networks/runtime /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_tesseract_android/src/textord /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_tesseract_android/src/viewer /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_tesseract_android/src/wordrec |
@ -0,0 +1,3 @@
|
||||
set solib-search-path /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/obj/local/armeabi |
||||
source /opt/android/android-ndk-r10d/prebuilt/common/gdb/common.setup |
||||
directory /opt/android/android-ndk-r10d/platforms/android-8/arch-arm/usr/include /opt/android/android-ndk-r10d/sources/cxx-stl/gnu-libstdc++ /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_leptonica_android /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_leptonica_android/src/src /opt/android/android-ndk-r10d/sources/cxx-stl/gnu-libstdc++/4.8/include /opt/android/android-ndk-r10d/sources/cxx-stl/gnu-libstdc++/4.8/libs/armeabi/include /opt/android/android-ndk-r10d/sources/cxx-stl/gnu-libstdc++/4.8/include/backward /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_tesseract_android/src/api /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_tesseract_android/src/ccmain /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_tesseract_android/src/ccstruct /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_tesseract_android/src/ccutil /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_tesseract_android/src/classify /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_tesseract_android/src/cube /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_tesseract_android/src/cutil /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_tesseract_android/src/dict /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_tesseract_android/src/opencl /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_tesseract_android/src/neural_networks/runtime /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_tesseract_android/src/textord /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_tesseract_android/src/viewer /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_tesseract_android/src/wordrec |
@ -0,0 +1,3 @@
|
||||
set solib-search-path /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/obj/local/mips |
||||
source /opt/android/android-ndk-r10d/prebuilt/common/gdb/common.setup |
||||
directory /opt/android/android-ndk-r10d/platforms/android-9/arch-mips/usr/include /opt/android/android-ndk-r10d/sources/cxx-stl/gnu-libstdc++ /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_leptonica_android /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_leptonica_android/src/src /opt/android/android-ndk-r10d/sources/cxx-stl/gnu-libstdc++/4.8/include /opt/android/android-ndk-r10d/sources/cxx-stl/gnu-libstdc++/4.8/libs/mips/include /opt/android/android-ndk-r10d/sources/cxx-stl/gnu-libstdc++/4.8/include/backward /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_tesseract_android/src/api /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_tesseract_android/src/ccmain /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_tesseract_android/src/ccstruct /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_tesseract_android/src/ccutil /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_tesseract_android/src/classify /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_tesseract_android/src/cube /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_tesseract_android/src/cutil /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_tesseract_android/src/dict /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_tesseract_android/src/opencl /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_tesseract_android/src/neural_networks/runtime /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_tesseract_android/src/textord /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_tesseract_android/src/viewer /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_tesseract_android/src/wordrec |
@ -0,0 +1,3 @@
|
||||
set solib-search-path /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/obj/local/x86 |
||||
source /opt/android/android-ndk-r10d/prebuilt/common/gdb/common.setup |
||||
directory /opt/android/android-ndk-r10d/platforms/android-9/arch-x86/usr/include /opt/android/android-ndk-r10d/sources/cxx-stl/gnu-libstdc++ /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_leptonica_android /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_leptonica_android/src/src /opt/android/android-ndk-r10d/sources/cxx-stl/gnu-libstdc++/4.8/include /opt/android/android-ndk-r10d/sources/cxx-stl/gnu-libstdc++/4.8/libs/x86/include /opt/android/android-ndk-r10d/sources/cxx-stl/gnu-libstdc++/4.8/include/backward /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_tesseract_android/src/api /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_tesseract_android/src/ccmain /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_tesseract_android/src/ccstruct /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_tesseract_android/src/ccutil /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_tesseract_android/src/classify /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_tesseract_android/src/cube /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_tesseract_android/src/cutil /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_tesseract_android/src/dict /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_tesseract_android/src/opencl /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_tesseract_android/src/neural_networks/runtime /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_tesseract_android/src/textord /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_tesseract_android/src/viewer /home/vins/AndroidStudioProjects/PointsPermis/tesseract/src/main/jni/com_googlecode_tesseract_android/src/wordrec |
After Width: | Height: | Size: 114 B |
After Width: | Height: | Size: 663 B |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 9.2 KiB |
After Width: | Height: | Size: 142 B |
After Width: | Height: | Size: 508 B |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 5.1 KiB |
After Width: | Height: | Size: 174 B |
After Width: | Height: | Size: 895 B |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 208 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 202 B |
After Width: | Height: | Size: 15 KiB |
@ -0,0 +1,25 @@
|
||||
<!-- A DrawerLayout is intended to be used as the top-level content view using match_parent for both width and height to consume the full space available. --> |
||||
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||
xmlns:tools="http://schemas.android.com/tools" android:id="@+id/drawer_layout" |
||||
android:layout_width="match_parent" android:layout_height="match_parent" |
||||
tools:context=".MainActivity"> |
||||
|
||||
<!-- As the main content view, the view below consumes the entire |
||||
space available using match_parent in both dimensions. --> |
||||
<FrameLayout android:id="@+id/container" android:layout_width="match_parent" |
||||
android:layout_height="match_parent" /> |
||||
|
||||
<!-- android:layout_gravity="start" tells DrawerLayout to treat |
||||
this as a sliding drawer on the left side for left-to-right |
||||
languages and on the right side for right-to-left languages. |
||||
If you're not building against API 17 or higher, use |
||||
android:layout_gravity="left" instead. --> |
||||
<!-- The drawer is given a fixed width in dp and extends the full height of |
||||
the container. --> |
||||
<fragment android:id="@+id/navigation_drawer" |
||||
android:layout_width="@dimen/navigation_drawer_width" android:layout_height="match_parent" |
||||
android:layout_gravity="start" |
||||
android:name="fr.android.pointspermis.NavigationDrawerFragment" |
||||
tools:layout="@layout/fragment_navigation_drawer" /> |
||||
|
||||
</android.support.v4.widget.DrawerLayout> |
@ -0,0 +1,63 @@
|
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||
android:layout_width="match_parent" android:layout_height="match_parent"> |
||||
|
||||
<LinearLayout |
||||
android:orientation="horizontal" |
||||
android:layout_width="fill_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_alignParentTop="true" |
||||
android:id="@+id/linearLayout"> |
||||
|
||||
<EditText |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:id="@+id/editTextDossier1" |
||||
android:layout_weight="3.89" |
||||
android:paddingLeft="10dp" |
||||
android:editable="true" |
||||
android:capitalize="characters" |
||||
android:clickable="true" |
||||
android:singleLine="true" |
||||
android:enabled="true" |
||||
android:focusable="true" |
||||
android:focusableInTouchMode="true" |
||||
android:windowSoftInputMode="stateAlwaysVisible" |
||||
android:autoText="true" |
||||
android:lines="1" /> |
||||
|
||||
<EditText |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:id="@+id/editTextDossier2" |
||||
android:layout_weight="1" |
||||
android:editable="true" |
||||
android:capitalize="characters" |
||||
android:clickable="true" |
||||
android:enabled="true" |
||||
android:singleLine="true" |
||||
android:focusable="true" |
||||
android:focusableInTouchMode="true" |
||||
android:windowSoftInputMode="stateAlwaysVisible" |
||||
android:autoText="true" |
||||
android:lines="1" /> |
||||
|
||||
<EditText |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:id="@+id/editTextDossier3" |
||||
android:layout_weight="1" |
||||
android:paddingRight="10dp" |
||||
android:editable="true" |
||||
android:capitalize="characters" |
||||
android:clickable="true" |
||||
android:enabled="true" |
||||
android:singleLine="true" |
||||
android:focusable="true" |
||||
android:focusableInTouchMode="true" |
||||
android:windowSoftInputMode="stateAlwaysVisible" |
||||
android:autoText="true" |
||||
android:lines="1" /> |
||||
</LinearLayout> |
||||
|
||||
</RelativeLayout> |
@ -0,0 +1,37 @@
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" |
||||
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" |
||||
android:paddingRight="@dimen/activity_horizontal_margin" |
||||
android:paddingTop="@dimen/activity_vertical_margin" |
||||
android:paddingBottom="@dimen/activity_vertical_margin" |
||||
tools:context=".MainActivity$PlaceholderFragment" |
||||
android:id="@+id/layout_fragment_main"> |
||||
|
||||
<TextView |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:id="@+id/textViewBirthday" |
||||
android:layout_marginTop="110dp" |
||||
android:layout_below="@+id/textViewUserName" |
||||
android:layout_centerHorizontal="true" /> |
||||
|
||||
<TextView |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:textAppearance="?android:attr/textAppearanceLarge" |
||||
android:id="@+id/textViewSolde" |
||||
android:layout_below="@+id/textViewBirthday" |
||||
android:layout_centerHorizontal="true" |
||||
android:layout_marginTop="99dp" /> |
||||
|
||||
<TextView |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:textAppearance="?android:attr/textAppearanceMedium" |
||||
android:id="@+id/textViewUserName" |
||||
android:layout_alignParentTop="true" |
||||
android:layout_alignLeft="@+id/textViewSolde" |
||||
android:layout_alignStart="@+id/textViewSolde" |
||||
android:layout_marginTop="34dp" /> |
||||
|
||||
</RelativeLayout> |
@ -0,0 +1,5 @@
|
||||
<ListView xmlns:android="http://schemas.android.com/apk/res/android" |
||||
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" |
||||
android:layout_height="match_parent" android:choiceMode="singleChoice" |
||||
android:divider="@android:color/transparent" android:dividerHeight="0dp" |
||||
android:background="#cccc" tools:context=".NavigationDrawerFragment" /> |
@ -0,0 +1,4 @@
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"> |
||||
<item android:id="@+id/action_settings" android:title="@string/action_settings" |
||||
android:orderInCategory="100" android:showAsAction="never" /> |
||||
</menu> |
@ -0,0 +1,15 @@
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android" |
||||
xmlns:tools="http://schemas.android.com/tools" tools:context=".MainActivity"> |
||||
<item |
||||
android:id="@+id/action_refresh" |
||||
android:orderInCategory="100" |
||||
android:icon="@drawable/ic_action_refresh" |
||||
android:showAsAction="withText|ifRoom" |
||||
android:title="@string/action_example"/> |
||||
|
||||
<item android:id="@+id/action_settings" android:title="@string/action_settings" |
||||
android:orderInCategory="100" android:showAsAction="never" /> |
||||
|
||||
<item android:id="@+id/action_quit" android:title="@string/action_quit" |
||||
android:orderInCategory="100" android:showAsAction="never" /> |
||||
</menu> |
@ -0,0 +1,6 @@
|
||||
<resources> |
||||
<!-- Example customization of dimensions originally defined in res/values/dimens.xml |
||||
(such as screen margins) for screens with more than 820dp of available width. This |
||||
would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). --> |
||||
<dimen name="activity_horizontal_margin">64dp</dimen> |
||||
</resources> |
@ -0,0 +1,9 @@
|
||||
<resources> |
||||
<!-- Default screen margins, per the Android Design guidelines. --> |
||||
<dimen name="activity_horizontal_margin">16dp</dimen> |
||||
<dimen name="activity_vertical_margin">16dp</dimen> |
||||
|
||||
<!-- Per the design guidelines, navigation drawers should be between 240dp and 320dp: |
||||
https://developer.android.com/design/patterns/navigation-drawer.html --> |
||||
<dimen name="navigation_drawer_width">240dp</dimen> |
||||
</resources> |
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<resources> |
||||
|
||||
<string name="app_name">PointsPermis</string> |
||||
<string name="title_home">Accueil</string> |
||||
<string name="title_settings">Paramètres</string> |
||||
<string name="title_section3">Section 3</string> |
||||
<string name="navigation_drawer_open">Ouvrir le volet de navigation</string> |
||||
<string name="navigation_drawer_close">Fermer le volet de navigation</string> |
||||
<string name="action_example">Actualiser</string> |
||||
<string name="action_settings">Paramètres</string> |
||||
<string name="action_valid">Valider</string> |
||||
<string name="action_quit">Quitter</string> |
||||
<string name="action_cancel">Annuler</string> |
||||
<string name="action_yes">Oui</string> |
||||
<string name="action_no">Non</string> |
||||
|
||||
</resources> |
@ -0,0 +1,44 @@
|
||||
<resources> |
||||
|
||||
<!-- Strings related to Settings --> |
||||
|
||||
|
||||
<string name="title_activity_settings">Paramètres</string> |
||||
|
||||
<!-- Connection settings --> |
||||
<string name="pref_header_connection">Connexion</string> |
||||
<string name="pref_descr_connection">Configuration de la connexion</string> |
||||
<string name="pref_title_dossier">Numéro de dossier</string> |
||||
<string name="pref_key_dossier">dossier</string> |
||||
<string name="pref_key_dossier1">dossier1</string> |
||||
<string name="pref_key_dossier2">dossier2</string> |
||||
<string name="pref_key_dossier3">dossier3</string> |
||||
<string name="pref_title_code">Code confidentiel</string> |
||||
<string name="pref_key_code">code</string> |
||||
|
||||
<!-- Settings for Notification & Sync --> |
||||
<string name="pref_header_notifications">Notifications</string> |
||||
<string name="pref_descr_notifications">Configuration des notifications</string> |
||||
<string name="pref_title_enable_notifications">Activer les notifications</string> |
||||
<string name="pref_key_enable_notifications">notifications</string> |
||||
<string name="pref_title_sync_frequency">Fréquence de synchronisation</string> |
||||
<string name="pref_key_sync_frequency">sync_frequency</string> |
||||
<string-array name="pref_sync_frequency_titles"> |
||||
<item>Mensuelle</item> |
||||
<item>Bimensuelle</item> |
||||
<item>Hebdomadaire</item> |
||||
<item>Journalière</item> |
||||
</string-array> |
||||
<string-array name="pref_sync_frequency_values"> |
||||
<item>30</item> |
||||
<item>15</item> |
||||
<item>7</item> |
||||
<item>1</item> |
||||
</string-array> |
||||
<string name="pref_title_ringtone">Sonnerie</string> |
||||
<string name="pref_key_ringtone">notifications_ringtone</string> |
||||
<string name="pref_ringtone_silent">Silencieuse</string> |
||||
<string name="pref_title_vibrate">Vibrer</string> |
||||
<string name="pref_key_vibrate">notifications_vibrate</string> |
||||
|
||||
</resources> |
@ -0,0 +1,8 @@
|
||||
<resources> |
||||
|
||||
<!-- Base application theme. --> |
||||
<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar"> |
||||
<!-- Customize your theme here. --> |
||||
</style> |
||||
|
||||
</resources> |
@ -0,0 +1,38 @@
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> |
||||
|
||||
<PreferenceCategory |
||||
android:summary="@string/pref_header_connection" |
||||
android:title="@string/pref_header_connection" > |
||||
|
||||
<!-- NOTE: EditTextPreference accepts EditText attributes. --> |
||||
<!-- NOTE: EditTextPreference's summary should be set to its value by the activity code. --> |
||||
<fr.android.pointspermis.settings.DossierDialogPreference |
||||
android:key="dossier" |
||||
android:title="@string/pref_title_dossier" |
||||
android:summary="Soit un champ, soit les trois !" /> |
||||
<!-- |
||||
<EditTextPreference |
||||
android:key="dossier" |
||||
android:title="@string/pref_title_dossier" |
||||
android:defaultValue="" |
||||
android:selectAllOnFocus="true" |
||||
android:inputType="textCapWords" |
||||
android:capitalize="words" |
||||
android:singleLine="true" |
||||
android:maxLines="1" /> |
||||
--> |
||||
|
||||
<EditTextPreference |
||||
android:key="code" |
||||
android:title="@string/pref_title_code" |
||||
android:defaultValue="" |
||||
android:selectAllOnFocus="true" |
||||
android:capitalize="words" |
||||
android:singleLine="true" |
||||
android:maxLines="1" |
||||
android:inputType="textCapWords" |
||||
android:password="true" /> |
||||
|
||||
</PreferenceCategory> |
||||
|
||||
</PreferenceScreen> |
@ -0,0 +1,12 @@
|
||||
<preference-headers xmlns:android="http://schemas.android.com/apk/res/android"> |
||||
|
||||
<!-- These settings headers are only used on tablets. --> |
||||
|
||||
<header android:fragment="fr.android.pointspermis.settings.SettingsActivity$ConnectionPreferenceFragment" |
||||
android:title="@string/pref_header_connection" /> |
||||
|
||||
<header |
||||
android:fragment="fr.android.pointspermis.settings.SettingsActivity$NotificationPreferenceFragment" |
||||
android:title="@string/pref_header_notifications" /> |
||||
|
||||
</preference-headers> |
@ -0,0 +1,46 @@
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> |
||||
|
||||
<PreferenceCategory |
||||
android:summary="@string/pref_descr_notifications" |
||||
android:title="@string/pref_header_notifications" > |
||||
|
||||
<!-- A 'parent' preference, which enables/disables child preferences (below) |
||||
when checked/unchecked. --> |
||||
<CheckBoxPreference |
||||
android:key="notifications" |
||||
android:title="@string/pref_title_enable_notifications" |
||||
android:defaultValue="false" /> |
||||
|
||||
<!-- NOTE: Hide buttons to simplify the UI. Users can touch outside the dialog to |
||||
dismiss it. --> |
||||
<!-- NOTE: ListPreference's summary should be set to its value by the activity code. --> |
||||
<ListPreference |
||||
android:dependency="notifications" |
||||
android:key="sync_frequency" |
||||
android:title="@string/pref_title_sync_frequency" |
||||
android:entries="@array/pref_sync_frequency_titles" |
||||
android:entryValues="@array/pref_sync_frequency_values" |
||||
android:defaultValue="30" |
||||
android:negativeButtonText="@null" |
||||
android:positiveButtonText="@null" /> |
||||
|
||||
<!-- Allows the user to choose a ringtone in the 'notification' category. --> |
||||
<!-- NOTE: This preference will be enabled only when the checkbox above is checked. --> |
||||
<!-- NOTE: RingtonePreference's summary should be set to its value by the activity code. --> |
||||
<RingtonePreference |
||||
android:dependency="notifications" |
||||
android:key="notifications_ringtone" |
||||
android:title="@string/pref_title_ringtone" |
||||
android:ringtoneType="notification" |
||||
android:defaultValue="content://settings/system/notification_sound" /> |
||||
|
||||
<!-- NOTE: This preference will be enabled only when the checkbox above is checked. --> |
||||
<CheckBoxPreference |
||||
android:dependency="notifications" |
||||
android:key="notifications_vibrate" |
||||
android:title="@string/pref_title_vibrate" |
||||
android:defaultValue="false" /> |
||||
|
||||
</PreferenceCategory> |
||||
|
||||
</PreferenceScreen> |
@ -0,0 +1,19 @@
|
||||
// Top-level build file where you can add configuration options common to all sub-projects/modules. |
||||
|
||||
buildscript { |
||||
repositories { |
||||
jcenter() |
||||
} |
||||
dependencies { |
||||
classpath 'com.android.tools.build:gradle:1.0.0' |
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong |
||||
// in the individual module build.gradle files |
||||
} |
||||
} |
||||
|
||||
allprojects { |
||||
repositories { |
||||
jcenter() |
||||
} |
||||
} |
@ -0,0 +1,18 @@
|
||||
# Project-wide Gradle settings. |
||||
|
||||
# IDE (e.g. Android Studio) users: |
||||
# Gradle settings configured through the IDE *will override* |
||||
# any settings specified in this file. |
||||
|
||||
# For more details on how to configure your build environment visit |
||||
# http://www.gradle.org/docs/current/userguide/build_environment.html |
||||
|
||||
# Specifies the JVM arguments used for the daemon process. |
||||
# The setting is particularly useful for tweaking memory settings. |
||||
# Default value: -Xmx10248m -XX:MaxPermSize=256m |
||||
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 |
||||
|
||||
# When configured, Gradle will run in incubating parallel mode. |
||||
# This option should only be used with decoupled projects. More details, visit |
||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects |
||||
# org.gradle.parallel=true |
@ -0,0 +1,6 @@
|
||||
#Wed Apr 10 15:27:10 PDT 2013 |
||||
distributionBase=GRADLE_USER_HOME |
||||
distributionPath=wrapper/dists |
||||
zipStoreBase=GRADLE_USER_HOME |
||||
zipStorePath=wrapper/dists |
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip |
@ -0,0 +1,164 @@
|
||||
#!/usr/bin/env bash |
||||
|
||||
############################################################################## |
||||
## |
||||
## Gradle start up script for UN*X |
||||
## |
||||
############################################################################## |
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. |
||||
DEFAULT_JVM_OPTS="" |
||||
|
||||
APP_NAME="Gradle" |
||||
APP_BASE_NAME=`basename "$0"` |
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value. |
||||
MAX_FD="maximum" |
||||
|
||||
warn ( ) { |
||||
echo "$*" |
||||
} |
||||
|
||||
die ( ) { |
||||
echo |
||||
echo "$*" |
||||
echo |
||||
exit 1 |
||||
} |
||||
|
||||
# OS specific support (must be 'true' or 'false'). |
||||
cygwin=false |
||||
msys=false |
||||
darwin=false |
||||
case "`uname`" in |
||||
CYGWIN* ) |
||||
cygwin=true |
||||
;; |
||||
Darwin* ) |
||||
darwin=true |
||||
;; |
||||
MINGW* ) |
||||
msys=true |
||||
;; |
||||
esac |
||||
|
||||
# For Cygwin, ensure paths are in UNIX format before anything is touched. |
||||
if $cygwin ; then |
||||
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` |
||||
fi |
||||
|
||||
# Attempt to set APP_HOME |
||||
# Resolve links: $0 may be a link |
||||
PRG="$0" |
||||
# Need this for relative symlinks. |
||||
while [ -h "$PRG" ] ; do |
||||
ls=`ls -ld "$PRG"` |
||||
link=`expr "$ls" : '.*-> \(.*\)$'` |
||||
if expr "$link" : '/.*' > /dev/null; then |
||||
PRG="$link" |
||||
else |
||||
PRG=`dirname "$PRG"`"/$link" |
||||
fi |
||||
done |
||||
SAVED="`pwd`" |
||||
cd "`dirname \"$PRG\"`/" >&- |
||||
APP_HOME="`pwd -P`" |
||||
cd "$SAVED" >&- |
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar |
||||
|
||||
# Determine the Java command to use to start the JVM. |
||||
if [ -n "$JAVA_HOME" ] ; then |
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then |
||||
# IBM's JDK on AIX uses strange locations for the executables |
||||
JAVACMD="$JAVA_HOME/jre/sh/java" |
||||
else |
||||
JAVACMD="$JAVA_HOME/bin/java" |
||||
fi |
||||
if [ ! -x "$JAVACMD" ] ; then |
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME |
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the |
||||
location of your Java installation." |
||||
fi |
||||
else |
||||
JAVACMD="java" |
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. |
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the |
||||
location of your Java installation." |
||||
fi |
||||
|
||||
# Increase the maximum file descriptors if we can. |
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then |
||||
MAX_FD_LIMIT=`ulimit -H -n` |
||||
if [ $? -eq 0 ] ; then |
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then |
||||
MAX_FD="$MAX_FD_LIMIT" |
||||
fi |
||||
ulimit -n $MAX_FD |
||||
if [ $? -ne 0 ] ; then |
||||
warn "Could not set maximum file descriptor limit: $MAX_FD" |
||||
fi |
||||
else |
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" |
||||
fi |
||||
fi |
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock |
||||
if $darwin; then |
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" |
||||
fi |
||||
|
||||
# For Cygwin, switch paths to Windows format before running java |
||||
if $cygwin ; then |
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"` |
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` |
||||
|
||||
# We build the pattern for arguments to be converted via cygpath |
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` |
||||
SEP="" |
||||
for dir in $ROOTDIRSRAW ; do |
||||
ROOTDIRS="$ROOTDIRS$SEP$dir" |
||||
SEP="|" |
||||
done |
||||
OURCYGPATTERN="(^($ROOTDIRS))" |
||||
# Add a user-defined pattern to the cygpath arguments |
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then |
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" |
||||
fi |
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh |
||||
i=0 |
||||
for arg in "$@" ; do |
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` |
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option |
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition |
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` |
||||
else |
||||
eval `echo args$i`="\"$arg\"" |
||||
fi |
||||
i=$((i+1)) |
||||
done |
||||
case $i in |
||||
(0) set -- ;; |
||||
(1) set -- "$args0" ;; |
||||
(2) set -- "$args0" "$args1" ;; |
||||
(3) set -- "$args0" "$args1" "$args2" ;; |
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;; |
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; |
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; |
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; |
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; |
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; |
||||
esac |
||||
fi |
||||
|
||||
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules |
||||
function splitJvmOpts() { |
||||
JVM_OPTS=("$@") |
||||
} |
||||
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS |
||||
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" |
||||
|
||||
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" |
@ -0,0 +1,90 @@
|
||||
@if "%DEBUG%" == "" @echo off |
||||
@rem ########################################################################## |
||||
@rem |
||||
@rem Gradle startup script for Windows |
||||
@rem |
||||
@rem ########################################################################## |
||||
|
||||
@rem Set local scope for the variables with windows NT shell |
||||
if "%OS%"=="Windows_NT" setlocal |
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. |
||||
set DEFAULT_JVM_OPTS= |
||||
|
||||
set DIRNAME=%~dp0 |
||||
if "%DIRNAME%" == "" set DIRNAME=. |
||||
set APP_BASE_NAME=%~n0 |
||||
set APP_HOME=%DIRNAME% |
||||
|
||||
@rem Find java.exe |
||||
if defined JAVA_HOME goto findJavaFromJavaHome |
||||
|
||||
set JAVA_EXE=java.exe |
||||
%JAVA_EXE% -version >NUL 2>&1 |
||||
if "%ERRORLEVEL%" == "0" goto init |
||||
|
||||
echo. |
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. |
||||
echo. |
||||
echo Please set the JAVA_HOME variable in your environment to match the |
||||
echo location of your Java installation. |
||||
|
||||
goto fail |
||||
|
||||
:findJavaFromJavaHome |
||||
set JAVA_HOME=%JAVA_HOME:"=% |
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe |
||||
|
||||
if exist "%JAVA_EXE%" goto init |
||||
|
||||
echo. |
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% |
||||
echo. |
||||
echo Please set the JAVA_HOME variable in your environment to match the |
||||
echo location of your Java installation. |
||||
|
||||
goto fail |
||||
|
||||
:init |
||||
@rem Get command-line arguments, handling Windowz variants |
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args |
||||
if "%@eval[2+2]" == "4" goto 4NT_args |
||||
|
||||
:win9xME_args |
||||
@rem Slurp the command line arguments. |
||||
set CMD_LINE_ARGS= |
||||
set _SKIP=2 |
||||
|
||||
:win9xME_args_slurp |
||||
if "x%~1" == "x" goto execute |
||||
|
||||
set CMD_LINE_ARGS=%* |
||||
goto execute |
||||
|
||||
:4NT_args |
||||
@rem Get arguments from the 4NT Shell from JP Software |
||||
set CMD_LINE_ARGS=%$ |
||||
|
||||
:execute |
||||
@rem Setup the command line |
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar |
||||
|
||||
@rem Execute Gradle |
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% |
||||
|
||||
:end |
||||
@rem End local scope for the variables with windows NT shell |
||||
if "%ERRORLEVEL%"=="0" goto mainEnd |
||||
|
||||
:fail |
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of |
||||
rem the _cmd.exe /c_ return code! |
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 |
||||
exit /b 1 |
||||
|
||||
:mainEnd |
||||
if "%OS%"=="Windows_NT" endlocal |
||||
|
||||
:omega |
@ -0,0 +1,37 @@
|
||||
ECLIPSE ANDROID PROJECT IMPORT SUMMARY |
||||
====================================== |
||||
|
||||
Ignored Files: |
||||
-------------- |
||||
The following files were *not* copied into the new Gradle project; you |
||||
should evaluate whether these are still needed in your project and if |
||||
so manually move them: |
||||
|
||||
* .gitignore |
||||
* COPYING |
||||
* build.xml |
||||
|
||||
Moved Files: |
||||
------------ |
||||
Android Gradle projects use a different directory structure than ADT |
||||
Eclipse projects. Here's how the projects were restructured: |
||||
|
||||
* AndroidManifest.xml => tesstwo/src/main/AndroidManifest.xml |
||||
* jni/ => tesstwo/src/main/jni/ |
||||
* res/ => tesstwo/src/main/res/ |
||||
* src/ => tesstwo/src/main/java/ |
||||
|
||||
Next Steps: |
||||
----------- |
||||
You can now build the project. The Gradle project needs network |
||||
connectivity to download dependencies. |
||||
|
||||
Bugs: |
||||
----- |
||||
If for some reason your project does not build, and you determine that |
||||
it is due to a bug or limitation of the Eclipse to Gradle importer, |
||||
please file a bug at http://b.android.com with category |
||||
Component-Tools. |
||||
|
||||
(This import summary is for your information only, and can be deleted |
||||
after import once you are satisfied with the results.) |
@ -0,0 +1,44 @@
|
||||
apply plugin: 'com.android.library' |
||||
android { |
||||
compileSdkVersion 19 |
||||
buildToolsVersion '21.1.2' |
||||
defaultConfig { |
||||
minSdkVersion 14 |
||||
targetSdkVersion 19 |
||||
} |
||||
buildTypes { |
||||
release { |
||||
minifyEnabled false |
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' |
||||
} |
||||
} |
||||
//// This prevents the auto generation of Android.mk |
||||
sourceSets.main.jni.srcDirs = [] |
||||
task buildNative(type: Exec, description: 'Compile JNI source via NDK') { |
||||
def ndkDir = android.plugin.ndkFolder |
||||
commandLine "$ndkDir/ndk-build", |
||||
'-C', file('src/main/jni').absolutePath, |
||||
'-j', Runtime.runtime.availableProcessors(), |
||||
'all', |
||||
'NDK_DEBUG=1' |
||||
} |
||||
task cleanNative(type: Exec, description: 'Clean JNI object files') { |
||||
def ndkDir = android.plugin.ndkFolder |
||||
commandLine "$ndkDir/ndk-build", |
||||
'-C', file('src/main/jni').absolutePath, |
||||
'clean' |
||||
} |
||||
clean.dependsOn 'cleanNative' |
||||
tasks.withType(JavaCompile) { |
||||
compileTask -> compileTask.dependsOn buildNative |
||||
} |
||||
compileOptions { |
||||
sourceCompatibility JavaVersion.VERSION_1_7 |
||||
targetCompatibility JavaVersion.VERSION_1_7 |
||||
} |
||||
productFlavors { |
||||
} |
||||
} |
||||
|
||||
dependencies { |
||||
} |
@ -0,0 +1,13 @@
|
||||
/** |
||||
* Automatically generated file. DO NOT MODIFY |
||||
*/ |
||||
package com.googlecode.tesseract.android; |
||||
|
||||
public final class BuildConfig { |
||||
public static final boolean DEBUG = Boolean.parseBoolean("true"); |
||||
public static final String APPLICATION_ID = "com.googlecode.tesseract.android"; |
||||
public static final String BUILD_TYPE = "debug"; |
||||
public static final String FLAVOR = ""; |
||||
public static final int VERSION_CODE = 1; |
||||
public static final String VERSION_NAME = ""; |
||||
} |
@ -0,0 +1,13 @@
|
||||
/** |
||||
* Automatically generated file. DO NOT MODIFY |
||||
*/ |
||||
package com.googlecode.tesseract.android; |
||||
|
||||
public final class BuildConfig { |
||||
public static final boolean DEBUG = false; |
||||
public static final String APPLICATION_ID = "com.googlecode.tesseract.android"; |
||||
public static final String BUILD_TYPE = "release"; |
||||
public static final String FLAVOR = ""; |
||||
public static final int VERSION_CODE = 1; |
||||
public static final String VERSION_NAME = ""; |
||||
} |