Commit 7587494a authored by Lily Tsai's avatar Lily Tsai

yay message app with tabs is working

parent 5ab88a38
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="WizardSettings">
<option name="children">
<map>
<entry key="imageWizard">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="imageAssetPanel">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="actionbar">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="clipartAsset">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="url" value="jar:file:/snap/android-studio/47/android-studio/plugins/android/lib/android.jar!/images/material_design_icons/communication/ic_email_black_24dp.xml" />
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
<option name="values">
<map>
<entry key="outputName" value="ic_recv" />
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
<option name="values">
<map>
<entry key="outputIconType" value="ACTIONBAR" />
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
</component>
</project>
\ No newline at end of file
......@@ -10,6 +10,7 @@
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/ebcagent" />
<option value="$PROJECT_DIR$/ebclibrary" />
<option value="$PROJECT_DIR$/ebcmessageapp" />
<option value="$PROJECT_DIR$/ebcutils" />
<option value="$PROJECT_DIR$/exampleapp" />
<option value="$PROJECT_DIR$/testapp" />
......
......@@ -5,11 +5,12 @@
<option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
<option name="myNullables">
<value>
<list size="4">
<list size="5">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
<item index="2" class="java.lang.String" itemvalue="javax.annotation.CheckForNull" />
<item index="3" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
<item index="4" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
</list>
</value>
</option>
......@@ -27,4 +28,7 @@
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>
\ No newline at end of file
......@@ -11,7 +11,6 @@ buildscript {
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.0'
classpath 'com.github.dcendents:android-maven-gradle-plugin:2.0'
classpath 'com.google.gms:google-services:3.2.0'
classpath 'me.tatarka:gradle-retrolambda:3.2.5'
classpath 'org.springframework.boot:spring-boot-gradle-plugin:1.5.10.RELEASE'
}
}
......
apply plugin: 'com.android.application'
android {
compileSdkVersion 26
buildToolsVersion '27.0.3'
defaultConfig {
applicationId "org.mpisws.ebcmessageapp"
minSdkVersion 26
targetSdkVersion 26
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'),
'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:design:26.1.0'
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.google.android.gms:play-services-auth:15.0.1'
implementation 'pub.devrel:easypermissions:0.3.0'
implementation('com.google.api-client:google-api-client-android:1.23.0') {
exclude group: 'org.apache.httpcomponents'
}
implementation('com.google.apis:google-api-services-calendar:v3-rev321-1.23.0') {
exclude group: 'org.apache.httpcomponents'
}
}
{
"project_info": {
"project_number": "982372089272",
"firebase_url": "https://ebctesterapplica-1519910772236.firebaseio.com",
"project_id": "ebctesterapplica-1519910772236",
"storage_bucket": "ebctesterapplica-1519910772236.appspot.com"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:982372089272:android:5d00400f4ad14480",
"android_client_info": {
"package_name": "org.mpisws.ebcmessageapp"
}
},
"oauth_client": [
{
"client_id": "982372089272-i30mo7dan9i7g0opkha9l3q82c04044t.apps.googleusercontent.com",
"client_type": 1,
"android_info": {
"package_name": "org.mpisws.ebcmessageapp",
"certificate_hash": "120fc2e0baba17cd022d8ed50842620f96948501"
}
},
{
"client_id": "982372089272-n4o6cvhhf6m0tc4hopts3jdgf4dal4bi.apps.googleusercontent.com",
"client_type": 3
},
{
"client_id": "982372089272-9s64lur9ab322ktvu65necd8f20c3103.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyC8PbgzfcJ_HFPhFoMx4CYWNTiBjUgJWd0"
}
],
"services": {
"analytics_service": {
"status": 1
},
"appinvite_service": {
"status": 2,
"other_platform_oauth_client": [
{
"client_id": "982372089272-n4o6cvhhf6m0tc4hopts3jdgf4dal4bi.apps.googleusercontent.com",
"client_type": 3
}
]
},
"ads_service": {
"status": 2
}
}
},
{
"client_info": {
"mobilesdk_app_id": "1:982372089272:android:defcf5a76f1dfec8",
"android_client_info": {
"package_name": "org.mpisws.testapp"
}
},
"oauth_client": [
{
"client_id": "982372089272-n4o6cvhhf6m0tc4hopts3jdgf4dal4bi.apps.googleusercontent.com",
"client_type": 3
},
{
"client_id": "982372089272-9s64lur9ab322ktvu65necd8f20c3103.apps.googleusercontent.com",
"client_type": 3
},
{
"client_id": "982372089272-7vqm9dkknjee8t1mfj74c3uefumbsa9e.apps.googleusercontent.com",
"client_type": 1,
"android_info": {
"package_name": "org.mpisws.testapp",
"certificate_hash": "120fc2e0baba17cd022d8ed50842620f96948501"
}
}
],
"api_key": [
{
"current_key": "AIzaSyC8PbgzfcJ_HFPhFoMx4CYWNTiBjUgJWd0"
}
],
"services": {
"analytics_service": {
"status": 1
},
"appinvite_service": {
"status": 2,
"other_platform_oauth_client": [
{
"client_id": "982372089272-n4o6cvhhf6m0tc4hopts3jdgf4dal4bi.apps.googleusercontent.com",
"client_type": 3
}
]
},
"ads_service": {
"status": 2
}
}
}
],
"configuration_version": "1"
}
\ No newline at end of file
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /home/tslilyai/Android/Sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# 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
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.mpisws.ebcmessageapp">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="Google Calendar API Android Quickstart"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="Google Calendar API Android Quickstart" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
\ No newline at end of file
package org.mpisws.ebcmessageapp;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class GetMessages extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.send_messages, container, false);
}
}
package org.mpisws.ebcmessageapp;
import android.Manifest;
import android.accounts.AccountManager;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.View;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.api.client.extensions.android.http.AndroidHttp;
import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential;
import com.google.api.client.googleapis.extensions.android.gms.auth.GooglePlayServicesAvailabilityIOException;
import com.google.api.client.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOException;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.util.DateTime;
import com.google.api.services.calendar.model.Event;
import com.google.api.services.calendar.model.Events;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import pub.devrel.easypermissions.AfterPermissionGranted;
import pub.devrel.easypermissions.EasyPermissions;
public class MainActivity extends AppCompatActivity {
/**
* Create the main activity.
*
* @param savedInstanceState previously saved instance data.
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TabLayout tabLayout = findViewById(R.id.tab_layout);
final ViewPager viewPager = findViewById(R.id.view_pager);
// Making new tabs and adding to tabLayout
tabLayout.addTab(tabLayout.newTab().setText("Send Messages").setIcon(R.drawable.ic_send));
tabLayout.addTab(tabLayout.newTab().setText("Get Messages").setIcon(R.drawable.ic_recv));
// Adding fragments to a list
List<Fragment> fragments = new Vector<Fragment>();
fragments.add(Fragment.instantiate(this, SendMessages.class.getName()));
fragments.add(Fragment.instantiate(this, GetMessages.class.getName()));
// Attaching fragments into tabLayout with ViewPager
viewPager.setAdapter(new SectionPagerAdapter(getSupportFragmentManager(), fragments));
tabLayout.setupWithViewPager(viewPager);
}
}
package org.mpisws.ebcmessageapp;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import java.util.List;
public class SectionPagerAdapter extends FragmentPagerAdapter {
private List<Fragment> fragments;
public SectionPagerAdapter(FragmentManager fm, List<Fragment> fragments) {
super(fm);
this.fragments = fragments;
}
@Override
public Fragment getItem(int position) {
return this.fragments.get(position);
}
@Override
public int getCount() {
return this.fragments.size();
}
@Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "First Tab";
case 1:
default:
return "Second Tab";
}
}
}
package org.mpisws.ebcmessageapp;
import android.Manifest;
import android.accounts.AccountManager;
import android.app.DatePickerDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.api.client.extensions.android.http.AndroidHttp;
import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential;
import com.google.api.client.googleapis.extensions.android.gms.auth.GooglePlayServicesAvailabilityIOException;
import com.google.api.client.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOException;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.util.DateTime;
import com.google.api.client.util.ExponentialBackOff;
import com.google.api.services.calendar.CalendarScopes;
import com.google.api.services.calendar.model.Event;
import com.google.api.services.calendar.model.Events;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import pub.devrel.easypermissions.AfterPermissionGranted;
import pub.devrel.easypermissions.EasyPermissions;
import static android.app.Activity.RESULT_OK;
public class SendMessages extends Fragment implements EasyPermissions.PermissionCallbacks {
GoogleAccountCredential mCredential;
private static final String DATE_FORMAT = "%d/%d/%d";
private static TextView mOutputText;
private static ProgressBar mProgress;
private static Button mDateButton;
private LocalDateTime date = LocalDateTime.now();
private static final String PREF_ACCOUNT_NAME = "accountName";
static final int REQUEST_ACCOUNT_PICKER = 1000;
static final int REQUEST_AUTHORIZATION = 1001;
static final int REQUEST_GOOGLE_PLAY_SERVICES = 1002;
static final int REQUEST_PERMISSION_GET_ACCOUNTS = 1003;
private static final String[] SCOPES = { CalendarScopes.CALENDAR};
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.get_messages, container, false);
mProgress = view.findViewById(R.id.progressbar);
mOutputText = view.findViewById(R.id.displaycalendarevents);
mDateButton = view.findViewById(R.id.getcalendarevents);
mDateButton.setText(String.format(DATE_FORMAT, date.getMonthValue(), date.getDayOfMonth(), date.getYear()));
view.findViewById(R.id.getcalendarevents).setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
mDateButton.setEnabled(false);
DatePickerDialog datePickerDialog = new DatePickerDialog(getView().getContext(),
new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
date = LocalDateTime.of(year, monthOfYear+1, dayOfMonth, 0, 0, 0);
mDateButton.setText(String.format(DATE_FORMAT, date.getMonthValue(), date.getDayOfMonth(), date.getYear()));
// actually set the data once we get the date
getResultsFromApi();
mDateButton.setEnabled(true);
}
}, date.getYear(), date.getMonthValue()-1, date.getDayOfMonth());
datePickerDialog.show();
}
});
// Initialize credentials and service object.
mCredential = GoogleAccountCredential.usingOAuth2(
view.getContext(), Arrays.asList(SCOPES))
.setBackOff(new ExponentialBackOff());
return view;
}
/**
* Attempt to call the API, after verifying that all the preconditions are
* satisfied. The preconditions are: Google Play Services installed, an
* account was selected and the device currently has online access. If any
* of the preconditions are not satisfied, the app will prompt the user as
* appropriate.
*/
private void getResultsFromApi() {
if (! isGooglePlayServicesAvailable()) {
acquireGooglePlayServices();
} else if (mCredential.getSelectedAccountName() == null) {
chooseAccount();
} else if (! isDeviceOnline()) {
mOutputText.setText("No network connection available.");
} else {
new MakeRequestTask(mCredential).execute();
}
}
/**
* An asynchronous task that handles the Google Calendar API call.
* Placing the API calls in their own task ensures the UI stays responsive.
*/
private class MakeRequestTask extends AsyncTask<Void, Void, List<String>> {
private com.google.api.services.calendar.Calendar mService = null;
private Exception mLastError = null;
MakeRequestTask(GoogleAccountCredential credential) {
HttpTransport transport = AndroidHttp.newCompatibleTransport();
JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
mService = new com.google.api.services.calendar.Calendar.Builder(
transport, jsonFactory, credential)
.setApplicationName("Google Calendar API Android Quickstart")
.build();
}
/**
* Background task to call Google Calendar API.
* @param params no parameters needed for this task.
*/
@Override
protected List<String> doInBackground(Void... params) {
try {
return getDataFromApi();
} catch (Exception e) {
mLastError = e;
cancel