Skip to content
This repository was archived by the owner on Apr 6, 2023. It is now read-only.

Commit 30784ed

Browse files
jbolingerfrankyn
authored andcommitted
Add language client sample (#71)
* add language client sample * add copy task for CI * update api activation link * fix missing link * fix unrelated CI dependency issue * unrelated CI issue again * another try at unrelated CI failure * another try at unrelated CI failure * another try at unrelated CI failure * another try at unrelated CI failure
1 parent 8244f1d commit 30784ed

35 files changed

Lines changed: 1134 additions & 0 deletions

endpoints-frameworks/legacy/app/build.gradle

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ android {
3333
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
3434
}
3535
}
36+
configurations.all {
37+
resolutionStrategy.force 'com.google.code.findbugs:jsr305:2.0.1'
38+
}
3639
}
3740

3841
dependencies {

endpoints-frameworks/v2/app/build.gradle

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ android {
4646
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
4747
}
4848
}
49+
configurations.all {
50+
resolutionStrategy.force 'com.google.code.findbugs:jsr305:2.0.1'
51+
}
4952
}
5053

5154
dependencies {

nl/LanguageClient/.gitignore

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
*.iml
2+
.gradle
3+
/local.properties
4+
/.idea/libraries
5+
/.idea/caches/
6+
/.idea/modules.xml
7+
/.idea/workspace.xml
8+
.DS_Store
9+
/build
10+
/captures
11+
.externalNativeBuild
12+
app/src/main/res/raw/credential.json
13+

nl/LanguageClient/README.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# Cloud Natural Language API Example
2+
3+
This directory contains an Android example that uses the
4+
[Cloud Natural Language API](https://cloud.google.com/natural-language/)
5+
with the [Google Cloud Client Library for Java]
6+
7+
## Prerequisites
8+
9+
### Enable the Data Loss Prevention API
10+
11+
If you have not already done so,
12+
[enable the Natural Language API for your project](https://console.cloud.google.com/flows/enableapi?apiid=language.googleapis.com).
13+
14+
### Set Up to Authenticate With Your Project's Credentials
15+
16+
This Android app uses a JSON credential file locally stored in the raw resources folder.
17+
***You should not do this in your production app.***
18+
Instead, you should set up your own backend server that authenticates app users.
19+
The server should delegate API calls from your client app and enforce usage quota per user.
20+
Alternatively, you should get an access token on the server side,
21+
and supply them to your client app. Tokens expire after a short amount of time. For example:
22+
23+
```java
24+
// read JSON credential into stream and generate a credential using an access token
25+
GoogleCredentials credentials = GoogleCredentials.fromStream(stream).createScoped(SCOPE);
26+
AccessToken token = credentials.refreshAccessToken();
27+
return new GoogleCredentials(accessToken).createScoped(SCOPE);
28+
```
29+
30+
In this example, we put the Service Account in the client so no backend server is needed
31+
to run it.
32+
33+
In order to try out this sample, visit the [Cloud Console](https://console.cloud.google.com/), and
34+
navigate to:
35+
`API Manager > Credentials > Create credentials > Service account key > New service account`.
36+
Create a new service account, and download the JSON credentials file. Put the file in the app
37+
resources as `app/src/main/res/raw/credential.json`.
38+
39+
Again, ***you should not do this in your production app.***
40+
41+
See the [Cloud Platform Auth Guide](https://cloud.google.com/docs/authentication#developer_workflow)
42+
for more information.
43+
44+
## Client Libraries on Android
45+
46+
The [Google Cloud Client Library for Java] that is used for this example can be used on Android,
47+
but it is not optimized and is considered experimental. Specifically, it does not use the
48+
[lite](https://github.com/google/protobuf/blob/master/java/lite.md) version of protocol buffers
49+
that are optimized for mobile, it has some dependencies that may not be needed on Android, and
50+
it does not help with the authentication issues mentioned the previous section. We are working
51+
on this and encourage you to try out the client libraries on Android and give us feedback so
52+
that we can improve them.
53+
54+
## Run the Example
55+
56+
Open this example and Android studio and run the app. Change the text in the MainActivity
57+
if you'd like to test the API with a different phrase.
58+
59+
[Google Cloud Client Library for Java]: https://github.com/GoogleCloudPlatform/google-cloud-java

nl/LanguageClient/app/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/build

nl/LanguageClient/app/build.gradle

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* Copyright 2018 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
apply plugin: 'com.android.application'
18+
19+
android {
20+
compileSdkVersion 27
21+
defaultConfig {
22+
applicationId "com.google.cloud.examples.language"
23+
minSdkVersion 23
24+
targetSdkVersion 27
25+
versionCode 1
26+
versionName "1.0"
27+
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
28+
}
29+
buildTypes {
30+
release {
31+
minifyEnabled false
32+
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
33+
}
34+
}
35+
compileOptions {
36+
targetCompatibility 1.8
37+
sourceCompatibility 1.8
38+
}
39+
// exclude files that are not needed from the cloud client libraries
40+
packagingOptions {
41+
exclude 'META-INF/LICENSE'
42+
exclude 'META-INF/INDEX.LIST'
43+
}
44+
}
45+
46+
dependencies {
47+
implementation fileTree(dir: 'libs', include: ['*.jar'])
48+
implementation 'com.android.support:appcompat-v7:27.1.1'
49+
50+
// include the language API
51+
implementation 'io.grpc:grpc-okhttp:1.10.0'
52+
implementation 'com.google.cloud:google-cloud-language:1.22.0'
53+
54+
testImplementation 'junit:junit:4.12'
55+
androidTestImplementation 'com.android.support.test:runner:1.0.2'
56+
androidTestImplementation 'com.android.support.test:rules:1.0.2'
57+
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
58+
}
59+
60+
task copySecretKey(type: Copy) {
61+
File secretKey = file "$System.env.GOOGLE_APPLICATION_CREDENTIALS"
62+
from secretKey.getParent()
63+
include secretKey.getName()
64+
into 'src/main/res/raw'
65+
rename secretKey.getName(), "credential.json"
66+
}
67+
preBuild.dependsOn(copySecretKey)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Add project specific ProGuard rules here.
2+
# You can control the set of applied configuration files using the
3+
# proguardFiles setting in build.gradle.
4+
#
5+
# For more details, see
6+
# http://developer.android.com/guide/developing/tools/proguard.html
7+
8+
# If your project uses WebView with JS, uncomment the following
9+
# and specify the fully qualified class name to the JavaScript interface
10+
# class:
11+
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12+
# public *;
13+
#}
14+
15+
# Uncomment this to preserve the line number information for
16+
# debugging stack traces.
17+
#-keepattributes SourceFile,LineNumberTable
18+
19+
# If you keep the line number information, uncomment this to
20+
# hide the original source file name.
21+
#-renamesourcefileattribute SourceFile
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Copyright 2018 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.cloud.examples.language;
18+
19+
import android.support.test.filters.LargeTest;
20+
import android.support.test.rule.ActivityTestRule;
21+
import android.support.test.runner.AndroidJUnit4;
22+
23+
import org.junit.Rule;
24+
import org.junit.Test;
25+
import org.junit.runner.RunWith;
26+
27+
import static android.support.test.espresso.Espresso.onView;
28+
import static android.support.test.espresso.assertion.ViewAssertions.matches;
29+
import static android.support.test.espresso.matcher.ViewMatchers.withId;
30+
import static android.support.test.espresso.matcher.ViewMatchers.withText;
31+
import static org.hamcrest.Matchers.containsString;
32+
33+
@RunWith(AndroidJUnit4.class)
34+
@LargeTest
35+
public class MainActivityTest {
36+
37+
@Rule
38+
public ActivityTestRule<MainActivity> mActivityRule =
39+
new ActivityTestRule(MainActivity.class);
40+
41+
@Test
42+
public void returnsIdentifiedEntity() {
43+
onView(withId(R.id.result_text))
44+
.check(matches(withText(containsString("California"))));
45+
}
46+
47+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!--
3+
~ Copyright 2018 Google LLC
4+
~
5+
~ Licensed under the Apache License, Version 2.0 (the "License");
6+
~ you may not use this file except in compliance with the License.
7+
~ You may obtain a copy of the License at
8+
~
9+
~ https://www.apache.org/licenses/LICENSE-2.0
10+
~
11+
~ Unless required by applicable law or agreed to in writing, software
12+
~ distributed under the License is distributed on an "AS IS" BASIS,
13+
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
~ See the License for the specific language governing permissions and
15+
~ limitations under the License.
16+
-->
17+
18+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
19+
package="com.google.cloud.examples.language">
20+
21+
<uses-permission android:name="android.permission.INTERNET"/>
22+
23+
<application
24+
android:allowBackup="true"
25+
android:icon="@mipmap/ic_launcher"
26+
android:label="@string/app_name"
27+
android:roundIcon="@mipmap/ic_launcher_round"
28+
android:supportsRtl="true"
29+
android:theme="@style/AppTheme">
30+
<activity android:name=".MainActivity">
31+
<intent-filter>
32+
<action android:name="android.intent.action.MAIN" />
33+
34+
<category android:name="android.intent.category.LAUNCHER" />
35+
</intent-filter>
36+
</activity>
37+
</application>
38+
39+
</manifest>
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/*
2+
* Copyright 2018 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.cloud.examples.language;
18+
19+
import android.os.AsyncTask;
20+
import android.os.Bundle;
21+
import android.support.v7.app.AppCompatActivity;
22+
import android.view.View;
23+
import android.widget.TextView;
24+
25+
import com.google.auth.oauth2.GoogleCredentials;
26+
import com.google.cloud.language.v1.AnalyzeEntitiesRequest;
27+
import com.google.cloud.language.v1.AnalyzeEntitiesResponse;
28+
import com.google.cloud.language.v1.Document;
29+
import com.google.cloud.language.v1.LanguageServiceClient;
30+
import com.google.cloud.language.v1.LanguageServiceSettings;
31+
32+
import java.io.IOException;
33+
34+
/**
35+
* This example demonstrates using the Cloud Natural Language client library to
36+
* perform text analysis.
37+
*/
38+
public class MainActivity extends AppCompatActivity {
39+
40+
private LanguageServiceClient mLanguageClient;
41+
private TextView mResultText;
42+
private TextView mWaitText;
43+
private View mProgressView;
44+
45+
@Override
46+
protected void onCreate(Bundle savedInstanceState) {
47+
super.onCreate(savedInstanceState);
48+
setContentView(R.layout.activity_main);
49+
50+
mResultText = findViewById(R.id.result_text);
51+
mWaitText = findViewById(R.id.wait_text);
52+
mProgressView = findViewById(R.id.progress);
53+
54+
// create the language client
55+
try {
56+
// NOTE: The line below uses an embedded credential (res/raw/credential.json).
57+
// You should not package a credential with real application.
58+
// Instead, you should get a credential securely from a server.
59+
mLanguageClient = LanguageServiceClient.create(
60+
LanguageServiceSettings.newBuilder()
61+
.setCredentialsProvider(() ->
62+
GoogleCredentials.fromStream(getApplicationContext()
63+
.getResources()
64+
.openRawResource(R.raw.credential)))
65+
.build());
66+
} catch (IOException e) {
67+
throw new IllegalStateException("Unable to create a language client", e);
68+
}
69+
70+
// get the text to analyze
71+
String text = "Hi there Sunnyvale California!";
72+
mWaitText.setText(getString(R.string.waiting_for_response, text));
73+
74+
// call the API
75+
new AnalyzeTask().execute(text);
76+
}
77+
78+
@Override
79+
protected void onDestroy() {
80+
super.onDestroy();
81+
82+
// shutdown the connection
83+
mLanguageClient.shutdown();
84+
}
85+
86+
private class AnalyzeTask extends AsyncTask<String, Void, AnalyzeEntitiesResponse> {
87+
88+
@Override
89+
protected AnalyzeEntitiesResponse doInBackground(String... args) {
90+
AnalyzeEntitiesRequest request = AnalyzeEntitiesRequest.newBuilder()
91+
.setDocument(Document.newBuilder()
92+
.setContent(args[0])
93+
.setType(Document.Type.PLAIN_TEXT)
94+
.build())
95+
.build();
96+
return mLanguageClient.analyzeEntities(request);
97+
}
98+
99+
@Override
100+
protected void onPostExecute(AnalyzeEntitiesResponse analyzeEntitiesResponse) {
101+
// update UI with results
102+
mProgressView.setVisibility(View.GONE);
103+
mResultText.setText(analyzeEntitiesResponse.toString());
104+
}
105+
}
106+
107+
}

0 commit comments

Comments
 (0)