Browse Source

Added initial consent dialog

pull/61/merge
Ezerous 6 years ago
parent
commit
fe364c20f4
No known key found for this signature in database GPG Key ID: 262B2954BBA319E3
  1. 22
      PRIVACY.md
  2. 7
      README.md
  3. 1
      app/build.gradle
  4. 1
      app/src/main/AndroidManifest.xml
  5. 76
      app/src/main/assets/PRIVACY.md
  6. 3
      app/src/main/assets/apache_libraries.html
  7. 31
      app/src/main/java/gr/thmmy/mthmmy/activities/LoginActivity.java
  8. 75
      app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java
  9. 4
      app/src/main/java/gr/thmmy/mthmmy/base/BaseApplication.java
  10. 40
      app/src/main/java/gr/thmmy/mthmmy/utils/LaunchType.java
  11. 27
      app/src/main/res/values-v21/styles.xml
  12. 2
      app/src/main/res/values/strings.xml
  13. 26
      app/src/main/res/values/styles.xml

22
PRIVACY.md

@ -1,6 +1,6 @@
# Privacy Policy # Privacy Policy
*Effective date: 7/10/2018* *Effective date: 13/10/2018*
Thmmy No Life ("us", "we", or "our") developed the mTHMMY mobile app (the "App") as an open source application. It is provided by us at no cost and is intended for use as is. Thmmy No Life ("us", "we", or "our") developed the mTHMMY mobile app (the "App") as an open source application. It is provided by us at no cost and is intended for use as is.
@ -16,7 +16,7 @@ Google Ireland Limited ("Google"), with offices at Gordon House, Barrow Street,
The majority of Firebase services run on global Google infrastructure. They could process data at any of the Google Cloud Platform locations or Google data center locations, within or outside the European Union (EU). The majority of Firebase services run on global Google infrastructure. They could process data at any of the Google Cloud Platform locations or Google data center locations, within or outside the European Union (EU).
The Commission Decision (EU) 2016/1250 of 12.07.2016 allows the transfer of data from an EU controller or processor of orders to organizations in the US that have committed themselves to adhere to the framework principles of the EU-US Privacy Shield (https://www.privacyshield.gov), including the additional principles, by way of self-certification with the US Department of Commerce. Google is subject to these principles through self-certification with the U.S. Department of Commerce. The Commission Decision (EU) 2016/1250 of 12.07.2016 allows the transfer of data from an EU controller or processor of orders to organizations in the US that have committed themselves to adhere to the framework principles of the EU-US Privacy Shield (<https://www.privacyshield.gov>), including the additional principles, by way of self-certification with the US Department of Commerce. Google is subject to these principles through self-certification with the U.S. Department of Commerce.
### General Information ### General Information
@ -37,22 +37,22 @@ The use of each Firebase service is explained below:
### Firebase Crashlytics ### Firebase Crashlytics
* **Purpose**: This service automatically collects and delivers analyses of errors and system crashes in real time and displays them in the Firebase Console. This helps us maintain the App and improve its stability. * **Purpose**: This service automatically collects and delivers analyses of errors and system crashes in real time and displays them in the Firebase Console. This helps us maintain the App and improve its stability.
* **Data collected**: Instance IDs and crash reports with information about register codes and your device, e.g. type of device and version of operating system. For more information: https://try.crashlytics.com/security/ * **Data collected**: Instance IDs and crash reports with information about register codes and your device, e.g. type of device and version of operating system. For more information: <https://try.crashlytics.com/security/>
* **Consent**: You will be prompted to choose if you want this service enabled when you open the App for the first time. After that, you can enable or disable it from the Settings inside the App. * **Consent**: You will be prompted to choose if you want this service enabled when you open the App for the first time. After that, you can enable or disable it from the Settings inside the App.
* **Retention**: Crash traces and their associated identifiers are kept for 90 days. * **Retention**: Crash traces and their associated identifiers are kept for 90 days.
### Google Analytics for Firebase ### Google Analytics for Firebase
* **Purpose**: This service provides analytics and attribution information for statistical purposes. The precise information collected can vary by the device and environment. * **Purpose**: This service provides analytics and attribution information for statistical purposes. The precise information collected can vary by the device and environment.
* **Data collected**: Instance IDs, Android IDs, Analytics App Instance IDs and custom events created by us. For more information: https://support.google.com/firebase/answer/6318039 * **Data collected**: Instance IDs, Android IDs, Analytics App Instance IDs and custom events created by us. For more information: <https://support.google.com/firebase/answer/6318039>
* **Consent**: You will be prompted to choose if you want this service enabled when you open the App for the first time. After that, you can enable or disable (and clear all collected data) from the Settings inside the App. * **Consent**: You will be prompted to choose if you want this service enabled when you open the App for the first time. After that, you can enable or disable (and clear all collected data) from the Settings inside the App.
* **Retention**: ID-associated data are retained for 60 days. Aggregate reporting and campaign data are retained without automatic expiration. * **Retention**: ID-associated data are retained for 60 days. Aggregate reporting and campaign data are retained without automatic expiration.
You can find further information on the data use by Google through Firebase following the links below: You can find further information on the data use by Google through Firebase following the links below:
https://firebase.google.com/terms/ <https://firebase.google.com/terms/>
https://firebase.google.com/terms/data-processing-terms <https://firebase.google.com/terms/data-processing-terms>
https://firebase.google.com/support/privacy/ <https://firebase.google.com/support/privacy/>
https://firebase.google.com/support/privacy/manage-iids <https://firebase.google.com/support/privacy/manage-iids>
## Other data ## Other data
@ -61,7 +61,7 @@ https://firebase.google.com/support/privacy/manage-iids
## About thmmy.gr ## About thmmy.gr
We have neither influence, nor responsibility on anything you read, write, download or upload by interacting with thmmy.gr through the App. For more information you can also read the Terms of Service of thmmy.gr at https://www.thmmy.gr/smf/index.php?topic=52522. We have neither influence, nor responsibility on anything you read, write, download or upload by interacting with thmmy.gr through the App. For more information you can also read the Terms of Service of thmmy.gr at <https://www.thmmy.gr/smf/index.php?topic=52522>.
## Third-Party Links ## Third-Party Links
@ -69,8 +69,8 @@ mTHMMY may contain links to third-party websites. Any access to and use of such
## Policy Updates ## Policy Updates
We may update this Privacy Policy from time to time and, thus, you are advised to review it periodically. The most recent version of our Privacy Policy can be found at https://github.com/ThmmyNoLife/mTHMMY/blob/develop/PRIVACY.md. We may update this Privacy Policy from time to time and, thus, you are advised to review it periodically. The most recent version of our Privacy Policy can be found at <https://github.com/ThmmyNoLife/mTHMMY/blob/develop/PRIVACY.md>.
## Contact Us ## Contact Us
If you have any question about our Privacy Policy, please contact us at thmmynolife@gmail.com. If you have any questions about our Privacy Policy, please contact us at [thmmynolife@gmail.com](mailto:thmmynolife@gmail.com).

7
README.md

@ -3,8 +3,9 @@
[![API](https://img.shields.io/badge/API-19%2B-blue.svg?style=flat)](https://android-arsenal.com/api?level=19) [![API](https://img.shields.io/badge/API-19%2B-blue.svg?style=flat)](https://android-arsenal.com/api?level=19)
[![Discord Channel](https://img.shields.io/badge/discord-public@mTHMMY-738bd7.svg?style=flat)][discord-server] [![Discord Channel](https://img.shields.io/badge/discord-public@mTHMMY-738bd7.svg?style=flat)][discord-server]
![alt text](app\src\main\res\mipmap-xhdpi\ic_launcher.png "mTHMMY")
mTHMMY is a mobile app for the [thmmy.gr](https://www.thmmy.gr) community. A mobile app for [thmmy.gr](https://www.thmmy.gr).
## Requirements ## Requirements
@ -20,6 +21,10 @@ The latest release version is available on Google Play:
Please refer to [CONTRIBUTING.md](/CONTRIBUTING.md) for details. Please refer to [CONTRIBUTING.md](/CONTRIBUTING.md) for details.
## Privacy Policy
Our Privacy Policy can be found [here](/PRIVACY.md).
## Contact ## Contact
Do not hesitate to contact us for any matter, either by sending an email to [thmmynolife@gmail.com](mailto:thmmynolife@gmail.com), or by joining our [Discord server][discord-server]. Do not hesitate to contact us for any matter, either by sending an email to [thmmynolife@gmail.com](mailto:thmmynolife@gmail.com), or by joining our [Discord server][discord-server].

1
app/build.gradle

@ -73,6 +73,7 @@ dependencies {
implementation 'com.bignerdranch.android:expandablerecyclerview:3.0.0-RC1'//TODO: deprecated! implementation 'com.bignerdranch.android:expandablerecyclerview:3.0.0-RC1'//TODO: deprecated!
implementation 'me.zhanghai.android.materialprogressbar:library:1.4.2' implementation 'me.zhanghai.android.materialprogressbar:library:1.4.2'
implementation 'com.jakewharton.timber:timber:4.7.0' implementation 'com.jakewharton.timber:timber:4.7.0'
implementation "ru.noties:markwon:2.0.0"
implementation 'net.gotev:uploadservice:3.4.2' implementation 'net.gotev:uploadservice:3.4.2'
implementation 'net.gotev:uploadservice-okhttp:3.4.2' implementation 'net.gotev:uploadservice-okhttp:3.4.2'
implementation 'android.arch.lifecycle:extensions:1.1.1' implementation 'android.arch.lifecycle:extensions:1.1.1'

1
app/src/main/AndroidManifest.xml

@ -21,6 +21,7 @@
<meta-data android:name="firebase_crashlytics_collection_enabled" android:value="false" /> <meta-data android:name="firebase_crashlytics_collection_enabled" android:value="false" />
<meta-data android:name="firebase_analytics_collection_enabled" android:value="false" /> <meta-data android:name="firebase_analytics_collection_enabled" android:value="false" />
<meta-data android:name="google_analytics_adid_collection_enabled" android:value="false" /> <meta-data android:name="google_analytics_adid_collection_enabled" android:value="false" />
<meta-data android:name="firebase_messaging_auto_init_enabled" android:value="false" />
<activity <activity
android:name=".activities.main.MainActivity" android:name=".activities.main.MainActivity"

76
app/src/main/assets/PRIVACY.md

@ -0,0 +1,76 @@
# Privacy Policy
*Effective date: 13/10/2018*
Thmmy No Life ("us", "we", or "our") developed the mTHMMY mobile app (the "App") as an open source application. It is provided by us at no cost and is intended for use as is.
As a user of the App, your privacy is protected and we feel a strong commitment to protect your privacy. The purpose of this Privacy Policy is to inform you about the collection, use and disclosure of your data, and the choices you have associated with them.
## Data processing
To be able to offer you all functions and services of the App in the most convenient way possible and to continuously improve it, we use a number of different cloud services. This means we will transfer your data to a third party – the cloud services provider.
Google Ireland Limited ("Google"), with offices at Gordon House, Barrow Street, Dublin 4, Ireland and, more specifically, Firebase, a Google subsidiary with its registered office in San Francisco, CA, U.S.A., is a third party – the cloud services provider – that stores and processes your data on our behalf (the "processor", as defined in Article 4, GDPR).
### Location of processing
The majority of Firebase services run on global Google infrastructure. They could process data at any of the Google Cloud Platform locations or Google data center locations, within or outside the European Union (EU).
The Commission Decision (EU) 2016/1250 of 12.07.2016 allows the transfer of data from an EU controller or processor of orders to organizations in the US that have committed themselves to adhere to the framework principles of the EU-US Privacy Shield (<https://www.privacyshield.gov>), including the additional principles, by way of self-certification with the US Department of Commerce. Google is subject to these principles through self-certification with the U.S. Department of Commerce.
### General Information
* The Firebase services that we use collect and further process anonymized information, data with no personally identifiable information which can be used to trace its source so that the people whom it describes can remain anonymous. These data are not subject to the same treatment as are personal data, particularly with regards to any desire you might have for accessing it, rectifying it or erasing it (Article 11, GDPR).
* Firebase uses the Instance ID of your mobile device to identify individual installations of this mobile app. Since each Instance ID is unique to a particular application and device, they give Firebase a way to refer to specific instances of the App.
* Your IP address transmitted by the App in the context of Firebase will not be merged with other collected data.
* Legal basis for the use of Firebase is Article 6 Par. 1 S. 1 letter (a) or (f), GDPR.
The use of each Firebase service is explained below:
### Firebase Cloud Messaging
* **Purpose**: This service is essential for the funcionality of the App. It uses anonymous push notification tokens in order to determine which devices to deliver the appropriate messages to.
* **Data collected**: Instance IDs.
* **Consent**: You will be prompted to agree to the use of this service when you open the App for the first time.
* **Retention**: Firebase retains Instance IDs until we make an API call for deletion. After the call, data are removed from live and backup systems within 180 days.
### Firebase Crashlytics
* **Purpose**: This service automatically collects and delivers analyses of errors and system crashes in real time and displays them in the Firebase Console. This helps us maintain the App and improve its stability.
* **Data collected**: Instance IDs and crash reports with information about register codes and your device, e.g. type of device and version of operating system. For more information: <https://try.crashlytics.com/security/>
* **Consent**: You will be prompted to choose if you want this service enabled when you open the App for the first time. After that, you can enable or disable it from the Settings inside the App.
* **Retention**: Crash traces and their associated identifiers are kept for 90 days.
### Google Analytics for Firebase
* **Purpose**: This service provides analytics and attribution information for statistical purposes. The precise information collected can vary by the device and environment.
* **Data collected**: Instance IDs, Android IDs, Analytics App Instance IDs and custom events created by us. For more information: <https://support.google.com/firebase/answer/6318039>
* **Consent**: You will be prompted to choose if you want this service enabled when you open the App for the first time. After that, you can enable or disable (and clear all collected data) from the Settings inside the App.
* **Retention**: ID-associated data are retained for 60 days. Aggregate reporting and campaign data are retained without automatic expiration.
You can find further information on the data use by Google through Firebase following the links below:
<https://firebase.google.com/terms/>
<https://firebase.google.com/terms/data-processing-terms>
<https://firebase.google.com/support/privacy/>
<https://firebase.google.com/support/privacy/manage-iids>
## Other data
* When downloading the mobile app, the necessary information is transferred to the App Store (Google Play), i.e. in particular the name, e-mail address and customer number of your customer account, time of download, payment information and the individual device identification number. We have no influence on this data collection and shall not be responsible for it. We only process the data if it is necessary for downloading the mobile app to your mobile device.
* The App provides functionality to login to thmmy.gr through an encrypted connection. This process generates session cookies that are stored on your device. Those cookies contain the same information as those that would be generated if you logged in using a web browser and we have no influence on them. Any other personal information that the App collects from you from thmmy.gr is only stored locally and never transmitted. You can delete all the data related to thmmy.gr anytime you wish, by logging out or clearing the App's data from your device's Settings.
## About thmmy.gr
We have neither influence, nor responsibility on anything you read, write, download or upload by interacting with thmmy.gr through the App. For more information you can also read the Terms of Service of thmmy.gr at <https://www.thmmy.gr/smf/index.php?topic=52522>.
## Third-Party Links
mTHMMY may contain links to third-party websites. Any access to and use of such linked websites is not governed by this Policy, but instead is governed by the privacy policies of those third party websites. We are not responsible for the information practices of such third party websites.
## Policy Updates
We may update this Privacy Policy from time to time and, thus, you are advised to review it periodically. The most recent version of our Privacy Policy can be found at <https://github.com/ThmmyNoLife/mTHMMY/blob/develop/PRIVACY.md>.
## Contact Us
If you have any questions about our Privacy Policy, please contact us at [thmmynolife@gmail.com](mailto:thmmynolife@gmail.com).

3
app/src/main/assets/apache_libraries.html

@ -65,6 +65,9 @@
<li> <li>
<h5><a href="https://github.com/gotev/android-upload-service">Android Upload Service</a>&nbsp;v3.4.2 (Copyright ©2013-2018 Aleksandar Gotev)</h5> <h5><a href="https://github.com/gotev/android-upload-service">Android Upload Service</a>&nbsp;v3.4.2 (Copyright ©2013-2018 Aleksandar Gotev)</h5>
</li> </li>
<li>
<h5><a href="https://github.com/noties/Markwon">Markwon</a>&nbsp;v2.0.0 (Copyright ©2017 Dimitry Ivanov)</h5>
</li>
</ul> </ul>

31
app/src/main/java/gr/thmmy/mthmmy/activities/LoginActivity.java

@ -3,10 +3,8 @@ package gr.thmmy.mthmmy.activities;
import android.content.Intent; import android.content.Intent;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.preference.PreferenceManager; import android.support.v7.preference.PreferenceManager;
import android.support.v7.widget.AppCompatButton; import android.support.v7.widget.AppCompatButton;
import android.view.ActionMode;
import android.view.View; import android.view.View;
import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodManager;
import android.widget.EditText; import android.widget.EditText;
@ -57,25 +55,22 @@ public class LoginActivity extends BaseActivity {
AppCompatButton btnGuest = findViewById(R.id.btnContinueAsGuest); AppCompatButton btnGuest = findViewById(R.id.btnContinueAsGuest);
//Login button Click Event //Login button Click Event
btnLogin.setOnClickListener(new View.OnClickListener() { btnLogin.setOnClickListener(view -> {
Timber.d("Login");
public void onClick(View view) { //Get username and password strings
Timber.d("Login"); username = inputUsername.getText().toString().trim();
password = inputPassword.getText().toString().trim();
//Get username and password strings //Check for empty data in the form
username = inputUsername.getText().toString().trim(); if (!validate()) {
password = inputPassword.getText().toString().trim(); onLoginFailed();
return;
//Check for empty data in the form
if (!validate()) {
onLoginFailed();
return;
}
//Login user
loginTask = new LoginTask();
loginTask.execute(username, password);
} }
//Login user
loginTask = new LoginTask();
loginTask.execute(username, password);
}); });
//Guest Button Action //Guest Button Action

75
app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java

@ -15,6 +15,7 @@ import android.support.annotation.NonNull;
import android.support.design.widget.BottomSheetDialog; import android.support.design.widget.BottomSheetDialog;
import android.support.v4.content.ContextCompat; import android.support.v4.content.ContextCompat;
import android.support.v4.content.FileProvider; import android.support.v4.content.FileProvider;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AppCompatActivity;
import android.support.v7.preference.PreferenceManager; import android.support.v7.preference.PreferenceManager;
import android.support.v7.widget.Toolbar; import android.support.v7.widget.Toolbar;
@ -36,7 +37,10 @@ import com.mikepenz.materialdrawer.DrawerBuilder;
import com.mikepenz.materialdrawer.model.PrimaryDrawerItem; import com.mikepenz.materialdrawer.model.PrimaryDrawerItem;
import com.mikepenz.materialdrawer.model.ProfileDrawerItem; import com.mikepenz.materialdrawer.model.ProfileDrawerItem;
import java.io.BufferedReader;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList; import java.util.ArrayList;
import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.R;
@ -53,8 +57,12 @@ import gr.thmmy.mthmmy.model.ThmmyFile;
import gr.thmmy.mthmmy.services.DownloadHelper; import gr.thmmy.mthmmy.services.DownloadHelper;
import gr.thmmy.mthmmy.session.SessionManager; import gr.thmmy.mthmmy.session.SessionManager;
import gr.thmmy.mthmmy.utils.FileUtils; import gr.thmmy.mthmmy.utils.FileUtils;
import gr.thmmy.mthmmy.utils.LaunchType;
import gr.thmmy.mthmmy.viewmodel.BaseViewModel; import gr.thmmy.mthmmy.viewmodel.BaseViewModel;
import okhttp3.OkHttpClient; import okhttp3.OkHttpClient;
import ru.noties.markwon.LinkResolverDef;
import ru.noties.markwon.Markwon;
import ru.noties.markwon.SpannableConfiguration;
import timber.log.Timber; import timber.log.Timber;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
@ -67,8 +75,10 @@ import static gr.thmmy.mthmmy.activities.settings.SettingsActivity.DEFAULT_HOME_
import static gr.thmmy.mthmmy.services.DownloadHelper.SAVE_DIR; import static gr.thmmy.mthmmy.services.DownloadHelper.SAVE_DIR;
import static gr.thmmy.mthmmy.session.SessionManager.SUCCESS; import static gr.thmmy.mthmmy.session.SessionManager.SUCCESS;
import static gr.thmmy.mthmmy.utils.FileUtils.getMimeType; import static gr.thmmy.mthmmy.utils.FileUtils.getMimeType;
import static gr.thmmy.mthmmy.utils.LaunchType.LAUNCH_TYPE.FIRST_LAUNCH_EVER;
import static gr.thmmy.mthmmy.utils.LaunchType.LAUNCH_TYPE.INDETERMINATE;
public abstract class BaseActivity extends AppCompatActivity { public abstract class BaseActivity extends AppCompatActivity implements SharedPreferences.OnSharedPreferenceChangeListener{
// Client & Cookies // Client & Cookies
protected static OkHttpClient client; protected static OkHttpClient client;
@ -116,6 +126,8 @@ public abstract class BaseActivity extends AppCompatActivity {
protected void onResume() { protected void onResume() {
super.onResume(); super.onResume();
updateDrawer(); updateDrawer();
if(LaunchType.getLaunchType()==FIRST_LAUNCH_EVER||LaunchType.getLaunchType()== INDETERMINATE)
showUserConsentDialog();
} }
@Override @Override
@ -714,6 +726,67 @@ public abstract class BaseActivity extends AppCompatActivity {
dialog.show(); dialog.show();
} }
//----------------------------PRIVACY POLICY------------------
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (key.equals(getString(R.string.pref_pp_accepted_key)))
if(!sharedPreferences.getBoolean(key, false))
showUserConsentDialog();
}
private void showUserConsentDialog(){
AlertDialog.Builder builder = new AlertDialog.Builder(this, R.style.AppCompatAlertDialogStyle);
builder.setTitle("User Agreement");
builder.setMessage(R.string.user_agreement_dialog_text);
builder.setPositiveButton("Yes, I want to help", (dialogInterface, i) -> FirebaseMessaging.getInstance().setAutoInitEnabled(true));
builder.setNegativeButton("Nope, leave me alone", (dialogInterface, i) -> FirebaseMessaging.getInstance().setAutoInitEnabled(true));
builder.setNeutralButton("Privacy Policy", (dialog, which) -> {/*Will be overridden below*/});
builder.setCancelable(false);
AlertDialog alertDialog = builder.create();
alertDialog.setOnShowListener(dialogInterface -> {
Button button = alertDialog.getButton(AlertDialog.BUTTON_NEUTRAL);
button.setOnClickListener(view -> showPrivacyPolicyDialog());
}); // Overridden like this so it won't be dismissed when user touches this button
alertDialog.show();
}
private void showPrivacyPolicyDialog() {
TextView privacyPolicyTextView = new TextView(this);
privacyPolicyTextView.setPadding(30,20,30,20);
privacyPolicyTextView.setTextColor(ContextCompat.getColor(this, R.color.primary_text));
SpannableConfiguration configuration = SpannableConfiguration.builder(this).linkResolver(new LinkResolverDef()).build();
StringBuilder stringBuilder = new StringBuilder();
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(getAssets().open("PRIVACY.md")));
String line;
while ((line = reader.readLine()) != null) {
stringBuilder.append(line);
stringBuilder.append("\n");
}
Markwon.setMarkdown(privacyPolicyTextView, configuration, stringBuilder.toString());
AlertDialog.Builder builder = new AlertDialog.Builder(this, R.style.AppCompatAlertDialogStyle);
builder.setView(privacyPolicyTextView);
builder.setPositiveButton("Close", (dialogInterface, i) -> dialogInterface.dismiss());
builder.show();
} catch (IOException e) {
Timber.e(e, "Error reading Privacy Policy from assets.");
} catch (Exception e) {
Timber.e(e, "Error in Privacy Policy dialog.");
} finally {
try {
if(reader!=null)
reader.close();
} catch (IOException e) {
Timber.e(e, "Error in Privacy Policy dialog (closing reader).");
}
}
}
//----------------------------------MISC---------------------- //----------------------------------MISC----------------------
protected void setMainActivity(MainActivity mainActivity) { protected void setMainActivity(MainActivity mainActivity) {
this.mainActivity = mainActivity; this.mainActivity = mainActivity;

4
app/src/main/java/gr/thmmy/mthmmy/base/BaseApplication.java

@ -165,6 +165,10 @@ public class BaseApplication extends Application {
} }
//Getters //Getters
public Context getContext() {
return getApplicationContext();
}
public OkHttpClient getClient() { public OkHttpClient getClient() {
return client; return client;
} }

40
app/src/main/java/gr/thmmy/mthmmy/utils/LaunchType.java

@ -0,0 +1,40 @@
package gr.thmmy.mthmmy.utils;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import gr.thmmy.mthmmy.BuildConfig;
import gr.thmmy.mthmmy.base.BaseApplication;
public class LaunchType {
public enum LAUNCH_TYPE {
FIRST_LAUNCH_EVER, FIRST_LAUNCH_AFTER_UPDATE, NORMAL_LAUNCH, INDETERMINATE
}
private static final String PREF_VERSION_CODE_KEY = "VERSION_CODE";
public static LAUNCH_TYPE getLaunchType() {
final int notThere = -1;
//Gets current version code
int currentVersionCode = BuildConfig.VERSION_CODE;
//Gets saved version code
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(BaseApplication.getInstance().getContext());
int savedVersionCode = prefs.getInt(PREF_VERSION_CODE_KEY, notThere);
//Checks for first run or upgrade
if (currentVersionCode == savedVersionCode) {
//This is just a normal run
return LAUNCH_TYPE.NORMAL_LAUNCH;
} else if (savedVersionCode == notThere) {
//Updates the shared preferences with the current version code
prefs.edit().putInt(PREF_VERSION_CODE_KEY, currentVersionCode).apply();
return LAUNCH_TYPE.FIRST_LAUNCH_EVER;
} else if (currentVersionCode > savedVersionCode) {
//Updates the shared preferences with the current version code
prefs.edit().putInt(PREF_VERSION_CODE_KEY, currentVersionCode).apply();
return LAUNCH_TYPE.FIRST_LAUNCH_AFTER_UPDATE;
}
//Probably shared preferences were manually changed by the user
return LAUNCH_TYPE.INDETERMINATE;
}
}

27
app/src/main/res/values-v21/styles.xml

@ -1,33 +1,10 @@
<resources> <resources>
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <style name="AppTheme" parent="BaseAppTheme">
<item name="colorPrimary">@color/primary</item>
<item name="colorPrimaryDark">@color/primary_dark</item>
<item name="colorAccent">@color/accent</item>
<item name="android:textColorPrimary">@color/primary_text</item>
<item name="android:textColorSecondary">@color/secondary_text</item>
<item name="android:windowBackground">@color/primary</item>
<item name="cardBackgroundColor">@color/card_background</item>
<item name="colorControlNormal">@color/iron</item>
<item name="colorControlActivated">@color/white</item>
<item name="colorControlHighlight">@color/white</item>
<item name="android:textColorHint">@color/iron</item>
<item name="colorButtonNormal">@color/primary</item>
<item name="alertDialogTheme">@style/AppCompatAlertDialogStyle</item>
<item name="android:windowContentTransitions">true</item> <item name="android:windowContentTransitions">true</item>
</style> </style>
<style name="AppTheme.NoActionBar"> <style name="AppTheme.NoActionBar" parent="BaseAppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item> <item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item> <item name="android:statusBarColor">@android:color/transparent</item>
</style> </style>
<style name="AppTheme.PreferenceTheme" parent="AppTheme.NoActionBar">
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
<item name="colorControlActivated">@color/accent</item>
</style>
</resources> </resources>

2
app/src/main/res/values/strings.xml

@ -14,6 +14,8 @@
<string name="info">Info</string> <string name="info">Info</string>
<string name="ok">OK</string> <string name="ok">OK</string>
<string name="cancel">Cancel</string> <string name="cancel">Cancel</string>
<string name="pref_pp_accepted_key">pref_pp_accepted</string>
<string name="user_agreement_dialog_text">"To use mTHMMY you have to agree to our Privacy Policy by choosing one of the buttons below. Choose \"Yes, I want to help\", if you consent to the collection of anonymized data that will help us improve the app. Otherwise, choose \"Nope, leave me alone\". You can change your preferences any time through the app's Settings.</string>
<!--Login Activity--> <!--Login Activity-->
<string name="thmmy_img_description">thmmy.gr</string> <string name="thmmy_img_description">thmmy.gr</string>

26
app/src/main/res/values/styles.xml

@ -1,7 +1,6 @@
<resources> <resources>
<!-- Base Theme to also be inherited in v21 -->
<!-- Dark application theme. --> <style name="BaseAppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="colorPrimary">@color/primary</item> <item name="colorPrimary">@color/primary</item>
<item name="colorPrimaryDark">@color/primary_dark</item> <item name="colorPrimaryDark">@color/primary_dark</item>
<item name="colorAccent">@color/accent</item> <item name="colorAccent">@color/accent</item>
@ -21,18 +20,23 @@
<item name="alertDialogTheme">@style/AppCompatAlertDialogStyle</item> <item name="alertDialogTheme">@style/AppCompatAlertDialogStyle</item>
</style> </style>
<style name="AppTheme.NoActionBar"> <!-- Dark application theme. -->
<style name="AppTheme" parent="BaseAppTheme"/>
<style name="BaseAppTheme.NoActionBar">
<item name="windowActionBar">false</item> <item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item> <item name="windowNoTitle">true</item>
</style> </style>
<style name="AppTheme.NoActionBar" parent="BaseAppTheme.NoActionBar"/>
<style name="AppTheme.PreferenceTheme" parent="AppTheme.NoActionBar"> <style name="AppTheme.PreferenceTheme" parent="AppTheme.NoActionBar">
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item> <item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
<item name="colorControlActivated">@color/accent</item> <item name="colorControlActivated">@color/accent</item>
</style> </style>
<style name="PopupMenuStyle"> <style name="PopupMenuStyle">
<item name="android:popupBackground">@color/primary</item> <item name="android:popupBackground">@color/primary_light</item>
<item name="android:textAppearanceLargePopupMenu">@color/accent</item> <item name="android:textAppearanceLargePopupMenu">@color/accent</item>
<item name="android:textAppearanceSmallPopupMenu">@color/accent</item> <item name="android:textAppearanceSmallPopupMenu">@color/accent</item>
</style> </style>
@ -46,14 +50,18 @@
<item name="android:textColor">@color/primary_text</item> <item name="android:textColor">@color/primary_text</item>
</style> </style>
<style name="PopupMenuItem.TopItem" parent="PopupMenuItem" > <style name="PopupMenuItem.TopItem" parent="PopupMenuItem">
<item name="android:paddingTop">8dp</item> <item name="android:paddingTop">8dp</item>
</style> </style>
<style name="PopupMenuItem.BottomItem" parent="PopupMenuItem" > <style name="PopupMenuItem.BottomItem" parent="PopupMenuItem">
<item name="android:paddingBottom">8dp</item> <item name="android:paddingBottom">8dp</item>
</style> </style>
<style name="PopupWindow" parent="Widget.AppCompat.PopupWindow">
<item name="android:background">@android:color/transparent</item>
</style>
<style name="ToolbarTheme" parent="ThemeOverlay.AppCompat.Light"> <style name="ToolbarTheme" parent="ThemeOverlay.AppCompat.Light">
<item name="android:textColorPrimary">@android:color/white</item> <item name="android:textColorPrimary">@android:color/white</item>
<item name="android:colorBackground">@color/colorPrimary</item> <item name="android:colorBackground">@color/colorPrimary</item>
@ -82,4 +90,8 @@
<item name="android:textColorPrimary">@color/primary_text</item> <item name="android:textColorPrimary">@color/primary_text</item>
<item name="android:colorBackground">@color/dialog_bg_semi_transparent</item> <item name="android:colorBackground">@color/dialog_bg_semi_transparent</item>
</style> </style>
<style name="LightBackgroundColoredButton" parent="Widget.AppCompat.ImageButton">
<item name="colorButtonNormal">@color/primary_light</item>
</style>
</resources> </resources>

Loading…
Cancel
Save