├── app
├── .gitignore
├── src
│ ├── main
│ │ ├── res
│ │ │ ├── values
│ │ │ │ ├── dimens.xml
│ │ │ │ ├── colors.xml
│ │ │ │ ├── styles.xml
│ │ │ │ ├── me_messages_snippets.xml
│ │ │ │ ├── myorganization_user_snippets.xml
│ │ │ │ ├── strings.xml
│ │ │ │ ├── me_snippets.xml
│ │ │ │ ├── myorganization_groups_snippets.xml
│ │ │ │ ├── me_events_snippets.xml
│ │ │ │ └── drives_snippets.xml
│ │ │ ├── drawable
│ │ │ │ ├── border_red.xml
│ │ │ │ ├── bkgrnd_rect.xml
│ │ │ │ └── ic_launcher.xml
│ │ │ ├── menu
│ │ │ │ └── snippet_list_menu.xml
│ │ │ ├── layout
│ │ │ │ ├── activity_snippet_detail.xml
│ │ │ │ ├── activity_snippet_list.xml
│ │ │ │ ├── list_segment.xml
│ │ │ │ ├── list_element.xml
│ │ │ │ ├── activity_signin.xml
│ │ │ │ └── fragment_snippet_detail.xml
│ │ │ └── values-w820dp
│ │ │ │ └── dimens.xml
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── microsoft
│ │ │ │ └── graph
│ │ │ │ └── snippets
│ │ │ │ ├── BaseActivity.java
│ │ │ │ ├── MSALAuthenticationCallback.java
│ │ │ │ ├── BaseFragment.java
│ │ │ │ ├── application
│ │ │ │ ├── AppModule.java
│ │ │ │ └── SnippetApp.java
│ │ │ │ ├── util
│ │ │ │ ├── IManifestReader.java
│ │ │ │ ├── SharedPrefsUtil.java
│ │ │ │ └── ManifestReader.java
│ │ │ │ ├── ServiceConstants.java
│ │ │ │ ├── snippet
│ │ │ │ ├── SnippetContent.java
│ │ │ │ ├── SnippetCategory.java
│ │ │ │ ├── AbstractSnippet.java
│ │ │ │ ├── MessageSnippets.java
│ │ │ │ ├── UsersSnippets.java
│ │ │ │ ├── MeSnippets.java
│ │ │ │ └── EventsSnippets.java
│ │ │ │ ├── SnippetDetailActivity.java
│ │ │ │ ├── SnippetListAdapter.java
│ │ │ │ ├── SnippetListActivity.java
│ │ │ │ ├── SnippetListFragment.java
│ │ │ │ ├── AuthenticationManager.java
│ │ │ │ ├── SignInActivity.java
│ │ │ │ └── SnippetDetailFragment.java
│ │ └── AndroidManifest.xml
│ └── androidTest
│ │ ├── getTestConfig.sh
│ │ ├── getTestConfig.bat
│ │ └── java
│ │ └── com
│ │ └── microsoft
│ │ └── graph
│ │ └── snippets
│ │ ├── TestCredentials.java
│ │ ├── SnippetDetailActivityTests.java
│ │ ├── SnippetListActivityTests.java
│ │ └── SignInActivityTests.java
├── proguard-rules.pro
└── build.gradle
├── settings.gradle
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── .travis.yml
├── .gitignore
├── gradle.properties
├── NOTICES.md
├── LICENSE
├── gradlew.bat
├── gradlew
├── README-Localized
├── README-zh-cn.md
├── README-zh-tw.md
└── README-ja-jp.md
└── CONTRIBUTING.md
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoftgraph/android-java-snippets-sample/master/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | sudo: false
2 | language: android
3 | android:
4 | components:
5 | - tools
6 | - platform-tools
7 | - extra
8 | - android-23
9 | - build-tools-27.0.3
10 |
11 | script:
12 | - ./gradlew clean build -x test
13 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Tue Apr 16 14:31:57 EAT 2019
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 | 48dp
6 |
7 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.ap_
2 | *.apk
3 | *.class
4 | *.dex
5 | *.iml
6 | *.ipr
7 | *.iws
8 | .DS_Store
9 | .classpath
10 | .gradle
11 | .idea
12 | .project
13 | /.idea/libraries
14 | /.idea/workspace.xml
15 | /build
16 | /captures
17 | /local.properties
18 | Thumbs.db
19 | bin/
20 | build/
21 | gen/
22 | out/
23 | testConfig.json
--------------------------------------------------------------------------------
/app/src/main/res/drawable/border_red.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bkgrnd_rect.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/snippet_list_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/java/com/microsoft/graph/snippets/BaseActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license.
3 | * See LICENSE in the project root for license information.
4 | */
5 | package com.microsoft.graph.snippets;
6 |
7 | import android.app.Activity;
8 |
9 | public abstract class BaseActivity extends Activity {
10 | }
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_snippet_detail.xml:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #AE4A00
4 | #804325
5 | #1CA41C
6 | #88FFFF00
7 | #88FF0000
8 | #00FFFFFF
9 |
--------------------------------------------------------------------------------
/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/java/com/microsoft/graph/snippets/MSALAuthenticationCallback.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.graph.snippets;
2 |
3 | import com.microsoft.identity.client.AuthenticationResult;
4 | import com.microsoft.identity.client.exception.MsalException;
5 |
6 | interface MSALAuthenticationCallback {
7 | void onSuccess(AuthenticationResult authenticationResult);
8 | void onError(MsalException exception);
9 | void onError(Exception exception);
10 | void onCancel();
11 | }
12 |
--------------------------------------------------------------------------------
/app/src/androidTest/getTestConfig.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | testConfig="{
4 | \"test_client_id\": \"$TEST_CLIENT_ID\",
5 | \"test_username\": \"$TEST_USERNAME\",
6 | \"test_password\": \"$1\"
7 | }"
8 | echo $testConfig
9 | echo $testConfig > testConfig.json
10 |
11 | adb devices | while read line
12 | do
13 | if [ ! "$line" = "" ] && [ `echo $line | awk '{print $2}'` = "device" ]
14 | then
15 | device=`echo $line | awk '{print $1}'`
16 | echo "$device $@ ..."
17 | adb -s $device push testConfig.json ./data/local
18 | fi
19 | done
20 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_snippet_list.xml:
--------------------------------------------------------------------------------
1 |
11 |
--------------------------------------------------------------------------------
/app/src/androidTest/getTestConfig.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 |
3 | SET testConfig={
4 | SET testConfig=%testConfig% "test_client_id": "%TEST_CLIENT_ID%",
5 | SET testConfig=%testConfig% "test_username": "%TEST_USERNAME%",
6 | SET testConfig=%testConfig% "test_password": "%1"
7 | SET testConfig=%testConfig% }
8 | echo %testConfig%
9 | echo %testConfig% > testConfig.json
10 |
11 | SET _adb_devices=%ANDROID_HOME%\platform-tools\adb.exe devices
12 | FOR /f "skip=1" %%G IN ('%_adb_devices%') DO %ANDROID_HOME%\platform-tools\adb.exe -s %%G push testConfig.json ./data/local
13 |
--------------------------------------------------------------------------------
/app/src/main/java/com/microsoft/graph/snippets/BaseFragment.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license.
3 | * See LICENSE in the project root for license information.
4 | */
5 | package com.microsoft.graph.snippets;
6 |
7 | import android.app.Fragment;
8 | import android.os.Bundle;
9 | import android.support.annotation.Nullable;
10 |
11 | public class BaseFragment extends Fragment {
12 |
13 | @Override
14 | public void onActivityCreated(@Nullable Bundle savedInstanceState) {
15 | super.onActivityCreated(savedInstanceState);
16 |
17 | }
18 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/microsoft/graph/snippets/application/AppModule.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license.
3 | * See LICENSE in the project root for license information.
4 | */
5 | package com.microsoft.graph.snippets.application;
6 | import com.microsoft.graph.snippets.ServiceConstants;
7 |
8 | public class AppModule {
9 |
10 | public static final String PREFS = "com.microsoft.o365_android_unified_API_REST_snippets";
11 |
12 | public String providesRestEndpoint() {
13 | return ServiceConstants.AUTHENTICATION_RESOURCE_ID;
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/app/src/main/java/com/microsoft/graph/snippets/util/IManifestReader.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.graph.snippets.util;
2 |
3 | import java.util.HashMap;
4 |
5 | public interface IManifestReader {
6 | String getApplicationMetadataValueString(String key);
7 | int getApplicationMetadataValueInt(String key);
8 | boolean getApplicationMetadataValueBoolean(String key);
9 | int getApplicationMetadataValueColor(String key);
10 | float getApplicationMetadataValueFloat(String key);
11 | String getIntentFilterAction(String activityName);
12 | String[] getIntentFilterCategories(String activityName);
13 | HashMap getIntentFilterData(String activityName);
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Users/johnaustin/AndroidSDK/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/list_segment.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
13 |
14 |
19 |
20 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
16 |
17 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/app/src/main/java/com/microsoft/graph/snippets/ServiceConstants.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license.
3 | * See LICENSE in the project root for license information.
4 | */
5 | package com.microsoft.graph.snippets;
6 |
7 | public class ServiceConstants {
8 | public static final String AUTHENTICATION_RESOURCE_ID = "https://graph.microsoft.com";
9 | public static final String REDIRECT_URI = "http://localhost/androidsnippets";
10 | // The Microsoft Graph delegated permissions that you set in the application
11 | // registration portal must match these scope values.
12 | // Update this constant with the scope (permission) values for your application:
13 | public static final String[] SCOPES = {"openid", "Mail.ReadWrite","Mail.Send","Files.ReadWrite",
14 | "User.Read.All", "Calendars.ReadWrite","Group.Read.All","Group.ReadWrite.All",};
15 | }
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
--------------------------------------------------------------------------------
/NOTICES.md:
--------------------------------------------------------------------------------
1 | #Third Party Notices for Microsoft Graph SDK Snippets sample for Android
2 |
3 | This project incorporates material from the project(s) listed below (collectively, "Third Party Code"). Microsoft is not the original author of the Third Party Code. The original copyright notices and licenses, under which Microsoft received such Third Party Code, are set out below together with the full text of such licenses. These notices and licenses are provided for informational purposes only. This Third Party Code is licensed to you under the terms set forth in the licenses set forth below. Microsoft reserves all other rights not expressly granted under this agreement, whether by implication, estoppel or otherwise.
4 |
5 | - Android SDK, which is provided by the Android Open Source Project and is used according to terms described in the [Creative Commons 2.5 Attribution License](http://creativecommons.org/licenses/by/2.5). The Android SDK is available [here](http://developer.android.com/sdk/index.html).
6 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/list_element.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
15 |
16 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Microsoft. All rights reserved.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/app/src/main/java/com/microsoft/graph/snippets/snippet/SnippetContent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license.
3 | * See LICENSE in the project root for license information.
4 | */
5 | package com.microsoft.graph.snippets.snippet;
6 |
7 | import java.util.ArrayList;
8 | import java.util.Collections;
9 | import java.util.List;
10 | import static com.microsoft.graph.snippets.snippet.DrivesSnippets.getDrivesSnippets;
11 | import static com.microsoft.graph.snippets.snippet.EventsSnippets.getEventsSnippets;
12 | import static com.microsoft.graph.snippets.snippet.GroupsSnippets.getGroupsSnippets;
13 | import static com.microsoft.graph.snippets.snippet.MeSnippets.getMeSnippets;
14 | import static com.microsoft.graph.snippets.snippet.MessageSnippets.getMessageSnippets;
15 | import static com.microsoft.graph.snippets.snippet.UsersSnippets.getUsersSnippets;
16 |
17 | public class SnippetContent {
18 |
19 |
20 | public static final List> ITEMS = new ArrayList<>();
21 |
22 | static {
23 | AbstractSnippet>[][] baseSnippets = new AbstractSnippet>[][]{
24 | getGroupsSnippets(),
25 | getEventsSnippets(),
26 | getMeSnippets(),
27 | getMessageSnippets(),
28 | getUsersSnippets(),
29 | getDrivesSnippets()
30 | };
31 |
32 | for (AbstractSnippet>[] snippetArray : baseSnippets) {
33 | Collections.addAll(ITEMS, snippetArray);
34 | }
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/app/src/main/java/com/microsoft/graph/snippets/util/SharedPrefsUtil.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license.
3 | * See LICENSE in the project root for license information.
4 | */
5 | package com.microsoft.graph.snippets.util;
6 |
7 | import android.content.Context;
8 | import android.content.SharedPreferences;
9 |
10 | import com.microsoft.graph.snippets.application.SnippetApp;
11 | import com.microsoft.graph.snippets.application.AppModule;
12 | import com.microsoft.identity.client.AuthenticationResult;
13 |
14 | public class SharedPrefsUtil {
15 |
16 | public static final String PREF_AUTH_TOKEN = "PREF_AUTH_TOKEN";
17 | public static final String PREF_USER_TENANT = "PREF_USER_TENANT";
18 | public static final String PREF_USER_ID = "PREF_USER_ID";
19 |
20 | public static SharedPreferences getSharedPreferences() {
21 | return SnippetApp.getApp().getSharedPreferences(AppModule.PREFS, Context.MODE_PRIVATE);
22 | }
23 |
24 | public static void persistUserID(AuthenticationResult result) {
25 | setPreference(PREF_USER_ID, result.getAccount().getUsername());
26 | }
27 |
28 | public static void persistAuthToken(AuthenticationResult result) {
29 | setPreference(PREF_AUTH_TOKEN, result.getAccessToken());
30 | }
31 |
32 | public static void persistUserTenant(String tenant) {
33 | getSharedPreferences().edit().putString(PREF_USER_TENANT, tenant).commit();
34 | }
35 |
36 | private static void setPreference(String key, String accessToken) {
37 | getSharedPreferences().edit().putString(key, accessToken).commit();
38 | }
39 |
40 | }
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/microsoft/graph/snippets/TestCredentials.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license.
3 | * See LICENSE in the project root for license information.
4 | */
5 | package com.microsoft.graph.snippets;
6 |
7 | import android.os.Environment;
8 | import com.google.gson.JsonObject;
9 | import com.google.gson.JsonParser;
10 | import java.io.File;
11 | import java.io.FileNotFoundException;
12 | import java.io.FileReader;
13 |
14 | public class TestCredentials {
15 | private static final String TEST_ARTIFACT_LOCATION = "local/testConfig.json";
16 | private static final String CLIENT_ID_TEST_ARTIFACT = "test_client_id";
17 | private static final String USERNAME_TEST_ARTIFACT = "test_username";
18 | private static final String PASSWORD_TEST_ARTIFACT = "test_password";
19 |
20 | public String clientId;
21 | public String username;
22 | public String password;
23 |
24 | public static TestCredentials getTestCredentials() throws FileNotFoundException {
25 | TestCredentials testCredentials = new TestCredentials();
26 | File testConfigFile = new File(Environment.getDataDirectory(), TEST_ARTIFACT_LOCATION);
27 | JsonObject testConfig = new JsonParser().parse(new FileReader(testConfigFile)).getAsJsonObject();
28 |
29 | testCredentials.clientId = testConfig.get(CLIENT_ID_TEST_ARTIFACT).getAsString();
30 | testCredentials.username = testConfig.get(USERNAME_TEST_ARTIFACT).getAsString();
31 | testCredentials.password = testConfig.get(PASSWORD_TEST_ARTIFACT).getAsString();
32 |
33 | return testCredentials;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/app/src/main/java/com/microsoft/graph/snippets/snippet/SnippetCategory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license.
3 | * See LICENSE in the project root for license information.
4 | */
5 | package com.microsoft.graph.snippets.snippet;
6 |
7 | import com.microsoft.graph.snippets.application.SnippetApp;
8 | import static com.microsoft.graph.snippets.R.string.section_drives;
9 | import static com.microsoft.graph.snippets.R.string.section_events;
10 | import static com.microsoft.graph.snippets.R.string.section_groups;
11 | import static com.microsoft.graph.snippets.R.string.section_me;
12 | import static com.microsoft.graph.snippets.R.string.section_messages;
13 | import static com.microsoft.graph.snippets.R.string.section_user;
14 |
15 | public class SnippetCategory {
16 | static final SnippetCategory eventsSnippetCategory
17 | = new SnippetCategory(section_events);
18 |
19 | static final SnippetCategory groupSnippetCategory
20 | = new SnippetCategory(section_groups);
21 |
22 | static final SnippetCategory userSnippetCategory
23 | = new SnippetCategory(section_user);
24 |
25 | static final SnippetCategory mailSnippetCategory
26 | = new SnippetCategory(section_messages);
27 |
28 | static final SnippetCategory meSnippetCategory
29 | = new SnippetCategory(section_me);
30 |
31 | static final SnippetCategory drivesSnippetCategory
32 | = new SnippetCategory(section_drives);
33 |
34 | final String mSection;
35 |
36 | SnippetCategory(int sectionId) {
37 | mSection = SnippetApp.getApp().getString(sectionId);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/app/src/main/res/values/me_messages_snippets.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 | Messages
11 |
12 |
13 | - Get user\'s messages
14 | - Gets the signed-in user\'s emails.
15 | - https://graph.microsoft.io/docs/api-reference/v1.0/api/message_get
16 | - false
17 | - graphServiceClient()\n .me()\n .messages()\n .buildRequest()\n .get();
18 |
19 |
20 | - Send an email
21 | - Sends an email as the signed-in user and saves a copy to their Sent Items folder.
22 | - https://graph.microsoft.io/docs/api-reference/v1.0/api/message_send
23 | - false
24 | -
25 | Message message = new Message();\n\n
26 | Recipient recipient = new Recipient();\n
27 | recipient.emailAddress = new EmailAddress();\n
28 | recipient.emailAddress.address =\n
29 | \"user@contoso.com\";\n
30 | message.toRecipients =\n
31 | Collections.singletonList(recipient);\n\n
32 |
33 | message.subject = \"Email subject\";\n\n
34 |
35 | ItemBody itemBody = new ItemBody();\n
36 | itemBody.contentType = BodyType.text;\n
37 | itemBody.content = \"Email body\";\n
38 | message.body = itemBody;\n\n
39 |
40 | graphServiceClient()\n .me()\n .messages()\n .sendMail(message, true)\n .buildRequest()\n .post();
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/app/src/main/java/com/microsoft/graph/snippets/SnippetDetailActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license.
3 | * See LICENSE in the project root for license information.
4 | */
5 | package com.microsoft.graph.snippets;
6 |
7 | import android.content.Intent;
8 | import android.os.Bundle;
9 | import android.support.v4.app.NavUtils;
10 | import android.view.MenuItem;
11 |
12 | public class SnippetDetailActivity extends BaseActivity {
13 | private SnippetDetailFragment mSnippetDetailFragment;
14 |
15 | @Override
16 | protected void onCreate(Bundle savedInstanceState) {
17 | super.onCreate(savedInstanceState);
18 | setContentView(R.layout.activity_snippet_detail);
19 | if (null != getActionBar()) {
20 | getActionBar().setDisplayHomeAsUpEnabled(true);
21 | }
22 | if (savedInstanceState == null) {
23 | Bundle arguments = new Bundle();
24 | arguments.putInt(SnippetDetailFragment.ARG_ITEM_ID,
25 | getIntent().getIntExtra(SnippetDetailFragment.ARG_ITEM_ID, 0));
26 | mSnippetDetailFragment = new SnippetDetailFragment();
27 | mSnippetDetailFragment.setArguments(arguments);
28 | getFragmentManager().beginTransaction()
29 | .add(R.id.snippet_detail_container, mSnippetDetailFragment)
30 | .commit();
31 | }
32 | }
33 |
34 | @Override
35 | public boolean onOptionsItemSelected(MenuItem item) {
36 | int id = item.getItemId();
37 | if (id == android.R.id.home) {
38 | NavUtils.navigateUpTo(this, new Intent(this, SnippetListActivity.class));
39 | return true;
40 | }
41 | return super.onOptionsItemSelected(item);
42 | }
43 |
44 | public boolean isExecutingRequest(){
45 | return mSnippetDetailFragment.isExecutingRequest();
46 | }
47 | }
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_signin.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
17 |
18 |
22 |
23 |
28 |
29 |
30 |
31 |
38 |
39 |
43 |
44 |
51 |
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/app/src/main/java/com/microsoft/graph/snippets/util/ManifestReader.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.graph.snippets.util;
2 |
3 | import android.content.pm.PackageInfo;
4 | import android.content.pm.PackageManager;
5 | import android.os.Bundle;
6 |
7 | import com.microsoft.graph.snippets.application.SnippetApp;
8 |
9 | import java.util.HashMap;
10 |
11 | /*
12 | Contains methods that access the application manifest
13 | */
14 | public class ManifestReader implements IManifestReader{
15 |
16 | /**
17 | * Gets the value of an AndroidManifest meta-data node. If the node value cannot be cast to String,
18 | * null is returned.
19 | * @param key String. The meta-data key value
20 | * @return String. The value associated with the key
21 | */
22 | @Override
23 | public String getApplicationMetadataValueString(String key) {
24 | String returnValue = "";
25 | try {
26 | PackageInfo info = SnippetApp.getContext().getPackageManager().getPackageInfo(
27 | SnippetApp.getContext().getPackageName(),
28 | PackageManager.GET_META_DATA);
29 | if (info.applicationInfo.metaData != null) {
30 | Bundle bundle = info.applicationInfo.metaData;
31 | returnValue = bundle.getString(key);
32 | }
33 | } catch (Exception e) {
34 | e.printStackTrace();
35 | }
36 | return returnValue;
37 | }
38 |
39 | @Override
40 | public int getApplicationMetadataValueInt(String key) {
41 | return 0;
42 | }
43 |
44 | @Override
45 | public boolean getApplicationMetadataValueBoolean(String key) {
46 | return false;
47 | }
48 |
49 | @Override
50 | public int getApplicationMetadataValueColor(String key) {
51 | return 0;
52 | }
53 |
54 | @Override
55 | public float getApplicationMetadataValueFloat(String key) {
56 | return 0;
57 | }
58 |
59 | @Override
60 | public String getIntentFilterAction(String activityName) {
61 | return null;
62 | }
63 |
64 | @Override
65 | public String[] getIntentFilterCategories(String activityName) {
66 | return new String[0];
67 | }
68 |
69 | @Override
70 | public HashMap getIntentFilterData(String activityName) {
71 | return null;
72 | }
73 |
74 |
75 | }
76 |
--------------------------------------------------------------------------------
/app/src/main/res/values/myorganization_user_snippets.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 | My Organization
11 |
12 | - Get all users
13 | - Gets all of the users in your tenant\'s directory.
14 | - https://graph.microsoft.io/docs/api-reference/v1.0/resources/organization
15 | - true
16 | - graphServiceClient()\n .me()\n .users()\n .buildRequest()\n .get();
17 |
18 |
19 | - Get all users (with $filter)
20 | - Gets all of the users in your tenant\'s directory who are from the United States, using $filter.
21 | - https://graph.microsoft.io/docs/api-reference/v1.0/resources/organization
22 | - true
23 | - List<Option> options = new LinkedList<>();\n
24 | options.add(\n
25 | new QueryOption(\n
26 | \"$filter\", \"country eq \'United States\'\"\n
27 | )\n
28 | );\n\n
29 | graphServiceClient()\n .me()\n .users()\n .buildRequest(options)\n .get();
30 |
31 |
32 | - Add user
33 | - Adds a new user to the tenant\'s directory.
34 | - https://graph.microsoft.io/docs/api-reference/v1.0/resources/organization
35 | - true
36 | - User user = new User();\n
37 | user.accountEnabled = true;\n
38 | user.displayName = \"The display name\";\n
39 | user.mailNickname = \"The mail nick name\";\n
40 | user.userPrincipalName =\n
41 | \"The mail nick name\" + "@" + \'the tenant\";\n
42 | PasswordProfile password =\n
43 | new PasswordProfile();\n
44 | password.password = \"the password\";\n
45 | password.forceChangePasswordNextSignIn =\n
46 | false;\n
47 | user.passwordProfile = password;\n\n
48 | graphServiceClient()\n .me()\n .users()\n .buildRequest()\n .post(user);
49 |
50 |
51 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 26
5 | buildToolsVersion '28.0.3'
6 | defaultConfig {
7 | applicationId "com.microsoft.graph.snippets"
8 | minSdkVersion 21
9 | targetSdkVersion 26
10 | versionCode 2
11 | versionName '1.5'
12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
13 | javaCompileOptions {
14 | annotationProcessorOptions {
15 | includeCompileClasspath false
16 | }
17 | }
18 | }
19 | buildTypes {
20 | release {
21 | minifyEnabled false
22 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
23 | }
24 | }
25 | packagingOptions {
26 | exclude 'META-INF/LICENSE.txt'
27 | exclude 'META-INF/NOTICE.txt'
28 | exclude 'META-INF/maven/com.google.guava/guava/pom.properties'
29 | exclude 'META-INF/maven/com.google.guava/guava/pom.xml'
30 | exclude 'META-INF/jersey-module-version'
31 | }
32 | configurations {
33 | all {
34 | resolutionStrategy.force 'com.android.support:support-annotations:25.3.1'
35 | }
36 | }
37 | productFlavors {
38 | }
39 | }
40 |
41 | dependencies {
42 | implementation 'com.android.volley:volley:1.0.0'
43 | implementation 'com.android.support:support-fragment:25.1.0'
44 | implementation 'com.android.support:appcompat-v7:25.1.0'
45 | // Butterknife
46 | implementation 'com.jakewharton:butterknife:8.4.0'
47 | annotationProcessor 'com.jakewharton:butterknife-compiler:8.4.0'
48 | implementation 'joda-time:joda-time:2.9.4'
49 | implementation 'com.google.guava:guava:19.0'
50 | // Test libraries
51 | androidTestImplementation 'com.android.support:support-annotations:25.1.0'
52 | //noinspection GradleCompatible
53 | androidTestImplementation 'com.android.support.test:runner:1.0.1'
54 | androidTestImplementation 'com.android.support.test:rules:0.5'
55 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:2.2.2'
56 | androidTestImplementation 'com.android.support.test.espresso:espresso-intents:2.2.2'
57 | androidTestImplementation 'com.android.support.test.espresso:espresso-web:2.2.2'
58 |
59 | implementation 'com.microsoft.graph:microsoft-graph-android-auth:0.1.0-SNAPSHOT'
60 | }
61 |
--------------------------------------------------------------------------------
/app/src/main/java/com/microsoft/graph/snippets/application/SnippetApp.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license.
3 | * See LICENSE in the project root for license information.
4 | */
5 | package com.microsoft.graph.snippets.application;
6 |
7 | import android.app.Application;
8 | import android.content.Context;
9 | import com.microsoft.graph.authentication.MSALAuthenticationProvider;
10 | import com.microsoft.graph.requests.extensions.GraphServiceClient;
11 | import com.microsoft.graph.models.extensions.IGraphServiceClient;
12 | import com.microsoft.graph.snippets.AuthenticationManager;
13 | import com.microsoft.graph.snippets.ServiceConstants;
14 | import com.microsoft.graph.snippets.SignInActivity;
15 |
16 | public class SnippetApp extends Application {
17 | private static SnippetApp sSnippetApp;
18 | private static SignInActivity signInActivity;
19 | private AuthenticationManager mAuthenticationManager;
20 | private MSALAuthenticationProvider msalAuthenticationProvider;
21 | private IGraphServiceClient graphClient;
22 |
23 | public static SnippetApp getApp() {
24 | return sSnippetApp;
25 | }
26 | public static SignInActivity getAppActivity() {return signInActivity;}
27 |
28 | @Override
29 | public void onCreate() {
30 | super.onCreate();
31 | sSnippetApp = this;
32 | signInActivity = new SignInActivity();
33 | mAuthenticationManager = AuthenticationManager.getInstance();
34 | }
35 |
36 | public IGraphServiceClient getGraphServiceClient() {
37 |
38 | if(msalAuthenticationProvider == null) {
39 | msalAuthenticationProvider = new MSALAuthenticationProvider(
40 | getAppActivity(),
41 | SnippetApp.getApp(),
42 | mAuthenticationManager.getPublicClient(),
43 | ServiceConstants.SCOPES);
44 | }
45 |
46 | if(graphClient == null) {
47 | graphClient =
48 | GraphServiceClient
49 | .builder()
50 | .authenticationProvider(msalAuthenticationProvider)
51 | .buildClient();
52 | }
53 |
54 | return graphClient;
55 | }
56 |
57 | public static Context getContext() {
58 | return sSnippetApp;
59 | }
60 |
61 | public void disconnect() {
62 | mAuthenticationManager.disconnect();
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 | Snippets sample
8 | Snippets
9 | Settings
10 | Organizational Account
11 | An error signing in has occurred. Check LogCat for details.
12 | Sign in with the account provided by your work or school to use with Office 365 or other Microsoft services
13 | The client ID or redirect URI is not valid. Enter a valid client ID and redirect URI in the ServiceConstants.java file and run again
14 | SnippetDetailActivity
15 | API documentation
16 | Run
17 | Code Snippet
18 | Result
19 | Status
20 | Raw Object
21 | copied to clipboard
22 | Requires Admin account
23 | directReports
24 | manager
25 | AboutMe,Responsibilities,Tags
26 | memberOf
27 | photo
28 | You can send an email by making a POST request to /me/sendMail.
29 | Microsoft Graph snippets
30 | Description of the Snippet here
31 | Get all pages
32 | PAGES
33 | Connect to Microsoft Graph
34 | Welcome to the Microsoft Graph SDK Snippets sample for Android. Let\'s sign in and get started…
35 | Diagnostics
36 | In progress
37 | Success
38 | Failure
39 | Disconnect
40 |
41 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
19 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
31 |
32 |
35 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
47 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/app/src/main/java/com/microsoft/graph/snippets/SnippetListAdapter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license.
3 | * See LICENSE in the project root for license information.
4 | */
5 | package com.microsoft.graph.snippets;
6 |
7 | import android.content.Context;
8 | import android.view.LayoutInflater;
9 | import android.view.View;
10 | import android.view.ViewGroup;
11 | import android.widget.BaseAdapter;
12 | import android.widget.TextView;
13 | import com.microsoft.graph.snippets.snippet.AbstractSnippet;
14 | import com.microsoft.graph.snippets.snippet.SnippetContent;
15 |
16 | public class SnippetListAdapter extends BaseAdapter {
17 |
18 | private Context mContext;
19 | private LayoutInflater mLayoutInflater;
20 |
21 | @Override
22 | public int getCount() {
23 | return SnippetContent.ITEMS.size();
24 | }
25 |
26 | @Override
27 | public AbstractSnippet> getItem(int position) {
28 | return (AbstractSnippet) SnippetContent.ITEMS.get(position);
29 | }
30 |
31 | @Override
32 | public long getItemId(int position) {
33 | return 0;
34 | }
35 |
36 | @Override
37 | public boolean isEnabled(int position) {
38 | return null != getItem(position).getDescription();
39 | }
40 |
41 | @Override
42 | public View getView(int position, View convertView, ViewGroup parent) {
43 | if (null == mContext) {
44 | mContext = parent.getContext();
45 | mLayoutInflater = LayoutInflater.from(mContext);
46 | }
47 |
48 | AbstractSnippet> clickedSnippet = getItem(position);
49 | boolean isSegment = (null == clickedSnippet.getDescription());
50 |
51 | final int id = isSegment ? R.layout.list_segment : R.layout.list_element;
52 | if (null == convertView || isWrongViewType(isSegment, convertView)) {
53 | convertView = mLayoutInflater.inflate(id, parent, false);
54 | }
55 |
56 | TextView name = (TextView) convertView.findViewById(R.id.txt_snippet_name);
57 | name.setText(clickedSnippet.getName());
58 |
59 | //Set text to indicate if Admin account is required to run the snippet
60 | if (!isSegment) {
61 | TextView adminIndicator = (TextView) convertView.findViewById(R.id.admin_indicator);
62 | if (adminIndicator != null) {
63 | if (clickedSnippet.getIsAdminRequired()) {
64 | //Admin account required
65 | adminIndicator.setText(R.string.admin);
66 | adminIndicator.setVisibility(View.VISIBLE);
67 | } else {
68 | //Admin account not required
69 | adminIndicator.setVisibility(View.GONE);
70 | }
71 | }
72 | }
73 | return convertView;
74 | }
75 |
76 | private boolean isWrongViewType(boolean isSegment, View convertView) {
77 | View v = convertView.findViewById(R.id.admin_indicator);
78 | return !isSegment && null == v || (isSegment && null != v);
79 | }
80 | }
--------------------------------------------------------------------------------
/app/src/main/res/values/me_snippets.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
11 | Me
12 |
13 | - Get user\'s information
14 | - Gets information about the signed-in user.
15 | - https://graph.microsoft.io/docs/api-reference/v1.0/api/user_get
16 | - false
17 | - graphServiceClient()\n .getMe()\n .buildRequest()\n .get();
18 |
19 |
20 | - Get user\'s responsibilities.
21 | - Gets responsibilities of the signed-in user by using $select.
22 | - https://graph.microsoft.io/docs/api-reference/v1.0/resources/user
23 | - false
24 | - final List<Option> options = new LinkedList<>();\n
25 | options.add(new QueryOption(\"$select\", \"AboutMe,Responsibilities,Tags\"));\n\n
26 | graphServiceClient()\n .getMe()\n .buildRequest(options)\n .get();
27 |
28 |
29 | - Get user\'s manager
30 | - Gets the signed-in user\'s manager.
31 | - https://graph.microsoft.io/docs/api-reference/v1.0/api/user_list_manager
32 | - false
33 | - graphServiceClient()\n .me()\n .manager()\n .buildRequest()\n .get();
34 |
35 |
36 | - Get user\'s direct reports
37 | - Gets the signed-in user\'s direct reports.
38 | - https://graph.microsoft.io/docs/api-reference/v1.0/api/user_list_directreports
39 | - false
40 | - graphServiceClient()\n .me()\n .directReports()\n .buildRequest()\n .get();
41 |
42 |
43 | - Get user\'s photo
44 | - Gets the signed-in user\'s photo.
45 | - https://graph.microsoft.io/docs/api-reference/v1.0/resources/user
46 | - false
47 | - graphServiceClient()\n .me()\n .photo()\n .buildRequest()\n .get();
48 |
49 |
50 | - Get groups user is member of
51 | - Gets the groups that the signed-in user is a member of.
52 | - https://graph.microsoft.io/docs/api-reference/v1.0/api/user_getmembergroups
53 | - false
54 | - graphServiceClient()\n .me()\n .memberOf()\n .buildRequest()\n .get();
55 |
56 |
57 |
--------------------------------------------------------------------------------
/app/src/main/res/values/myorganization_groups_snippets.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 | Groups
11 |
12 |
13 | - Get groups
14 | - Gets all of the groups in your tenant\'s directory.
15 | - https://graph.microsoft.io/docs/api-reference/v1.0/api/group_list_memberof
16 | - false
17 | - graphServiceClient()\n .groups()\n .buildRequest()\n .get();
18 |
19 |
20 | - Add group
21 | - Adds a new security group to the tenant.
22 | - https://graph.microsoft.io/docs/api-reference/v1.0/resources/group
23 | - false
24 | -
25 | Group group = new Group();\n
26 | group.displayName = \"Name of group\";\n
27 | group.mailNickname = \"Group nickname\";\n
28 | group.mailEnabled = false;\n
29 | group.securityEnabled = false;\n
30 | group.groupTypes =\n
31 | Collections.singletonList(\"Unified\");\n\n
32 | graphServiceClient()\n .groups()\n .buildRequest()\n .post(group);
33 |
34 |
35 | - Get a specific group
36 | - Gets information about a group in the tenant by ID.
37 | - https://graph.microsoft.io/docs/api-reference/v1.0/api/group_get
38 | - false
39 | - graphServiceClient()\n .groups()\n .byId(guid)\n .buildRequest()\n .get();
40 |
41 |
42 | - Delete a group
43 | - Adds a new group to the tenant, then deletes the group.
44 | - https://graph.microsoft.io/docs/api-reference/v1.0/api/group_delete
45 | - false
46 | - graphServiceClient()\n .groups()\n .byId(guid)\n .buildRequest()\n .delete();
47 |
48 |
49 | - Get group members
50 | - Gets the members of a group.
51 | - https://graph.microsoft.io/docs/api-reference/v1.0/api/group_list_members
52 | - false
53 | - graphServiceClient()\n .groups()\n .byId(guid)\n .members()\n .buildRequest()\n .get();
54 |
55 |
56 | - Get group owners
57 | - Gets the owners of a group.
58 | - https://graph.microsoft.io/docs/api-reference/v1.0/api/group_list_owners
59 | - false
60 | - graphServiceClient()\n .groups()\n .byId(guid)\n .owners()\n .buildRequest()\n .get();
61 |
62 |
63 |
--------------------------------------------------------------------------------
/app/src/main/java/com/microsoft/graph/snippets/SnippetListActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license.
3 | * See LICENSE in the project root for license information.
4 | */
5 | package com.microsoft.graph.snippets;
6 |
7 | import android.content.Context;
8 | import android.content.Intent;
9 | import android.os.Bundle;
10 | import com.microsoft.graph.snippets.application.SnippetApp;
11 | import com.microsoft.graph.snippets.application.AppModule;
12 |
13 | public class SnippetListActivity extends BaseActivity
14 | implements SnippetListFragment.Callbacks {
15 |
16 | private boolean mTwoPane;
17 |
18 | @Override
19 | protected void onCreate(Bundle savedInstanceState) {
20 | super.onCreate(savedInstanceState);
21 | setContentView(R.layout.activity_snippet_list);
22 |
23 | if (findViewById(R.id.snippet_detail_container) != null) {
24 | // The detail container view will be present only in the
25 | // large-screen layouts (res/values-large and
26 | // res/values-sw600dp). If this view is present, then the
27 | // activity should be in two-pane mode.
28 | mTwoPane = true;
29 | // In two-pane mode, list items should be given the
30 | // 'activated' state when touched.
31 | ((SnippetListFragment) getFragmentManager()
32 | .findFragmentById(R.id.snippet_list))
33 | .setActivateOnItemClick(true);
34 | }
35 | }
36 |
37 | @Override
38 | public void onItemSelected(int position) {
39 | if (mTwoPane) {
40 | // In two-pane mode, show the detail view in this activity by
41 | // adding or replacing the detail fragment using a
42 | // fragment transaction.
43 | Bundle arguments = new Bundle();
44 | arguments.putInt(SnippetDetailFragment.ARG_ITEM_ID, position);
45 | SnippetDetailFragment fragment = new SnippetDetailFragment();
46 | fragment.setArguments(arguments);
47 | getFragmentManager().beginTransaction()
48 | .replace(R.id.snippet_detail_container, fragment)
49 | .commit();
50 | } else {
51 | // In single-pane mode, simply start the detail activity
52 | // for the selected item ID.
53 | Intent detailIntent = new Intent(this, SnippetDetailActivity.class);
54 | detailIntent.putExtra(SnippetDetailFragment.ARG_ITEM_ID, position);
55 | startActivity(detailIntent);
56 | }
57 | }
58 |
59 | @Override
60 | public void onDisconnectClicked() {
61 | finish();
62 | // drop the application shared preferences to clear any old auth tokens
63 | getSharedPreferences(AppModule.PREFS, Context.MODE_PRIVATE)
64 | .edit() // get the editor
65 | .clear() // clear it
66 | .apply(); // asynchronously apply
67 | SnippetApp.getApp().disconnect();
68 | Intent login = new Intent(this, SignInActivity.class);
69 | login.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
70 | startActivity(login);
71 | }
72 | }
--------------------------------------------------------------------------------
/app/src/main/res/values/me_events_snippets.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 | Events
10 |
11 |
12 | - User\'s events
13 | - Gets the signed-in user\'s calendar events.
14 | - https://graph.microsoft.io/docs/api-reference/v1.0/api/user_list_events
15 | - false
16 | - graphServiceClient()\n .me()\n .events()\n .buildRequest()\n .get();
17 |
18 |
19 | - Add an event
20 | - Adds an event to the signed-in user\'s calendar.
21 | - https://graph.microsoft.io/docs/api-reference/v1.0/api/user_post_events
22 | - false
23 | -
24 | Event event = new Event();\n
25 | event.subject = "Microsoft Graph SDK Discussion";\n
26 | DateTimeTimeZone start =\n
27 | new DateTimeTimeZone();\n
28 | start.dateTime = DateTime.now().toString();\n
29 | event.start = start;\n\n
30 |
31 | DateTimeTimeZone end =\n
32 | new DateTimeTimeZone();\n
33 | end.dateTime =\n
34 | DateTime.now().plusHours(1).toString();\n
35 | event.end = end;\n\n
36 |
37 | start.timeZone = end.timeZone = "UTC";\n\n
38 |
39 | Location location = new Location();\n
40 | location.displayName = "Bill's Office";\n
41 | event.location = location;\n\n
42 |
43 | Attendee attendee = new Attendee();\n
44 | attendee.type = AttendeeType.required;\n
45 | attendee.emailAddress = new EmailAddress();\n
46 | attendee.emailAddress.address =\n
47 | "mara@fabrikam.com";\n
48 | event.attendees =\n
49 | Collections.singletonList(attendee);\n\n
50 |
51 | ItemBody msg = new ItemBody();\n
52 | msg.content = "Let's discuss…";\n
53 | msg.contentType = BodyType.text;\n
54 | event.body = msg;\n\n
55 | graphServiceClient()\n .me()\n .events()\n .buildRequest()\n .post(event);
56 |
57 |
58 | - Update an event
59 | - Adds an event to the signed-in user\'s calendar, then updates the subject of the event.
60 | - https://graph.microsoft.io/docs/api-reference/v1.0/api/event_update
61 | - false
62 | -
63 | event.subject = "Updated event";\n\n
64 |
65 | graphServiceClient()\n .me()\n .events()\n .byId(eventId)\n .buildRequest()\n .patch(event);
66 |
67 |
68 | - Delete an event
69 | - Adds an event to the signed-in user\'s calendar, then deletes the event.
70 | - https://graph.microsoft.io/docs/api-reference/v1.0/api/event_delete
71 | - false
72 | - graphServiceClient()\n .me()\n .events()\n .byId(eventId)\n .buildRequest()\n .delete();
73 |
74 |
75 |
--------------------------------------------------------------------------------
/app/src/main/java/com/microsoft/graph/snippets/snippet/AbstractSnippet.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license.
3 | * See LICENSE in the project root for license information.
4 | */
5 | package com.microsoft.graph.snippets.snippet;
6 |
7 | import com.microsoft.graph.concurrency.ICallback;
8 | import com.microsoft.graph.models.extensions.IGraphServiceClient;
9 | import com.microsoft.graph.snippets.application.SnippetApp;
10 |
11 | public abstract class AbstractSnippet {
12 |
13 | private static final int mNameIndex = 0;
14 | private static final int mDescIndex = 1;
15 | private static final int mUrlIndex = 2;
16 | private static final int mIsAdminRequiredIndex = 3;
17 | private static final int mCodeSnippetIndex = 4;
18 | protected final IGraphServiceClient mGraphServiceClient;
19 |
20 | boolean mIsAdminRequired;
21 | private String mName, mDesc, mUrl, mCodeSnippet;
22 |
23 | /**
24 | * Snippet constructor
25 | *
26 | * @param category Snippet category as corresponds to UI displayed sections (organization, me, groups, etc...)
27 | * @param descriptionArray The String array for the specified snippet
28 | */
29 | public AbstractSnippet(
30 | SnippetCategory category,
31 | Integer descriptionArray) {
32 | //Get snippet configuration information from the
33 | //XML configuration for the snippet
34 | getSnippetArrayContent(category, descriptionArray);
35 | mGraphServiceClient = SnippetApp.getApp().getGraphServiceClient();
36 | }
37 |
38 |
39 | /**
40 | * Gets the items from the specified snippet XML string array and stores the values
41 | * in private class fields
42 | *
43 | * @param category Snippet category as corresponds to UI displayed sections (organization, me, groups, etc...)
44 | * @param descriptionArray The String array for the specified snippet
45 | */
46 | private void getSnippetArrayContent(SnippetCategory category, Integer descriptionArray) {
47 | if (null != descriptionArray) {
48 | String[] params = SnippetApp.getApp().getResources().getStringArray(descriptionArray);
49 |
50 | try {
51 | mName = params[mNameIndex];
52 | mDesc = params[mDescIndex];
53 | mUrl = params[mUrlIndex];
54 | mCodeSnippet = params[mCodeSnippetIndex];
55 | String isAdminRequired = params[mIsAdminRequiredIndex];
56 | mIsAdminRequired = isAdminRequired.equalsIgnoreCase("true");
57 | } catch (IndexOutOfBoundsException ex) {
58 | throw new RuntimeException(
59 | "Invalid array in "
60 | + category.mSection
61 | + " snippet XML file"
62 | , ex);
63 | }
64 | } else {
65 | mName = category.mSection;
66 | mDesc = mUrl = null;
67 | }
68 | }
69 |
70 | public String getName() {
71 | return mName;
72 | }
73 |
74 | public String getDescription() {
75 | return mDesc;
76 | }
77 |
78 | public String getCodeSnippet() { return mCodeSnippet; }
79 |
80 | public String getUrl() {
81 | return mUrl;
82 | }
83 |
84 | public boolean getIsAdminRequired() {
85 | return mIsAdminRequired;
86 | }
87 |
88 | public abstract void request(ICallback callback);
89 | }
90 |
--------------------------------------------------------------------------------
/app/src/main/res/values/drives_snippets.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 | Drives
11 |
12 | - Get user\'s drive
13 | - Gets the signed-in user\'s drive.
14 | - https://graph.microsoft.io/docs/api-reference/v1.0/resources/drive
15 | - false
16 | - graphServiceClient()\n .me()\n .drive()\n .buildRequest()\n .get();
17 |
18 |
19 | - Get children under root
20 | - Gets the metadata list of children files under the root folder.
21 | - https://graph.microsoft.io/docs/api-reference/v1.0/api/item_list_children
22 | - false
23 | - graphServiceClient()\n .me()\n .drive()\n .root()\n .children()\n .buildRequest()\n .get();
24 |
25 |
26 | - Create a file under root
27 | - Gets the metadata list of children files under the root folder.
28 | - https://graph.microsoft.io/docs/api-reference/v1.0/api/item_post_children
29 | - false
30 | - graphServiceClient()\n .me()\n .drive()\n .root()\n .children(guid)\n .content()\n .buildRequest()\n .put(byteArray);
31 |
32 |
33 | - Download a file under root
34 | - Gets the contents of a file under the root folder.
35 | - https://graph.microsoft.io/docs/api-reference/v1.0/api/item_get
36 | - false
37 | - graphServiceClient()\n .me()\n .drive()\n .items()\n .byId(guid)\n .getContent()\n .buildRequest()\n .get();
38 |
39 |
40 | - Update the contents of a file under root
41 | - Gets the metadata list of children files under the root folder.
42 | - https://graph.microsoft.io/docs/api-reference/v1.0/api/item_update
43 | - false
44 | - graphServiceClient()\n .getMe()\n .getDrive()\n .getItems()\n .byId(guid)\n .content()\n .buildRequest()\n .put(byteArray)\n .getRawObject();
45 |
46 |
47 | - Delete a file under root
48 | - Gets the metadata list of children files under the root folder.
49 | - https://graph.microsoft.io/docs/api-reference/v1.0/api/item_delete
50 | - false
51 | - graphServiceClient()\n .me()\n .drive()\n .items()\n .byId(guid)\n .buildRequest()\n .delete();
52 |
53 |
54 | - Rename a file in the root
55 | - Renames a file under the root folder.
56 | - https://graph.microsoft.io/docs/api-reference/v1.0/api/item_update
57 | - false
58 | - DriveItem driveItem = new DriveItem();\ndriveItem.name = \"Updated name\";\n\ngraphServiceClient()\n .me()\n .drive()\n .items()\n .byId(guid)\n .buildRequest()\n .patch(driveItem);
59 |
60 |
61 | - Create a folder under root
62 | - Creates a folder under the root folder.
63 | - https://graph.microsoft.io/docs/api-reference/v1.0/api/item_post_children
64 | - false
65 | - DriveItem driveItem = new DriveItem();\ndriveItem.name = guid;\ndriveItem.folder = new Folder();\n\ngetGraphServiceClient()\n .me()\n .drive()\n .root()\n .children()\n .buildRequest()\n .post(driveItem);
66 |
67 |
--------------------------------------------------------------------------------
/app/src/main/java/com/microsoft/graph/snippets/SnippetListFragment.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license.
3 | * See LICENSE in the project root for license information.
4 | */
5 | package com.microsoft.graph.snippets;
6 |
7 | import android.app.ListFragment;
8 | import android.content.Context;
9 | import android.os.Bundle;
10 | import android.view.Menu;
11 | import android.view.MenuInflater;
12 | import android.view.MenuItem;
13 | import android.view.View;
14 | import android.widget.ListView;
15 |
16 | public class SnippetListFragment extends ListFragment {
17 |
18 | private static final String STATE_ACTIVATED_POSITION = "activated_position";
19 | private static Callbacks sDummyCallbacks = new Callbacks() {
20 | @Override
21 | public void onItemSelected(int position) {
22 | }
23 |
24 | @Override
25 | public void onDisconnectClicked() {
26 | }
27 | };
28 | private Callbacks mCallbacks = sDummyCallbacks;
29 | private int mActivatedPosition = ListView.INVALID_POSITION;
30 |
31 | public SnippetListFragment() {
32 | }
33 |
34 | @Override
35 | public void onCreate(Bundle savedInstanceState) {
36 | super.onCreate(savedInstanceState);
37 | setHasOptionsMenu(true);
38 | setListAdapter(new SnippetListAdapter());
39 | }
40 |
41 | @Override
42 | public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
43 | inflater.inflate(R.menu.snippet_list_menu, menu);
44 | super.onCreateOptionsMenu(menu, inflater);
45 | }
46 |
47 | @Override
48 | public boolean onOptionsItemSelected(MenuItem item) {
49 | if (R.id.disconnect == item.getItemId()) {
50 | mCallbacks.onDisconnectClicked();
51 | return true;
52 | }
53 | return super.onOptionsItemSelected(item);
54 | }
55 |
56 | @Override
57 | public void onViewCreated(View view, Bundle savedInstanceState) {
58 | super.onViewCreated(view, savedInstanceState);
59 |
60 | // Restore the previously serialized activated item position.
61 | if (savedInstanceState != null
62 | && savedInstanceState.containsKey(STATE_ACTIVATED_POSITION)) {
63 | setActivatedPosition(savedInstanceState.getInt(STATE_ACTIVATED_POSITION));
64 | }
65 | }
66 |
67 | @Override
68 | public void onAttach(Context context) {
69 | super.onAttach(context);
70 |
71 | // Activities containing this fragment must implement its callbacks.
72 | if (!(context instanceof Callbacks)) {
73 | throw new IllegalStateException("Activity must implement fragment's callbacks.");
74 | }
75 |
76 | mCallbacks = (Callbacks) context;
77 | }
78 |
79 | @Override
80 | public void onDetach() {
81 | super.onDetach();
82 |
83 | // Reset the active callbacks interface to the dummy implementation.
84 | mCallbacks = sDummyCallbacks;
85 | }
86 |
87 | @Override
88 | public void onListItemClick(ListView listView, View view, int position, long id) {
89 | super.onListItemClick(listView, view, position, id);
90 | mCallbacks.onItemSelected(position);
91 | }
92 |
93 | @Override
94 | public void onSaveInstanceState(Bundle outState) {
95 | super.onSaveInstanceState(outState);
96 | if (mActivatedPosition != ListView.INVALID_POSITION) {
97 | // Serialize and persist the activated item position.
98 | outState.putInt(STATE_ACTIVATED_POSITION, mActivatedPosition);
99 | }
100 | }
101 |
102 | public void setActivateOnItemClick(boolean activateOnItemClick) {
103 | // When setting CHOICE_MODE_SINGLE, ListView will automatically
104 | // give items the 'activated' state when touched.
105 | getListView().setChoiceMode(activateOnItemClick
106 | ? ListView.CHOICE_MODE_SINGLE
107 | : ListView.CHOICE_MODE_NONE);
108 | }
109 |
110 | private void setActivatedPosition(int position) {
111 | if (position == ListView.INVALID_POSITION) {
112 | getListView().setItemChecked(mActivatedPosition, false);
113 | } else {
114 | getListView().setItemChecked(position, true);
115 | }
116 |
117 | mActivatedPosition = position;
118 | }
119 |
120 | public interface Callbacks {
121 | void onItemSelected(int position);
122 | void onDisconnectClicked();
123 | }
124 | }
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/microsoft/graph/snippets/SnippetDetailActivityTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license.
3 | * See LICENSE in the project root for license information.
4 | */
5 | package com.microsoft.graph.snippets;
6 |
7 | import android.content.Intent;
8 | import android.support.test.espresso.IdlingResource;
9 | import android.support.test.espresso.intent.Intents;
10 | import android.support.test.rule.ActivityTestRule;
11 | import android.support.test.runner.AndroidJUnit4;
12 | import org.junit.After;
13 | import org.junit.Before;
14 | import org.junit.BeforeClass;
15 | import org.junit.Rule;
16 | import org.junit.Test;
17 | import org.junit.runner.RunWith;
18 | import java.io.FileNotFoundException;
19 | import java.util.List;
20 | import static android.support.test.espresso.Espresso.onView;
21 | import static android.support.test.espresso.Espresso.registerIdlingResources;
22 | import static android.support.test.espresso.Espresso.unregisterIdlingResources;
23 | import static android.support.test.espresso.action.ViewActions.click;
24 | import static android.support.test.espresso.assertion.ViewAssertions.matches;
25 | import static android.support.test.espresso.matcher.ViewMatchers.withContentDescription;
26 | import static android.support.test.espresso.matcher.ViewMatchers.withId;
27 |
28 | @RunWith(AndroidJUnit4.class)
29 | public class SnippetDetailActivityTests {
30 | private static TestCredentials testCredentials;
31 |
32 | @Rule
33 | public ActivityTestRule mSignInActivityRule = new ActivityTestRule<>(SignInActivity.class, false, false);
34 | @Rule
35 | public ActivityTestRule mSnippetListActivityRule = new ActivityTestRule<>(SnippetListActivity.class, false, false);
36 | @Rule
37 | public ActivityTestRule mSnippetDetailActivityRule = new ActivityTestRule<>(SnippetDetailActivity.class, false, false);
38 |
39 | @BeforeClass
40 | public static void setupEnvironment() throws FileNotFoundException {
41 | testCredentials = TestCredentials.getTestCredentials();
42 | ServiceConstants.CLIENT_ID = testCredentials.clientId;
43 | }
44 |
45 | @Before
46 | public void initIntents(){
47 | Intents.init();
48 | }
49 |
50 | @After
51 | public void releaseIntents() {
52 | Intents.release();
53 | }
54 |
55 | @Test
56 | public void RunSnippets_Success() throws InterruptedException{
57 | SignInActivityTests.AzureADSignIn(testCredentials.username, testCredentials.password, mSignInActivityRule);
58 |
59 | List snippetIndexes = SnippetListActivityTests.getSnippetsIndexes(mSnippetListActivityRule);
60 |
61 | for(int index : snippetIndexes) {
62 | runSnippet(index, R.string.stoplight_success);
63 | }
64 | }
65 |
66 | @Test
67 | public void RunSnippets_NoToken() throws InterruptedException{
68 | SnippetListActivityTests.Disconnect(mSnippetListActivityRule);
69 |
70 | List snippetIndexes = SnippetListActivityTests.getSnippetsIndexes(mSnippetListActivityRule);
71 |
72 | for(int index : snippetIndexes) {
73 | runSnippet(index, R.string.stoplight_failure);
74 | }
75 | }
76 |
77 | private void runSnippet(int index, int expectedStatusColor) {
78 | Intent itemIdIntent = new Intent();
79 | itemIdIntent.putExtra("item_id", index);
80 | SnippetDetailActivity snippetDetailActivity = mSnippetDetailActivityRule.launchActivity(itemIdIntent);
81 |
82 | SnippetDetailActivityIdlingResource idlingResource = new SnippetDetailActivityIdlingResource(snippetDetailActivity);
83 | registerIdlingResources(idlingResource);
84 |
85 | onView(withId(R.id.btn_run)).perform(click());
86 |
87 | onView(withId(R.id.txt_status_color)).check(matches(withContentDescription(expectedStatusColor)));
88 | unregisterIdlingResources(idlingResource);
89 | snippetDetailActivity.finish();
90 | }
91 |
92 | private class SnippetDetailActivityIdlingResource implements IdlingResource {
93 | private SnippetDetailActivity activity;
94 | private ResourceCallback callback;
95 |
96 | public SnippetDetailActivityIdlingResource(SnippetDetailActivity activity) {
97 | this.activity = activity;
98 | }
99 |
100 | @Override
101 | public String getName() {
102 | return this.getClass().getName();
103 | }
104 |
105 | @Override
106 | public boolean isIdleNow() {
107 | Boolean idle = activity != null &&
108 | callback != null &&
109 | !activity.isExecutingRequest();
110 | if (idle) callback.onTransitionToIdle();
111 | return idle;
112 | }
113 |
114 | @Override
115 | public void registerIdleTransitionCallback(ResourceCallback resourceCallback) {
116 | this.callback = resourceCallback;
117 | }
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/microsoft/graph/snippets/SnippetListActivityTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license.
3 | * See LICENSE in the project root for license information.
4 | */
5 | package com.microsoft.graph.snippets;
6 |
7 | import android.support.test.InstrumentationRegistry;
8 | import android.support.test.espresso.intent.Intents;
9 | import android.support.test.rule.ActivityTestRule;
10 | import android.support.test.runner.AndroidJUnit4;
11 | import android.widget.ListAdapter;
12 | import android.widget.ListView;
13 | import com.microsoft.graph.snippets.snippet.AbstractSnippet;
14 | import org.junit.After;
15 | import org.junit.Assert;
16 | import org.junit.Before;
17 | import org.junit.Rule;
18 | import org.junit.Test;
19 | import org.junit.runner.RunWith;
20 | import java.util.ArrayList;
21 | import java.util.List;
22 | import static android.support.test.espresso.Espresso.onView;
23 | import static android.support.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu;
24 | import static android.support.test.espresso.action.ViewActions.click;
25 | import static android.support.test.espresso.intent.Intents.intended;
26 | import static android.support.test.espresso.intent.matcher.ComponentNameMatchers.hasShortClassName;
27 | import static android.support.test.espresso.intent.matcher.IntentMatchers.hasComponent;
28 | import static android.support.test.espresso.intent.matcher.IntentMatchers.toPackage;
29 | import static android.support.test.espresso.matcher.ViewMatchers.withText;
30 | import static org.hamcrest.core.AllOf.allOf;
31 |
32 | @RunWith(AndroidJUnit4.class)
33 | public class SnippetListActivityTests {
34 | public static int CURRENT_NUMBER_OF_CATEGORIES = 6;
35 | @Rule
36 | public ActivityTestRule mSnippetListActivityRule = new ActivityTestRule<>(SnippetListActivity.class, false, false);
37 |
38 | @Before
39 | public void initIntents(){
40 | Intents.init();
41 | }
42 |
43 | @After
44 | public void releaseIntents() {
45 | Intents.release();
46 | }
47 |
48 | @Test
49 | public void checkRightNumberOfCategories() {
50 | int adapterSize = getItemsCount(mSnippetListActivityRule);
51 | int actualSnippets = getActualSnippetsCount(mSnippetListActivityRule);
52 |
53 | Assert.assertEquals(
54 | "The number of categories is incorrect",
55 | CURRENT_NUMBER_OF_CATEGORIES,
56 | adapterSize - actualSnippets
57 | );
58 | }
59 |
60 | @Test
61 | public void Disconnect() {
62 | Disconnect(mSnippetListActivityRule);
63 | }
64 |
65 | public static void Disconnect(ActivityTestRule snippetListActivityTestRule) {
66 | SnippetListActivity snippetListActivity = snippetListActivityTestRule.launchActivity(null);
67 |
68 | openActionBarOverflowOrOptionsMenu(InstrumentationRegistry.getTargetContext());
69 |
70 | // Espresso can't find menu items by id. We'll use the text property.
71 | onView(withText(R.string.disconnect_menu_item))
72 | .perform(click());
73 |
74 | intended(allOf(
75 | hasComponent(hasShortClassName(".SignInActivity")),
76 | toPackage("com.microsoft.graph.snippets")
77 | ));
78 |
79 | snippetListActivity.finish();
80 | }
81 |
82 | private int getItemsCount(ActivityTestRule snippetListActivityRule){
83 | SnippetListActivity snippetListActivity = snippetListActivityRule.launchActivity(null);
84 |
85 | ListAdapter listAdapter = getListAdapter(snippetListActivity);
86 | int numItems = listAdapter.getCount();
87 |
88 | snippetListActivity.finish();
89 |
90 | return numItems;
91 | }
92 |
93 | private int getActualSnippetsCount(ActivityTestRule snippetListActivityRule) {
94 | List actualSnippetsIndexes = getSnippetsIndexes(snippetListActivityRule);
95 | return actualSnippetsIndexes.size();
96 | }
97 |
98 | public static List getSnippetsIndexes(ActivityTestRule snippetListActivityRule) {
99 | SnippetListActivity snippetListActivity = snippetListActivityRule.launchActivity(null);
100 |
101 | ListAdapter listAdapter = getListAdapter(snippetListActivity);
102 | int numItems = listAdapter.getCount();
103 |
104 | List snippetIndexes = new ArrayList<>();
105 |
106 | // Get the index of items in the adapter that
107 | // are actual snippets and not categories, which don't have a Url
108 | for (int i = 0; i < numItems; i++) {
109 | if(((AbstractSnippet)listAdapter.getItem(i)).getUrl() != null) {
110 | snippetIndexes.add(i);
111 | }
112 | }
113 |
114 | snippetListActivity.finish();
115 |
116 | return snippetIndexes;
117 | }
118 |
119 | private static ListAdapter getListAdapter (SnippetListActivity snippetListActivity) {
120 | return ((ListView) snippetListActivity
121 | .getSupportFragmentManager()
122 | .findFragmentById(R.id.snippet_list)
123 | .getView()
124 | .findViewById(android.R.id.list))
125 | .getAdapter();
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/microsoft/graph/snippets/SignInActivityTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license.
3 | * See LICENSE in the project root for license information.
4 | */
5 | package com.microsoft.graph.snippets;
6 |
7 | import android.support.test.espresso.NoMatchingViewException;
8 | import android.support.test.espresso.intent.Intents;
9 | import android.support.test.espresso.web.webdriver.DriverAtoms;
10 | import android.support.test.espresso.web.webdriver.Locator;
11 | import android.support.test.rule.ActivityTestRule;
12 | import android.support.test.runner.AndroidJUnit4;
13 | import junit.framework.AssertionFailedError;
14 | import org.junit.After;
15 | import org.junit.Before;
16 | import org.junit.BeforeClass;
17 | import org.junit.Rule;
18 | import org.junit.Test;
19 | import org.junit.runner.RunWith;
20 | import java.io.FileNotFoundException;
21 | import static android.support.test.espresso.Espresso.onView;
22 | import static android.support.test.espresso.action.ViewActions.click;
23 | import static android.support.test.espresso.intent.Intents.intended;
24 | import static android.support.test.espresso.intent.matcher.ComponentNameMatchers.hasShortClassName;
25 | import static android.support.test.espresso.intent.matcher.IntentMatchers.hasComponent;
26 | import static android.support.test.espresso.intent.matcher.IntentMatchers.toPackage;
27 | import static android.support.test.espresso.matcher.ViewMatchers.withId;
28 | import static android.support.test.espresso.web.sugar.Web.onWebView;
29 | import static android.support.test.espresso.web.webdriver.DriverAtoms.clearElement;
30 | import static android.support.test.espresso.web.webdriver.DriverAtoms.findElement;
31 | import static android.support.test.espresso.web.webdriver.DriverAtoms.webClick;
32 | import static org.hamcrest.core.AllOf.allOf;
33 |
34 | @RunWith(AndroidJUnit4.class)
35 | public class SignInActivityTests {
36 | private static final String USER_ID_TEXT_ELEMENT = "cred_userid_inputtext";
37 | private static final String PASSWORD_TEXT_ELEMENT = "cred_password_inputtext";
38 | private static final String SIGN_IN_BUTTON_ELEMENT = "cred_sign_in_button";
39 | private static TestCredentials testCredentials;
40 |
41 | @Rule
42 | public ActivityTestRule mSignInActivityRule = new ActivityTestRule<>(SignInActivity.class, false, false);
43 | @Rule
44 | public ActivityTestRule mSnippetListActivityRule = new ActivityTestRule<>(SnippetListActivity.class, false, false);
45 |
46 | @BeforeClass
47 | public static void setupEnvironment() throws FileNotFoundException {
48 | testCredentials = TestCredentials.getTestCredentials();
49 | ServiceConstants.CLIENT_ID = testCredentials.clientId;
50 | }
51 |
52 | @Before
53 | public void initIntents(){
54 | Intents.init();
55 | }
56 |
57 | @After
58 | public void releaseIntents() {
59 | Intents.release();
60 | }
61 |
62 | @Test
63 | public void AzureADSignIn_Success() throws InterruptedException{
64 | AzureADSignIn(testCredentials.username, testCredentials.password, mSignInActivityRule);
65 | }
66 |
67 | @Test(expected = AssertionFailedError.class)
68 | public void AzureADSignIn_Fail() throws InterruptedException{
69 | AzureADSignIn("fake@fake.onmicrosoft.com", "fake_password", mSignInActivityRule);
70 | }
71 |
72 | public static void AzureADSignIn(String username, String password, ActivityTestRule signInActivityTestRule) throws InterruptedException {
73 | SignInActivity signInActivity = signInActivityTestRule.launchActivity(null);
74 |
75 | onView(withId(R.id.o365_signin)).perform(click());
76 |
77 | try {
78 | onWebView()
79 | .withElement(findElement(Locator.ID, USER_ID_TEXT_ELEMENT))
80 | .perform(clearElement())
81 | // Enter text into the input element
82 | .perform(DriverAtoms.webKeys(username))
83 | // Set focus on the username input text
84 | // The form validates the username when this field loses focus
85 | .perform(webClick())
86 | .withElement(findElement(Locator.ID, PASSWORD_TEXT_ELEMENT))
87 | // Now we force focus on this element to make
88 | // the username element to lose focus and validate
89 | .perform(webClick())
90 | .perform(clearElement())
91 | // Enter text into the input element
92 | .perform(DriverAtoms.webKeys(password));
93 |
94 | Thread.sleep(2000, 0);
95 |
96 | onWebView()
97 | .withElement(findElement(Locator.ID, SIGN_IN_BUTTON_ELEMENT))
98 | .perform(webClick());
99 | } catch (NoMatchingViewException ex) {
100 | // If user is already logged in, the flow will go directly to SnippetListActivity
101 | } finally {
102 | Thread.sleep(2000, 0);
103 | }
104 |
105 | // Finally, verify that SnippetListActivity is on top
106 | intended(allOf(
107 | hasComponent(hasShortClassName(".SnippetListActivity")),
108 | toPackage("com.microsoft.graph.snippets")
109 | ));
110 |
111 | signInActivity.finish();
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
5 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/app/src/main/java/com/microsoft/graph/snippets/snippet/MessageSnippets.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license.
3 | * See LICENSE in the project root for license information.
4 | */
5 | package com.microsoft.graph.snippets.snippet;
6 |
7 | import android.content.SharedPreferences;
8 | import com.google.gson.JsonObject;
9 | import com.microsoft.graph.concurrency.ICallback;
10 | import com.microsoft.graph.core.ClientException;
11 | import com.microsoft.graph.models.extensions.EmailAddress;
12 | import com.microsoft.graph.models.extensions.ItemBody;
13 | import com.microsoft.graph.models.extensions.Message;
14 | import com.microsoft.graph.models.extensions.Recipient;
15 | import com.microsoft.graph.models.generated.BodyType;
16 | import com.microsoft.graph.requests.extensions.IMessageCollectionPage;
17 | import com.microsoft.graph.snippets.R;
18 | import com.microsoft.graph.snippets.application.SnippetApp;
19 | import com.microsoft.graph.snippets.util.SharedPrefsUtil;
20 | import java.util.Collections;
21 | import static com.microsoft.graph.snippets.R.array.get_user_messages;
22 | import static com.microsoft.graph.snippets.R.array.send_an_email_message;
23 |
24 | public abstract class MessageSnippets extends AbstractSnippet {
25 | /**
26 | * Snippet constructor
27 | *
28 | * @param descriptionArray The String array for the specified snippet
29 | */
30 | public MessageSnippets(Integer descriptionArray) {
31 | super(SnippetCategory.mailSnippetCategory, descriptionArray);
32 | }
33 |
34 | static MessageSnippets[] getMessageSnippets() {
35 | return new MessageSnippets[]{
36 | // Marker element
37 | new MessageSnippets(null) {
38 | @Override
39 | public void request(ICallback callback) {
40 | // Not implemented
41 | }
42 | },
43 | // Snippets
44 |
45 | /* Get messages from mailbox for signed in user
46 | * HTTP GET https://graph.microsoft.com/{version}/me/messages
47 | * @see https://graph.microsoft.io/docs/api-reference/v1.0/api/user_list_messages
48 | */
49 | new MessageSnippets(get_user_messages) {
50 | @Override
51 | public void request(final ICallback callback) {
52 | mGraphServiceClient
53 | .me()
54 | .messages()
55 | .buildRequest()
56 | .get(new ICallback() {
57 | @Override
58 | public void success(IMessageCollectionPage iMessageCollectionPage) {
59 | callback.success(iMessageCollectionPage.getRawObject());
60 | }
61 |
62 | @Override
63 | public void failure(ClientException ex) {
64 | callback.failure(ex);
65 | }
66 | });
67 | }
68 | },
69 |
70 | /* Sends an email message on behalf of the signed in user
71 | * HTTP POST https://graph.microsoft.com/{version}/me/messages/sendMail
72 | * @see https://graph.microsoft.io/docs/api-reference/v1.0/api/user_post_messages
73 | */
74 | new MessageSnippets(send_an_email_message) {
75 | @Override
76 | public void request(final ICallback callback) {
77 | Message message = createMessageObject();
78 |
79 | mGraphServiceClient
80 | .me()
81 | .sendMail(message, true)
82 | .buildRequest()
83 | .post(new ICallback() {
84 | @Override
85 | public void success(Void aVoid) {
86 | callback.success(null);
87 | }
88 |
89 | @Override
90 | public void failure(ClientException ex) {
91 | callback.failure(ex);
92 | }
93 | });
94 | }
95 | }
96 | };
97 | }
98 |
99 | @Override
100 | public abstract void request(ICallback callback);
101 |
102 | private static Message createMessageObject() {
103 | // Get a context so we can interrogate Resources & SharedPreferences
104 | SnippetApp app = SnippetApp.getApp();
105 | SharedPreferences prefs = SharedPrefsUtil.getSharedPreferences();
106 |
107 | Message message = new Message();
108 | Recipient recipient = new Recipient();
109 | recipient.emailAddress = new EmailAddress();
110 | recipient.emailAddress.address = prefs.getString(SharedPrefsUtil.PREF_USER_ID, "");
111 |
112 | message.toRecipients = Collections.singletonList(recipient);
113 | message.subject = app.getString(R.string.mail_subject);
114 |
115 | ItemBody itemBody = new ItemBody();
116 | itemBody.contentType = BodyType.TEXT;
117 | itemBody.content = app.getString(R.string.mail_body);
118 | message.body = itemBody;
119 |
120 | return message;
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_snippet_detail.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
13 |
14 |
18 |
19 |
33 |
34 |
46 |
47 |
48 |
49 |
58 |
59 |
60 |
61 |
67 |
68 |
75 |
76 |
83 |
84 |
94 |
95 |
102 |
103 |
108 |
109 |
117 |
118 |
119 |
127 |
128 |
129 |
130 |
131 |
138 |
139 |
149 |
150 |
151 |
152 |
--------------------------------------------------------------------------------
/app/src/main/java/com/microsoft/graph/snippets/snippet/UsersSnippets.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license.
3 | * See LICENSE in the project root for license information.
4 | */
5 | package com.microsoft.graph.snippets.snippet;
6 |
7 | import android.content.SharedPreferences;
8 | import com.google.gson.JsonObject;
9 | import com.microsoft.graph.concurrency.ICallback;
10 | import com.microsoft.graph.core.ClientException;
11 | import com.microsoft.graph.models.extensions.PasswordProfile;
12 | import com.microsoft.graph.models.extensions.User;
13 | import com.microsoft.graph.options.Option;
14 | import com.microsoft.graph.options.QueryOption;
15 | import com.microsoft.graph.requests.extensions.IUserCollectionPage;
16 | import com.microsoft.graph.snippets.util.SharedPrefsUtil;
17 | import java.util.LinkedList;
18 | import java.util.List;
19 | import java.util.UUID;
20 | import static com.microsoft.graph.snippets.R.array.get_organization_filtered_users;
21 | import static com.microsoft.graph.snippets.R.array.get_organization_users;
22 | import static com.microsoft.graph.snippets.R.array.insert_organization_user;
23 | import static com.microsoft.graph.snippets.util.SharedPrefsUtil.PREF_USER_TENANT;
24 |
25 | public abstract class UsersSnippets extends AbstractSnippet {
26 |
27 | public UsersSnippets(Integer descriptionArray) {
28 | super(SnippetCategory.userSnippetCategory, descriptionArray);
29 | }
30 |
31 | static UsersSnippets[] getUsersSnippets() {
32 | return new UsersSnippets[]{
33 | // Marker element
34 | new UsersSnippets(null) {
35 |
36 | @Override
37 | public void request(ICallback callback) {
38 | // Not implemented
39 | }
40 | },
41 |
42 | /*
43 | * Gets all of the users in your tenant\'s directory.
44 | * HTTP GET https://graph.microsoft.com/{version}/myOrganization/users
45 | * @see https://graph.microsoft.io/docs/api-reference/v1.0/api/user_list
46 | */
47 | new UsersSnippets(get_organization_users) {
48 | @Override
49 | public void request(final ICallback callback) {
50 | mGraphServiceClient
51 | .users()
52 | .buildRequest()
53 | .get(new ICallback() {
54 | @Override
55 | public void success(IUserCollectionPage iUserCollectionPage) {
56 | callback.success(iUserCollectionPage.getRawObject());
57 | }
58 |
59 | @Override
60 | public void failure(ClientException ex) {
61 | callback.failure(ex);
62 | }
63 | });
64 | }
65 | },
66 |
67 | /*
68 | * Gets all of the users in your tenant's directory who are from the United States, using $filter.
69 | * HTTP GET https://graph.microsoft.com/{version}/myOrganization/users?$filter=country eq \'United States\'
70 | * @see http://graph.microsoft.io/docs/overview/query_parameters
71 | */
72 | new UsersSnippets(get_organization_filtered_users) {
73 | @Override
74 | public void request(final ICallback callback) {
75 | final List