Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
bleeding182 committed Jun 29, 2018
1 parent 4d484b5 commit ec6f6d0
Show file tree
Hide file tree
Showing 76 changed files with 3,131 additions and 0 deletions.
45 changes: 45 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Built application files
*.apk
*.ap_

# Files for the Dalvik VM
*.dex

# Java class files
*.class

# Generated files
bin/
gen/

# Gradle files
.gradle/
build/

# Local configuration file (sdk path, etc)
local.properties
release.properties
*.keystore

# Proguard folder generated by Eclipse
proguard/

# Log Files
*.log

# Intellij project files
*.iml
*.ipr
*.iws
.idea/

# Realm
*.timestamp

# Windows Image Previews
Thumbs.db

# OSX
.DS_Store
*.swp
*.lock
30 changes: 30 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
language: android
jdk: oraclejdk8
android:
components:
- build-tools-27.0.3
- android-27
- extra-google-google_play_services
- extra-google-m2repository
- extra-android-m2repository
install: true
before_script:
- touch local.properties
script: "./gradlew build"
before_cache:
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
- rm -fr $HOME/.gradle/caches/*/plugin-resolution/
cache:
directories:
- "$HOME/.gradle/caches/"
- "$HOME/.gradle/wrapper/"
- "$HOME/.android/build-cache"
deploy:
skip_cleanup: true
provider: script
script: "./gradlew bintrayUpload"
on:
tags: true
env:
global:
secure: fBJ6f9l32u/dIodgYysCsKAqmmV/ZN0WQ8c4Fo/dSaJhx2yZkmg5CgIzKdRjNi+obpWavscoi2TCEzdUhBcb1tmiODTA8K3WL/vfFeFwh90fOiZoaQMFwTMkq1u1AIdv8JwAusGO42A9MYIurDd1zOCdLlQPGG56p+7+vTxbYpR1EkSgSq68XV+Zpb7+zZo3Ejlt2WEzd4ujWDfrLVV0ybfnHB6yPjrp6DjYmfexwv5mrAkuTZnZuA7a7j7TKCArAE/H6bFvn9Y810Iv/WWZbyyP0eCCexEMYm4nIhyTVyjuUEMqnl8U1Mt1A1P+JYT7SlpyyYG6iiHZRPUNvpm9KAfoiuWPl9CxW7Qf5/xvFOUcVhmQ7CeB4vDxM3jRmcYHYGIh3akSAfs+bmhGXLk2Py3sIT2UeUXmYeepS1JB8YwzItg2/qkelS/OJlPmIeYCXcfHueP3OK/p7oXtvm/F/SgYWAikYRNWHp3ZoJ5dtTkm6jQ7m7MrOSnQOhCGR6kyF7TjjlI0VZiozvKFycZhlnW2rS+jvMlIuRZtso6Vmvuz/ZRmIQryY0DLrNIznilb9fSCD4tpgOJAAekB3lbt38Kx9+sofuoOQ8yMYXDiRVlp2pTxLXUShZZjLGyLQM60tam7fE2LoT4AUyjq1Vgy1Xdcu4tZk5oLEznJbbFz1Xg=
62 changes: 62 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
## Policy Manager Library

To support some GDPR requirements this library includes a WebView wrapper to show your terms and supplies an interface to update the timestamp when they were last accepted.

To comply with [Art. 21 GDPR - Right to object](https://gdpr-info.eu/art-21-gdpr/) links in the policy that end with the fragment `#app-opt-out` provide an option to opt-out from tracking done under [Art. 6 (e) or (f)](https://gdpr-info.eu/art-6-gdpr/).

## Setup

Start by adding some meta data to your `<application>` tag in the manifest. If your policy is not static you can also supply it later at runtime.

<meta-data
android:name="@string/gdpr_sdk__policy"
android:value="@string/privacy_policy" />

<meta-data android:name="@string/gdpr_sdk__services" android:resource="@xml/services"/>

Next create a `services.xml` in your `values/xml` directory.

<?xml version="1.0" encoding="utf-8"?>
<services>
<service name="@string/service_analytics" />

<service name="@string/service_firebase">
<!-- You can optionally define some bindings if you provide your own layout -->
<bind id="@android:id/text2">Description</bind>
</service>
</services>

## Usage

### Registration

On your registration you should link to the terms of service that the user has to accept. You can use `PrivacyPolicySwitch` which provides a link next to a switch, or you can implement your own.
You can call `GDPRPolicyManager.instance().getPolicyIntent()` to get an intent to start the Activity.

<at.allaboutapps.gdpr.widget.PrivacyPolicySwitch
android:id="@+id/policy_accepted"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="My text"
android:paddingEnd="?android:listPreferredItemPaddingEnd"
android:paddingStart="?android:listPreferredItemPaddingStart" />

### Login

After the login or acceptance it is _your responsibility_ to update the latest saved timestamp.

GDPRPolicyManager.instance().setPolicyAccepted(true) // if local, uses current timestamp
GDPRPolicyManager.instance().setPolicyAccepted(timestamp) // queried from server

### Policy Changes

You should query your server about changes to the policy. Call `manager.updateLatestPolicyTimestamp(timestamp)` to update the cached data. You could do this at every app start, or from a background job.

In your Activity you can use `manager.shouldShowPolicy()` to check the current status and display a dialog.
You can extend `PolicyUpdateDialogFragment` if you need some further customizations on the dialog design.

if (manager.shouldShowPolicy()) {
// show dialog to accept / read
PolicyUpdateDialogFragment.newInstance()
.show(supportFragmentManager)
}
1 change: 1 addition & 0 deletions app/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
34 changes: 34 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'

android {
compileSdkVersion 27
defaultConfig {
applicationId "at.allaboutapps.gdprpolicysdk"
minSdkVersion 19
targetSdkVersion 27
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}

dependencies {
implementation project(':library')

implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:27.1.1'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}
repositories {
mavenCentral()
}
21 changes: 21 additions & 0 deletions app/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
29 changes: 29 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="at.allaboutapps.gdprpolicysdk">

<uses-permission android:name="android.permission.INTERNET" />

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<meta-data android:name="@string/gdpr_sdk__policy" android:value="@string/privacy_policy" />
<meta-data android:name="@string/gdpr_sdk__services" android:resource="@xml/gdpr_services"/>

<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<receiver android:name=".ServicesBroadcastReceiver">
<intent-filter>
<action android:name="at.allaboutapps.gdpr.SERVICES_CHANGED" />
</intent-filter>
</receiver>
</application>
</manifest>
48 changes: 48 additions & 0 deletions app/src/main/assets/bacon_policy.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<html>
<body>
<h1>Bacon Policy</h1>
<p>
Bacon ipsum dolor amet bacon meatball shank tenderloin ham. Ham hock landjaeger ham buffalo,
kevin venison tail. Pork loin ball tip filet mignon landjaeger cupim. Venison boudin porchetta,
frankfurter chicken doner ball tip ribeye pork bresaola pork loin. Swine shank filet mignon
bresaola pork chop andouille, pig brisket shankle ham hock capicola picanha biltong shoulder.
Shank alcatra filet mignon, corned beef ribeye turducken burgdoggen ham hock doner fatback
tongue ground round kielbasa tenderloin strip steak.
</p>
<p>
Venison bacon andouille jerky ham spare ribs pork tail cupim. Frankfurter pork chop chicken,
short loin pork spare ribs ham hock ham burgdoggen tri-tip buffalo. Pancetta buffalo boudin ham
hock. Tail tri-tip leberkas tenderloin corned beef pastrami. Pastrami tail jerky, ham flank
brisket pancetta frankfurter turducken. Bresaola bacon pastrami landjaeger capicola buffalo pig
chicken cow ball tip chuck burgdoggen filet mignon frankfurter.
</p>
<p><a href="#app-opt-out">Opt out of bacon</a></p>
<p>
Bresaola tri-tip leberkas fatback, pork belly pork chop beef ribs brisket alcatra ball tip
andouille bacon shoulder pork t-bone. Pork belly short ribs turkey rump. Pastrami tri-tip pork
chop, chuck boudin short ribs kevin tongue ham doner capicola cupim. Pancetta venison biltong
picanha ground round filet mignon doner shank ribeye prosciutto sirloin. Tri-tip kevin ball tip,
shoulder short ribs ham pork belly chuck ribeye. Kielbasa tenderloin sausage pig chuck venison
jowl biltong frankfurter sirloin.
</p>
<p>
Ham hock biltong shank frankfurter salami. Burgdoggen jowl bacon venison shoulder. Shank salami
brisket drumstick meatball leberkas. Biltong ball tip t-bone, bacon chuck tail ham frankfurter
salami. Tail alcatra frankfurter pork meatball chuck ball tip shank pork loin boudin. Bacon
fatback chicken, ribeye capicola prosciutto cow jerky pancetta.
</p>
<p><a href="">Become Vegan</a></p>
<p>
Leberkas andouille ground round tongue. Hamburger bacon picanha tri-tip pork pancetta ham hock
rump andouille, pig flank tail prosciutto landjaeger. Rump salami chicken, pancetta porchetta
pork loin pork chop drumstick meatloaf chuck shank ham frankfurter jowl ground round. Pancetta
pork belly salami, kielbasa fatback landjaeger short loin. Doner jowl meatloaf strip steak, pork
belly brisket cupim jerky bacon tongue pork loin tenderloin chuck porchetta buffalo.
</p>
<p>
<b>Mail:</b> <a href="mailto:me@me.com">me@me.com</a><br/>
<b>Phone:</b> <a href="tel:+44 3 14 15 96">+44 3 14 15 96</a><br/>
<b>Wobsite:</b> <a href="http://www.google.com">Google</a><br/>
</p>
</body>
</html>
44 changes: 44 additions & 0 deletions app/src/main/java/at/allaboutapps/gdprpolicysdk/MainActivity.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package at.allaboutapps.gdprpolicysdk

import android.os.Bundle
import android.os.Handler
import android.support.v7.app.AppCompatActivity
import android.widget.CompoundButton
import at.allaboutapps.gdpr.GDPRPolicyManager
import at.allaboutapps.gdpr.PolicyUpdateDialogFragment
import at.allaboutapps.gdpr.widget.PrivacyPolicySwitch

class MainActivity : AppCompatActivity() {

private lateinit var manager: GDPRPolicyManager

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

setContentView(R.layout.activity_main)

val policySwitch = findViewById<PrivacyPolicySwitch>(R.id.policy_accepted)

manager = GDPRPolicyManager.instance()

//fetch latest policy version from server on a regular basis
Handler().postDelayed({
// update date of latest changes
manager.updateLatestPolicyTimestamp(System.currentTimeMillis())
}, 5 * 1000)

policySwitch.checkedChangeListener = CompoundButton.OnCheckedChangeListener { _, checked ->
}
}

override fun onStart() {
super.onStart()

// check if there is s change queued
if (manager.shouldShowPolicy()) {
// show dialog to accept / read
PolicyUpdateDialogFragment.newInstance()
.show(supportFragmentManager)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package at.allaboutapps.gdprpolicysdk

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import at.allaboutapps.gdpr.GdprServiceIntent

class ServicesBroadcastReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {


if (GdprServiceIntent.ACTION_SERVICES_CHANGED != intent.action) {
return
}

val servicesEnabled = intent.getBooleanExtra(GdprServiceIntent.EXTRA_ENABLED, true)

// <insert here disable tracking>
// e.g. FirebaseAnalytics.setAnalyticsCollectionEnabled(servicesEnabled );

// <insert here disable crash reporting if possible (firebase is, crashlytics isn't)>
//
}

}
34 changes: 34 additions & 0 deletions app/src/main/res/drawable-v24/ic_launcher_foreground.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportHeight="108"
android:viewportWidth="108">
<path
android:fillType="evenOdd"
android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
android:strokeColor="#00000000"
android:strokeWidth="1">
<aapt:attr name="android:fillColor">
<gradient
android:endX="78.5885"
android:endY="90.9159"
android:startX="48.7653"
android:startY="61.0927"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
android:strokeColor="#00000000"
android:strokeWidth="1" />
</vector>
Loading

0 comments on commit ec6f6d0

Please sign in to comment.