Commit 10e2780c authored by Bastien Zigmann's avatar Bastien Zigmann

Mise en ligne des sources de l'application mobile

parent 5d7d86b0
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
/captures
.externalNativeBuild
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
<option name="resolveModulePerSourceSet" value="false" />
</GradleProjectSettings>
</option>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="NullableNotNullManager">
<option name="myDefaultNullable" value="android.support.annotation.Nullable" />
<option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
<option name="myNullables">
<value>
<list size="4">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
</list>
</value>
</option>
<option name="myNotNulls">
<value>
<list size="4">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
</list>
</value>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/GeocroppingApp.iml" filepath="$PROJECT_DIR$/GeocroppingApp.iml" />
<module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
</modules>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
</set>
</option>
</component>
</project>
\ No newline at end of file
apply plugin: 'com.android.application'
android {
compileSdkVersion 26
defaultConfig {
applicationId "geocropping.com.geocroppingapp"
minSdkVersion 15
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
}
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":1},"path":"app-release.apk","properties":{"packageId":"geocropping.com.geocroppingapp","split":"","minSdkVersion":"15"}}]
\ No newline at end of file
package geocropping.com.geocroppingapp;
import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() throws Exception {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getTargetContext();
assertEquals("geocropping.com.geocroppingapp", appContext.getPackageName());
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="geocropping.com.geocroppingapp">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="Geocropping"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name="NetworkChangeReceiver">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
<action android:name="android.net.wifi.WIFI_STATE_CHANGED"/>
</intent-filter>
</receiver>
</application>
</manifest>
\ No newline at end of file
package geocropping.com.geocroppingapp;
import android.app.AlertDialog;
import android.content.DialogInterface;
public class DebugPerso {
AlertDialog.Builder build;
AlertDialog alert;
public DebugPerso(){
this.build = new AlertDialog.Builder(MainActivity.getAppContext());
}
public void afficherMessage(String str) {
this.build.setMessage(str).setCancelable(true);
this.alert = this.build.create();
alert.show();
}
public void afficherMessage(String str, String btnOui) {
this.build.setMessage(str).setCancelable(true).setPositiveButton(btnOui, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
alert.cancel();
}
});
this.alert = this.build.create();
alert.show();
}
}
package geocropping.com.geocroppingapp;
import android.Manifest;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.webkit.GeolocationPermissions;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class MainActivity extends AppCompatActivity {
private static final int REQUEST_GPS = 0;
private static final int REQUEST_WIFI = 1;
private static WebView wv;
private static Context context;
// Quand on fait retour, si on l'a autorisé fait un retour sur la webview
@Override
public void onBackPressed() {
if (wv.canGoBack()) {
wv.goBack();
} else {
super.onBackPressed();
}
}
private void buildAlertMessageNoGps() {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Le GPS semble être désactivé, l'activer?")
.setCancelable(false)
.setPositiveButton("Oui", new DialogInterface.OnClickListener() {
public void onClick(@SuppressWarnings("unused") final DialogInterface dialog, @SuppressWarnings("unused") final int id) {
startActivity(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS));
}
})
.setNegativeButton("Non", new DialogInterface.OnClickListener() {
public void onClick(final DialogInterface dialog, @SuppressWarnings("unused") final int id) {
dialog.cancel();
callJS("geocropping.MobileSetGPSPosition(false);");
}
});
final AlertDialog alert = builder.create();
alert.show();
}
public static Context getAppContext() {
return context;
}
public static WebView getAppWebview() {
return MainActivity.wv;
}
public void callJS(String js) {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
wv.evaluateJavascript(js, new ValueCallback<String>() {
@Override
public void onReceiveValue(String s) {
// nothing to see here
}
});
} else {
wv.loadUrl("javascript:" + js);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
switch (requestCode) {
case REQUEST_GPS: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// La permission est donnée
configureGPS();
} else {
// La permission est refusée
this.finish();
}
return;
}
case REQUEST_WIFI: {
// ajouter ici le paramétrage du wifi si il y en a un un jour
}
}
}
private void configureGPS() {
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
// Détection du on/off du GPS
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 0, new LocationListener() {
@Override
public void onLocationChanged(Location location) {
}
@Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
@Override
public void onProviderEnabled(String s) {
callJS("geocropping.MobileSetGPSPosition(true);");
}
@Override
public void onProviderDisabled(String s) {
callJS("geocropping.MobileSetGPSPosition(false);");
}
});
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.context = this;
setContentView(R.layout.activity_main);
// vérification que les droits sont bien donné pour l'accès au gps
if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_GPS);
}else{
configureGPS();
}
// De même avec le wifi
if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_NETWORK_STATE) != PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_NETWORK_STATE}, REQUEST_WIFI);
}
// Vérification de la connexion internet au lancement
boolean IsConnected = NetworkUtil.getConnectivityStatusString(MainActivity.getAppContext());
if(!IsConnected) {
NetworkChangeReceiver.buildAlertMessageNoConnection();
}
// Vérification du GPS au lancement
boolean IsLocalised = (((LocationManager) getSystemService( Context.LOCATION_SERVICE ))).isProviderEnabled(LocationManager.GPS_PROVIDER);
if ( !IsLocalised ) {
buildAlertMessageNoGps();
}
// Parametrage de la WebView
wv = findViewById(R.id.wv);
WebSettings wvSettings = wv.getSettings();
wv.setWebViewClient(new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
});
// Activer javascript
wvSettings.setJavaScriptEnabled(true);
wv.setFocusable(true);
wv.setFocusableInTouchMode(true);
// Mettre la render priority en haute
wvSettings.setRenderPriority(WebSettings.RenderPriority.HIGH);
wvSettings.setDomStorageEnabled(true);
wvSettings.setGeolocationEnabled(true);
wv.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
wv.setWebChromeClient(new WebChromeClient(){
@Override
public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {
callback.invoke(origin, true, false);
}
});
// Charger la page
wv.loadUrl("https://geocropping.xsalto.com/");
// Pour appler du Js, il faut que la page ai fini de charger
wv.setWebViewClient(new WebViewClient(){
@Override
public void onPageFinished(WebView wv, String url){
callJS("geocropping._setOnMobileApp();");
}
});
// Pour pouvoir débug sur chrome (chrome://inspect)
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
WebView.setWebContentsDebuggingEnabled(true);
}
}
}
\ No newline at end of file
package geocropping.com.geocroppingapp;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
public class NetworkChangeReceiver extends BroadcastReceiver {
public static void buildAlertMessageNoConnection(){
final AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.getAppContext());
builder.setMessage("Connexion perdue").setCancelable(false).setPositiveButton("Recharger", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
boolean IsConnected = NetworkUtil.getConnectivityStatusString(MainActivity.getAppContext());
if(IsConnected)
MainActivity.getAppWebview().reload();
else
buildAlertMessageNoConnection();
}
});
AlertDialog alert = builder.create();
alert.show();
}
@Override
public void onReceive(final Context context, final Intent intent) {
boolean IsConnected = NetworkUtil.getConnectivityStatusString(context);
if(!IsConnected){
buildAlertMessageNoConnection();
}
}
}
\ No newline at end of file
package geocropping.com.geocroppingapp;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
public class NetworkUtil {
public static int TYPE_WIFI = 1;
public static int TYPE_MOBILE = 2;
public static int TYPE_NOT_CONNECTED = 0;
public static int getConnectivityStatus(Context context) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
if (null != activeNetwork) {
if(activeNetwork.getType() == ConnectivityManager.TYPE_WIFI)
return TYPE_WIFI;
if(activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE)
return TYPE_MOBILE;
}
return TYPE_NOT_CONNECTED;
}
public static boolean getConnectivityStatusString(Context context) {
int conn = NetworkUtil.getConnectivityStatus(context);
boolean status = false ;
if (conn == NetworkUtil.TYPE_WIFI) {
status = true;
} else if (conn == NetworkUtil.TYPE_MOBILE) {
status = true;
} else if (conn == NetworkUtil.TYPE_NOT_CONNECTED) {
status = false;
}