How To Create Android Translation App
How To Create Android Translation App
Like 0
NG APACHE
NOW TRENDING:
PDFBOX IN ANDROID HOW TO CREATE AND ADD CONTENT TO PDF FILE WITH APACHE PDFBOX IN ANDROID HOW TO READ PDF FILE WITH APACHE PDFBOX IN AN
Tweet
Save
ANDROID CREATE APP FROM SCRATCH TUTORIALS CODE SNIPPETS TEMPLATES HOT LIBRARIES BUY CODE
We are going to use Yandex Translation API for translating user entered words.
There are many companies that offer translation service and their prices vary. But the three
most popular translation services are Google Cloud Vision Translation, Microsoft Cloud
BUY SOURCE CODES FOR $10
Translation and Yandex.
$10.00 – Buy Now
You can read more about different companies that offer translation services with a simple
google search.
You can contact us for any of these source code
ANDROID PROGRAMMING TOPICS WE WILL COVER HERE Android Youtube Player App
The dependency section of build.gradle is well commented. The comments give us an idea
of what each or group of libraries do.
1. dependencies {
2. implementation fileTree(dir: 'libs', include: ['*.jar'])
3. implementation 'androidx.appcompat:appcompat:1.0.2'
4. implementation 'androidx.constraintlayout:constraintlayout:2.0.0-
alpha2'
5. implementation 'com.google.android.material:material:1.1.0-alpha01'
6.
7. //Recycler view
8. implementation 'androidx.recyclerview:recyclerview:1.0.0'
9.
10. //Room persistence data
11. implementation "android.arch.persistence.room:rxjava2:1.1.1"
12. implementation 'androidx.room:room-common:2.1.0-alpha03'
13. implementation 'androidx.room:room-runtime:2.1.0-alpha03'
14. annotationProcessor "androidx.room:room-compiler:2.1.0-alpha03"
15. implementation 'android.arch.lifecycle:livedata:1.1.1'
16.
17. //Live Model
18. implementation "androidx.lifecycle:lifecycle-extensions:2.0.0"
19. implementation "androidx.lifecycle:lifecycle-viewmodel:2.0.0"
20. implementation "androidx.lifecycle:lifecycle-runtime:2.0.0"
21. annotationProcessor "androidx.lifecycle:lifecycle-compiler:2.0.0"
22.
23. //Network call - Retrofit
24. implementation 'com.squareup.retrofit2:retrofit:2.4.0'
25. implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
26. implementation 'com.google.code.gson:gson:2.8.5'
27. implementation 'com.squareup.retrofit2:converter-scalars:2.3.0'
28. implementation 'com.squareup.retrofit2:adapter-rxjava:2.4.0'
29. implementation "com.jakewharton.retrofit:retrofit2-rxjava2-
adapter:1.0.0"
30.
31. //logging Networking call
32. implementation 'com.squareup.okhttp3:logging-interceptor:3.10.0'
33. implementation 'com.squareup.okhttp3:okhttp:3.10.0'
34.
35. //fast Adapter
36. implementation 'com.mikepenz:fastadapter:3.3.1'
37.
38. // dependency injection
39. implementation "com.google.dagger:dagger:2.16"
40. annotationProcessor "com.google.dagger:dagger-compiler:2.16"
41. annotationProcessor "com.google.dagger:dagger-android-processor:2.16"
42. implementation "com.google.dagger:dagger-android-support:2.16"
43.
44. //Reactive
45. implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
46. implementation 'io.reactivex.rxjava2:rxjava:2.2.4'
47.
48. //debug db
49. debugImplementation 'com.amitshekhar.android:debug-db:1.0.3'
50.
51. //Runtime permission
52. implementation 'com.karumi:dexter:5.0.0'
53.
54. testImplementation 'junit:junit:4.12'
55. androidTestImplementation 'androidx.test:runner:1.1.1-alpha01'
56. androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1-
alpha01'
57. }
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.constraintlayout:constraintlayout:2.0.0-alph
implementation 'com.google.android.material:material:1.1.0-alpha01'
//Recycler view
implementation 'androidx.recyclerview:recyclerview:1.0.0'
//Live Model
implementation "androidx.lifecycle:lifecycle-extensions:2.0.0"
implementation "androidx.lifecycle:lifecycle-viewmodel:2.0.0"
implementation "androidx.lifecycle:lifecycle-runtime:2.0.0"
annotationProcessor "androidx.lifecycle:lifecycle-compiler:2.0.0"
//fast Adapter
implementation 'com.mikepenz:fastadapter:3.3.1'
// dependency injection
implementation "com.google.dagger:dagger:2.16"
annotationProcessor "com.google.dagger:dagger-compiler:2.16"
annotationProcessor "com.google.dagger:dagger-android-processor:2.16"
implementation "com.google.dagger:dagger-android-support:2.16"
//Reactive
implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
implementation 'io.reactivex.rxjava2:rxjava:2.2.4'
//debug db
debugImplementation 'com.amitshekhar.android:debug-db:1.0.3'
//Runtime permission
implementation 'com.karumi:dexter:5.0.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.1.1-alpha01'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1
}
3. UPDATE COLORS.XML
Open res folder > strings.xml and add the code below to it.
4. UPDATE STYLES.XML
1. <resources>
2.
3. <!-- Base application theme. -->
4. <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
5. <!-- Customize your theme here. -->
6. <item name="colorPrimary">@color/colorPrimary</item>
7. <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
8. <item name="colorAccent">@color/colorAccent</item>
9. </style>
10.
11. <style name="AppTheme.NoActionBar">
12. <item name="windowActionBar">false</item>
13. <item name="windowNoTitle">true</item>
14. </style>
15.
16. <style name="AppTheme.AppBarOverlay"
parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
17.
18. <style name="AppTheme.PopupOverlay"
parent="ThemeOverlay.AppCompat.Light" />
19.
20. </resources>
<resources>
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
</resources>
5. UPDATE STRINGS.XML
Open res folder > strings.xml and add the code below to it.
1. <resources>
2. <string name="app_name">Android Translation</string>
3. <string
name="title_activity_list_translation">ListTranslationActivity</string>
4. </resources>
<resources>
<string name="app_name">Android Translation</string>
<string name="title_activity_list_translation">ListTranslationActivit
</resources>
The translator app features are separated by folders. We will also include folders/packages
for related classes.
Below is how the project is structured. The storetranslation and texttranslation house store
translated list page and the main translator page.
You will be prompted to sign up or login if you have not done any of them. When you final
login, you will be navigated to a page like below.
You will see your translation API key. Copy it and keep in a safe place. We will use it later in
the project.
Please not that when you are on a free quota in Yandex you don’t need to add payment to
your account. Once you add payment you will automatically lose your free quota.
First, create a new folder and name it texttranslation. Right click on the folder and go to
New > Activity > Empty Activity.
Open the activity_text_translation.xml. In the layout file, we will add all the widgets and
ViewGroup our UI requires. Copy and paste the code below inside the layout file.
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.47" />
<androidx.cardview.widget.CardView
android:id="@+id/cardView"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="16dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
app:layout_constraintBottom_toTopOf="@+id/guideline2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="5dp">
<androidx.appcompat.widget.AppCompatEditText
android:id="@+id/original_text_et"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
android:background="@drawable/border"
android:gravity="top"
android:hint="Touch and Start Typing..."
android:padding="8dp"
android:scrollbars="vertical"
android:textAppearance="@style/TextAppearance.AppCompat.B
app:layout_constraintBottom_toTopOf="@+id/paste_btn"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.floatingactionbutton.FloatingAct
android:id="@+id/paste_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
android:clickable="true"
app:backgroundTint="@color/colorWhite"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/guideline6"
app:layout_constraintStart_toStartOf="@+id/guideline4"
app:srcCompat="@drawable/ic_content_paste" />
<com.google.android.material.floatingactionbutton.FloatingAct
android:id="@+id/cancel_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
android:clickable="true"
app:backgroundTint="@color/colorWhite"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/guideline7"
app:layout_constraintHorizontal_bias="0.583"
app:layout_constraintStart_toStartOf="@+id/guideline6"
app:srcCompat="@drawable/ic_cancel" />
<com.google.android.material.floatingactionbutton.FloatingAct
android:id="@+id/voice_to_text_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
android:clickable="true"
app:backgroundTint="@color/colorWhite"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/guideline8"
app:layout_constraintStart_toStartOf="@+id/guideline7"
app:srcCompat="@drawable/ic_mic_blue_700_24dp" />
<com.google.android.material.floatingactionbutton.FloatingAct
android:id="@+id/read_aloud_original_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
android:clickable="true"
app:backgroundTint="@color/colorWhite"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/guideline5"
app:layout_constraintStart_toStartOf="@+id/guideline8"
app:srcCompat="@drawable/ic_volume_up" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_begin="16dp" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_end="16dp" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.25" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline8"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.75" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:id="@+id/cardView2"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="16dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="@+id/guideline2">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="5dp">
<ScrollView
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
android:fillViewport="true"
app:layout_constraintBottom_toTopOf="@+id/copy_translatio
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/translated_text_tv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/border"
android:textColor="@color/colorBlack" />
</ScrollView>
<com.google.android.material.floatingactionbutton.FloatingAct
android:id="@+id/copy_translation_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
android:clickable="true"
app:backgroundTint="@color/colorWhite"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/guideline9"
app:layout_constraintStart_toStartOf="@+id/guideline11"
app:srcCompat="@drawable/ic_content_copy_blue" />
<com.google.android.material.floatingactionbutton.FloatingAct
android:id="@+id/share_translation_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
android:clickable="true"
app:backgroundTint="@color/colorWhite"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/guideline12"
app:layout_constraintHorizontal_bias="0.583"
app:layout_constraintStart_toStartOf="@+id/guideline11"
app:srcCompat="@drawable/ic_share_blue" />
<com.google.android.material.floatingactionbutton.FloatingAct
android:id="@+id/like_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
android:clickable="true"
app:backgroundTint="@color/colorWhite"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/guideline13"
app:layout_constraintStart_toStartOf="@+id/guideline12"
app:srcCompat="@drawable/ic_save_blue" />
<com.google.android.material.floatingactionbutton.FloatingAct
android:id="@+id/read_aloud_translation_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
android:clickable="true"
app:backgroundTint="@color/colorWhite"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/guideline10"
app:layout_constraintStart_toStartOf="@+id/guideline13"
app:srcCompat="@drawable/ic_volume_up" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline9"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_begin="16dp" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline10"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_end="16dp" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline11"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.25" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline12"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline13"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.75" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
<com.google.android.material.floatingactionbutton.FloatingActionButto
android:id="@+id/translate_text__btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
app:layout_constraintBottom_toTopOf="@+id/cardView2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/cardView"
app:srcCompat="@drawable/ic_send_white" />
</androidx.constraintlayout.widget.ConstraintLayout>
The drawable icons used in some of the widgets can be obtain from the drawable folder or
you can create your own icons. If everything works well with no error, you will get a UI
similar to the image below.
Open the TextTranslationActivity class, we will get instances of the widgets we added in the
layout file. In other to avoid repetition and boilerplate code, we will use ButterKnife library
for View binding and event listeners.
Copy and paste the code below to your android app. As you can see, the code is well
commented and very explanatory.
1. package com.inducesmile.androidtranslation.texttranslation;
2.
3. import android.app.ProgressDialog;
4. import android.content.ActivityNotFoundException;
5. import android.content.Intent;
6. import android.os.Bundle;
7. import android.speech.RecognizerIntent;
8. import android.speech.tts.TextToSpeech;
9. import android.text.TextUtils;
10. import android.util.Log;
11. import android.view.Menu;
12. import android.view.MenuItem;
13. import android.view.View;
14. import android.widget.AdapterView;
15. import android.widget.ArrayAdapter;
16. import android.widget.Spinner;
17. import android.widget.Toast;
18.
19. import com.google.android.material.floatingactionbutton.FloatingActionButton
20. import com.inducesmile.androidtranslation.R;
21. import com.inducesmile.androidtranslation.repository.api.model.YandexRespons
22. import com.inducesmile.androidtranslation.repository.database.model.Translat
23. import com.inducesmile.androidtranslation.texttranslation.dialog.SaveDialog;
24. import com.inducesmile.androidtranslation.utils.CommonUtils;
25. import com.inducesmile.androidtranslation.utils.Constants;
26. import com.inducesmile.androidtranslation.utils.CopyPasteText;
27. import com.inducesmile.androidtranslation.utils.ShareUtils;
28. import com.inducesmile.androidtranslation.utils.TextToVoice;
29.
30. import java.util.ArrayList;
31. import java.util.Arrays;
32. import java.util.List;
33. import java.util.Locale;
34. import java.util.Objects;
35.
36. import javax.inject.Inject;
37.
38. import androidx.appcompat.app.AppCompatActivity;
39. import androidx.appcompat.widget.AppCompatEditText;
40. import androidx.appcompat.widget.AppCompatTextView;
41. import androidx.constraintlayout.widget.ConstraintLayout;
42. import androidx.lifecycle.Observer;
43. import dagger.android.AndroidInjection;
44.
45. public class TextTranslationActivity extends AppCompatActivity implements Vi
46.
47. private static final String TAG = TextTranslationActivity.class.getSimpl
48.
49.
50. private AppCompatEditText mOriginalText;
51. private AppCompatTextView mTranslatedText;
52.
53. private ConstraintLayout mLayout;
54.
55. private String originalText = "";
56. private String translatedText = "";
57. private String transAbbr = "en";
58. private String origAbbr = "en";
59.
60. private FloatingActionButton pasteText, deleteText, speakText, readText,
61. favoriteText, translateReadText, convertTex
62.
63. private TextToSpeech tts;
64.
65. private ProgressDialog mProgressDialog;
66.
67. private CopyPasteText copyPasteText;
68.
69. private Spinner spinner, translationSpinner;
70.
71. @Inject
72. TextTranslationViewModel textTranslationViewModel;
73.
74.
75. @Override
76. protected void onCreate(Bundle savedInstanceState) {
77. super.onCreate(savedInstanceState);
78. setContentView(R.layout.activity_text_translation);
79.
80. setTitle("");
81. AndroidInjection.inject(this);
82.
83. copyPasteText = new CopyPasteText(this);
84.
85. mOriginalText = (AppCompatEditText)findViewById(R.id.original_text_e
86. mTranslatedText = (AppCompatTextView)findViewById(R.id.translated_te
87.
88. pasteText = (FloatingActionButton)findViewById(R.id.paste_btn);
89. deleteText = (FloatingActionButton)findViewById(R.id.cancel_btn);
90. speakText = (FloatingActionButton)findViewById(R.id.voice_to_text_bt
91. readText = (FloatingActionButton)findViewById(R.id.read_aloud_origin
92.
93. copyText = (FloatingActionButton)findViewById(R.id.copy_translation_
94. shareText = (FloatingActionButton)findViewById(R.id.share_translatio
95. favoriteText = (FloatingActionButton)findViewById(R.id.like_btn);
96. translateReadText = (FloatingActionButton)findViewById(R.id.read_alo
97.
98. convertText = (FloatingActionButton)findViewById(R.id.translate_text
99.
100. pasteText.setOnClickListener(this);
101. deleteText.setOnClickListener(this);
102. speakText.setOnClickListener(this);
103. readText.setOnClickListener(this);
104.
105. copyText.setOnClickListener(this);
106. shareText.setOnClickListener(this);
107. favoriteText.setOnClickListener(this);
108. translateReadText.setOnClickListener(this);
109.
110. convertText.setOnClickListener(new View.OnClickListener() {
111. @Override
112. public void onClick(View v) {
113. String userTextInput = getOriginalText();
114. List<String> list = Arrays.asList(Constants.YANDEX_TRANSLATE
115. if(TextUtils.isEmpty(userTextInput)){
116. Toast.makeText(TextTranslationActivity.this, "Content to
empty ...", Toast.LENGTH_SHORT).show();
117. }else if(TextUtils.isEmpty(transAbbr)){
118. Toast.makeText(TextTranslationActivity.this, "Target Lan
Toast.LENGTH_SHORT).show();
119. }
120. else if(!list.contains(transAbbr)) {
121. Toast.makeText(TextTranslationActivity.this, "Target Lan
Toast.LENGTH_SHORT).show();
122. }else {
123. textTranslationViewModel.makeApiTranslationCall(userText
124. }
125. }
126. });
127.
128. watchTranslatedText();
129. }
130.
131.
132. //Watch translated text for change
133. private void watchTranslatedText(){
134. textTranslationViewModel.getYandexResponse().observe(this, new Obser
{
135. @Override
136. public void onChanged(YandexResponse yandexResponse) {
137. if (yandexResponse != null) {
138. translatedText = String.valueOf(yandexResponse.getText()
139. translatedText = translatedText.replaceAll("\\p{P}", "")
140. mTranslatedText.setText(translatedText);
141. }
142. }
143. });
144. }
145.
146. private boolean isOriginalTextExist(){
147. String textContent = Objects.requireNonNull(mOriginalText.getText())
148. return TextUtils.isEmpty(textContent);
149. }
150.
151. private boolean isTranslatedTextExist(){
152. String textContent = Objects.requireNonNull(mTranslatedText.getText(
153. return TextUtils.isEmpty(textContent);
154. }
155.
156.
157. private String getOriginalText(){
158. return Objects.requireNonNull(mOriginalText.getText()).toString();
159. }
160.
161.
162. private String getTranslatedText(){
163. return Objects.requireNonNull(mTranslatedText.getText()).toString();
164. }
165.
166.
167. @Override
168. public boolean onCreateOptionsMenu(Menu menu) {
169. getMenuInflater().inflate(R.menu.text_translate_menu, menu);
170.
171. MenuItem item = menu.findItem(R.id.original_lang_spinner);
172. populateFirstSpinner(item);
173.
174. MenuItem item2 = menu.findItem(R.id.translate_lang_spinner);
175. populateSecondSpinner(item2);
176.
177. return super.onCreateOptionsMenu(menu);
178. }
179.
180.
181. @Override
182. public boolean onOptionsItemSelected(MenuItem item) {
183. int clickItem = item.getItemId();
184. if(clickItem == R.id.switch_item){
185.
186. //Switch selected language
187. String firstText = (String)spinner.getSelectedItem();
188. String secondText = (String)translationSpinner.getSelectedItem()
189. int firstIndex = CommonUtils.getLanguageIndexPosition(firstText)
190. int secondIndex = CommonUtils.getLanguageIndexPosition(secondTex
191.
192. spinner.setSelection(secondIndex);
193. translationSpinner.setSelection(firstIndex);
194.
195. // switch language abbreviation
196. String tempAbbreviation = origAbbr;
197. transAbbr = origAbbr;
198. origAbbr = tempAbbreviation;
199.
200. //switching text content
201. mOriginalText.setText(getTranslatedText());
202. mTranslatedText.setText(getOriginalText());
203.
204.
205. }
206. return super.onOptionsItemSelected(item);
207. }
208.
209.
210.
211. //Language option for original text
212. private void populateFirstSpinner(MenuItem item){
213. spinner = (Spinner) item.getActionView();
214. ArrayAdapter<String> languageAdapter = new ArrayAdapter<String>(this
R.layout.custom_spinner_item, CommonUtils.sortedListString());
215.
216. languageAdapter.setDropDownViewResource(android.R.layout.simple_spin
217. spinner.setAdapter(languageAdapter);
218. spinner.setSelection(CommonUtils.getEnglishLanguagePosition());
219.
220. spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedList
221. @Override
222. public void onItemSelected(AdapterView<?> parent, View view, int
223. String item = parent.getItemAtPosition(position).toString();
224.
225. int index =
Arrays.asList(Constants.YANDEX_TRANSLATE_SUPPORTED_LANGUAGE).indexOf(item);
226. origAbbr = Constants.YANDEX_TRANSLATE_ABBR[index];
227. }
228.
229. @Override
230. public void onNothingSelected(AdapterView<?> adapterView) {
231.
232. }
233. });
234. }
235.
236.
237. //Language option for translation
238. private void populateSecondSpinner(MenuItem item){
239. translationSpinner = (Spinner) item.getActionView();
240. ArrayAdapter<String> translationAdapter = new ArrayAdapter<String>(t
R.layout.custom_spinner_item, CommonUtils.sortedListString());
241.
242.
translationAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dr
243. translationSpinner.setAdapter(translationAdapter);
244. translationSpinner.setSelection(CommonUtils.getEnglishLanguagePositi
245.
246. translationSpinner.setOnItemSelectedListener(new AdapterView.OnItemS
247. @Override
248. public void onItemSelected(AdapterView<?> parent, View view, int
249. String item = parent.getItemAtPosition(position).toString();
250.
251. int index =
Arrays.asList(Constants.YANDEX_TRANSLATE_SUPPORTED_LANGUAGE).indexOf(item);
252. transAbbr = Constants.YANDEX_TRANSLATE_ABBR[index];
253. }
254.
255. @Override
256. public void onNothingSelected(AdapterView<?> adapterView) {
257.
258. }
259. });
260. }
261.
262.
263. //All button options used in the translation app
264. @Override
265. public void onClick(View v) {
266. FloatingActionButton floatingActionButton = (FloatingActionButton)v;
267. int buttonId = floatingActionButton.getId();
268.
269. switch (buttonId){
270. //paste translation text
271. case R.id.paste_btn:
272. String copiedContext = copyPasteText.pasteTextContent();
273. if(TextUtils.isEmpty(copiedContext)){
274. Toast.makeText(TextTranslationActivity.this, "Paste cont
Toast.LENGTH_SHORT).show();
275. }else{
276. mOriginalText.setText(copiedContext);
277. }
278. break;
279. //Delete translation text
280. case R.id.cancel_btn:
281. mOriginalText.setText("");
282. break;
283. //context translation text to voice
284. case R.id.voice_to_text_btn:
285. askSpeechInput();
286. break;
287. //text to sppech
288. case R.id.read_aloud_original_btn:
289. if(isOriginalTextExist()){
290. Toast.makeText(TextTranslationActivity.this, "Text is em
Toast.LENGTH_SHORT).show();
291. }else{
292. TextToVoice textToVoice = new TextToVoice(TextTranslatio
293. textToVoice.turnTextToSpeech(getOriginalText());
294. }
295. break;
296. //copy translation text
297. case R.id.copy_translation_btn:
298. if(isTranslatedTextExist()){
299. Toast.makeText(TextTranslationActivity.this, "Translatio
Toast.LENGTH_SHORT).show();
300. }else{
301. copyPasteText.copyTextContent(getTranslatedText());
302. }
303. break;
304. //share translation text
305. case R.id.share_translation_btn:
306. ShareUtils.shareTranslatedText(TextTranslationActivity.this,
getTranslatedText());
307. break;
308. case R.id.like_btn:
309. //The like id was changed to save.
310. if(TextUtils.isEmpty(getOriginalText()) ||
TextUtils.isEmpty(getTranslatedText())){
311. Toast.makeText(TextTranslationActivity.this, "Translatio
Toast.LENGTH_SHORT).show();
312. }else{
313. SaveDialog deleteDialog = new SaveDialog(TextTranslation
314. TranslationObject saveObject = new TranslationObject(get
getTranslatedText());
315. deleteDialog.addNewMessage(textTranslationViewModel, sav
316. }
317.
318. break;
319. case R.id.read_aloud_translation_btn:
320. if (isTranslatedTextExist()) {
321. Toast.makeText(TextTranslationActivity.this, "Text is em
Toast.LENGTH_SHORT).show();
322. } else {
323. TextToVoice textToVoice = new TextToVoice(TextTranslatio
324. textToVoice.turnTextToSpeech(getTranslatedText());
325. }
326. break;
327. default:
328. break;
329. }
330. }
331.
332.
333. //Android speech input
334. private void askSpeechInput() {
335. Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH)
336. intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
337. intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault()
338. intent.putExtra(RecognizerIntent.EXTRA_PROMPT, "Hi speak something")
339. try {
340. startActivityForResult(intent, Constants.REQ_CODE_SPEECH_INPUT);
341. } catch (ActivityNotFoundException a) {
342. Log.d(TAG, "Error " + a.getMessage());
343. }
344. }
345.
346.
347. @Override
348. protected void onActivityResult(int requestCode, int resultCode, Intent
349. super.onActivityResult(requestCode, resultCode, data);
350.
351. switch (requestCode) {
352. case Constants.REQ_CODE_SPEECH_INPUT: {
353. if (resultCode == RESULT_OK && null != data) {
354. ArrayList<String> result =
data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
355. mOriginalText.setText(result.get(0));
356. }
357. break;
358. }
359. }
360. }
361.
362. }
package com.inducesmile.androidtranslation.texttranslation;
import android.app.ProgressDialog;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.os.Bundle;
import android.speech.RecognizerIntent;
import android.speech.tts.TextToSpeech;
import android.text.TextUtils;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.Toast;
import com.google.android.material.floatingactionbutton.FloatingActionBut
import com.inducesmile.androidtranslation.R;
import com.inducesmile.androidtranslation.repository.api.model.YandexResp
import com.inducesmile.androidtranslation.repository.database.model.Trans
import com.inducesmile.androidtranslation.texttranslation.dialog.SaveDial
import com.inducesmile.androidtranslation.utils.CommonUtils;
import com.inducesmile.androidtranslation.utils.Constants;
import com.inducesmile.androidtranslation.utils.CopyPasteText;
import com.inducesmile.androidtranslation.utils.ShareUtils;
import com.inducesmile.androidtranslation.utils.TextToVoice;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import javax.inject.Inject;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.AppCompatEditText;
import androidx.appcompat.widget.AppCompatTextView;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.lifecycle.Observer;
import dagger.android.AndroidInjection;
@Inject
TextTranslationViewModel textTranslationViewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_text_translation);
setTitle("");
AndroidInjection.inject(this);
mOriginalText = (AppCompatEditText)findViewById(R.id.original_tex
mTranslatedText = (AppCompatTextView)findViewById(R.id.translated
pasteText = (FloatingActionButton)findViewById(R.id.paste_btn);
deleteText = (FloatingActionButton)findViewById(R.id.cancel_btn);
speakText = (FloatingActionButton)findViewById(R.id.voice_to_text
readText = (FloatingActionButton)findViewById(R.id.read_aloud_ori
copyText = (FloatingActionButton)findViewById(R.id.copy_translati
shareText = (FloatingActionButton)findViewById(R.id.share_transla
favoriteText = (FloatingActionButton)findViewById(R.id.like_btn);
translateReadText = (FloatingActionButton)findViewById(R.id.read_
convertText = (FloatingActionButton)findViewById(R.id.translate_t
pasteText.setOnClickListener(this);
deleteText.setOnClickListener(this);
speakText.setOnClickListener(this);
readText.setOnClickListener(this);
copyText.setOnClickListener(this);
shareText.setOnClickListener(this);
favoriteText.setOnClickListener(this);
translateReadText.setOnClickListener(this);
convertText.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String userTextInput = getOriginalText();
List<String> list = Arrays.asList(Constants.YANDEX_TRANSL
if(TextUtils.isEmpty(userTextInput)){
Toast.makeText(TextTranslationActivity.this, "Content
}else if(TextUtils.isEmpty(transAbbr)){
Toast.makeText(TextTranslationActivity.this, "Target
}
else if(!list.contains(transAbbr)) {
Toast.makeText(TextTranslationActivity.this, "Target
}else {
textTranslationViewModel.makeApiTranslationCall(userT
}
}
});
watchTranslatedText();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.text_translate_menu, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int clickItem = item.getItemId();
if(clickItem == R.id.switch_item){
spinner.setSelection(secondIndex);
translationSpinner.setSelection(firstIndex);
}
return super.onOptionsItemSelected(item);
}
languageAdapter.setDropDownViewResource(android.R.layout.simple_s
spinner.setAdapter(languageAdapter);
spinner.setSelection(CommonUtils.getEnglishLanguagePosition());
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedL
@Override
public void onItemSelected(AdapterView<?> parent, View view,
String item = parent.getItemAtPosition(position).toString
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
}
translationAdapter.setDropDownViewResource(android.R.layout.simpl
translationSpinner.setAdapter(translationAdapter);
translationSpinner.setSelection(CommonUtils.getEnglishLanguagePos
translationSpinner.setOnItemSelectedListener(new AdapterView.OnIt
@Override
public void onItemSelected(AdapterView<?> parent, View view,
String item = parent.getItemAtPosition(position).toString
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
}
switch (buttonId){
//paste translation text
case R.id.paste_btn:
String copiedContext = copyPasteText.pasteTextContent();
if(TextUtils.isEmpty(copiedContext)){
Toast.makeText(TextTranslationActivity.this, "Paste c
}else{
mOriginalText.setText(copiedContext);
}
break;
//Delete translation text
case R.id.cancel_btn:
mOriginalText.setText("");
break;
//context translation text to voice
case R.id.voice_to_text_btn:
askSpeechInput();
break;
//text to sppech
case R.id.read_aloud_original_btn:
if(isOriginalTextExist()){
Toast.makeText(TextTranslationActivity.this, "Text is
}else{
TextToVoice textToVoice = new TextToVoice(TextTransla
textToVoice.turnTextToSpeech(getOriginalText());
}
break;
//copy translation text
case R.id.copy_translation_btn:
if(isTranslatedTextExist()){
Toast.makeText(TextTranslationActivity.this, "Transla
}else{
copyPasteText.copyTextContent(getTranslatedText());
}
break;
//share translation text
case R.id.share_translation_btn:
ShareUtils.shareTranslatedText(TextTranslationActivity.th
break;
case R.id.like_btn:
//The like id was changed to save.
if(TextUtils.isEmpty(getOriginalText()) || TextUtils.isEm
Toast.makeText(TextTranslationActivity.this, "Transla
}else{
SaveDialog deleteDialog = new SaveDialog(TextTranslat
TranslationObject saveObject = new TranslationObject(
deleteDialog.addNewMessage(textTranslationViewModel,
}
break;
case R.id.read_aloud_translation_btn:
if (isTranslatedTextExist()) {
Toast.makeText(TextTranslationActivity.this, "Text is
} else {
TextToVoice textToVoice = new TextToVoice(TextTransla
textToVoice.turnTextToSpeech(getTranslatedText());
}
break;
default:
break;
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Inte
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case Constants.REQ_CODE_SPEECH_INPUT: {
if (resultCode == RESULT_OK && null != data) {
ArrayList<String> result = data.getStringArrayListExt
mOriginalText.setText(result.get(0));
}
break;
}
}
}
1. @Inject
2. TextTranslationViewModel textTranslationViewModel;
@Inject
TextTranslationViewModel textTranslationViewModel;
We will need to create a this in the same folder. It will inherit from android ViewModel class
The ViewModel class is responsible for analyzing and preparing our remote data from the
currency API.
public class TextTranslationViewModel extends BaseViewModel<ITextInterfac
The source code is not free to download because we spent a lot of time to create these apps from scratch
and your little support will help us to even create more apps from scratch.
Buy
SUMMARY
We have walk through the core feature of android translator app and I guess you have a
better insight on how to continue to improve your source code.
I will suggest you buy the source code to learn how other features were implemented.
If you have questions and suggestions, kindly use the comment box below to get in touch
I look forward in seeing you in our next build from scratch episode.
How to build Android How to build Android How to build Android How to Create Android
Calculator App Dictionary App from Scientific Calculator App Currency Converter Using
Scratch Apilayer from Scratch
Tags: Android translation app, build translation app, create translation ap, make
translation app
Inducesmile
I learn and write about Android, Swift, C, Assembly, C++, Python,
Flutter, Kotlin, React Native and Internet of Things
ADD A COMMENT
This site uses Akismet to reduce spam. Learn how your comment data is processed.
INDUCESMILE – ANDROID TUTORIAL, ANDROID APPS, ANDROID STUDIO, ANDROID SDK, ANDROID DEVELOPMENT COPYRIGHT © 2020.
34