Compare commits

...

46 Commits
main ... 1.5.6

Author SHA1 Message Date
0fc0c9e42e Merge branch 'release/1.5.6' 2019-11-05 21:02:32 +01:00
a53efc52bc Updated CHANGELOG 2019-11-05 21:02:16 +01:00
cfdbecb0aa
Rollcall: Fixed SWADroid allows multiple simultaneous submissions of the attendance list (#263)
* Fix #262

* Updated CHANGELOG

* Rollcall: Fixed The default image is not displayed if the user does not have a photo
2019-11-05 20:53:15 +01:00
0126888e10
Update gradle version (#261) 2019-11-04 19:57:17 +01:00
b0e6017169
Update README.md 2019-10-26 18:41:27 +02:00
a48ce0df57 Added codecov token 2019-10-26 18:33:16 +02:00
f8b0d99011
Update README.md 2019-10-26 18:13:48 +02:00
dependabot-preview[bot]
c365299c18 Bump firebase-core from 17.2.0 to 17.2.1 (#260)
Bumps firebase-core from 17.2.0 to 17.2.1.

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-26 18:09:40 +02:00
dependabot-preview[bot]
15587d7717 Bump zxing-android-embedded from 3.6.0 to 4.0.2 (#259)
Bumps zxing-android-embedded from 3.6.0 to 4.0.2.

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-26 17:59:45 +02:00
4b0fd37702 Merge remote-tracking branch 'origin/develop' into develop 2019-10-26 17:48:05 +02:00
37901a00c4 Updated minSdkVersion to 24 (Android 7.0) 2019-10-26 17:47:53 +02:00
dependabot-preview[bot]
43e95486f3 Bump gson from 2.8.5 to 2.8.6 (#258)
Bumps [gson](https://github.com/google/gson) from 2.8.5 to 2.8.6.
- [Release notes](https://github.com/google/gson/releases)
- [Changelog](https://github.com/google/gson/blob/master/CHANGELOG.md)
- [Commits](https://github.com/google/gson/compare/gson-parent-2.8.5...gson-parent-2.8.6)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-26 17:38:46 +02:00
588afa9b11 Updated dependencies 2019-10-26 17:23:14 +02:00
d927ee059d
Update README.md 2019-10-26 17:16:37 +02:00
fb35c63781
Updated Travis CI references (#252)
* Updated build dependencies

* Updated Travis CI references
2019-07-09 22:21:57 +02:00
22d1fcd515 Merge tag '1.5.5' into develop
1.5.5
2019-07-08 19:52:15 +02:00
cdb3b4eab1 Merge branch 'release/1.5.5' 2019-07-08 19:52:04 +02:00
43ff17b45a Updated CHANGELOG 2019-07-08 19:51:05 +02:00
a90f540b0f
Fix CHANGELOG typos (#251) 2019-07-08 19:39:19 +02:00
c98bef5721
Disable CHANGELOG popup on application upgrade (#250) 2019-07-08 18:44:37 +02:00
27fd02949c
Update Firebase dependency (#249) 2019-07-08 18:05:57 +02:00
f493255aa0
Migrate to android-Q (#248) 2019-06-06 20:54:01 +02:00
80552ce4f3
Switch from Google Analytics to Firebase (#247)
* Switch from Google Analytics to Firebase

* Fix google-services.json.enc path

* Fix google-services.json.enc path (try 2)

* Fix google-services.json.enc path (try 3)

* Fix google-services.json.enc path (try 4)

* Fix google-services.json.enc path (try 5)

* Fix google-services.json.enc path (try 6)

* Fix Android Build Tools version

* Fix BuildConfigField SWAD_APP_KEY
2019-05-02 18:38:45 +02:00
4bee25297c
Update dependencies (#246) 2019-03-31 16:52:39 +02:00
ea01cc5057
Support for Android 9 (#245)
* Update Android Build Tools and dependencies

* Update Android dependencies
2018-09-25 20:14:56 +02:00
2cb2d05c34
Update issue templates (#244)
* Update issue templates

* Remove old issue template

* Refactor templates
2018-09-06 19:18:42 +02:00
8d04106149
Update gradle plugin (#243)
* Update gradle plugin

* Remove ignored file
2018-06-08 22:15:59 +02:00
1709868480
Update SDK to final release 28 (#242)
Update SDK to final release 28
2018-06-07 18:38:35 +02:00
b641f7de4d
Add Slack integration with Travis CI (#241) 2018-05-18 16:51:24 +02:00
0ac9e32363
Enable APK Autodeploy in Travis CI (#240)
Enable APK Autodeploy in Travis CI
2018-05-18 00:51:10 +02:00
5da9b7ac24
Update API version to Android P Preview (#239)
* Upgraded to Android P

* Fix Travis CI (Try 1)

* Fix Travis CI (Try 2)

* Fix Travis CI (Try 3)

* Fix Travis CI (Try 4)

* Fix Travis CI (Try 5)

* Fix Travis CI (Try 6)

* Fix Travis CI (Try 7)

* Fix Travis CI (Try 8)

* Revert Fix Travis CI (Try 8)

* Minor change

* Add parsing of the lint report in Travis CI

* Refactor Gradle config

* Add TODO comments
2018-05-16 22:12:42 +02:00
0859220101 Updated dependencies 2018-05-02 18:32:41 +02:00
61ef72b0c6 Updated README 2018-04-21 22:23:10 +02:00
949c2028d7 Updated issue template 2018-04-18 20:21:05 +02:00
c6eb60efa5
Create ISSUE_TEMPLATE.md 2018-04-18 20:15:49 +02:00
926ea7ed69
Merge pull request #237 from Amab/add-code-of-conduct-1
Create CODE_OF_CONDUCT.md
2018-04-18 16:58:14 +02:00
76e8de86c7
Create CODE_OF_CONDUCT.md 2018-04-18 16:46:37 +02:00
de989a3819
Create PULL_REQUEST_TEMPLATE.md 2018-04-18 16:44:35 +02:00
dc4a6835a7
Create CONTRIBUTING.md 2018-04-18 16:42:12 +02:00
a635003381 Updated dependencies 2018-04-16 17:16:17 +02:00
28328df06d Updated dependencies 2018-04-03 13:04:42 +02:00
b5d53af477 Merge tag '1.5.4' into develop
1.5.4
2018-02-25 13:32:02 +01:00
69f2c34531 Merge branch 'release/1.5.4' 2018-02-25 13:31:52 +01:00
b1b84cd26d Bumped version 2018-02-25 13:30:45 +01:00
7ededb89c2
Merge pull request #236 from Cadiducho/groupNameFix
Fix #235
2018-02-25 13:19:47 +01:00
Dani Matilla
7412ef3485
Fix behaviour with multiple choices 2018-02-20 13:11:49 +01:00
75 changed files with 813 additions and 781 deletions

46
.github/CODE_OF_CONDUCT.md vendored Normal file
View File

@ -0,0 +1,46 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at swadroid@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/

13
.github/CONTRIBUTING.md vendored Normal file
View File

@ -0,0 +1,13 @@
## Contributing to SWADroid
*Before opening a pull request*, consider:
- Is the change important and ready enough to ask the community to spend time reviewing?
- Have you searched for existing, related GitHub issues and pull requests?
- Is the change being proposed clearly explained and motivated?
When you contribute code, you affirm that the contribution is your original work and that you
license the work to the project under the project's open source license. Whether or not you
state this explicitly, by submitting any copyrighted material via pull request, email, or
other means you agree to license the material under the project's open source license and
warrant that you have the legal authority to do so.

35
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@ -0,0 +1,35 @@
---
name: Bug report
about: Create a report to help us improve
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]
**Additional context**
Add any other context about the problem here.

View File

@ -0,0 +1,17 @@
---
name: Feature request
about: Suggest an idea for this project
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

10
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@ -0,0 +1,10 @@
## What changes were proposed in this pull request?
(Please fill in changes proposed in this fix)
## How was this patch tested?
(Please explain how this patch was tested. E.g. unit tests, integration tests, manual tests)
(If this patch involves UI changes, please attach a screenshot; otherwise, remove this)
Please review https://github.com/Amab/SWADroid/blob/develop/CONTRIBUTING.md before opening a pull request.

64
.gitignore vendored
View File

@ -1,10 +1,58 @@
.idea
.gradle
build
import-summary.txt
# Built application files
*.apk
*.ap_
*.aab
# Files for the ART/Dalvik VM
*.dex
# Java class files
*.class
# Generated files
bin/
gen/
out/
# Gradle files
.gradle/
build/
# Local configuration file (sdk path, etc)
local.properties
/SWADroid/SWADroid-SWADroid.iml
/SWADroid.iml
app/lint.xml
/SWADroid/google-services.json
keystore.properties
# Proguard folder generated by Eclipse
proguard/
# Log Files
*.log
# Android Studio Navigation editor temp files
.navigation/
# Android Studio captures folder
captures/
# IntelliJ
*.iml
.idea/
# Keystore files
# Uncomment the following lines if you do not want to check your keystore files in.
*.jks
*.keystore
# External native build folder generated in Android Studio 2.2 and later
.externalNativeBuild
# Google Services (e.g. APIs or Firebase)
# google-services.json
# lint
lint/intermediates/
lint/generated/
lint/outputs/
lint/tmp/
# lint/reports/
/SWADroid/src/debug/

View File

@ -1,19 +1,57 @@
sudo: false
language: android
jdk:
- oraclejdk8
android:
components:
- tools
- tools
- platform-tools
- build-tools-27.0.3
- android-27
- extra-android-m2repository
- extra-android-support
- extra-google-m2repository
- extra-google-google_play_services
script:
- "./gradlew build connectedCheck"
jdk: oraclejdk8
env:
global:
- ANDROID_API=29
- ANDROID_BUILD_TOOLS=29.0.2
- secure: eY3bGKw4jZ+HHkkMBZHiL2dhcz+RJYHib0WC77SSVHLJcCg63pBvs420i4rjNQHycMs+PhRSlR79jdglDTm8svphhRjSts6VMkHDxObwJIyLF8vAZ0PfjhqfOXO+4+Fx6pRIjwM7cBMOQrDfSimJHRB+z/f2AJfUIsaMSlltGVya7nmrLY/fO4dtl4wPnejslj3mhnBAxr+a2Or978RwI2TMpxBovHZKFT/46wJTcMzKXGdXU64M8nmQmpcKHeIKIBiR4g+A2tahC+Us4tFxxoTDd3R+IAzj7Gvjd5JuMlYmQ3quRv2M08u9OJNiT14LpDXy19fZKdw/QNHg3S8JVis8kJDkv6z4HyZXTIBgISZpCZZti04GP29Lj+1f4ISRFc6uxankDuRgfX8ucsxoEPJVq3PfJlpTdP7wjlQtEGv0HF/3MNNyruNbLHFiCgHOANwEOX44INtw6XylPEftmw4y4ptntFG3VXyV1Zi+732Qe4b2QNTbvLPrsmkCRKzo59vKKAzBBhvYvFVITcWbySqdx9/n1H25SRL2Q96nPGQSQyBF6obzzFcjMKkknPle1PXvAfb171964cdIK6/zo9rh/ZCL3+gAKZibmGWvbeztWYl5ON8B8x8mgLO/qgPIotY+aqwmsY06pKrqi6adYZacMF+UgtbLJlhnird6ugk=
- secure: EmcSyXk/5pEJhbRX9DSFzhQGYvGaYdxjDuQwmLuxUGitGpFQZbWexTAK/l0LLcIRsiSmucY7KJgOpL7I6odh2kVUZedarj8/5K1P69ljDDB7bfG8jyOLZvHJ1JTZRuKvUnT846zQwQWTnLXF9N4LaQ86FVqSW2bGHqptIivEjDEVh78V3g4PDsbX5aQ5LjTlSn7bezu9chpVS0fnRlqjAa6U2kUwUt+DDaSHEOs35Z89jT7JoonGFrMsyA7S26CQhOBYE3w76AllIea+MWzPJX3V364ZIzPBnQAkCz02oVI3n+LHZkzUCYHkY8DXWXNy6+/sulFa6L1v6bt8DzF1vwJ+nTNVqmqSDYBe2s1qAUZ+4o8l/THMndxC11LjbbEExG4ekBRFvRsOOf0pBps3Yr4ry27gaj4+9Ap2JCKKOQwm0izh48AJiy0Y8pzIzTO5wB5B7a4czLJmzaNWkPVXw4lKg2ldJ4sd6EBqUZqG2vRmN6VwHb8gHFNaQTH3feBRhYTpkv1wWUuhvclNn5yoZzcSxMT/b8d89e5DahoBYMW48c6jb5wL/EoY3bHp3mjtnTW8oIIjyZK8FjYX+8IqeEoue8bDDqNUN71xmRvp+0CX1iXnfgUeDWnYhXHTewOlJu6i509wGrZPxYjgwAdnpfTyGXPq7Vin9CkNHMw9fbA=
- secure: WS7Jgz0L0aMEZmg4/HxPb9nO7oER9z23n8n508UVQ0DyKL92UPhfVol7+Cob8zuO5SJl5TPOh58gd/C0Prq8t5q3mwlDA9buhnb1uef7pwZOFzQOF0o8RuPSpxLgu8tFlDooWrG9oxZObXwh84TXGX7zgoiWr9Y318qsQSHCiv9Ue9kgJxkjk9wVanJws7zHWAevfFzyoEvqtkDTqNie4RJbMEOdeX+TyUpc77Si2UpAC23Mpl8q+qZr32cgxk3MzSdhJk2C3Vz5MS6LBZ7ynyv+em+/vz2RBlFLetrcknHY8lgE060itWcns6Pj/8tv2SQbJptVFToXbfay/EVleApojHG4w5DFDzQt8a3Az0lBnqOxv3BiAPRcr49/A08qXAKh30p6YBiSvVd8zK+MZoMoj2dDQhdXb72nv0yHZmzkiaQEOGnsBD4Gt3epn/KoJke3W0ffBZOfJNScACW0Gta2XLImZsekb4sjfOF84HrISSMiXunlLpgtcC4C3Pn9VV/6+uciIMqMFDYkJMe2gyRNA2vSyZ61n/ioTLOHYzhYHjZUXB4MOlonYTiFuF4HmVVHO2J9CpOdFFP7hrkWK3HzvcQm9k8dxUkuKDoOlRb+CSlrEZO24V+TaY2DDr1bcitA77VJp90Cz2RpLC3tvSvThgY2VNk+OEbeSrP5DNA=
before_cache:
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
- rm -rf $HOME/.gradle/caches/*/plugin-resolution/
cache:
directories:
- "$HOME/.gradle/caches/"
- "$HOME/.gradle/wrapper/"
- "$HOME/.android/build-cache"
before_install:
- openssl aes-256-cbc -K $encrypted_b7f76037f2f7_key -iv $encrypted_b7f76037f2f7_iv
-in $TRAVIS_BUILD_DIR/SWADroid/src/prod/google-services.json.enc -out $TRAVIS_BUILD_DIR/SWADroid/src/prod/google-services.json
-d
- yes | sdkmanager "build-tools;${ANDROID_BUILD_TOOLS}"
- yes | sdkmanager "platform-tools"
- yes | sdkmanager "tools"
- yes | sdkmanager "platforms;android-${ANDROID_API}"
- yes | sdkmanager "extras;android;m2repository"
- yes | sdkmanager --list
- chmod +x gradlew
- yes | sdkmanager "platforms;android-27"
script:
- "./gradlew clean test build connectedCheck -Pbuild=prod"
after_failure: cat $TRAVIS_BUILD_DIR/SWADroid/build/reports/lint-results.xml
before_deploy:
- openssl aes-256-cbc -K $encrypted_855ad244b8b2_key -iv $encrypted_855ad244b8b2_iv
-in keystore.jks.enc -out keystore.jks -d
- cd SWADroid/build/outputs/apk/release
- jarsigner -sigalg SHA1withRSA -digestalg SHA1 -keystore ${TRAVIS_BUILD_DIR}/keystore.jks
-storepass $storepass -keypass $keypass SWADroid-release-unsigned.apk amab
- jarsigner -verify SWADroid-release-unsigned.apk
- "${ANDROID_HOME}/build-tools/${ANDROID_BUILD_TOOLS}/zipalign -p 4 SWADroid-release-unsigned.apk
SWADroid-release.apk"
deploy:
provider: releases
api_key:
secure: ePphqb/bHjJC1wwlVfw3DNOZtluX7B/3G8a8uWDkDIBpKHqCykpnXUNmgnWEO9iQ+GUmSdkAHn+z9tKv+MAdBRgSw2Xfc8sEsj6lsWUjJxHk7/eQOdzE0FC8y8WjrKHpwbFEJAi03YId/0ruIBltMzCWyylxMTAXonrL9yAvGn9EL5m1y1Fap58XNUmDwnP+4yoTfTuXOOJrmppFGUKlR22xhI6j/zvVW1LeyA7kpp42X/76rgnSS78Fj4s/O8kN0aa6c9PM38rWg1TqgBRRuV+2PMWmZn3EfjdzBl2d+D5pJ+gPS9e+gSWpKtTkatZ+CKwSBvQSpNE6K7B1FSCSR+Gy9FtnnH0BMyeP71kMFDgU+zagZjuQZnVgRAIDYdaquNq52EwcStXV5LrqpzNpkgAfrNOSVfLZWS1eEkGy6q8WqpvBO8OcnseaiaNl4VNNRZn1e7FziDZHkA/SCr3aLOVYp4FkVK7Z+yiH2EbLJ5SeKuPWv7pEbBmNR7lzsZGZ0Rt6FmVN3yuA1/4oIN0zgdSwNEoqYGRXqG0bNeghwjLPCkpMJ3W8h82fblX40hk/f3bB3aGN9BX/oBa06MEFTSxUtp4pwfhRQVe0/13+oR2G6yei+fuGJSsil6FmaOB0jNoMvtMLI0IhQ47AflRW4QfAHnO+lbfP8ZmWdLgBidk=
file: "$TRAVIS_BUILD_DIR/SWADroid/build/outputs/apk/release/SWADroid-release.apk"
skip_cleanup: true
name: SWADroid $TRAVIS_TAG
body: Automated release from Travis CI.
target_commitsh: "$TRAVIS_COMMIT"
on:
tags: true
repo: Amab/SWADroid
branch: master
notifications:
slack:
secure: FDRqQsWyWvSg3uXYV1jtxh209yYdE9wqMRx2Jmf9ivRMowSDqAfLaOD8hlAjD/DnBCBhVpSkOzT4+treByU1qpLXcWBpewl1GukK3jD6AoqD4Xtmp3xOAJsG1BvqeYp48Q95lZFgZ8WxV2IXO4/rAi3GcCDKVYGs3fEEwk/aVEfFDyHE7oT+mruZqrFHbwcPbObTucJWjFLu+VdCSdJ6HTN/gm/04TVg5ox0fqeyxqyAxW3QOEu/2EUOZ78ijrab7+Cn32KluoTlTDJY0+iSszYQll08+g2LsJruyzqWJzp8y0jZMs23e63ge16WrnzCHknTFIUXNG8/OVwCb2gsBA+RIchqEWLiKuOPtkSTZoMCqulDPYVOdGBJbv1CdJW4TKNmnLfsA9EMHlcv+50zcz7rq9115i4qPsous0gKw8Bc+tSL3S28YP81J8UmvTeQjAPgC7iQIeXHNvPpM62hP2v/sK9BUhmsfrFopeQGPVY5vLKXvAF+dJHuyUNK1T17iVyxa55D9Et6QeHqLsHgLKUx22RW128a0FuaFwD1EIKNuj0q+Fn8DNcXtyHoKVdGCD/K3nbDPwx+IsIvHTJfPwDL/cX8eXj+ggK32nuJVQwXLDMloz3xFKe+wO19/7kMzyKQD4Brq4xX2qQ3fiE5uRj6BIxJ2q8wuey3uuJMPVA=

View File

@ -5,18 +5,21 @@ Android client for e-learning platform [![SWADroid](https://openswad.org/logo/sw
[![SWADroid](http://developer.android.com/images/brand/en_generic_rgb_wo_45.png)](https://play.google.com/store/apps/details?id=es.ugr.swad.swadroid)
- Code: `git clone https://github.com/Amab/SWADroid.git`
- Issue tracker: https://github.com/Amab/SWADroid/issues
[![SWADroid](http://upload.wikimedia.org/wikipedia/commons/c/c8/Farm-Fresh_twitter_1.png)](http://twitter.com/SWADroid)[![SWADroid](http://upload.wikimedia.org/wikipedia/commons/4/4d/Farm-Fresh_facebook.png)](https://www.facebook.com/SWADroid)[![SWADroid](http://upload.wikimedia.org/wikipedia/commons/b/ba/Google_plus_32.png)](https://plus.google.com/115615684349730524355/posts)[![SWADroid](https://upload.wikimedia.org/wikipedia/commons/thumb/5/5c/Telegram_Messenger.png/35px-Telegram_Messenger.png?uselang=es)](https://telegram.me/swadroid)[![SWADroid](https://s.w.org/about/images/logos/wordpress-logo-32-blue.png)](http://swadroid.wordpress.com)
[![SWADroid](http://upload.wikimedia.org/wikipedia/commons/c/c8/Farm-Fresh_twitter_1.png)](http://twitter.com/SWADroid)[![SWADroid](http://upload.wikimedia.org/wikipedia/commons/4/4d/Farm-Fresh_facebook.png)](https://www.facebook.com/SWADroid)[![SWADroid](https://upload.wikimedia.org/wikipedia/commons/thumb/5/5c/Telegram_Messenger.png/35px-Telegram_Messenger.png?uselang=es)](https://telegram.me/swadroid)[![SWADroid](https://s.w.org/about/images/logos/wordpress-logo-32-blue.png)](http://swadroid.wordpress.com)
CI Status
---------
|Branch|CI status|
|------|---------|
|develop|[![Build Status](https://travis-ci.org/Amab/SWADroid.svg?branch=develop)](https://travis-ci.org/Amab/SWADroid)|
|master|[![Build Status](https://travis-ci.org/Amab/SWADroid.svg?branch=master)](https://travis-ci.org/Amab/SWADroid)|
|develop|[![Build Status](https://travis-ci.com/Amab/SWADroid.svg?branch=develop)](https://travis-ci.com/Amab/SWADroid)|
|master|[![Build Status](https://travis-ci.com/Amab/SWADroid.svg?branch=master)](https://travis-ci.com/Amab/SWADroid)|
[![Releases](https://img.shields.io/github/release/Amab/SWADroid.svg)](https://github.com/Amab/SWADroid/releases/latest)
[![Dependabot Status](https://api.dependabot.com/badges/status?host=github&repo=Amab/SWADroid)](https://dependabot.com)
[![libraries.io](https://img.shields.io/librariesio/github/Amab/SWADroid.svg)](https://libraries.io/github/Amab/SWADroid)
[![codecov](https://codecov.io/gh/Amab/SWADroid/branch/develop/graph/badge.svg)](https://codecov.io/gh/Amab/SWADroid)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/41ded03ee87d4ceaaafc976a7529bcf3)](https://www.codacy.com/manual/Amab/SWADroid?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=Amab/SWADroid&amp;utm_campaign=Badge_Grade)
Copyright and License
---------------------
@ -57,4 +60,4 @@ Contributing
SWADroid is an open source project. I encourage contributions.
The Github team has also been kind enough to write up some great [documentation](https://help.github.com/articles/about-pull-requests/) on working with pull requests. Contributions should be performed on [topic branches](http://progit.org/book/ch3-4.html) in your personal forks - just issue your pull requests from there.
The Github team has also been kind enough to write up some great [documentation](https://help.github.com/articles/about-pull-requests/) on working with pull requests.

View File

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id="SWADroid" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="" external.system.module.version="unspecified" 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" />
<option name="BUILDABLE" value="false" />
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.gradle" />
</content>
<orderEntry type="jdk" jdkName="1.8" jdkType="JavaSDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@ -1,16 +1,51 @@
apply plugin: 'com.android.application'
apply plugin: 'com.google.gms.google-services'
import org.ajoberstar.grgit.Grgit
ext {
git = org.ajoberstar.grgit.Grgit.open()
git = Grgit.open()
gitVersionCode = git.tag.list().size()
gitVersionName = "${git.describe()}"
}
travisBuild = System.getenv("TRAVIS") == "true"
//return a BuildConfigField from a properties file.
def static getBuildConfigField(String property){
def travisBuild = System.getenv("TRAVIS") == "true"
def value
if(travisBuild) {
value = "\"" + System.getenv(property) + "\""
} else {
Properties properties = new Properties()
properties.load(new FileInputStream("keystore.properties"))
value = "\"" + properties.getProperty(property) + "\""
}
return value
}
def build_param = "${build}"
if (build_param != "prod") {
//exclude development build
android.variantFilter { variant ->
if (variant.buildType.name == 'prod') {
variant.setIgnore(true)
}
}
} else {
//exclude all except development build
android.variantFilter { variant ->
if (variant.buildType.name != 'prod') {
variant.setIgnore(true)
}
}
}
android {
compileSdkVersion 27
buildToolsVersion "27.0.3"
compileSdkVersion "android-29"
buildToolsVersion '29.0.2'
dexOptions {
maxProcessCount=2
@ -26,62 +61,31 @@ android {
versionCode gitVersionCode
versionName gitVersionName
minSdkVersion 14
targetSdkVersion 27
android.applicationVariants.all { variant ->
def appName
//Check if an applicationName property is supplied; if not use the name of the parent project.
if (project.hasProperty("applicationName")) {
appName = applicationName
} else {
appName = parent.name
}
variant.outputs.all { output ->
outputFileName = "${appName}-${output.baseName}-${variant.versionName}.apk"
}
}
minSdkVersion 24
targetSdkVersion 29
testApplicationId "es.ugr.swad.swadroid.test"
testInstrumentationRunner "android.test.InstrumentationTestRunner"
buildConfigField "String", "SWAD_APP_KEY", getBuildConfigField("SWAD_APP_KEY")
}
buildTypes {
debug {
versionNameSuffix '-DEBUG'
}
buildTypes.each {
it.buildConfigField "String", "SWAD_APP_KEY", getBuildConfigField("SWAD_APP_KEY")
it.buildConfigField "String", "ANALYTICS_API_KEY", getBuildConfigField("ANALYTICS_API_KEY")
prod {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
//return a BuildConfigField from a properties file.
def getBuildConfigField(String property){
def value
if(travisBuild) {
value = "\"" + System.getenv(property) + "\""
} else {
Properties properties = new Properties()
properties.load(new FileInputStream("keystore.properties"))
value = "\"" + properties.getProperty(property) + "\""
}
return value
}
dependencies {
compile 'com.android.support:support-v4:27.0.2'
compile 'com.android.support:appcompat-v7:27.0.2'
compile 'com.google.android.gms:play-services-analytics:11.8.0'
compile 'com.google.code.ksoap2-android:ksoap2-android:3.6.2'
compile 'commons-io:commons-io:2.6'
compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
compile 'com.journeyapps:zxing-android-embedded:3.5.0@aar'
compile 'com.google.zxing:core:3.3.1'
compile 'com.google.code.gson:gson:2.8.2'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'com.google.code.ksoap2-android:ksoap2-android:3.6.4'
implementation 'commons-io:commons-io:2.6'
implementation 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
implementation 'com.journeyapps:zxing-android-embedded:4.0.2@aar'
implementation 'com.google.zxing:core:3.4.0'
implementation 'com.google.code.gson:gson:2.8.6'
implementation 'com.google.firebase:firebase-core:17.2.1'
}

View File

@ -0,0 +1,51 @@
{
"project_info": {
"project_number": "",
"project_id": ""
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:123456789012:android:1234567890123456",
"android_client_info": {
"package_name": "es.ugr.swad.swadroid"
}
},
"oauth_client": [
{
"client_id": "",
"client_type": 3
},
{
"client_id": "",
"client_type": 1,
"android_info": {
"package_name": "es.ugr.swad.swadroid",
"certificate_hash": ""
}
}
],
"api_key": [
{
"current_key": ""
}
],
"services": {
"analytics_service": {
"status": 2,
"analytics_property": {
"tracking_id": ""
}
},
"appinvite_service": {
"status": 1,
"other_platform_oauth_client": []
},
"ads_service": {
"status": 1
}
}
}
],
"configuration_version": "1"
}

View File

@ -342,7 +342,7 @@
<service android:name="com.google.android.gms.analytics.CampaignTrackingService" />
<provider
android:name="android.support.v4.content.FileProvider"
android:name="androidx.core.content.FileProvider"
android:authorities="es.ugr.swad.swadroid.fileprovider"
android:exported="false"
android:grantUriPermissions="true">

View File

@ -28,8 +28,4 @@ public class Config {
* SWAD application key
*/
public static final String SWAD_APP_KEY = BuildConfig.SWAD_APP_KEY;
/**
* Google Analytics application key
*/
public static final String ANALYTICS_API_KEY = BuildConfig.ANALYTICS_API_KEY;
}

View File

@ -49,7 +49,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import es.ugr.swad.swadroid.analytics.SWADroidTracker;
import es.ugr.swad.swadroid.database.DataBaseHelper;
import es.ugr.swad.swadroid.gui.DialogFactory;
import es.ugr.swad.swadroid.gui.MenuExpandableListActivity;
@ -159,8 +158,6 @@ public class SWADMain extends MenuExpandableListActivity {
public void onCreate(Bundle icicle) {
int lastVersion, currentVersion;
SWADroidTracker.initTracker(getApplicationContext());
//Initialize screen
super.onCreate(icicle);
@ -181,6 +178,7 @@ public class SWADMain extends MenuExpandableListActivity {
//If this is an upgrade, show upgrade dialog
} else if (lastVersion < currentVersion) {
//showUpgradeDialog(this);
upgradeApp(lastVersion, currentVersion);
}
@ -188,7 +186,7 @@ public class SWADMain extends MenuExpandableListActivity {
currentRole = -1;
} catch (Exception ex) {
error(ex.getMessage(), ex, true);
error(ex.getMessage(), ex);
}
}
@ -227,8 +225,6 @@ public class SWADMain extends MenuExpandableListActivity {
createSpinnerAdapter();
createMenu();
}
SWADroidTracker.sendScreenView(getApplicationContext(), TAG);
}
private void showBirthdayMessage() {
@ -244,6 +240,8 @@ public class SWADMain extends MenuExpandableListActivity {
* @param currentVersion Current version of application
*/
private void firstRun(int currentVersion) {
Log.i(TAG, "Running application for first time. Setting current version to " + currentVersion);
Intent activity = new Intent(this, AccountAuthenticator.class);
//Configure automatic synchronization
@ -254,6 +252,8 @@ public class SWADMain extends MenuExpandableListActivity {
firstRun = true;
Preferences.initializeSelectedCourse();
Log.i(TAG, "First initialization completed successfully");
}
/**
@ -262,7 +262,8 @@ public class SWADMain extends MenuExpandableListActivity {
* @param currentVersion Version to which the application is updated
*/
private void upgradeApp(int lastVersion, int currentVersion) throws NoSuchAlgorithmException {
showUpgradeDialog(this);
Log.i(TAG, "Upgrading application from version " + lastVersion + " to version " + currentVersion);
dbHelper.upgradeDB();
if(lastVersion < 52) {
@ -285,6 +286,8 @@ public class SWADMain extends MenuExpandableListActivity {
}
Preferences.setLastVersion(currentVersion);
Log.i(TAG, "Application upgraded from version " + lastVersion + " to version " + currentVersion);
}
@Override

View File

@ -1,175 +0,0 @@
/*
*
* * This file is part of SWADroid.
* *
* * Copyright (C) 2010 Juan Miguel Boyero Corral <juanmi1982@gmail.com>
* *
* * SWADroid is free software: you can redistribute it and/or modify
* * it under the terms of the GNU General Public License as published by
* * the Free Software Foundation, either version 3 of the License, or
* * (at your option) any later version.
* *
* * SWADroid is distributed in the hope that it will be useful,
* * but WITHOUT ANY WARRANTY; without even the implied warranty of
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* * GNU General Public License for more details.
* *
* * You should have received a copy of the GNU General Public License
* * along with SWADroid. If not, see <http://www.gnu.org/licenses/>.
*
*/
package es.ugr.swad.swadroid.analytics;
import android.content.Context;
import android.util.Log;
import com.google.android.gms.analytics.ExceptionReporter;
import com.google.android.gms.analytics.GoogleAnalytics;
import com.google.android.gms.analytics.HitBuilders;
import com.google.android.gms.analytics.StandardExceptionParser;
import com.google.android.gms.analytics.Tracker;
import java.util.HashMap;
import es.ugr.swad.swadroid.Config;
import es.ugr.swad.swadroid.Constants;
/**
* Tracker for Google Play
*
* @author Juan Miguel Boyero Corral <juanmi1982@gmail.com>
*/
public class SWADroidTracker {
/**
* SWADroidTracker tag name for Logcat
*/
private static final String TAG = Constants.APP_TAG + " SWADroidTracker";
/**
* Enum used to identify the tracker that needs to be used for tracking.
*
* A single tracker is usually enough for most purposes. In case you do need multiple trackers,
* storing them all in Application object helps ensure that they are created only once per
* application instance.
*/
public enum TrackerName {
APP_TRACKER, // Tracker used only in this app.
GLOBAL_TRACKER, // Tracker used by all the apps from a company. eg: roll-up tracking.
ECOMMERCE_TRACKER, // Tracker used by all ecommerce transactions from a company.
}
private static HashMap<TrackerName, Tracker> mTrackers = new HashMap<>();
private static boolean isTrackerEnabled() {
return (!Config.ANALYTICS_API_KEY.isEmpty());
}
private static synchronized Tracker getTracker(Context context) {
if (!mTrackers.containsKey(TrackerName.APP_TRACKER)) {
GoogleAnalytics analytics = GoogleAnalytics.getInstance(context);
Tracker t = analytics.newTracker(Config.ANALYTICS_API_KEY);
t.enableExceptionReporting(true);
t.enableAutoActivityTracking(true);
mTrackers.put(TrackerName.APP_TRACKER, t);
}
return mTrackers.get(TrackerName.APP_TRACKER);
}
public static void initTracker(Context context) {
// Initialize a tracker using a Google Analytics property ID.
if(isTrackerEnabled()) {
GoogleAnalytics.getInstance(context).newTracker(Config.ANALYTICS_API_KEY);
ExceptionReporter exceptionHandler =
new ExceptionReporter(
getTracker(context),
Thread.getDefaultUncaughtExceptionHandler(),
context);
StandardExceptionParser exceptionParser =
new StandardExceptionParser(context, null) {
@Override
public String getDescription(String threadName, Throwable t) {
return "{" + threadName + "} " + Log.getStackTraceString(t);
}
};
exceptionHandler.setExceptionParser(exceptionParser);
// Make myHandler the new default uncaught exception handler.
Thread.setDefaultUncaughtExceptionHandler(exceptionHandler);
Log.i(TAG, "Google Play Services available. SWADroidTracker enabled");
} else {
Log.w(TAG, "Google Play Services not available. SWADroidTracker disabled");
}
}
public static void sendScreenView(Context context, String path) {
if(isTrackerEnabled()) {
// Get tracker.
Tracker t = getTracker(context);
// Set screen name.
// Where path is a String representing the screen name.
t.setScreenName(path);
// Send a screen view.
t.send(new HitBuilders.ScreenViewBuilder().build());
Log.i(TAG, "ScreenView sent for screen " + path);
}
}
public static void sendScreenView(Context context, String path, String category, String action, String label) {
if(isTrackerEnabled()) {
// Get tracker.
Tracker t = getTracker(context);
// Set screen name.
// Where path is a String representing the screen name.
t.setScreenName(path);
// Send a screen view.
t.send(new HitBuilders.ScreenViewBuilder().build());
// This event will also be sent with &cd=Home%20Screen.
// Build and send an Event.
t.send(new HitBuilders.EventBuilder()
.setCategory(category)
.setAction(action)
.setLabel(label)
.build());
// Clear the screen name field when we're done.
t.setScreenName(null);
Log.i(TAG, "ScreenView sent for screen " + path);
}
}
public static void sendException(Context context, Exception e, boolean fatal) {
if(isTrackerEnabled()) {
// Get tracker.
Tracker t = getTracker(context);
StandardExceptionParser exceptionParser =
new StandardExceptionParser(context, null) {
@Override
public String getDescription(String threadName, Throwable t) {
return "{" + threadName + "} " + Log.getStackTraceString(t);
}
};
t.send(new HitBuilders.ExceptionBuilder()
.setDescription(exceptionParser.getDescription(Thread.currentThread().getName(), e))
.setFatal(fatal)
.build()
);
Log.e(TAG, e.getMessage(), e);
}
}
}

View File

@ -1,7 +0,0 @@
<html>
<head>
</head>
<body>
Analytics package.
</body>
</html>

View File

@ -38,7 +38,6 @@ import java.util.Collection;
import java.util.List;
import es.ugr.swad.swadroid.Constants;
import es.ugr.swad.swadroid.analytics.SWADroidTracker;
import es.ugr.swad.swadroid.model.Course;
import es.ugr.swad.swadroid.model.Event;
import es.ugr.swad.swadroid.model.FrequentUser;
@ -417,8 +416,7 @@ public class DataBaseHelper {
null, //userBirthday
ent.getInt("userRole"));
} catch (ParseException e) {
//Send exception details to Google Analytics
SWADroidTracker.sendException(mCtx, e, false);
Log.e(TAG, e.getMessage(), e);
}
break;
case DataBaseHelper.DB_TABLE_USERS_ATTENDANCES:
@ -618,8 +616,7 @@ public class DataBaseHelper {
null,
ent.getInt("userRole"));
} catch (ParseException e) {
//Send exception details to Google Analytics
SWADroidTracker.sendException(mCtx, e, false);
Log.e(TAG, e.getMessage(), e);
}
}
@ -2315,7 +2312,6 @@ public class DataBaseHelper {
* Delete all tables from database
*/
public void clearDB() {
SWADroidTracker.sendScreenView(mCtx, TAG + " clearDB");
db.deleteTables();
Log.i(TAG, "All tables deleted");
}
@ -2324,7 +2320,7 @@ public class DataBaseHelper {
* Clean data of all tables from database. Removes users photos from external storage
*/
public void cleanTables() {
SWADroidTracker.sendScreenView(mCtx, TAG + " cleanTables");
Log.i(TAG, "Emptying all tables");
db.emptyTables();
compactDB();
@ -2340,8 +2336,7 @@ public class DataBaseHelper {
try {
wait();
} catch (InterruptedException e) {
//Send exception details to Google Analytics
SWADroidTracker.sendException(mCtx, e, false);
Log.e(TAG, e.getMessage(), e);
}
}
@ -2365,8 +2360,8 @@ public class DataBaseHelper {
notifyAll();
} else {
//Send exception details to Google Analytics
SWADroidTracker.sendException(mCtx, new DataBaseHelperException("No active transactions"), false);
Exception e = new DataBaseHelperException("No active transactions");
Log.e(TAG, e.getMessage(), e);
}
}
@ -2378,6 +2373,7 @@ public class DataBaseHelper {
* Compact the database
*/
private void compactDB() {
Log.i(TAG, "Compacting database");
db.getDB().execSQL("VACUUM;");
Log.i(TAG, "Database compacted");
}
@ -2396,6 +2392,9 @@ public class DataBaseHelper {
*/
public void upgradeDB() {
int dbVersion = db.getDB().getVersion();
Log.i(TAG, "Upgrading database");
/*
* Modify database keeping data:
* 1. Create temporary table __DB_TABLE_GROUPS (with the new model)

View File

@ -24,7 +24,7 @@ import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.graphics.BitmapFactory;
import android.support.v4.app.NotificationCompat;
import androidx.core.app.NotificationCompat;
import es.ugr.swad.swadroid.utils.NotificationUtils;

View File

@ -19,7 +19,6 @@ import org.apache.commons.io.IOUtils;
import java.io.InputStream;
import es.ugr.swad.swadroid.R;
import es.ugr.swad.swadroid.analytics.SWADroidTracker;
/**
* Class for create dialogs.
@ -238,8 +237,6 @@ public class DialogFactory {
* @param tag Module tag
* @param message Error message string
* @param ex Exception thrown
* @param sendException true if the error report has to be sent
* false otherwise
* @param isDebuggable true if the application is debuggable (develop mode). Activates Logcat messages
* false otherwise
* @param onClickListener ClickListener associated to the neutral button
@ -247,7 +244,7 @@ public class DialogFactory {
*/
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public static AlertDialog createErrorDialog(Context context, String tag, String message, Exception ex,
boolean sendException, boolean isDebuggable, DialogInterface.OnClickListener onClickListener) {
boolean isDebuggable, DialogInterface.OnClickListener onClickListener) {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context)
.setTitle(R.string.title_error_dialog)
@ -258,11 +255,6 @@ public class DialogFactory {
if (ex != null) {
Log.e(tag, ex.getMessage(), ex);
// Send exception details to Google Analytics
if (!isDebuggable && sendException) {
SWADroidTracker.sendException(context, ex, false);
}
}
return alertDialogBuilder.create();

View File

@ -26,7 +26,7 @@ import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
@ -138,14 +138,14 @@ public class MenuActivity extends AppCompatActivity {
*
* @param message Error message to show.
*/
protected void error(String message, Exception ex, boolean sendException) {
protected void error(String message, Exception ex) {
DialogInterface.OnClickListener onClickListener = new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
finish();
}
};
AlertDialog errorDialog = DialogFactory.createErrorDialog(this, TAG, message, ex, sendException,
AlertDialog errorDialog = DialogFactory.createErrorDialog(this, TAG, message, ex,
isDebuggable, onClickListener);
errorDialog.show();
@ -208,7 +208,7 @@ public class MenuActivity extends AppCompatActivity {
getPackageName(), 0);
isDebuggable = (ApplicationInfo.FLAG_DEBUGGABLE != 0);
} catch (Exception ex) {
error(ex.getMessage(), ex, true);
error(ex.getMessage(), ex);
}
}
@ -232,7 +232,7 @@ public class MenuActivity extends AppCompatActivity {
try {
dbHelper = new DataBaseHelper(this);
} catch (Exception ex) {
error(ex.getMessage(), ex, true);
error(ex.getMessage(), ex);
}
}
}

View File

@ -26,7 +26,7 @@ import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
@ -145,14 +145,14 @@ public class MenuExpandableListActivity extends AppCompatActivity {
*
* @param message Error message to show.
*/
protected void error(String message, Exception ex, boolean sendException) {
protected void error(String message, Exception ex) {
DialogInterface.OnClickListener onClickListener = new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
finish();
}
};
AlertDialog errorDialog = DialogFactory.createErrorDialog(this, TAG, message, ex, sendException,
AlertDialog errorDialog = DialogFactory.createErrorDialog(this, TAG, message, ex,
isDebuggable, onClickListener);
errorDialog.show();
@ -224,7 +224,7 @@ public class MenuExpandableListActivity extends AppCompatActivity {
isDebuggable = (ApplicationInfo.FLAG_DEBUGGABLE != 0);
isSWADMain = this instanceof SWADMain;
} catch (Exception ex) {
error(ex.getMessage(), ex, true);
error(ex.getMessage(), ex);
}
}
@ -248,7 +248,7 @@ public class MenuExpandableListActivity extends AppCompatActivity {
try {
dbHelper = new DataBaseHelper(this);
} catch (Exception ex) {
error(ex.getMessage(), ex, true);
error(ex.getMessage(), ex);
}
}

View File

@ -24,7 +24,7 @@ import android.animation.ValueAnimator;
import android.annotation.TargetApi;
import android.graphics.Rect;
import android.os.Build;
import android.support.v4.widget.SwipeRefreshLayout;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;

View File

@ -29,6 +29,8 @@ import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
import com.google.firebase.analytics.FirebaseAnalytics;
import org.ksoap2.SoapFault;
import org.ksoap2.transport.HttpResponseException;
import org.kxml2.kdom.Element;
@ -63,6 +65,10 @@ public abstract class Module extends MenuActivity {
* Class Module's tag name for Logcat
*/
private static final String TAG = Constants.APP_TAG + " Module";
/**
* Obtain Firebase Analytics instance
*/
protected FirebaseAnalytics mFirebaseAnalytics = FirebaseAnalytics.getInstance(this);
/**
* Async Task for background jobs
*/
@ -332,7 +338,6 @@ public abstract class Module extends MenuActivity {
protected void onPostExecute(Void unused) {
String errorMsg;
int httpStatusCode;
boolean sendException = true;
if (e != null) {
/**
@ -345,11 +350,9 @@ public abstract class Module extends MenuActivity {
switch (es.faultstring) {
case "Bad log in":
errorMsg = getString(R.string.errorBadLoginMsg);
sendException = false;
break;
case "Bad web service key":
errorMsg = getString(R.string.errorBadLoginMsg);
sendException = false;
// Force logout and reset password (this will show again
// the login screen)
@ -365,7 +368,6 @@ public abstract class Module extends MenuActivity {
}
} else if ((e.getClass() == TimeoutException.class) || (e.getClass() == SocketTimeoutException.class)) {
errorMsg = getString(R.string.errorTimeoutMsg);
sendException = false;
} else if ((e.getClass() == CertificateException.class) || (e .getClass() == SSLException.class)) {
errorMsg = getString(R.string.errorServerCertificateMsg);
} else if (e.getClass() == HttpResponseException.class) {
@ -378,7 +380,6 @@ public abstract class Module extends MenuActivity {
break;
case 503: errorMsg = getString(R.string.errorServiceUnavailableMsg);
sendException = false;
break;
default: errorMsg = e.getMessage();
@ -396,7 +397,7 @@ public abstract class Module extends MenuActivity {
}
// Request finalized with errors
error(errorMsg, e, sendException);
error(errorMsg, e);
setResult(RESULT_CANCELED);
// Launch database rollback

View File

@ -21,6 +21,8 @@ package es.ugr.swad.swadroid.modules.account;
import android.os.Bundle;
import com.google.firebase.analytics.FirebaseAnalytics;
import org.ksoap2.SoapFault;
import org.ksoap2.serialization.SoapObject;
@ -122,6 +124,10 @@ public class CreateAccount extends Module {
//Request finalized without errors
setResult(RESULT_OK);
Bundle bundle = new Bundle();
bundle.putString(FirebaseAnalytics.Param.METHOD, "requestService");
mFirebaseAnalytics.logEvent(FirebaseAnalytics.Event.SIGN_UP, bundle);
}
/* (non-Javadoc)

View File

@ -22,7 +22,7 @@ import android.content.Intent;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatActivity;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
@ -44,7 +44,6 @@ import es.ugr.swad.swadroid.Constants;
import es.ugr.swad.swadroid.gui.ProgressScreen;
import es.ugr.swad.swadroid.preferences.Preferences;
import es.ugr.swad.swadroid.R;
import es.ugr.swad.swadroid.analytics.SWADroidTracker;
import es.ugr.swad.swadroid.gui.DialogFactory;
import es.ugr.swad.swadroid.utils.Utils;
@ -196,8 +195,6 @@ public class CreateAccountActivity extends AppCompatActivity implements AdapterV
* Creates a new account
*/
private void createAccount() {
SWADroidTracker.sendScreenView(getApplicationContext(), "SWADroid CreateAccount");
Intent intent;
// Values for text field at the time of the create account attempt.
@ -317,7 +314,7 @@ public class CreateAccountActivity extends AppCompatActivity implements AdapterV
}
errorDialog = DialogFactory.createErrorDialog(this, TAG,
errorMsg, null, false, false, new DialogInterface.OnClickListener() {
errorMsg, null, false, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {

View File

@ -31,7 +31,6 @@ import java.util.List;
import java.util.Vector;
import es.ugr.swad.swadroid.Constants;
import es.ugr.swad.swadroid.analytics.SWADroidTracker;
import es.ugr.swad.swadroid.database.DataBaseHelper;
import es.ugr.swad.swadroid.model.Course;
import es.ugr.swad.swadroid.model.Model;
@ -90,8 +89,6 @@ public class Courses extends Module {
@Override
protected void onStart() {
super.onStart();
SWADroidTracker.sendScreenView(getApplicationContext(), TAG);
runConnection();
}
@ -210,12 +207,7 @@ public class Courses extends Module {
try {
dbHelper.emptyTable(DataBaseHelper.DB_TABLE_COURSES);
} catch (Exception e) {
e.printStackTrace();
//Send exception details to Google Analytics
if (!isDebuggable) {
SWADroidTracker.sendException(context, e, false);
}
Log.e(TAG, e.getMessage(), e);
}
}

View File

@ -19,13 +19,16 @@
package es.ugr.swad.swadroid.modules.downloads;
import android.content.Context;
import android.util.Log;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collections;
@ -33,8 +36,9 @@ import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import es.ugr.swad.swadroid.analytics.SWADroidTracker;
import es.ugr.swad.swadroid.Constants;
/**
@ -60,6 +64,11 @@ public class DirectoryNavigator {
*/
private Context mContext;
/**
* Downloads tag name for Logcat
*/
private static final String TAG = Constants.APP_TAG + " DirectoryNavigator";
/**
* Constructor.
*
@ -278,9 +287,8 @@ public class DirectoryNavigator {
}
}
}
} catch (Exception e) {
//Send exception details to Google Analytics
SWADroidTracker.sendException(mContext, e, false);
} catch (ParserConfigurationException | IOException | SAXException ex) {
Log.e(TAG, ex.getMessage(), ex);
}
//If we don't find the entire path, we throw an exception.

View File

@ -31,10 +31,10 @@ import android.graphics.Typeface;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.FileProvider;
import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.core.content.FileProvider;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
@ -56,7 +56,6 @@ import java.util.List;
import es.ugr.swad.swadroid.Constants;
import es.ugr.swad.swadroid.R;
import es.ugr.swad.swadroid.analytics.SWADroidTracker;
import es.ugr.swad.swadroid.gui.FontManager;
import es.ugr.swad.swadroid.gui.MenuActivity;
import es.ugr.swad.swadroid.gui.ProgressScreen;
@ -190,7 +189,6 @@ public class DownloadsManager extends MenuActivity {
@Override
protected void onStart() {
super.onStart();
SWADroidTracker.sendScreenView(getApplicationContext(), TAG);
// check Android 6 permission
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)

View File

@ -27,7 +27,6 @@ import java.net.URL;
import es.ugr.swad.swadroid.Constants;
import es.ugr.swad.swadroid.R;
import es.ugr.swad.swadroid.analytics.SWADroidTracker;
/**
* Download the file located at the given URL, save it to a file.
@ -72,9 +71,6 @@ public class FileDownloaderAsyncTask extends AsyncTask<String, Integer, Boolean>
} catch (MalformedURLException e) {
Log.e(TAG, "Incorrect URL", e);
//Send exception details to Google Analytics
SWADroidTracker.sendException(mContext, e, false);
downloadSuccess = false;
}

View File

@ -29,7 +29,6 @@ import java.util.Vector;
import es.ugr.swad.swadroid.Constants;
import es.ugr.swad.swadroid.R;
import es.ugr.swad.swadroid.analytics.SWADroidTracker;
import es.ugr.swad.swadroid.model.Group;
import es.ugr.swad.swadroid.modules.login.Login;
import es.ugr.swad.swadroid.modules.Module;
@ -73,14 +72,12 @@ public class GetFile extends Module {
@Override
protected void onStart() {
super.onStart();
SWADroidTracker.sendScreenView(getApplicationContext(), TAG);
try {
runConnection();
} catch (Exception e) {
String errorMsg = getString(R.string.errorServerResponseMsg);
error(errorMsg, e, true);
error(errorMsg, e);
}
}

View File

@ -21,8 +21,8 @@ package es.ugr.swad.swadroid.modules.groups;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Typeface;
import android.support.v4.content.ContextCompat;
import android.support.v4.util.LongSparseArray;
import androidx.core.content.ContextCompat;
import androidx.collection.LongSparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
@ -198,16 +198,16 @@ public class EnrollmentExpandableListAdapter extends BaseExpandableListAdapter {
if (multiple == 0 && role != Constants.TEACHER_TYPE_CODE) { //single inscriptions:
holder.checkBox.setVisibility(View.GONE);
holder.radioButton.setVisibility(View.VISIBLE);
holder.radioButton.setText(groupName);
} else { //multiple inscriptions :
holder.checkBox.setVisibility(View.VISIBLE);
holder.radioButton.setVisibility(View.GONE);
holder.checkBox.setText(groupName);
holder.checkBox.setChecked(member != 0);
}
holder.radioButton.setText(groupName);
holder.checkBox.setChecked(member != 0);
holder.nStudentText.setText(context.getString(R.string.numStudent) + ": " + String.valueOf(students));
if (maxStudents != -1) {

View File

@ -13,7 +13,6 @@ import java.util.Vector;
import es.ugr.swad.swadroid.Constants;
import es.ugr.swad.swadroid.R;
import es.ugr.swad.swadroid.analytics.SWADroidTracker;
import es.ugr.swad.swadroid.database.DataBaseHelper;
import es.ugr.swad.swadroid.model.GroupType;
import es.ugr.swad.swadroid.model.Model;
@ -59,14 +58,12 @@ public class GroupTypes extends Module {
@Override
protected void onStart() {
super.onStart();
SWADroidTracker.sendScreenView(getApplicationContext(), TAG);
try {
runConnection();
} catch (Exception e) {
String errorMsg = getString(R.string.errorServerResponseMsg);
error(errorMsg, e, true);
error(errorMsg, e);
}
}

View File

@ -31,7 +31,6 @@ import java.util.Vector;
import es.ugr.swad.swadroid.Constants;
import es.ugr.swad.swadroid.R;
import es.ugr.swad.swadroid.analytics.SWADroidTracker;
import es.ugr.swad.swadroid.database.DataBaseHelper;
import es.ugr.swad.swadroid.model.Group;
import es.ugr.swad.swadroid.model.Model;
@ -79,14 +78,12 @@ public class Groups extends Module {
@Override
protected void onStart() {
super.onStart();
SWADroidTracker.sendScreenView(getApplicationContext(), TAG);
try {
runConnection();
} catch (Exception e) {
String errorMsg = getString(R.string.errorServerResponseMsg);
error(errorMsg, e, true);
error(errorMsg, e);
}
}

View File

@ -24,7 +24,7 @@ import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.util.LongSparseArray;
import androidx.collection.LongSparseArray;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
@ -35,7 +35,6 @@ import java.util.List;
import es.ugr.swad.swadroid.Constants;
import es.ugr.swad.swadroid.R;
import es.ugr.swad.swadroid.analytics.SWADroidTracker;
import es.ugr.swad.swadroid.database.DataBaseHelper;
import es.ugr.swad.swadroid.gui.DialogFactory;
import es.ugr.swad.swadroid.gui.MenuExpandableListActivity;
@ -93,8 +92,6 @@ public class MyGroupsManager extends MenuExpandableListActivity {
showProgressLoading();
SWADroidTracker.sendScreenView(getApplicationContext(), TAG);
List<Model> groupTypes = dbHelper.getAllRows(DataBaseHelper.DB_TABLE_GROUP_TYPES, "courseCode = " + courseCode, "groupTypeName");
List<Group> groups = dbHelper.getGroups(courseCode);
if ((!groupTypes.isEmpty()) && (!groups.isEmpty())) {

View File

@ -88,7 +88,7 @@ public class SendMyGroups extends Module {
runConnection();
} catch (Exception e) {
String errorMsg = getString(R.string.errorServerResponseMsg);
error(errorMsg, e, true);
error(errorMsg, e);
}
}

View File

@ -14,7 +14,6 @@ import org.ksoap2.serialization.SoapObject;
import es.ugr.swad.swadroid.Constants;
import es.ugr.swad.swadroid.R;
import es.ugr.swad.swadroid.analytics.SWADroidTracker;
import es.ugr.swad.swadroid.gui.ProgressScreen;
import es.ugr.swad.swadroid.gui.WebViewFactory;
import es.ugr.swad.swadroid.model.User;
@ -149,12 +148,11 @@ public class Information extends Module {
protected void onStart() {
super.onStart();
SWADroidTracker.sendScreenView(getApplicationContext(), TAG + " " + infoTypeToAdd);
try {
runConnection();
} catch (Exception e) {
String errorMsg = getString(R.string.errorServerResponseMsg);
error(errorMsg, e, true);
error(errorMsg, e);
}
}

View File

@ -22,6 +22,8 @@ package es.ugr.swad.swadroid.modules.login;
import android.os.Bundle;
import android.util.Log;
import com.google.firebase.analytics.FirebaseAnalytics;
import org.ksoap2.SoapFault;
import org.ksoap2.serialization.SoapObject;
@ -173,6 +175,10 @@ public class Login extends Module {
//Request finalized without errors
setResult(RESULT_OK);
Bundle bundle = new Bundle();
bundle.putString(FirebaseAnalytics.Param.METHOD, "requestService");
mFirebaseAnalytics.logEvent(FirebaseAnalytics.Event.LOGIN, bundle);
}
/* (non-Javadoc)

View File

@ -21,7 +21,7 @@ import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatActivity;
import android.text.InputType;
import android.text.TextUtils;
import android.util.Log;
@ -43,7 +43,6 @@ import java.util.List;
import es.ugr.swad.swadroid.Constants;
import es.ugr.swad.swadroid.R;
import es.ugr.swad.swadroid.analytics.SWADroidTracker;
import es.ugr.swad.swadroid.gui.DialogFactory;
import es.ugr.swad.swadroid.gui.ProgressScreen;
import es.ugr.swad.swadroid.modules.account.CreateAccountActivity;
@ -222,7 +221,6 @@ public class LoginActivity extends AppCompatActivity implements AdapterView.OnIt
* are presented and no actual login attempt is made.
*/
private void attemptLogin() {
SWADroidTracker.sendScreenView(getApplicationContext(), "SWADroid Login");
// Values for ID and password at the time of the login attempt.
String idValue;
@ -353,8 +351,6 @@ public class LoginActivity extends AppCompatActivity implements AdapterView.OnIt
}
private void whyMyPasswordNotWorkDialog() {
SWADroidTracker.sendScreenView(getApplicationContext(), "SWADroid WhyMyPasswordNotWork");
AlertDialog passwordNotWorkDialog =
DialogFactory.createNeutralDialog(this,
R.layout.dialog_why_password,
@ -373,8 +369,6 @@ public class LoginActivity extends AppCompatActivity implements AdapterView.OnIt
}
private void recoverPasswordDialog() {
SWADroidTracker.sendScreenView(getApplicationContext(), "SWADroid RecoverPassword");
AlertDialog.Builder builder = new AlertDialog.Builder(this);
final EditText user = new EditText(getApplicationContext());

View File

@ -26,7 +26,6 @@ import android.util.Log;
import org.ksoap2.serialization.SoapObject;
import es.ugr.swad.swadroid.Constants;
import es.ugr.swad.swadroid.analytics.SWADroidTracker;
import es.ugr.swad.swadroid.model.User;
import es.ugr.swad.swadroid.modules.Module;
import es.ugr.swad.swadroid.modules.login.Login;
@ -73,8 +72,6 @@ public class GetMarks extends Module {
protected void onStart() {
super.onStart();
SWADroidTracker.sendScreenView(getApplicationContext(), TAG);
fileCode = this.getIntent().getLongExtra("fileCode", 0);
runConnection();

View File

@ -11,7 +11,6 @@ import android.webkit.WebView;
import es.ugr.swad.swadroid.Constants;
import es.ugr.swad.swadroid.R;
import es.ugr.swad.swadroid.analytics.SWADroidTracker;
import es.ugr.swad.swadroid.gui.MenuActivity;
import es.ugr.swad.swadroid.gui.WebViewFactory;
import es.ugr.swad.swadroid.modules.courses.Courses;
@ -49,8 +48,6 @@ public class Marks extends MenuActivity {
protected void onStart() {
super.onStart();
SWADroidTracker.sendScreenView(getApplicationContext(), TAG);
String content = this.getIntent().getStringExtra("content");
content = Utils.fixLinks(content);

View File

@ -22,7 +22,7 @@ import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Paint;
import android.os.Bundle;
import android.support.v7.app.AlertDialog;
import androidx.appcompat.app.AlertDialog;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
@ -46,7 +46,6 @@ import java.util.Vector;
import es.ugr.swad.swadroid.Constants;
import es.ugr.swad.swadroid.R;
import es.ugr.swad.swadroid.analytics.SWADroidTracker;
import es.ugr.swad.swadroid.database.DataBaseHelper;
import es.ugr.swad.swadroid.gui.ImageFactory;
import es.ugr.swad.swadroid.gui.ProgressScreen;
@ -231,12 +230,6 @@ public class Messages extends Module {
setMETHOD_NAME("sendMessage");
}
@Override
protected void onStart() {
super.onStart();
SWADroidTracker.sendScreenView(getApplicationContext(), TAG);
}
/**
* Reads user input
*/
@ -463,7 +456,7 @@ public class Messages extends Module {
}
} catch (Exception e) {
String errorMsg = getString(R.string.errorServerResponseMsg);
error(errorMsg, e, true);
error(errorMsg, e);
}
return true;
case android.R.id.home:

View File

@ -7,9 +7,9 @@ import android.content.res.Configuration;
import android.graphics.Typeface;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.SearchView;
import androidx.core.view.MenuItemCompat;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.SearchView;
import android.text.SpannableString;
import android.text.style.StyleSpan;
import android.util.Log;
@ -28,7 +28,6 @@ import java.util.List;
import java.util.Vector;
import es.ugr.swad.swadroid.Constants;
import es.ugr.swad.swadroid.R;
import es.ugr.swad.swadroid.analytics.SWADroidTracker;
import es.ugr.swad.swadroid.database.DataBaseHelper;
import es.ugr.swad.swadroid.gui.ProgressScreen;
import es.ugr.swad.swadroid.model.FrequentUser;
@ -199,12 +198,6 @@ public class SearchUsers extends Module implements SearchView.OnQueryTextListene
setMETHOD_NAME("findUsers");
}
@Override
protected void onStart() {
super.onStart();
SWADroidTracker.sendScreenView(getApplicationContext(), TAG);
}
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
@Override
public boolean onCreateOptionsMenu(Menu menu) {

View File

@ -33,7 +33,6 @@ import android.widget.Toast;
import es.ugr.swad.swadroid.Constants;
import es.ugr.swad.swadroid.R;
import es.ugr.swad.swadroid.analytics.SWADroidTracker;
import es.ugr.swad.swadroid.gui.DialogFactory;
import es.ugr.swad.swadroid.model.User;
import es.ugr.swad.swadroid.modules.courses.Courses;
@ -84,7 +83,7 @@ public class Notices extends Module {
}
} catch (Exception e) {
String errorMsg = getString(R.string.errorServerResponseMsg);
error(errorMsg, e, true);
error(errorMsg, e);
}
}
};
@ -189,7 +188,7 @@ public class Notices extends Module {
@Override
protected void onStart() {
super.onStart();
SWADroidTracker.sendScreenView(getApplicationContext(), TAG);
selectedCourseCode = Courses.getSelectedCourseCode();
launchNoticeDialog();
}

View File

@ -30,7 +30,6 @@ import android.widget.TextView;
import es.ugr.swad.swadroid.Constants;
import es.ugr.swad.swadroid.R;
import es.ugr.swad.swadroid.analytics.SWADroidTracker;
import es.ugr.swad.swadroid.gui.ImageFactory;
import es.ugr.swad.swadroid.gui.MenuActivity;
import es.ugr.swad.swadroid.gui.WebViewFactory;
@ -122,7 +121,6 @@ public class NotificationItem extends MenuActivity {
Log.w(TAG, "Not connected: Marking the notification " + notifCode + " as read in SWAD was deferred");
}
}
SWADroidTracker.sendScreenView(getApplicationContext(), TAG);
}
/* (non-Javadoc)

View File

@ -30,7 +30,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.widget.SwipeRefreshLayout;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
@ -50,7 +50,6 @@ import java.util.Vector;
import es.ugr.swad.swadroid.Constants;
import es.ugr.swad.swadroid.R;
import es.ugr.swad.swadroid.analytics.SWADroidTracker;
import es.ugr.swad.swadroid.database.DataBaseHelper;
import es.ugr.swad.swadroid.gui.AlertNotificationFactory;
import es.ugr.swad.swadroid.model.Model;
@ -341,7 +340,6 @@ public class Notifications extends Module implements
@Override
protected void onResume() {
super.onResume();
SWADroidTracker.sendScreenView(getApplicationContext(), TAG);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(NotificationsSyncAdapterService.START_SYNC);
@ -543,7 +541,7 @@ public class Notifications extends Module implements
try {
dbHelper.emptyTable(DataBaseHelper.DB_TABLE_NOTIFICATIONS);
} catch (Exception e) {
error(e.getMessage(), e, true);
error(e.getMessage(), e);
}
}
@ -570,7 +568,7 @@ public class Notifications extends Module implements
notifCount = intent.getIntExtra("notifCount", 0);
errorMessage = intent.getStringExtra("errorMessage");
if ((errorMessage != null) && !errorMessage.equals("")) {
error(errorMessage, null, true);
error(errorMessage, null);
} else if (notifCount == 0) {
Toast.makeText(context, R.string.NoNotificationsMsg,
Toast.LENGTH_LONG).show();

View File

@ -20,7 +20,7 @@ package es.ugr.swad.swadroid.modules.notifications;
import android.app.Activity;
import android.graphics.Typeface;
import android.support.v4.content.ContextCompat;
import androidx.core.content.ContextCompat;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

View File

@ -24,7 +24,6 @@ import android.util.Log;
import org.ksoap2.serialization.SoapPrimitive;
import es.ugr.swad.swadroid.Constants;
import es.ugr.swad.swadroid.analytics.SWADroidTracker;
import es.ugr.swad.swadroid.modules.Module;
import es.ugr.swad.swadroid.modules.login.Login;
import es.ugr.swad.swadroid.utils.Utils;
@ -53,13 +52,6 @@ public class NotificationsMarkAllAsRead extends Module {
getSupportActionBar().hide();
runConnection();
}
@Override
protected void onStart() {
super.onStart();
SWADroidTracker.sendScreenView(getApplicationContext(), TAG);
}
/* (non-Javadoc)
* @see es.ugr.swad.swadroid.modules.Module#requestService()

View File

@ -52,7 +52,6 @@ import javax.net.ssl.SSLException;
import es.ugr.swad.swadroid.Config;
import es.ugr.swad.swadroid.Constants;
import es.ugr.swad.swadroid.R;
import es.ugr.swad.swadroid.analytics.SWADroidTracker;
import es.ugr.swad.swadroid.database.DataBaseHelper;
import es.ugr.swad.swadroid.gui.AlertNotificationFactory;
import es.ugr.swad.swadroid.model.Model;
@ -106,7 +105,6 @@ public class NotificationsSyncAdapterService extends Service {
@Override
public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) {
boolean sendException = true;
int httpStatusCode;
try {
@ -121,11 +119,9 @@ public class NotificationsSyncAdapterService extends Service {
switch (es.faultstring) {
case "Bad log in":
errorMessage = mContext.getString(R.string.errorBadLoginMsg);
sendException = false;
break;
case "Bad web service key":
errorMessage = mContext.getString(R.string.errorBadLoginMsg);
sendException = false;
// Force logout and reset password (this will show again
// the login screen)
@ -141,7 +137,6 @@ public class NotificationsSyncAdapterService extends Service {
}
} else if ((e.getClass() == TimeoutException.class) || (e.getClass() == SocketTimeoutException.class)) {
errorMessage = mContext.getString(R.string.errorTimeoutMsg);
sendException = false;
} else if ((e.getClass() == CertificateException.class) || (e .getClass() == SSLException.class)) {
errorMessage = mContext.getString(R.string.errorServerCertificateMsg);
} else if (e.getClass() == HttpResponseException.class) {
@ -154,7 +149,6 @@ public class NotificationsSyncAdapterService extends Service {
break;
case 503: errorMessage = mContext.getString(R.string.errorServiceUnavailableMsg);
sendException = false;
break;
default: errorMessage = e.getMessage();
@ -176,12 +170,7 @@ public class NotificationsSyncAdapterService extends Service {
dbHelper.endTransaction(false);
}
//Send exception details to Google Analytics
if(sendException) {
SWADroidTracker.sendException(mContext, e, false);
} else {
Log.e(TAG, errorMessage, e);
}
Log.e(TAG, errorMessage, e);
//Notify synchronization stop
Intent stopIntent = new Intent();
@ -215,9 +204,6 @@ public class NotificationsSyncAdapterService extends Service {
webserviceClient = null;
} catch (Exception e) {
Log.e(TAG, "Error initializing database and preferences", e);
//Send exception details to Google Analytics
SWADroidTracker.sendException(mCtx, e, false);
}
super.onCreate();

View File

@ -18,7 +18,6 @@ import java.util.Map;
import es.ugr.swad.swadroid.Constants;
import es.ugr.swad.swadroid.R;
import es.ugr.swad.swadroid.analytics.SWADroidTracker;
import es.ugr.swad.swadroid.gui.MenuActivity;
import es.ugr.swad.swadroid.modules.login.Login;
@ -65,8 +64,6 @@ public class GenerateQR extends MenuActivity {
protected void onStart() {
super.onStart();
SWADroidTracker.sendScreenView(getApplicationContext(), TAG);
if (!Login.isLogged() || (Login.getLoggedUser() == null)) {
Intent activity = new Intent(getApplicationContext(), Login.class);
startActivityForResult(activity, Constants.LOGIN_REQUEST_CODE);
@ -116,7 +113,7 @@ public class GenerateQR extends MenuActivity {
qrCode = barcodeEncoder.encodeBitmap(qrContents, BarcodeFormat.QR_CODE, CODE_WIDTH, CODE_HEIGHT, hintMap);
qr_image.setImageBitmap(qrCode);
} catch (WriterException e) {
error(e.getMessage(), e, true);
error(e.getMessage(), e);
}
}
}

View File

@ -3,7 +3,7 @@ package es.ugr.swad.swadroid.modules.rollcall;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatActivity;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;

View File

@ -23,7 +23,7 @@ package es.ugr.swad.swadroid.modules.rollcall;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Typeface;
import android.support.v4.content.ContextCompat;
import androidx.core.content.ContextCompat;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

View File

@ -80,7 +80,7 @@ public class EventsDownload extends Module {
runConnection();
} catch (Exception e) {
String errorMsg = getString(R.string.errorServerResponseMsg);
error(errorMsg, e, true);
error(errorMsg, e);
}
}

View File

@ -27,7 +27,7 @@ import android.database.Cursor;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.widget.SwipeRefreshLayout;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import android.util.Log;
import android.view.View;
import android.widget.AbsListView;
@ -39,7 +39,6 @@ import java.lang.ref.WeakReference;
import es.ugr.swad.swadroid.Constants;
import es.ugr.swad.swadroid.R;
import es.ugr.swad.swadroid.analytics.SWADroidTracker;
import es.ugr.swad.swadroid.gui.DialogFactory;
import es.ugr.swad.swadroid.gui.MenuExpandableListActivity;
import es.ugr.swad.swadroid.gui.ProgressScreen;
@ -51,197 +50,197 @@ import es.ugr.swad.swadroid.modules.courses.Courses;
* @author Juan Miguel Boyero Corral <juanmi1982@gmail.com>
*/
public class Rollcall extends MenuExpandableListActivity implements
SwipeRefreshLayout.OnRefreshListener {
SwipeRefreshLayout.OnRefreshListener {
/**
* Rollcall tag name for Logcat
*/
private static final String TAG = Constants.APP_TAG + " Rollcall";
/**
* ListView of events
*/
private static ListView lvEvents;
/**
* Adapter for ListView of events
*/
private static EventsCursorAdapter adapter;
private final RefreshAdapterHandler mHandler = new RefreshAdapterHandler(this);
private final Runnable mRunnable = new Runnable() {
@Override
public void run() {
/**
* Rollcall tag name for Logcat
*/
private static final String TAG = Constants.APP_TAG + " Rollcall";
/**
* ListView of events
*/
private ListView lvEvents;
/**
* Adapter for ListView of events
*/
private static EventsCursorAdapter adapter;
private final RefreshAdapterHandler mHandler = new RefreshAdapterHandler(this);
private final Runnable mRunnable = new Runnable() {
@Override
public void run() {
/*
Database cursor for Adapter of events
*/
Cursor dbCursor = dbHelper.getEventsCourseCursor(Courses.getSelectedCourseCode());
startManagingCursor(dbCursor);
Cursor dbCursor = dbHelper.getEventsCourseCursor(Courses.getSelectedCourseCode());
startManagingCursor(dbCursor);
/*
* If there aren't events to show, hide the events lvEvents
* and show the empty events message
*/
if ((dbCursor == null) || (dbCursor.getCount() == 0)) {
Log.d(TAG, "Events list is empty");
/*
* If there aren't events to show, hide the events lvEvents
* and show the empty events message
*/
if ((dbCursor == null) || (dbCursor.getCount() == 0)) {
Log.d(TAG, "Events list is empty");
emptyEventsTextView.setText(R.string.eventsEmptyListMsg);
emptyEventsTextView.setVisibility(View.VISIBLE);
emptyEventsTextView.setText(R.string.eventsEmptyListMsg);
emptyEventsTextView.setVisibility(View.VISIBLE);
lvEvents.setVisibility(View.GONE);
} else {
Log.d(TAG, "Events list is not empty");
lvEvents.setVisibility(View.GONE);
} else {
Log.d(TAG, "Events list is not empty");
emptyEventsTextView.setVisibility(View.GONE);
lvEvents.setVisibility(View.VISIBLE);
}
emptyEventsTextView.setVisibility(View.GONE);
lvEvents.setVisibility(View.VISIBLE);
}
adapter = new EventsCursorAdapter(getBaseContext(), dbCursor, dbHelper);
lvEvents.setAdapter(adapter);
adapter = new EventsCursorAdapter(getBaseContext(), dbCursor, dbHelper);
lvEvents.setAdapter(adapter);
mProgressScreen.hide();
}
};
/**
* TextView for the empty events message
*/
private TextView emptyEventsTextView;
/**
* Layout with "Pull to refresh" function
*/
private SwipeRefreshLayout refreshLayout;
/**
* Progress screen
*/
private ProgressScreen mProgressScreen;
/**
* ListView click listener
*/
private ListView.OnItemClickListener clickListener = new ListView.OnItemClickListener() {
mProgressScreen.hide();
}
};
/**
* TextView for the empty events message
*/
private TextView emptyEventsTextView;
/**
* Layout with "Pull to refresh" function
*/
private SwipeRefreshLayout refreshLayout;
/**
* Progress screen
*/
private ProgressScreen mProgressScreen;
/**
* ListView click listener
*/
private ListView.OnItemClickListener clickListener = new ListView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent activity = new Intent(getApplicationContext(),
UsersActivity.class);
activity.putExtra("attendanceEventCode",
(int) adapter.getItemId(position));
startActivity(activity);
}
};
/* (non-Javadoc)
* @see es.ugr.swad.swadroid.MenuExpandableListActivity#onCreate(android.os.Bundle)
*/
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent activity = new Intent(getApplicationContext(),
UsersActivity.class);
activity.putExtra("attendanceEventCode",
(int) adapter.getItemId(position));
startActivity(activity);
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.list_items_pulltorefresh);
refreshLayout = findViewById(R.id.swipe_container_list);
emptyEventsTextView = findViewById(R.id.list_item_title);
View mProgressScreenView = findViewById(R.id.progress_screen);
mProgressScreen = new ProgressScreen(mProgressScreenView, refreshLayout,
getString(R.string.loadingMsg), this);
lvEvents = findViewById(R.id.list_pulltorefresh);
lvEvents.setOnItemClickListener(clickListener);
lvEvents.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView absListView, int scrollState) {
}
@Override
public void onScroll(AbsListView absListView, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
boolean enable = true;
if ((lvEvents != null) && (lvEvents.getChildCount() > 0)) {
// check if the first item of the list is visible
boolean firstItemVisible = lvEvents.getFirstVisiblePosition() == 0;
// check if the top of the first item is visible
boolean topOfFirstItemVisible = lvEvents.getChildAt(0).getTop() == 0;
// enabling or disabling the refresh layout
enable = firstItemVisible && topOfFirstItemVisible;
}
refreshLayout.setEnabled(enable);
}
});
refreshLayout.setOnRefreshListener(this);
setAppearance();
getSupportActionBar().setSubtitle(Courses.getSelectedCourseShortName());
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
};
/* (non-Javadoc)
* @see es.ugr.swad.swadroid.MenuExpandableListActivity#onCreate(android.os.Bundle)
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.list_items_pulltorefresh);
/* (non-Javadoc)
* @see es.ugr.swad.swadroid.MenuExpandableListActivity#Override(android.os.Bundle)
*/
@Override
protected void onStart() {
super.onStart();
refreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_container_list);
emptyEventsTextView = (TextView) findViewById(R.id.list_item_title);
View mProgressScreenView = findViewById(R.id.progress_screen);
mProgressScreen = new ProgressScreen(mProgressScreenView, refreshLayout,
getString(R.string.loadingMsg), this);
lvEvents = (ListView) findViewById(R.id.list_pulltorefresh);
lvEvents.setOnItemClickListener(clickListener);
lvEvents.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView absListView, int scrollState) {
}
@Override
public void onScroll(AbsListView absListView, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
boolean enable = true;
if ((lvEvents != null) && (lvEvents.getChildCount() > 0)) {
// check if the first item of the list is visible
boolean firstItemVisible = lvEvents.getFirstVisiblePosition() == 0;
// check if the top of the first item is visible
boolean topOfFirstItemVisible = lvEvents.getChildAt(0).getTop() == 0;
// enabling or disabling the refresh layout
enable = firstItemVisible && topOfFirstItemVisible;
}
refreshLayout.setEnabled(enable);
}
});
refreshLayout.setOnRefreshListener(this);
setAppearance();
getSupportActionBar().setSubtitle(Courses.getSelectedCourseShortName());
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
/* (non-Javadoc)
* @see es.ugr.swad.swadroid.MenuExpandableListActivity#Override(android.os.Bundle)
*/
@Override
protected void onStart() {
super.onStart();
SWADroidTracker.sendScreenView(getApplicationContext(), TAG);
//Refresh ListView of events
refreshAdapter();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
switch (requestCode) {
case Constants.ROLLCALL_EVENTS_DOWNLOAD_REQUEST_CODE:
//Refresh ListView of events
refreshAdapter();
break;
}
}
private void refreshAdapter() {
mHandler.post(mRunnable);
}
private void refreshEvents() {
mProgressScreen.show();
Intent activity = new Intent(this, EventsDownload.class);
startActivityForResult(activity, Constants.ROLLCALL_EVENTS_DOWNLOAD_REQUEST_CODE);
}
/**
* It shows the SwipeRefreshLayout progress
*/
private void showSwipeProgress() {
refreshLayout.setRefreshing(true);
}
/**
* It shows the SwipeRefreshLayout progress
*/
private void hideSwipeProgress() {
refreshLayout.setRefreshing(false);
}
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
private void setAppearance() {
refreshLayout.setColorSchemeResources(android.R.color.holo_blue_bright,
android.R.color.holo_green_light,
android.R.color.holo_orange_light,
android.R.color.holo_red_light);
}
private boolean hasPendingEvents() {
boolean hasPendingEvents = false;
TextView sendingStateTextView;
int i = 0;
if ((lvEvents != null) && (lvEvents.getChildCount() > 0)) {
while(!hasPendingEvents && (i<lvEvents.getChildCount())) {
sendingStateTextView = (TextView) lvEvents.getChildAt(i).findViewById(R.id.sendingStateTextView);
hasPendingEvents = sendingStateTextView.getText().equals(getString(R.string.sendingStatePending));
i++;
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
switch (requestCode) {
case Constants.ROLLCALL_EVENTS_DOWNLOAD_REQUEST_CODE:
refreshAdapter();
break;
}
super.onActivityResult(requestCode, resultCode, intent);
}
return hasPendingEvents;
}
private void refreshAdapter() {
mHandler.post(mRunnable);
}
private void refreshEvents() {
mProgressScreen.show();
Intent activity = new Intent(this, EventsDownload.class);
startActivityForResult(activity, Constants.ROLLCALL_EVENTS_DOWNLOAD_REQUEST_CODE);
}
/**
* It shows the SwipeRefreshLayout progress
*/
private void showSwipeProgress() {
refreshLayout.setRefreshing(true);
}
/**
* It shows the SwipeRefreshLayout progress
*/
private void hideSwipeProgress() {
refreshLayout.setRefreshing(false);
}
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
private void setAppearance() {
refreshLayout.setColorSchemeResources(android.R.color.holo_blue_bright,
android.R.color.holo_green_light,
android.R.color.holo_orange_light,
android.R.color.holo_red_light);
}
private boolean hasPendingEvents() {
boolean hasPendingEvents = false;
TextView sendingStateTextView;
int i = 0;
if ((lvEvents != null) && (lvEvents.getChildCount() > 0)) {
while(!hasPendingEvents && (i<lvEvents.getChildCount())) {
sendingStateTextView = lvEvents.getChildAt(i).findViewById(R.id.sendingStateTextView);
hasPendingEvents = sendingStateTextView.getText().equals(getString(R.string.sendingStatePending));
i++;
}
}
return hasPendingEvents;
}
private void updateEvents() {
showSwipeProgress();
@ -251,48 +250,48 @@ public class Rollcall extends MenuExpandableListActivity implements
hideSwipeProgress();
}
/**
* It must be overriden by parent classes if manual swipe is enabled.
*/
@Override
public void onRefresh() {
if(!hasPendingEvents()) {
updateEvents();
} else {
AlertDialog cleanEventsDialog = DialogFactory.createWarningDialog(this,
-1,
R.string.areYouSure,
R.string.updatePendingEventsMsg,
R.string.yesMsg,
R.string.noMsg,
true,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
/**
* It must be overriden by parent classes if manual swipe is enabled.
*/
@Override
public void onRefresh() {
if(!hasPendingEvents()) {
updateEvents();
} else {
AlertDialog cleanEventsDialog = DialogFactory.createWarningDialog(this,
-1,
R.string.areYouSure,
R.string.updatePendingEventsMsg,
R.string.yesMsg,
R.string.noMsg,
true,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
updateEvents();
}
},
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
},
null);
updateEvents();
}
},
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
},
null);
cleanEventsDialog.show();
cleanEventsDialog.show();
}
hideSwipeProgress();
}
hideSwipeProgress();
}
private static class RefreshAdapterHandler extends Handler {
private static class RefreshAdapterHandler extends Handler {
private final WeakReference<Rollcall> mActivity;
private final WeakReference<Rollcall> mActivity;
public RefreshAdapterHandler(Rollcall activity) {
mActivity = new WeakReference<>(activity);
}
public RefreshAdapterHandler(Rollcall activity) {
mActivity = new WeakReference<>(activity);
}
}
}

View File

@ -31,10 +31,10 @@ import android.database.Cursor;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.widget.SwipeRefreshLayout;
import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
@ -49,7 +49,6 @@ import java.util.List;
import es.ugr.swad.swadroid.Constants;
import es.ugr.swad.swadroid.R;
import es.ugr.swad.swadroid.analytics.SWADroidTracker;
import es.ugr.swad.swadroid.database.DataBaseHelper;
import es.ugr.swad.swadroid.gui.DialogFactory;
import es.ugr.swad.swadroid.gui.MenuExpandableListActivity;
@ -75,7 +74,7 @@ public class UsersActivity extends MenuExpandableListActivity implements
/**
* ListView of users
*/
private static ListView lvUsers;
private ListView lvUsers;
/**
* Adapter for ListView of users
*/
@ -106,6 +105,16 @@ public class UsersActivity extends MenuExpandableListActivity implements
*/
private IntentIntegrator integrator;
/**
* Button for send attendances to SWAD
*/
private MenuItem mSendUsersMenuItem;
/**
* Button for clear all users for an event
*/
private MenuItem mCleanUsersMenuItem;
/* (non-Javadoc)
* @see es.ugr.swad.swadroid.MenuExpandableListActivity#onCreate(android.os.Bundle)
*/
@ -114,14 +123,14 @@ public class UsersActivity extends MenuExpandableListActivity implements
super.onCreate(savedInstanceState);
setContentView(R.layout.list_items_pulltorefresh);
refreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_container_list);
emptyUsersTextView = (TextView) findViewById(R.id.list_item_title);
refreshLayout = findViewById(R.id.swipe_container_list);
emptyUsersTextView = findViewById(R.id.list_item_title);
View mProgressScreenView = findViewById(R.id.progress_screen);
mProgressScreen = new ProgressScreen(mProgressScreenView, refreshLayout,
getString(R.string.loadingMsg), this);
lvUsers = (ListView) findViewById(R.id.list_pulltorefresh);
lvUsers = findViewById(R.id.list_pulltorefresh);
lvUsers.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
@ -158,7 +167,6 @@ public class UsersActivity extends MenuExpandableListActivity implements
@Override
protected void onStart() {
super.onStart();
SWADroidTracker.sendScreenView(getApplicationContext(), TAG);
//Refresh ListView of users
refreshAdapter();
@ -167,6 +175,9 @@ public class UsersActivity extends MenuExpandableListActivity implements
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
refreshAdapter();
setActionMenuItemsEnabled(true);
super.onActivityResult(requestCode, resultCode, intent);
}
private void refreshAdapter() {
@ -245,39 +256,50 @@ public class UsersActivity extends MenuExpandableListActivity implements
*/
@Override
public void onRefresh() {
setActionMenuItemsEnabled(false);
showSwipeProgress();
refreshUsers();
hideSwipeProgress();
setActionMenuItemsEnabled(true);
}
private String getUsersCodes() {
String usersCodes = "";
StringBuilder usersCodes = new StringBuilder();
List<UserAttendance> usersList = dbHelper.getUsersEvent(eventCode);
//Concatenate the user code of all users checked as present and separate them with commas
for(UserAttendance user : usersList) {
if(user.isUserPresent()) {
usersCodes += user.getId() + ",";
usersCodes.append(user.getId()).append(",");
}
}
//Remove final comma
if(!usersCodes.isEmpty()) {
usersCodes = usersCodes.substring(0, usersCodes.length()-1);
if(usersCodes.length() > 0) {
usersCodes = new StringBuilder(usersCodes.substring(0, usersCodes.length() - 1));
}
return usersCodes;
return usersCodes.toString();
}
private void scanQRCode() {
integrator.initiateScan();
}
private void setActionMenuItemsEnabled(boolean enabled) {
mSendUsersMenuItem.setEnabled(enabled);
mCleanUsersMenuItem.setEnabled(enabled);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.rollcall_activity_actions, menu);
mSendUsersMenuItem = menu.findItem(R.id.action_sendMsg);
mCleanUsersMenuItem = menu.findItem(R.id.action_cleanUsers);
return super.onCreateOptionsMenu(menu);
}
@ -298,12 +320,14 @@ public class UsersActivity extends MenuExpandableListActivity implements
}
} else {
//If the device has no rear camera available show error message
error(getString(R.string.noCameraFound), null, false);
error(getString(R.string.noCameraFound), null);
}
return true;
case R.id.action_sendMsg:
setActionMenuItemsEnabled(false);
String usersCodes = getUsersCodes();
Intent activity = new Intent(getApplicationContext(),
@ -320,6 +344,8 @@ public class UsersActivity extends MenuExpandableListActivity implements
return true;
case R.id.action_cleanUsers:
setActionMenuItemsEnabled(false);
AlertDialog cleanDBDialog = DialogFactory.createWarningDialog(this,
-1,
R.string.areYouSure,
@ -360,7 +386,7 @@ public class UsersActivity extends MenuExpandableListActivity implements
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[],
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
switch (requestCode) {
case Constants.PERMISSIONS_REQUEST_CAMERA: {

View File

@ -108,7 +108,7 @@ public class UsersCursorAdapter extends CursorAdapter {
String userFirstname = crypto.decrypt(cursor.getString(cursor.getColumnIndex("userFirstname")));
String userID = crypto.decrypt(cursor.getString(cursor.getColumnIndex("userID")));
final long userCode = cursor.getLong(cursor.getColumnIndex("userCode"));
String userPhoto = cursor.getString(cursor.getColumnIndex("photoPath"));
String userPhoto = crypto.decrypt(cursor.getString(cursor.getColumnIndex("photoPath")));
boolean present = Utils.parseIntBool(cursor.getInt(cursor.getColumnIndex("present")));
// Replace NULL value for strings returned by the webservice with the empty string
@ -127,10 +127,10 @@ public class UsersCursorAdapter extends CursorAdapter {
final ViewHolder holder = (ViewHolder) view.getTag();
view.setTag(holder);
holder.image = (ImageView) view.findViewById(R.id.imageView1);
holder.text1 = (TextView) view.findViewById(R.id.TextView1);
holder.text2 = (TextView) view.findViewById(R.id.TextView2);
holder.checkbox = (CheckBox) view.findViewById(R.id.check);
holder.image = view.findViewById(R.id.imageView1);
holder.text1 = view.findViewById(R.id.TextView1);
holder.text2 = view.findViewById(R.id.TextView2);
holder.checkbox = view.findViewById(R.id.check);
holder.checkbox.setChecked(present);
holder.checkbox.setOnClickListener(new View.OnClickListener() {
@ -152,12 +152,13 @@ public class UsersCursorAdapter extends CursorAdapter {
}
});
holder.image.setImageResource(R.drawable.usr_bl);
if(userPhoto != null) {
ImageFactory.displayImage(loader, crypto.decrypt(userPhoto), holder.image);
if((userPhoto != null) && !userPhoto.isEmpty()) {
ImageFactory.displayImage(loader, userPhoto, holder.image);
} else {
holder.image.setImageResource(R.drawable.usr_bl);
}
holder.text1.setText(userSurname1 + " " + userSurname2 + ", " + userFirstname);
holder.text1.setText(String.format("%s %s, %s", userSurname1, userSurname2, userFirstname));
holder.text2.setText(userID);
}
@ -166,10 +167,10 @@ public class UsersCursorAdapter extends CursorAdapter {
View view = inflater.inflate(R.layout.users_list_item, parent, false);
ViewHolder holder = new ViewHolder();
holder.image = (ImageView) view.findViewById(R.id.imageView1);
holder.text1 = (TextView) view.findViewById(R.id.TextView1);
holder.text2 = (TextView) view.findViewById(R.id.TextView2);
holder.checkbox = (CheckBox) view.findViewById(R.id.check);
holder.image = view.findViewById(R.id.imageView1);
holder.text1 = view.findViewById(R.id.TextView1);
holder.text2 = view.findViewById(R.id.TextView2);
holder.checkbox = view.findViewById(R.id.check);
view.setTag(holder);
return view;

View File

@ -81,7 +81,7 @@ public class UsersDownload extends Module {
runConnection();
} catch (Exception e) {
String errorMsg = getString(R.string.errorServerResponseMsg);
error(errorMsg, e, true);
error(errorMsg, e);
}
}
@ -122,7 +122,7 @@ public class UsersDownload extends Module {
if (userSurname1.equalsIgnoreCase(Constants.NULL_VALUE)) userSurname1 = "";
if (userSurname2.equalsIgnoreCase(Constants.NULL_VALUE)) userSurname2 = "";
if (userFirstname.equalsIgnoreCase(Constants.NULL_VALUE)) userFirstname = "";
if (userPhoto.equalsIgnoreCase(Constants.NULL_VALUE)) userPhoto = null;
if (userPhoto.equalsIgnoreCase(Constants.NULL_VALUE)) userPhoto = "";
//Inserts user data into database
dbHelper.insertUser(new User(userCode, null, userID, userNickname, userSurname1, userSurname2,
@ -153,7 +153,7 @@ public class UsersDownload extends Module {
if (numUsers == 0) {
Toast.makeText(this, R.string.noUsersAvailableMsg, Toast.LENGTH_LONG).show();
} else {
String msg = String.valueOf(numUsers) + " " + getResources().getString(R.string.usersUpdated);
String msg = numUsers + " " + getResources().getString(R.string.usersUpdated);
Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
}

View File

@ -91,7 +91,7 @@ public class UsersSend extends Module {
runConnection();
} catch (Exception e) {
String errorMsg = getString(R.string.errorServerResponseMsg);
error(errorMsg, e, true);
error(errorMsg, e);
}
}

View File

@ -20,7 +20,7 @@ package es.ugr.swad.swadroid.modules.tests;
import android.content.Context;
import android.graphics.Color;
import android.support.v4.content.ContextCompat;
import androidx.core.content.ContextCompat;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;

View File

@ -30,7 +30,6 @@ import java.util.List;
import es.ugr.swad.swadroid.Constants;
import es.ugr.swad.swadroid.R;
import es.ugr.swad.swadroid.analytics.SWADroidTracker;
import es.ugr.swad.swadroid.gui.ImageListItem;
import es.ugr.swad.swadroid.gui.MenuActivity;
import es.ugr.swad.swadroid.gui.ProgressScreen;
@ -71,8 +70,6 @@ public class Tests extends MenuActivity implements OnItemClickListener {
mProgressScreen = new ProgressScreen(mProgressScreenView, mTestsMenuLayoutView,
getString(R.string.syncronizingMsg), this);
SWADroidTracker.sendScreenView(getApplicationContext(), TAG);
for (int i = 0; i < titles.length; i++) {
ImageListItem item = new ImageListItem(images[i], titles[i]);
imageListItems.add(item);

View File

@ -81,7 +81,7 @@ public class TestsConfigDownload extends Module {
runConnection();
} catch (Exception e) {
String errorMsg = getString(R.string.errorServerResponseMsg);
error(errorMsg, e, true);
error(errorMsg, e);
}
}

View File

@ -23,8 +23,8 @@ import android.database.Cursor;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.MenuItemCompat;
import androidx.core.content.ContextCompat;
import androidx.core.view.MenuItemCompat;
import android.text.InputType;
import android.util.Log;
import android.util.SparseBooleanArray;
@ -51,7 +51,6 @@ import java.util.List;
import es.ugr.swad.swadroid.Constants;
import es.ugr.swad.swadroid.R;
import es.ugr.swad.swadroid.analytics.SWADroidTracker;
import es.ugr.swad.swadroid.database.DataBaseHelper;
import es.ugr.swad.swadroid.gui.MenuActivity;
import es.ugr.swad.swadroid.gui.WebViewFactory;
@ -152,8 +151,6 @@ public class TestsMake extends MenuActivity {
numberPicker.setMinValue(test.getMin());
numberPicker.setValue(test.getDef());
numberPicker.setVisibility(View.VISIBLE);
SWADroidTracker.sendScreenView(getApplicationContext(), TAG + " NumQuestions");
}
/**
@ -214,8 +211,6 @@ public class TestsMake extends MenuActivity {
checkBoxesList.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
checkBoxesList.setOnItemClickListener(tagsAnswersTypeItemClickListener);
checkBoxesList.setDividerHeight(0);
SWADroidTracker.sendScreenView(getApplicationContext(), TAG + " Tags");
}
/**
@ -275,8 +270,6 @@ public class TestsMake extends MenuActivity {
checkBoxesList.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
checkBoxesList.setOnItemClickListener(tagsAnswersTypeItemClickListener);
checkBoxesList.setDividerHeight(0);
SWADroidTracker.sendScreenView(getApplicationContext(), TAG + " AnswerTypes");
}
/**
@ -632,8 +625,6 @@ public class TestsMake extends MenuActivity {
});
showQuestion(0);
SWADroidTracker.sendScreenView(getApplicationContext(), TAG + " Question");
}
/**
@ -658,8 +649,6 @@ public class TestsMake extends MenuActivity {
//Shows the test
showTest();
} else {
SWADroidTracker.sendScreenView(getApplicationContext(), TAG + " No questions criteria");
Toast.makeText(this, R.string.testNoQuestionsMeetsSpecifiedCriteriaMsg, Toast.LENGTH_LONG).show();
finish();
}
@ -701,8 +690,6 @@ public class TestsMake extends MenuActivity {
} else {
textView = (TextView) findViewById(R.id.testResultsText);
textView.setText(R.string.testNoResultsMsg);
SWADroidTracker.sendScreenView(getApplicationContext(), TAG + " Feedback " + Test.FEEDBACK_NONE);
}
}
@ -794,8 +781,6 @@ public class TestsMake extends MenuActivity {
if (test != null) {
selectNumQuestions();
} else {
SWADroidTracker.sendScreenView(getApplicationContext(), TAG + " No questions");
Toast.makeText(this, R.string.testNoQuestionsCourseMsg, Toast.LENGTH_LONG).show();
finish();
}
@ -845,7 +830,6 @@ public class TestsMake extends MenuActivity {
return true;
case R.id.action_show_details:
if (test.getFeedback().equals(Test.FEEDBACK_MIN)) {
SWADroidTracker.sendScreenView(getApplicationContext(), TAG + " Feedback " + Test.FEEDBACK_MIN);
Toast.makeText(this, R.string.testNoDetailsMsg, Toast.LENGTH_LONG).show();
} else {
//Show totals button only

View File

@ -32,7 +32,6 @@ import java.security.NoSuchAlgorithmException;
import java.util.List;
import es.ugr.swad.swadroid.Constants;
import es.ugr.swad.swadroid.analytics.SWADroidTracker;
import es.ugr.swad.swadroid.database.DataBaseHelper;
import es.ugr.swad.swadroid.model.LoginInfo;
import es.ugr.swad.swadroid.modules.courses.Courses;
@ -186,7 +185,6 @@ public class Preferences {
dbHelper = new DataBaseHelper(ctx);
} catch (Exception e) {
Log.e(TAG, e.getMessage());
SWADroidTracker.sendException(ctx, e, false);
}
}
}

View File

@ -24,7 +24,7 @@ import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
@ -33,12 +33,11 @@ import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceActivity;
import android.preference.PreferenceScreen;
import android.provider.Settings;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import com.google.firebase.analytics.FirebaseAnalytics;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Date;
@ -46,13 +45,11 @@ import java.util.List;
import es.ugr.swad.swadroid.Constants;
import es.ugr.swad.swadroid.R;
import es.ugr.swad.swadroid.analytics.SWADroidTracker;
import es.ugr.swad.swadroid.gui.DialogFactory;
import es.ugr.swad.swadroid.modules.login.Login;
import es.ugr.swad.swadroid.modules.login.LoginActivity;
import es.ugr.swad.swadroid.sync.SyncUtils;
import es.ugr.swad.swadroid.utils.Crypto;
import es.ugr.swad.swadroid.utils.NotificationUtils;
import es.ugr.swad.swadroid.utils.Utils;
/**
@ -65,6 +62,10 @@ public class PreferencesActivity extends PreferenceActivity implements OnPrefere
* PreferencesActivity tag name for Logcat
*/
private static final String TAG = Constants.APP_TAG + " PreferencesActivity";
/**
* Obtain Firebase Analytics instance
*/
protected FirebaseAnalytics mFirebaseAnalytics = FirebaseAnalytics.getInstance(this);
/**
* Application context
*/
@ -130,11 +131,6 @@ public class PreferencesActivity extends PreferenceActivity implements OnPrefere
* Synchronization preferences changed flag
*/
private boolean syncPrefsChanged = false;
/**
* SWAD server to use
*/
//private String mServer;
/**
* User password preference changed flag
@ -146,14 +142,14 @@ public class PreferencesActivity extends PreferenceActivity implements OnPrefere
*
* @param message Error message to show.
*/
private void error(String message, Exception ex, boolean sendException) {
private void error(String message, Exception ex) {
DialogInterface.OnClickListener onClickListener = new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
finish();
}
};
AlertDialog errorDialog = DialogFactory.createErrorDialog(this, TAG, message, ex, sendException,
AlertDialog errorDialog = DialogFactory.createErrorDialog(this, TAG, message, ex,
isDebuggable, onClickListener);
errorDialog.show();
@ -178,7 +174,7 @@ public class PreferencesActivity extends PreferenceActivity implements OnPrefere
getPackageName(), 0);
isDebuggable = (ApplicationInfo.FLAG_DEBUGGABLE != 0);
} catch (Exception ex) {
error(ex.getMessage(), ex, true);
error(ex.getMessage(), ex);
}
logOutPref = findPreference(Preferences.LOGOUTPREF);
@ -304,6 +300,12 @@ public class PreferencesActivity extends PreferenceActivity implements OnPrefere
sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, getString(R.string.app_name));
sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, getString(R.string.shareBodyMsg));
startActivity(Intent.createChooser(sharingIntent, getString(R.string.shareTitle_menu)));
Bundle bundle = new Bundle();
bundle.putString(FirebaseAnalytics.Param.ITEM_ID, "1");
bundle.putString(FirebaseAnalytics.Param.CONTENT_TYPE, "text");
mFirebaseAnalytics.logEvent(FirebaseAnalytics.Event.SHARE, bundle);
return true;
}
});
@ -319,11 +321,11 @@ public class PreferencesActivity extends PreferenceActivity implements OnPrefere
return true;
}
});
try {
currentVersionPref.setSummary(getPackageManager().getPackageInfo(getPackageName(), 0).versionName);
} catch (NameNotFoundException e) {
SWADroidTracker.sendException(getApplicationContext(), e, false);
} catch (PackageManager.NameNotFoundException ex) {
error(ex.getMessage(), ex);
}
}
@ -369,7 +371,7 @@ public class PreferencesActivity extends PreferenceActivity implements OnPrefere
}
} catch (NoSuchAlgorithmException ex) {
error(ex.getMessage(), ex, true);
error(ex.getMessage(), ex);
}
} else if(Preferences.SYNCENABLEPREF.equals(key)) {
boolean syncEnabled = (Boolean) newValue;

View File

@ -21,6 +21,7 @@
package es.ugr.swad.swadroid.utils;
import android.content.Context;
import android.util.Log;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
@ -34,7 +35,6 @@ import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
import es.ugr.swad.swadroid.Constants;
import es.ugr.swad.swadroid.analytics.SWADroidTracker;
/**
* Cryptographic class for encryption purposes.
@ -80,8 +80,7 @@ public class Crypto {
ecipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
} catch (Exception e) {
//Send exception details to Google Analytics
SWADroidTracker.sendException(mContext, e, false);
Log.e(TAG, e.getMessage());
}
}
@ -99,8 +98,7 @@ public class Crypto {
} catch (Exception e) {
rVal = "Error encrypting: " + e.getMessage();
//Send exception details to Google Analytics
SWADroidTracker.sendException(mContext, e, false);
Log.e(TAG, e.getMessage());
}
return rVal;
}
@ -119,8 +117,7 @@ public class Crypto {
} catch (Exception e) {
rVal = "Error encrypting: " + e.getMessage();
//Send exception details to Google Analytics
SWADroidTracker.sendException(mContext, e, false);
Log.e(TAG, e.getMessage());
}
return rVal;
}

View File

@ -20,6 +20,7 @@
package es.ugr.swad.swadroid.utils;
import android.content.Context;
import android.util.Log;
import java.security.MessageDigest;
import java.security.SecureRandom;
@ -30,7 +31,6 @@ import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import es.ugr.swad.swadroid.Constants;
import es.ugr.swad.swadroid.analytics.SWADroidTracker;
/**
* Cryptographic class for encryption purposes.
@ -49,8 +49,7 @@ public class OldCrypto {
byte[] result = encrypt(rawKey, cleartext.getBytes("UTF-8"));
return Base64.encodeBytes(result);
} catch (Exception e) {
//Send exception details to Google Analytics
SWADroidTracker.sendException(ctx, e, false);
Log.e(TAG, e.getMessage());
}
return "error";
}
@ -62,8 +61,7 @@ public class OldCrypto {
byte[] result = decrypt(rawKey, enc);
return new String(result, "UTF-8");
} catch (Exception e) {
//Send exception details to Google Analytics
SWADroidTracker.sendException(ctx, e, false);
Log.e(TAG, e.getMessage());
}
return "error";
}
@ -107,8 +105,7 @@ public class OldCrypto {
}
return hexString.toString();
} catch (Exception e) {
//Send exception details to Google Analytics
SWADroidTracker.sendException(ctx, e, false);
Log.e(TAG, e.getMessage());
}
return "error";
}

View File

@ -9,7 +9,7 @@
android:id="@+id/courseNameLayout"
layout="@layout/course_or_group_name" />
<android.support.v4.widget.SwipeRefreshLayout
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipe_container_expandablelist"
android:layout_width="match_parent"
android:layout_height="match_parent" >
@ -30,6 +30,6 @@
android:layout_height="match_parent"
android:cacheColorHint="@color/background" />
</LinearLayout>
</android.support.v4.widget.SwipeRefreshLayout>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</LinearLayout>

View File

@ -7,7 +7,7 @@
<include layout="@layout/progress_screen" />
<android.support.v4.widget.SwipeRefreshLayout
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipe_container_list"
android:layout_width="match_parent"
android:layout_height="match_parent" >
@ -29,6 +29,6 @@
android:cacheColorHint="@color/background" >
</ListView>
</LinearLayout>
</android.support.v4.widget.SwipeRefreshLayout>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</LinearLayout>

View File

@ -6,7 +6,7 @@
android:id="@+id/action_search_field"
android:icon="@drawable/ic_search_user"
swadroid:showAsAction="ifRoom|collapseActionView"
swadroid:actionViewClass="android.support.v7.widget.SearchView"
swadroid:actionViewClass="androidx.appcompat.widget.SearchView"
android:title="@string/search" />
<item

View File

@ -14,6 +14,26 @@
</style>
</head>
<body bgcolor="white">
<h4>1.5.6 (2019-11-05)</h4>
<ul>
<li type="disc"><strong>Pasar lista:</strong> Corregida ejecución simultánea de varios envíos de la lista de asistencia</li>
</ul>
<body bgcolor="white">
<h4>1.5.5 (2019-07-08)</h4>
<ul>
<li type="disc">Añadido soporte para Android-Q</li>
<li type="disc">Corregidas erratas en el historial de cambios</li>
</ul>
<body bgcolor="white">
<h4>1.5.4 (2018-02-25)</h4>
<ul>
<lh class="fix">[CORRECCIONES]</lh>
<li type="disc"><strong>Grupos:</strong> Corregida visualización del nombre de los grupos de selección única</li>
</ul>
<body bgcolor="white">
<h4>1.5.3 (2017-10-25)</h4>
<ul>
@ -39,27 +59,27 @@
<h4>1.5.0 (2016-09-01)</h4>
<ul>
<lh class="new">[NOVEDADES]</lh>
<li type="disc"><strong>Mensajes&#58;</strong> A&ntilde;adida b&uacute;squeda de destinatarios</li>
<li type="disc"><strong>Mensajes:</strong> A&ntilde;adida b&uacute;squeda de destinatarios</li>
</ul>
<h4>1.4.0 (2016-07-25)</h4>
<ul>
<lh class="new">[NOVEDADES]</lh>
<li type="disc"><strong>Men&uacute; principal&#58;</strong> A&ntilde;adido men&uacute; para
<li type="disc"><strong>Men&uacute; principal:</strong> A&ntilde;adido men&uacute; para
usuarios que no tienen ninguna asignatura</li>
</ul>
<ul>
<lh class="fix">[CORRECCIONES]</lh>
<li type="disc"><strong>Calificaciones&#58;</strong> Corregida consulta de calificaciones desde el rol estudiante</li>
<li type="disc"><strong>Calificaciones:</strong> Corregida consulta de calificaciones desde el rol estudiante</li>
</ul>
<h4>1.3.4 (2016-07-17)</h4>
<ul>
<lh class="update">[ACTUALIZACIONES]</lh>
<li type="disc"><strong>Login&#58;</strong> Ahora es obligatorio seleccionar el servidor correcto</li>
<li type="disc"><strong>Pasar lista&#58;</strong> Ahora se pueden escanear c&oacute;digos en cualquier orientaci&oacute;n
<li type="disc"><strong>Login:</strong> Ahora es obligatorio seleccionar el servidor correcto</li>
<li type="disc"><strong>Pasar lista:</strong> Ahora se pueden escanear c&oacute;digos en cualquier orientaci&oacute;n
del dispositivo</li>
<li type="disc"><strong>Calificaciones&#58;</strong> Ahora se muestra un aviso si el ID (DNI&#47;C&eacute;dula) del estudiante
<li type="disc"><strong>Calificaciones:</strong> Ahora se muestra un aviso si el ID (DNI-C&eacute;dula) del estudiante
no ha sido verificado por el profesor o si no existen calificaciones disponibles</li>
<li type="disc"><strong>Interfaz&#58;</strong> Mejoras menores</li>
<li type="disc"><strong>Interfaz:</strong> Mejoras menores</li>
</ul>
<h4>1.3.3 (2016-01-31)</h4>
<ul>

View File

@ -14,6 +14,26 @@
</style>
</head>
<body bgcolor="white">
<h4>1.5.6 (2019-11-05)</h4>
<ul>
<li type="disc"><strong>Rollcall:</strong> Fixed SWADroid allows multiple simultaneous submissions of the attendance list</li>
</ul>
<body bgcolor="white">
<h4>1.5.5 (2019-07-08)</h4>
<ul>
<li type="disc">Added support for Android-Q</li>
<li type="disc">Fixed CHANGELOG typos</li>
</ul>
<body bgcolor="white">
<h4>1.5.4 (2018-02-25)</h4>
<ul>
<lh class="fix">[FIXES]</lh>
<li type="disc"><strong>Groups:</strong> Fixed display of the name of single choice groups</li>
</ul>
<body bgcolor="white">
<h4>1.5.3 (2017-10-25)</h4>
<ul>
@ -39,25 +59,25 @@
<h4>1.5.0 (2016-09-01)</h4>
<ul>
<lh class="new">[NEW]</lh>
<li type="disc"><strong>Messages&#58;</strong> Added search of recipients</li>
<li type="disc"><strong>Messages:</strong> Added search of recipients</li>
</ul>
<h4>1.4.0 (2016-07-25)</h4>
<ul>
<lh class="new">[NEW]</lh>
<li type="disc"><strong>Main menu&#58;</strong> Added menu for users who have no course</li>
<li type="disc"><strong>Main menu:</strong> Added menu for users who have no course</li>
</ul>
<ul>
<lh class="fix">[FIXES]</lh>
<li type="disc"><strong>Marks&#58;</strong> Fixed consultation of marks from the student role</li>
<li type="disc"><strong>Marks:</strong> Fixed consultation of marks from the student role</li>
</ul>
<h4>1.3.4 (2016-07-17)</h4>
<ul>
<lh class="update">[UPDATES]</lh>
<li type="disc"><strong>Login&#58;</strong> Now it is mandatory to select a server</li>
<li type="disc"><strong>Rollcall&#58;</strong> Now you can scan codes in any orientation of the device</li>
<li type="disc"><strong>Marks&#58;</strong> Now a warning is showed if the student ID has not yet been verified
<li type="disc"><strong>Login:</strong> Now it is mandatory to select a server</li>
<li type="disc"><strong>Rollcall:</strong> Now you can scan codes in any orientation of the device</li>
<li type="disc"><strong>Marks:</strong> Now a warning is showed if the student ID has not yet been verified
by the teacher or there are no marks currently available</li>
<li type="disc"><strong>UI&#58;</strong> Minor improvements</li>
<li type="disc"><strong>UI:</strong> Minor improvements</li>
</ul>
<h4>1.3.3 (2016-01-31)</h4>
<ul>

Binary file not shown.

View File

@ -5,8 +5,9 @@ buildscript {
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.1'
classpath 'org.ajoberstar:grgit:1.8.0'
classpath 'com.android.tools.build:gradle:3.5.2'
classpath 'org.ajoberstar:grgit:2.1.1'
classpath 'com.google.gms:google-services:4.3.2'
}
}

View File

@ -11,6 +11,8 @@
# 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
android.enableJetifier=true
android.useAndroidX=true
org.gradle.jvmargs=-Xmx2560M
# When configured, Gradle will run in incubating parallel mode.

View File

@ -1,6 +1,6 @@
#Wed Oct 25 20:37:21 CEST 2017
#Tue Aug 20 19:44:44 CEST 2019
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.3-all.zip

BIN
keystore.jks.enc Normal file

Binary file not shown.