JSON Driven Consent in Android

by Mir Suhail

In medical terms, consent is a single or multi paged form signed by a participant prior to a medical procedure or survey to confirm that he or she agrees to the procedure and is aware of any risks that might be involved in survey/study.

Getting Started

Here, we will discuss how to develop an android consent app that lets the participant get information about the survey/study and agree or disagree to it at the end. The content of the consent would come from json file. Hence,  if the content or the number of pages in the consent changes, the developer need not put in extra effort to change it.

1. Creating New Project

Create a new project in Android Studio from File ⇒ New Project. When it prompts you to select default activity, select Empty Activity and proceed. Name it as MainActivity. Add following code to the MainActivity.

MainActivity.java
package com.appliedinformatics.android.consentapp;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;

import com.appliedinformatics.android.consentapp.ConsentActivity;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;


public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.i(Constants.TAG, "I am in the Main Activity");
        startConsent();
    }

    public void startConsent(){
        /*Calling the Consent Activity*/
        Log.i(Constants.TAG, "Starting Consent Activity");
        Intent intent = new Intent(MainActivity.this, ConsentActivity.class);
        startActivityForResult(intent, Constants.REQUEST_CODE_CONSENT);
    }
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == Constants.REQUEST_CODE_CONSENT && resultCode == RESULT_OK) {
            Log.d(Constants.TAG, "Consent Completed Successfully");
        }
        super.onActivityResult(requestCode, resultCode, data);
    }
}

Add another activity and call it ConsentActivity. Consent Activity would extend from an abstract activity called ConsentBrain. Create two new classes and call it ConsentBrain and DynamicFragments. ConsentBrain contains the xml layout file called activity_consent.

Replace the contents of ConsentBrain, ConsentActivity, DynamicFragments and activity_consent with the following code.

ConsentActivity.java
package com.appliedinformatics.android.consentapp;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.util.Log;


import com.appliedinformatics.android.consentapp.Constants;
import com.appliedinformatics.android.consentapp.MainActivity;
import com.appliedinformatics.android.consentapp.R;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class ConsentActivity extends ConsentBrain {
    boolean require_name;
    boolean require_signature;
    static String TAG = "ConsentApp";
    private static String DATA_JSON_PATH;
    SharedPreferences sharedPreferences;

    public ConsentActivity(){
        DATA_JSON_PATH = consentJSON.json;
        Log.i(Constants.TAG, "JSON Path "+ DATA_JSON_PATH);
    }

    @Override
    public void init(@Nullable Bundle savedInstanceState) {
        String json = loadJSONFromAsset(getApplicationContext(), DATA_JSON_PATH);
        sharedPreferences = getSharedPreferences(Constants.SHARED_PREF_NAME, MODE_MULTI_PROCESS);
        Log.i(Constants.TAG, "Json \n"+json);
        try {
            parseJson(json);
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    private void parseJson(String json) throws JSONException {
        SharedPreferences.Editor editor = sharedPreferences.edit();
        JSONObject jsonresponse = new JSONObject(json);
        String first_name = jsonresponse.getString("first_name");
        String last_name = jsonresponse.getString("last_name");
        String description = jsonresponse.getString("description");
        String title = jsonresponse.getString("title");
        String institute = jsonresponse.getString("institute");
        String email = jsonresponse.getString("email");
        String trial_id = jsonresponse.getString("id");
        editor.putString(Constants.SHARED_PREF_TRIAL_ID, trial_id);
        editor.commit();
        JSONObject consentObject = jsonresponse.getJSONObject("consent");
        require_name = consentObject.getBoolean("require_name");
        require_signature = consentObject.getBoolean("require_signature");
        JSONArray consent_sections = sortJsonArray(consentObject.getJSONArray("sections"));
        addSlide(R.layout.consent_layout, title, description, "" );
        for (int i = 0; i< consent_sections.length(); i++){
            JSONObject result = consent_sections.getJSONObject(i);
            String type = result.getString("type");
            String page_title = result.getString("title");
            String short_description = result.getString("short_description");
            String long_description = result.getString("description");
            int order = result.getInt("order");
            addSlide(R.layout.consent_layout, page_title, short_description, long_description );
        }
    }


    @Override
    public void onDisagreePressed() {
        AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
        //Setting Dialog Logo
        //alertDialog.setIcon(R.drawable.bermuda_icon);
        // Setting Dialog Title
        alertDialog.setTitle("Disagree");
        // Setting Dialog Message
        alertDialog.setMessage("You will not be able to proceed if you disagree. Press OK to continue.");
        // Setting Positive "Yes" Button
        alertDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                // Write your code here to invoke Agree event
                Intent intent = new Intent(getApplicationContext(), MainActivity.class);
                startActivity(intent);
            }
        });
        // Setting Negative "NO" Button
        alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                dialog.cancel();
            }
        });
        // Showing Alert Message
        alertDialog.show();
    }

    @Override
    public void onAgreePressed() {
        AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
        //Setting Dialog Logo
        //alertDialog.setIcon(R.drawable.bermuda_icon);
        // Setting Dialog Title
        alertDialog.setTitle("Review");
        // Setting Dialog Message
        alertDialog.setMessage("Do you agree with the study terms and give your consent for the study");
        // Setting Positive "Yes" Button
        alertDialog.setPositiveButton("Agree", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                if (require_name || require_signature )
                    loadConsentConfirmation(false);
                else
                    loadConsentConfirmation(true);

                // Write your code here to invoke Agree event
            }
        });
        // Setting Negative "NO" Button
        alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                // Write your code here to invoke NO event
//                    Toast.makeText(getApplicationContext(), "You clicked on Cancel", Toast.LENGTH_SHORT).show();
                dialog.cancel();
            }
        });
        // Showing Alert Message
        alertDialog.show();
    }

    @Override
    protected void onCancelPressed() {
        startActivity(new Intent(this, MainActivity.class));
    }

    @Override
    public void onDotSelected(int index) {
        super.onDotSelected(index);
    }

    public static String loadJSONFromAsset(Context context, String fileName) {
        String json = null;
        try {
            InputStream is = context.getAssets().open(fileName);
            int size = is.available();
            byte[] buffer = new byte[size];
            is.read(buffer);
            is.close();
            json = new String(buffer, "UTF-8");
        } catch (IOException ex) {
            Log.d(TAG, "Exception Occurred : " + ex.getMessage());
            return null;
        }
        return json;
    }

    public void loadConsentConfirmation(boolean show_thanks){
        Intent intent = new Intent(this, ConsentConfirmation.class);
        intent.putExtra(Constants.REQUIRE_NAME, String.valueOf(require_name));
        intent.putExtra(Constants.REQUIRE_SIGN, String.valueOf(require_signature));
        intent.putExtra(Constants.SHOW_THANKS, String.valueOf(show_thanks));
        startActivity(intent);
    }

    public JSONArray sortJsonArray(JSONArray jsonArray){
        JSONArray jsonArr = jsonArray;
        JSONArray sortedJsonArray = new JSONArray();

        List<JSONObject> jsonValues = new ArrayList<JSONObject>();

        for (int i = 0; i < jsonArr.length(); i++) {
            try {
                jsonValues.add(jsonArr.getJSONObject(i));
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
        Collections.sort( jsonValues, new Comparator<JSONObject>() {
            //You can change "Name" with "ID" if you want to sort by ID
            private static final String KEY_NAME = "order";

            @Override
            public int compare(JSONObject a, JSONObject b) {
                Integer valA = null;
                Integer valB = null;

                try {
                    valA = (Integer) a.get(KEY_NAME);
                    valB = (Integer) b.get(KEY_NAME);
                }
                catch (JSONException e) {
                    //do something
                }

                return valA.compareTo(valB);
                //if you want to change the sort order, simply use the following:
                //return -valA.compareTo(valB);
            }
        });

        for (int i = 0; i < jsonArr.length(); i++) {
            sortedJsonArray.put(jsonValues.get(i));
        }
        Log.i(Constants.TAG, "Sorted Array\n"+sortedJsonArray);
        return sortedJsonArray;
    }
}

 

ConsentBrain.java
package com.appliedinformatics.android.consentapp;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.TextView;

import com.appliedinformatics.android.consentapp.Constants;
import com.appliedinformatics.android.consentapp.R;

import java.util.List;
import java.util.Vector;

public abstract class ConsentBrain extends AppCompatActivity {

    private PagerAdapter mPagerAdapter;
    public ViewPager pager;
    public List<Fragment> fragments = new Vector<>();
    private int slidesNumber;
    private boolean showBack = true;
    private boolean showAgree = true;
    static String json_Path;

    @Override
    final protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_consent);
        Intent intent = getIntent();
        json_Path = intent.getStringExtra(Constants.JSON_PATH_KEY);
        final ImageButton backButton = (ImageButton) findViewById(R.id.back);
        final ImageButton nextButton = (ImageButton) findViewById(R.id.next);
        final TextView agreeButton = (TextView) findViewById(R.id.agree);
        final TextView disagreeButton = (TextView) findViewById(R.id.disagree);
        final TextView cancelButton = (TextView) findViewById(R.id.cancel_action);
        cancelButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                onCancelPressed();
            }
        });
        backButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(@NonNull View v) {
                pager.setCurrentItem(pager.getCurrentItem() - 1);
                pager.setVisibility(View.VISIBLE);

            }
        });

        nextButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(@NonNull View v) {
                pager.setCurrentItem(pager.getCurrentItem() + 1);
                pager.setVisibility(View.VISIBLE);

            }
        });

        agreeButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(@NonNull View v) {
                onAgreePressed();
            }
        });

        disagreeButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(@NonNull View v) {
               onDisagreePressed();
            }
        });
        mPagerAdapter = new PagerAdapter(super.getSupportFragmentManager(), fragments);
        pager = (ViewPager) findViewById(R.id.view_pager);

        pager.setAdapter(this.mPagerAdapter);
        pager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {

                int a = pager.getCurrentItem();
                Log.i(Constants.TAG,"pooooooos---pager"+a);
                Log.i(Constants.TAG,"pooooooos---pager"+position);
                if (position == 0){
                    showBack = false;
                }else{
                    showBack = true;
                }
                if (position == slidesNumber - 1) {
                    if (showAgree) {
                        nextButton.setVisibility(View.INVISIBLE);
                        agreeButton.setVisibility(View.VISIBLE);
                        disagreeButton.setVisibility(View.VISIBLE);

                    } else {
                        agreeButton.setVisibility(View.INVISIBLE);
                        disagreeButton.setVisibility(View.INVISIBLE);
                    }
                } else {
                    backButton.setVisibility(View.VISIBLE);
                    agreeButton.setVisibility(View.GONE);
                    disagreeButton.setVisibility(View.GONE);
                    nextButton.setVisibility(View.VISIBLE);
                }

                if (!showBack) {
                    backButton.setVisibility(View.INVISIBLE);
                }
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });

        init(savedInstanceState);
        slidesNumber = fragments.size();

        if (slidesNumber == 1) {
            nextButton.setVisibility(View.GONE);
            agreeButton.setVisibility(View.VISIBLE);
        }
    }

    public ViewPager getPager() {
        return pager;
    }

    public void addSlide(int layout,String title, String short_text, String long_text) {
        Log.i(Constants.TAG,title +"\n"+short_text +"\n"+long_text);
        Fragment fragment = DynamicFrgments.newInstance(layout,title, short_text, long_text,fragments.size());
        fragments.add(fragment);
        mPagerAdapter.notifyDataSetChanged();
    }

    @NonNull
    public List<Fragment> getSlides() {
        return mPagerAdapter.getFragments();
    }

    public abstract void init(@Nullable Bundle savedInstanceState);

    public abstract void onDisagreePressed();

    public abstract void onAgreePressed();

    protected abstract void onCancelPressed();

    public void onDotSelected(int index) {
    }

    @Override
    protected void attachBaseContext(Context newBase) {
        super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase));
    }

    public static String getJsonPath(){
        return json_Path;
    }
}

 

DynamicFragments.java
package com.appliedinformatics.android.researchdroid.Consent;

import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.appliedinformatics.android.consentapp.MainActivity;
import com.appliedinformatics.android.consentapp.R;

public class DynamicFragments extends Fragment {
    private static final String ARG_LAYOUT_RES_ID = "layoutResId";
    private static final String ARG_LAYOUT_ID_CONSENT = "id_consent";
    private static final String ARG_LAYOUT_TITLE_TEXT = "title_text";
    private static final String ARG_LAYOUT_SHORT_TEXT = "short_text";
    private static final String ARG_LAYOUT_LONG_TEXT = "long_text";
    private int layoutResId;
    private String  title_text;
    private String  short_text;
    private String  long_text;
    TextView consentHeader = null;
    int incremental_id = 0;
    LinearLayout linearLayout;

    public static DynamicFragments newInstance(int layoutResId,String title, String short_text, String long_text,int id) {
        DynamicFragments addingSlide = new DynamicFragments();
        Bundle args = new Bundle();
        args.putInt(ARG_LAYOUT_RES_ID, layoutResId);
        args.putInt(ARG_LAYOUT_ID_CONSENT, id);
        args.putString(ARG_LAYOUT_TITLE_TEXT, title);
        args.putString(ARG_LAYOUT_SHORT_TEXT, short_text);
        args.putString(ARG_LAYOUT_LONG_TEXT, long_text);
        addingSlide.setArguments(args);
        return addingSlide;
    }

    public DynamicFragments() {}

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        linearLayout = (LinearLayout) getActivity().findViewById(R.id.topPanel);
        consentHeader = (TextView) getActivity().findViewById(R.id.consentHeading);
        if(getArguments() != null && getArguments().containsKey(ARG_LAYOUT_RES_ID))
            layoutResId = getArguments().getInt(ARG_LAYOUT_RES_ID);
        if(getArguments() != null && getArguments().containsKey(ARG_LAYOUT_ID_CONSENT))
            incremental_id = getArguments().getInt(ARG_LAYOUT_ID_CONSENT);
        if(getArguments() != null && getArguments().containsKey(ARG_LAYOUT_TITLE_TEXT))
            title_text = getArguments().getString(ARG_LAYOUT_TITLE_TEXT);
        if(getArguments() != null && getArguments().containsKey(ARG_LAYOUT_SHORT_TEXT))
            short_text = getArguments().getString(ARG_LAYOUT_SHORT_TEXT);
        if(getArguments() != null && getArguments().containsKey(ARG_LAYOUT_LONG_TEXT))
            long_text = getArguments().getString(ARG_LAYOUT_LONG_TEXT);
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View v = inflater.inflate(layoutResId, container, false);
        View link = v.findViewById(R.id.link_view);
        final View main = v.findViewById(R.id.consent_main);
        final View learnmore = v.findViewById(R.id.relativelearmmore);
        linearLayout = (LinearLayout) getActivity().findViewById(R.id.topPanel);
        TextView title_text = (TextView) v.findViewById(R.id.consentHeading);
        title_text.setText(this.title_text);
        TextView title_text_learnMore = (TextView) v.findViewById(R.id.consentHeading_learnMore);
        title_text_learnMore.setText(this.title_text);
        TextView short_text = (TextView) v.findViewById(R.id.consent_body);
        short_text.setText(this.short_text);
        TextView long_text = (TextView) v.findViewById(R.id.longtextview);

        long_text.setText(this.long_text);
        View link_back = v.findViewById(R.id.learn_moreBack);
        final LinearLayout buttonStrip = (LinearLayout) getActivity().findViewById(R.id.bottom);
        if (link !=null){
            link.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    learnmore.setVisibility(View.VISIBLE);
                    main.setVisibility(View.GONE);
                    if (linearLayout!=null)
                        linearLayout.setVisibility(View.GONE);
                    buttonStrip.setVisibility(View.GONE);
                }
            });
        }
        link_back.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                main.setVisibility(View.VISIBLE);
                learnmore.setVisibility(View.GONE);
                linearLayout.setVisibility(View.VISIBLE);
                buttonStrip.setVisibility(View.VISIBLE);


            }
        });
        return v;
    }

    protected void onCancelPressed() {
        startActivity(new Intent(getActivity(), MainActivity.class));
    }
}

 

activity_consent.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:id="@+id/relativeLayout">
    <LinearLayout
        android:id="@+id/topPanel"
        android:background="#00000000"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:gravity="bottom"
        android:layout_alignParentTop="true"
        android:orientation="horizontal" >
        <FrameLayout
            android:background="#00000000"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginBottom="5sp" >
            <Button
                android:id="@+id/cancel_action"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                style="@style/SectionIdentifier"
                android:layout_gravity="right"
                android:minWidth="65dp"
                android:gravity="center"
                android:background="@null"
                android:text="Cancel"
                fontPath="font/Roboto-Light.ttf"
                android:textColor="@color/theme_color"/>

        </FrameLayout>
    </LinearLayout>
    <android.support.v4.view.ViewPager
        android:id="@+id/view_pager"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/topPanel">
    </android.support.v4.view.ViewPager>
    <LinearLayout
        android:id="@+id/bottom"
        android:background="#00000000"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:gravity="bottom"
        android:layout_alignParentBottom="true"
        android:orientation="vertical" >
        <FrameLayout
            android:background="#00000000"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            >
            <FrameLayout
                android:id="@+id/indicator_container"
                android:layout_width="wrap_content"
                android:layout_height="fill_parent"
                android:layout_gravity="center" />

            <ImageButton
                android:layout_width="wrap_content"
                android:layout_height="fill_parent"
                android:layout_gravity="left"
                android:id="@+id/back"
                android:minWidth="30dp"
                style="?attr/borderlessButtonStyle"
                android:background="@null"
                android:src="@drawable/backthin"
                android:layout_marginLeft="90sp"
                android:visibility="invisible"/>

            <ImageButton
                android:layout_width="wrap_content"
                android:layout_height="fill_parent"
                style="?attr/borderlessButtonStyle"
                android:id="@+id/next"
                android:minWidth="30dp"
                android:layout_gravity="right"
                android:background="@null"
                android:src="@drawable/nextthin"
                android:layout_marginRight="90sp"/>

            <Button
                android:layout_width="wrap_content"
                android:layout_height="fill_parent"
                android:layout_gravity="left"
                style="@style/NoButtonStyle"
                android:minWidth="90dp"
                android:id="@+id/disagree"
                android:text="Disagree"
                android:textColor="@color/theme_color"
                android:visibility="gone"/>

            <Button
                android:layout_width="wrap_content"
                android:layout_height="fill_parent"
                style="@style/NoButtonStyle"
                android:id="@+id/agree"
                android:layout_gravity="right"
                android:minWidth="90dp"
                android:text="Agree"
                android:textColor="@color/theme_color"
                android:visibility="gone"/>
        </FrameLayout>
    </LinearLayout>
</RelativeLayout>

After this, we will create one more template layout called consent_layout.xml.

consent_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    xmlns:android="http://schemas.android.com/apk/res/android">
    <RelativeLayout
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        android:id="@+id/consent_main">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="80sp"
        android:id="@+id/image_layout"
        android:layout_below="@+id/topPanel">
        <ImageView
            android:layout_height="100sp"
            android:layout_width="match_parent"
            android:id="@+id/image"
            android:scaleType="fitCenter"
            android:layout_centerHorizontal="true"/>
    </RelativeLayout>

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/linearLayout"
        android:layout_below="@+id/image_layout"
        android:layout_marginTop="5sp"
        android:layout_marginLeft="20sp"
        android:layout_marginRight="20sp" >

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            style="@style/Headline"
            android:text="Heading"
            android:id="@+id/consentHeading" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            style="@style/Body"
            android:id="@+id/consent_body"
            android:text="Body"
            android:layout_marginTop="5sp" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            style="@style/LinkStyle"
            android:text="Learn More"
            android:id="@+id/link_view"
            android:layout_marginTop="10sp" />
    </LinearLayout>
    </RelativeLayout>
    <RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/relativelearmmore"
        android:visibility="gone">
        <FrameLayout
            android:background="#00000000"
            android:id="@+id/learnmoreTopFrame"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize" >
            <Button
                android:id="@+id/learn_moreBack"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:minWidth="65dp"
                style="@style/SectionIdentifier"
                android:layout_gravity="right"
                android:background="@null"
                android:text="Done"
                android:gravity="center"
                fontPath="font/Roboto-Light.ttf"
                android:textColor="@color/theme_color"/>
        </FrameLayout>
        <RelativeLayout android:layout_height="match_parent"
            android:layout_width="match_parent"
            android:layout_alignParentBottom="true"
            android:layout_below="@+id/learnmoreTopFrame"
            android:layout_marginRight="20sp"
            android:layout_marginLeft="20sp"
            android:layout_marginTop="20sp">
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                style="@style/Headline"
                android:text="Heading"
                android:id="@+id/consentHeading_learnMore" />
            <android.support.v4.widget.NestedScrollView
                xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_marginBottom="5sp"
                android:layout_marginTop="5sp"
                android:fadeScrollbars="false"
                android:layout_below="@+id/consentHeading_learnMore">
                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="LoremIpsum"
                    style="@style/Body"
                    android:id="@+id/longtextview"
                    android:layout_alignParentTop="true"/>
            </android.support.v4.widget.NestedScrollView>
        </RelativeLayout>
    </RelativeLayout>
</RelativeLayout>

2. Adding JSON file in Assets folder

Right click on app in top hierarchy,  go to New, select Folder and click on Assets Folder. You will notice that assets folder would have been added to the project adjacent to res folder. Now right click on assets folder, select new and add a Json file and call it as consentJSON. Replace the contents of this file with following content.

Note: We can change the value but keys must remain same.

consentJSON.xml
{"first_name": "a", "last_name": "a",
    "consent": 
        {"sections": 
          [{"short_description": "aaa", "order": 0, "type": "overview", "description": "aaaa", "title": "aaa"},
           {"short_description": "bbb", "order": 1, "type": "data_gathering", "description": "bbbb", "title": "bbb"},
           {"short_description": "ccc", "order": 2, "type": "privacy", "description": "ccccc", "title": "ccc"}],
         "require_name": true, "require_signature": true},
     "description": "a", "title": "a", "institute": "a",
     "email": "a@a.com", "id": 1}

ConsentBrain contains viewPager Adapter which actually helps in traversing through the consent pages. We supply consent pages with viewpager that are generated dynamically. From each entry in consentJSON file, we create a fragment page with the help of DynamicFragments class. The pages generated gets added to the fragment stack and then the view pager traverses through the same page stack.

Here’s how the final consent app would look like:

consent app imageimage2

Leave a Reply

Your email address will not be published. Required fields are marked *

Mobile Research Apps

We have deep expertise in design and development of mobile research apps that work on both iOS and Android securely.

Contact us now

Popular Posts