Skip to content

Commit

Permalink
* lowered minSdk to 15
Browse files Browse the repository at this point in the history
* added withExplicitConsentForEachService
  • Loading branch information
MFlisar committed May 22, 2018
1 parent 49cbb77 commit 955ee4d
Show file tree
Hide file tree
Showing 12 changed files with 169 additions and 32 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ repositories {
2. add the compile statement to your module's `build.gradle`:
```groovy
dependencies {
implementation 'com.github.MFlisar:GDPRDialog:0.3'
implementation 'com.github.MFlisar:GDPRDialog:0.4'
}
```

Expand All @@ -64,6 +64,7 @@ GDPRSetup setup = new GDPRSetup(GDPR.ADMOB_NETWORK); // add all networks you use
// setup.withPaidVersion(allowNonPersonalisedOptionAsWell);
// setup.withExplicitAgeConfirmation(true);
// setup.withCheckRequestLocation(true);
// setup.withExplicitConsentForEachService(true)
GDPR.getInstance().checkIfNeedsToBeShown(this /* extends AppCompatActivity & GDPR.IGDPRCallback */, setup);
```
3. implement the `GDPR.IGDPRCallback` in your activity
Expand Down Expand Up @@ -92,4 +93,5 @@ Check out the [demo](https://github.com/MFlisar/GDPRDialog/blob/master/app/src/m
* [x] german
* [ ] others
* [ ] offer bottom dialog layout as well
* [ ] if `withExplicitConsentForEachService` is used, the user currently needs to accept every service => could be improved to define some as optional
* add more networks (dropbox, ...)
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public class SetupActivity extends AppCompatActivity implements View.OnClickList
private CheckBox cbAllowNonPersonalisedForPaidVersions;
private CheckBox cbAskForAge;
private CheckBox cbCheckRequestLocation;
private CheckBox cbExplicitConsentForEachService;

@Override
protected void onCreate(Bundle savedInstanceState) {
Expand All @@ -33,6 +34,7 @@ protected void onCreate(Bundle savedInstanceState) {
cbAllowNonPersonalisedForPaidVersions = findViewById(R.id.cbAllowNonPersonalisedForPaidVersions);
cbAskForAge = findViewById(R.id.cbAskForAge);
cbCheckRequestLocation = findViewById(R.id.cbCheckRequestLocation);
cbExplicitConsentForEachService = findViewById(R.id.cbExplicitConsentForEachService);

cbAllowNonPersonalisedForPaidVersions.setEnabled(cbHasPaidVersion.isChecked());
cbHasPaidVersion.setOnCheckedChangeListener((buttonView, isChecked) -> cbAllowNonPersonalisedForPaidVersions.setEnabled(isChecked));
Expand All @@ -48,6 +50,7 @@ protected void onDestroy() {
cbAllowNonPersonalisedForPaidVersions = null;
cbAskForAge = null;
cbCheckRequestLocation = null;
cbExplicitConsentForEachService = null;
super.onDestroy();
}

Expand Down Expand Up @@ -77,7 +80,9 @@ public void onClick(View v)
if (cbCheckRequestLocation.isChecked()) {
setup.withCheckRequestLocation(true);
}

if (cbExplicitConsentForEachService.isChecked()) {
setup.withExplicitConsentForEachService(true);
}
intent.putExtra("setup", setup);
startActivity(intent);
}
Expand Down
6 changes: 6 additions & 0 deletions app/src/main/res/layout/activity_setup.xml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@
android:layout_height="wrap_content"
android:text="Special settings"/>

<CheckBox
android:id="@+id/cbExplicitConsentForEachService"
android:text="Explicitly require consent for each service (only if more than one is used)"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>

<CheckBox
android:id="@+id/cbAskForAge"
android:text="Explicitly ask for users age confirmation"
Expand Down
2 changes: 1 addition & 1 deletion library/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ android {
compileSdkVersion 27
buildToolsVersion "27.0.3"
defaultConfig {
minSdkVersion 16
minSdkVersion 15
targetSdkVersion 27
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.View;
Expand Down Expand Up @@ -63,7 +64,7 @@ private void onSaveConsentAndCloseActivity() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
finishAndRemoveTask();
} else {
finishAffinity();
ActivityCompat.finishAffinity(this);
}
} else {
finish();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ public String getHtmlLink() {
return "<a href=\"" + mLink + "\">" + mName + "</a>";
}

public String getCheckboxHtmlLink(Context context) {
return mName + " (<a href=\"" + mLink + "\">" + context.getString(R.string.gdpr_link) + "</a>)";
}

// ----------------
// Parcelable
// ----------------
Expand Down
15 changes: 15 additions & 0 deletions library/src/main/java/com/michaelflisar/gdprdialog/GDPRSetup.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public class GDPRSetup implements Parcelable {
private boolean mExplicitAgeConfirmation = false;
private boolean mNoToolbarTheme = false;
private boolean mCheckRequestLocation = false;
private boolean mExplicitConsentForEachService = false;

public GDPRSetup(GDPRNetwork... adNetworks) {
if (adNetworks == null || adNetworks.length == 0) {
Expand Down Expand Up @@ -48,6 +49,11 @@ public GDPRSetup withCheckRequestLocation(boolean checkRequestLocation) {
return this;
}

public GDPRSetup withExplicitConsentForEachService(boolean explicitConsentForEachService) {
mExplicitConsentForEachService = explicitConsentForEachService;
return this;
}

// ----------------
// Functions
// ----------------
Expand All @@ -68,6 +74,9 @@ public final String getNetworksCommaSeperated(Context context, boolean withLinks
return networks;
}

public final GDPRNetwork[] networks() {
return mAdNetworks;
}
public final boolean hasPaidVersion() {
return mHasPaidVersion;
}
Expand Down Expand Up @@ -96,6 +105,10 @@ public final boolean checkRequestLocation() {
return mCheckRequestLocation;
}

public final boolean explicitConsentForEachService() {
return mExplicitConsentForEachService;
}

public final boolean containsAdNetwork() {
for (GDPRNetwork network : mAdNetworks) {
if (network.isAdNetwork()) {
Expand All @@ -121,6 +134,7 @@ public GDPRSetup(Parcel in) {
mExplicitAgeConfirmation = in.readByte() == 1;
mNoToolbarTheme = in.readByte() == 1;
mCheckRequestLocation = in.readByte() == 1;
mExplicitConsentForEachService = in.readByte() == 1;
}

@Override
Expand All @@ -137,6 +151,7 @@ public void writeToParcel(Parcel dest, int flags) {
dest.writeByte(mExplicitAgeConfirmation ? (byte) 1 : 0);
dest.writeByte(mNoToolbarTheme ? (byte) 1 : 0);
dest.writeByte(mCheckRequestLocation ? (byte) 1 : 0);
dest.writeByte(mExplicitConsentForEachService ? (byte) 1 : 0);
}

public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@
import android.support.v7.widget.Toolbar;
import android.text.Html;
import android.text.method.LinkMovementMethod;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ViewFlipper;
Expand All @@ -18,20 +21,25 @@
import com.michaelflisar.gdprdialog.GDPRSetup;
import com.michaelflisar.gdprdialog.R;

import java.util.ArrayList;
import java.util.List;

public class GDPRViewManager
{
public static String ARG_SETUP = "ARG_SETUP";

private static String KEY_STEP = "KEY_STEP";
private static String KEY_AGE_CONFIRMED = "KEY_AGE_CONFIRMED";
private static String KEY_SELECTED_CONSENT = "KEY_SELECTED_CONSENT";
private static String KEY_EXPLICITLY_CONFIRMED_SERVICES = "KEY_EXPLICITLY_CONFIRMED_SERVICES";

private GDPRSetup mSetup;
private GDPR.IGDPRCallback mCallback = null;

private int mCurrentStep = 0;
private GDPRConsent mSelectedConsent = null;
private boolean mAgeConfirmed = false;
private ArrayList<Integer> mExplicitlyConfirmedServices = new ArrayList<>();

public GDPRViewManager(Bundle args, Bundle savedInstanceState) {
mSetup = args.getParcelable(ARG_SETUP);
Expand All @@ -41,6 +49,12 @@ public GDPRViewManager(Bundle args, Bundle savedInstanceState) {
mSelectedConsent = GDPRConsent.values()[savedInstanceState.getInt(KEY_SELECTED_CONSENT)];
}
mAgeConfirmed = savedInstanceState.getBoolean(KEY_AGE_CONFIRMED);
mExplicitlyConfirmedServices = savedInstanceState.getIntegerArrayList(KEY_EXPLICITLY_CONFIRMED_SERVICES);
} else {
mExplicitlyConfirmedServices.clear();
for (int i = 0; i< mSetup.networks().length; i++) {
mExplicitlyConfirmedServices.add(0);
}
}
}

Expand All @@ -50,6 +64,7 @@ public void save(Bundle outState) {
outState.putInt(KEY_SELECTED_CONSENT, mSelectedConsent.ordinal());
}
outState.putBoolean(KEY_AGE_CONFIRMED, mAgeConfirmed);
outState.putIntegerArrayList(KEY_EXPLICITLY_CONFIRMED_SERVICES, mExplicitlyConfirmedServices);
}

public void setCallback(Object callback) {
Expand Down Expand Up @@ -84,20 +99,21 @@ public void init(Activity activity, View view, IOnFinishView onFinishViewListene
final Button btDisagree = view.findViewById(R.id.btDisagree);
final Button btNoConsentAtAll = view.findViewById(R.id.btNoConsentAtAll);
final Button btCloseAfterNoConsentAccepted = view.findViewById(R.id.btCloseAfterNoConsentAccepted);
final TextView tvText = view.findViewById(R.id.tvText);
final TextView tvText1 = view.findViewById(R.id.tvText1);
final TextView tvText2 = view.findViewById(R.id.tvText2);
final TextView tvServices = view.findViewById(R.id.tvServices);
final LinearLayout llServices = view.findViewById(R.id.llServices);
final TextView tvTextNonPersonalAccepted = view.findViewById(R.id.tvTextNonPersonalAccepted);
final TextView tvTextPersonalAccepted = view.findViewById(R.id.tvTextPersonalAccepted);
final TextView tvTextNothingAccepted = view.findViewById(R.id.tvTextNothingAccepted);
final TextView tvAdsInfo = view.findViewById(R.id.tvAdsInfo);
final CheckBox cbAge = view.findViewById(R.id.cbAge);
String text = activity.getString(R.string.gdpr_dialog_text_part1, mSetup.getNetworksCommaSeperated(activity, true));
if (mSetup.explicitAgeConfirmation()) {
text += activity.getString(R.string.gdpr_dialog_text_part2_no_age);
} else {
text += activity.getString(R.string.gdpr_dialog_text_part2_with_age);
}

String text1 = activity.getString(R.string.gdpr_dialog_text_part1);
String text2 = activity.getString(R.string.gdpr_dialog_text_part2, mSetup.explicitAgeConfirmation() ? activity.getString(R.string.gdpr_dialog_text_part2_no_age) : activity.getString(R.string.gdpr_dialog_text_part2_with_age));
final String withdrawConsentInfoAddon = activity.getString(R.string.gdpr_withdraw_consent_info_addon);
tvText.setText(Html.fromHtml(text));
tvText1.setText(Html.fromHtml(text1));
tvText2.setText(Html.fromHtml(text2));
tvTextNonPersonalAccepted.setText(Html.fromHtml(activity.getString(R.string.gdpr_dialog_text_after_accepted_non_personal, mSetup.getNetworksCommaSeperated(activity,false), withdrawConsentInfoAddon)));
tvTextPersonalAccepted.setText(Html.fromHtml(activity.getString(R.string.gdpr_dialog_text_after_accepted_personal, withdrawConsentInfoAddon)));
if (mSetup.hasPaidVersion()) {
Expand All @@ -107,6 +123,27 @@ public void init(Activity activity, View view, IOnFinishView onFinishViewListene
tvTextNothingAccepted.setText(Html.fromHtml(activity.getString(R.string.gdpr_dialog_text_after_accepted_nothing, withdrawConsentInfoAddon)));
}

// we only accept this flag if more than one networks are used
if (mSetup.explicitConsentForEachService() && mSetup.networks().length > 1) {
tvServices.setVisibility(View.GONE);
LayoutInflater inflater = LayoutInflater.from(activity);
for (int i = 0; i< mSetup.networks().length; i++) {
View row = inflater.inflate(R.layout.gdpr_consent_row, null);
CheckBox cb = row.findViewById(R.id.cbCheckbox);
cb.setChecked(mExplicitlyConfirmedServices.get(i) == 1);
int finalI = i;
cb.setOnCheckedChangeListener((buttonView, isChecked) -> mExplicitlyConfirmedServices.set(finalI, isChecked ? 1 : 0));
TextView tv = row.findViewById(R.id.tvText);
tv.setText(Html.fromHtml(mSetup.networks()[i].getCheckboxHtmlLink(activity)));
tv.setMovementMethod(LinkMovementMethod.getInstance());
llServices.addView(row);
}
} else {
String textServices = mSetup.getNetworksCommaSeperated(activity, true);
tvServices.setText(Html.fromHtml(textServices));
llServices.setVisibility(View.GONE);
}

if (!mSetup.containsAdNetwork() || (mSetup.hasPaidVersion() && !mSetup.allowNonPersonalisedForPaidVersion())) {
tvAdsInfo.setVisibility(View.GONE);
}
Expand All @@ -126,7 +163,7 @@ public void init(Activity activity, View view, IOnFinishView onFinishViewListene
}
}

tvText.setMovementMethod(LinkMovementMethod.getInstance());
tvServices.setMovementMethod(LinkMovementMethod.getInstance());
tvTextNonPersonalAccepted.setMovementMethod(LinkMovementMethod.getInstance());

updateSelectedPage(vfFlipper, view);
Expand All @@ -136,7 +173,7 @@ public void init(Activity activity, View view, IOnFinishView onFinishViewListene
// ------------------

view.findViewById(R.id.btAgree).setOnClickListener(v -> {
if (!isAgeValid(v.getContext(), true)) {
if (!isAgeValid(v.getContext(), true) || !isAllConsentGiven(v.getContext())) {
return;
}
mSelectedConsent = GDPRConsent.PERSONAL_CONSENT;
Expand All @@ -145,7 +182,7 @@ public void init(Activity activity, View view, IOnFinishView onFinishViewListene
});

view.findViewById(R.id.btDisagree).setOnClickListener(v -> {
if (!isAgeValid(v.getContext(), false)) {
if (!isAgeValid(v.getContext(), false) || !isAllConsentGiven(v.getContext())) {
return;
}
if (mSetup.hasPaidVersion()) {
Expand Down Expand Up @@ -216,6 +253,25 @@ private boolean isAgeValid(Context context, boolean agree) {
return true;
}

private boolean isAllConsentGiven(Context context) {
if (mSetup.explicitConsentForEachService()) {
int consentsGiven = 0;
for (int i = 0; i < mExplicitlyConfirmedServices.size(); i++) {
if (mExplicitlyConfirmedServices.get(i) == 1) {
consentsGiven++;
}
}
if (mSetup.networks().length != consentsGiven) {
Toast.makeText(context, R.string.gdpr_not_all_services_accepted, Toast.LENGTH_LONG).show();
return false;
} else {
return true;
}
} else {
return true;
}
}

private void updateSelectedPage(ViewFlipper vfFlipper, View view) {
vfFlipper.setDisplayedChild(mCurrentStep);
// TODO: resize dialog...
Expand Down
21 changes: 21 additions & 0 deletions library/src/main/res/layout/gdpr_consent_row.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">

<CheckBox
android:id="@+id/cbCheckbox"
android:saveEnabled="false"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical" />

<TextView
android:id="@+id/tvText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="1" />

</LinearLayout>
Loading

0 comments on commit 955ee4d

Please sign in to comment.