diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..69665be --- /dev/null +++ b/.travis.yml @@ -0,0 +1,30 @@ +language: android + +android: + components: + - tools + - platform-tools + - extra-android-support + - extra-android-m2repository + +jdk: + - oraclejdk8 + +branches: + except: + - gh-pages + +before_install: + - mkdir "$ANDROID_HOME/licenses" || true + - echo -e "\n8933bad161af4178b1185d1a37fbf41ea5269c55\nd56f5187479451eabf01fb78af6dfcb131a6481e\nd56f5187479451eabf01fb78af6dfcb131a6481e\n24333f8a63b6825ea9c5514f83c2829b004d1fee" > "$ANDROID_HOME/licenses/android-sdk-license" + +licenses: + - android-sdk-license-.+ + - '.+' + +script: + ./gradlew clean build + +cache: + directories: + - $HOME/.m2 diff --git a/app/build.gradle b/app/build.gradle index 14a3e28..5cf7a3f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -9,8 +9,8 @@ copper { projectName = "AskSample" publications { - genSourcesForVariant = {false} - artiConfig = project.hasProperty('artiServer')?project.artiServer:"arti01" + genSourcesForVariant = { false } + artiConfig = project.hasProperty('artiServer') ? project.artiServer : "arti01" } } @@ -25,7 +25,7 @@ android { targetSdkVersion 28 versionCode versioning.info.versionCode versionName versioning.info.display - testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { @@ -39,36 +39,41 @@ android { exclude 'META-INF/main.kotlin_module' exclude 'META-INF/lib_release.kotlin_module' } + + // Butterknife requires Java 8. + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) - androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', { - exclude group: 'com.android.support', module: 'support-annotations' - }) - implementation 'com.android.support:appcompat-v7:28.0.0' - implementation 'com.android.support.constraint:constraint-layout:1.1.3' - implementation 'com.android.support:design:28.0.0' - implementation 'com.android.support:support-media-compat:28.0.0' - implementation 'com.android.support:support-v4:28.0.0' - implementation 'com.android.support:cardview-v7:28.0.0' + implementation 'androidx.appcompat:appcompat:1.1.0' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + implementation 'com.google.android.material:material:1.1.0' + implementation 'androidx.media:media:1.1.0' + implementation 'androidx.legacy:legacy-support-v4:1.0.0' + implementation 'androidx.cardview:cardview:1.0.0' + implementation 'androidx.preference:preference:1.1.0' + implementation 'com.takisoft.preferencex:preferencex:1.1.0' // Coppernic - implementation 'fr.coppernic.sdk.ask:CpcAsk:3.5.2' - implementation 'fr.coppernic.sdk.core:CpcCore:1.8.14' - implementation'fr.coppernic.sdk.cpcutils:CpcUtilsLib:6.18.4' + implementation 'fr.coppernic.sdk.ask:CpcAsk:chasse' + implementation 'fr.coppernic.sdk.core:CpcCore:1.9.0' + implementation 'fr.coppernic.sdk.cpcutils:CpcUtilsLib:6.19.0' // Butter knife - implementation 'com.jakewharton:butterknife:8.8.1' - annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1' + implementation 'com.jakewharton:butterknife:10.2.0' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.0' // Timber implementation 'com.jakewharton.timber:timber:4.7.1' implementation 'fr.bipi.treessence:treessence:0.3.0' - testImplementation 'junit:junit:4.12' - androidTestImplementation 'com.android.support.test:runner:1.0.2' - androidTestImplementation 'com.android.support.test:rules:1.0.2' - androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' - androidTestImplementation 'com.android.support.test.espresso:espresso-contrib:3.0.2' + testImplementation 'junit:junit:4.13' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test:rules:1.2.0' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.2.0' } diff --git a/app/src/androidTest/java/fr/coppernic/samples/ask/HuntInstrumentedTest.java b/app/src/androidTest/java/fr/coppernic/samples/ask/HuntInstrumentedTest.java index 65142e4..887c19d 100644 --- a/app/src/androidTest/java/fr/coppernic/samples/ask/HuntInstrumentedTest.java +++ b/app/src/androidTest/java/fr/coppernic/samples/ask/HuntInstrumentedTest.java @@ -1,18 +1,7 @@ package fr.coppernic.samples.ask; -import android.app.PendingIntent; -import android.content.BroadcastReceiver; import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; import android.os.SystemClock; -import android.support.test.InstrumentationRegistry; -import android.support.test.espresso.UiController; -import android.support.test.espresso.ViewAction; -import android.support.test.espresso.matcher.ViewMatchers; -import android.support.test.filters.LargeTest; -import android.support.test.rule.ActivityTestRule; -import android.support.test.runner.AndroidJUnit4; import android.view.View; import android.widget.TextView; @@ -23,11 +12,20 @@ import org.junit.Test; import org.junit.runner.RunWith; -import static android.support.test.espresso.Espresso.onView; -import static android.support.test.espresso.action.ViewActions.click; -import static android.support.test.espresso.matcher.ViewMatchers.isAssignableFrom; -import static android.support.test.espresso.matcher.ViewMatchers.withId; -import static org.junit.Assert.*; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.espresso.UiController; +import androidx.test.espresso.ViewAction; +import androidx.test.espresso.matcher.ViewMatchers; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.filters.LargeTest; +import androidx.test.rule.ActivityTestRule; + +import static androidx.test.espresso.Espresso.onView; +import static androidx.test.espresso.action.ViewActions.click; +import static androidx.test.espresso.matcher.ViewMatchers.isAssignableFrom; +import static androidx.test.espresso.matcher.ViewMatchers.withId; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; /** * Instrumentation test, which will execute on an Android device. @@ -42,9 +40,9 @@ public class HuntInstrumentedTest { public ActivityTestRule activityRule = new ActivityTestRule<> (MainActivity.class); @Test - public void useAppContext() throws Exception { + public void useAppContext() { // Context of the app under test. - Context appContext = InstrumentationRegistry.getTargetContext(); + Context appContext = ApplicationProvider.getApplicationContext(); assertEquals("fr.coppernic.samples.ask", appContext.getPackageName()); } @@ -84,7 +82,7 @@ public void stabilityTest() { clickOnEnterHuntPhase(); SystemClock.sleep(500); String result = getText(ViewMatchers.withId(R.id.tvAtrValue)); - assertTrue(result.compareTo(initialValue) == 0); + assertEquals(0, result.compareTo(initialValue)); } } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 4ab43f8..b19bf7c 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -11,7 +11,10 @@ android:roundIcon="@drawable/rfid_blue" android:supportsRtl="true" android:theme="@style/AppTheme" - tools:ignore="GoogleAppIndexingWarning"> + tools:ignore="AllowBackup,GoogleAppIndexingWarning"> + { // RFID reader private Reader reader; @@ -46,6 +54,8 @@ public class MainActivity extends AppCompatActivity implements PowerListener, In TextView tvAtrValue; @BindView(R.id.btnSamGetAtr) Button btnGetSamAtr; + //Settings + private SharedPreferences sharedPreferences; @Override protected void onCreate(Bundle savedInstanceState) { @@ -56,6 +66,8 @@ protected void onCreate(Bundle savedInstanceState) { ButterKnife.bind(this); + sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); + PowerManager.get().registerListener(this); } @@ -69,6 +81,22 @@ protected void onDestroy() { // InstanceListener implementation + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.menu, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == R.id.action_settings) { + Intent intent = new Intent(this, SettingsActivity.class); + startActivity(intent); + return true; + } + return super.onOptionsItemSelected(item); + } + @Override public void onCreated(Reader reader) { this.reader = reader; @@ -135,6 +163,7 @@ public void onSwCardDetectionCheckedChanged(final CompoundButton buttonView, boo if (checked) { // Clears Tag data showTag(null); + // Sets the card detection sCARD_SearchExt search = new sCARD_SearchExt(); search.OTH = 1; @@ -148,7 +177,8 @@ public void onSwCardDetectionCheckedChanged(final CompoundButton buttonView, boo search.MV5k = 1; search.TICK = 1; int mask = Defines.SEARCH_MASK_INNO | Defines.SEARCH_MASK_ISOA | Defines.SEARCH_MASK_ISOB | Defines.SEARCH_MASK_MIFARE | Defines.SEARCH_MASK_MONO | Defines.SEARCH_MASK_MV4K | Defines.SEARCH_MASK_MV5K | Defines.SEARCH_MASK_TICK | Defines.SEARCH_MASK_OTH; - SearchParameters parameters = new SearchParameters(search, mask, (byte) 0x01, (byte) 0x00); + SearchParameters parameters = + new SearchParameters(search, mask, (byte) 0x01, getTimeout(), getRfOffTimeout()); // Starts card detection reader.startDiscovery(parameters, new ReaderListener() { @Override @@ -330,4 +360,24 @@ public void onPowerUp(CpcResult.RESULT result, Peripheral peripheral) { public void onPowerDown(CpcResult.RESULT result, Peripheral peripheral) { enableUiAfterReaderInstantiation(false); } + + private byte getTimeout() { + + String s = sharedPreferences.getString(SettingsActivity.KEY_SEARCH_TIMEOUT, "200"); + if (s == null) { + s = "200"; + } + + int i = Integer.parseInt(s); + + return (byte) (i / 10); + } + + private long getRfOffTimeout() { + String s = sharedPreferences.getString(SettingsActivity.KEY_RF_OFF_TIMEOUT, "0"); + if (s == null) { + s = "0"; + } + return Long.parseLong(s); + } } diff --git a/app/src/main/java/fr/coppernic/samples/ask/settings/SettingsActivity.java b/app/src/main/java/fr/coppernic/samples/ask/settings/SettingsActivity.java new file mode 100644 index 0000000..e1ec0cd --- /dev/null +++ b/app/src/main/java/fr/coppernic/samples/ask/settings/SettingsActivity.java @@ -0,0 +1,37 @@ +package fr.coppernic.samples.ask.settings; + +import android.os.Bundle; + +import com.takisoft.preferencex.PreferenceFragmentCompat; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AppCompatActivity; +import fr.coppernic.samples.ask.R; + +public class SettingsActivity extends AppCompatActivity { + + public static final String KEY_SEARCH_TIMEOUT = "search_timeout"; + public static final String KEY_RF_OFF_TIMEOUT = "rf_off_timeout"; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.settings_activity); + getSupportFragmentManager() + .beginTransaction() + .replace(R.id.settings, new SettingsFragment()) + .commit(); + ActionBar actionBar = getSupportActionBar(); + if (actionBar != null) { + actionBar.setDisplayHomeAsUpEnabled(true); + } + } + + public static class SettingsFragment extends PreferenceFragmentCompat { + @Override + public void onCreatePreferencesFix(@Nullable Bundle savedInstanceState, String rootKey) { + setPreferencesFromResource(R.xml.root_preferences, rootKey); + } + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_settings.xml b/app/src/main/res/drawable/ic_settings.xml new file mode 100644 index 0000000..9319555 --- /dev/null +++ b/app/src/main/res/drawable/ic_settings.xml @@ -0,0 +1,13 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index aac8647..ad93211 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,25 +1,26 @@ - + tools:context="fr.coppernic.samples.ask.MainActivity" + android:keepScreenOn="true"> - - - + - + diff --git a/app/src/main/res/layout/content_main.xml b/app/src/main/res/layout/content_main.xml index db31f84..6779047 100644 --- a/app/src/main/res/layout/content_main.xml +++ b/app/src/main/res/layout/content_main.xml @@ -1,5 +1,5 @@ - - - @@ -41,7 +41,7 @@ android:layout_marginRight="8dp" app:layout_constraintRight_toRightOf="parent" /> - - - + - + - - - - + - + - - @@ -311,8 +311,8 @@ android:layout_marginRight="8dp" app:layout_constraintRight_toRightOf="parent" /> - + - + - + diff --git a/app/src/main/res/layout/settings_activity.xml b/app/src/main/res/layout/settings_activity.xml new file mode 100644 index 0000000..de6591a --- /dev/null +++ b/app/src/main/res/layout/settings_activity.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/menu.xml b/app/src/main/res/menu/menu.xml new file mode 100644 index 0000000..8c09734 --- /dev/null +++ b/app/src/main/res/menu/menu.xml @@ -0,0 +1,14 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7ea5c73..d7d9d25 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -20,4 +20,14 @@ HSP Innovatron Error selecting SAM Error resetting SAM + Settings + + + Discovery + Sync + + + Search timeout (ms) + Rf off timeout (ms) + diff --git a/app/src/main/res/xml/root_preferences.xml b/app/src/main/res/xml/root_preferences.xml new file mode 100644 index 0000000..07beb92 --- /dev/null +++ b/app/src/main/res/xml/root_preferences.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + diff --git a/build.gradle b/build.gradle index fa94336..7358876 100644 --- a/build.gradle +++ b/build.gradle @@ -1,11 +1,12 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { repositories { - maven { url 'https://artifactory.coppernic.fr/artifcatory/plugins-release'} + maven { url 'https://artifactory.coppernic.fr/artifactory/plugins-release'} maven { url 'https://artifactory.coppernic.fr/artifactory/libs-release'} maven { url "https://plugins.gradle.org/m2/" } jcenter() google() + } dependencies { classpath 'com.android.tools.build:gradle:3.2.0' @@ -16,9 +17,10 @@ buildscript { allprojects { repositories { jcenter() - maven { url 'https://artifactory.coppernic.fr/artifcatory/plugins-release'} + maven { url 'https://artifactory.coppernic.fr/artifactory/plugins-release'} maven { url 'https://artifactory.coppernic.fr/artifactory/libs-release'} google() + mavenLocal() } } diff --git a/gradle.properties b/gradle.properties index aac7c9b..9e6fce1 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,6 +9,8 @@ # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. +android.enableJetifier=true +android.useAndroidX=true org.gradle.jvmargs=-Xmx1536m # When configured, Gradle will run in incubating parallel mode.