diff --git a/README.md b/README.md new file mode 100644 index 0000000..6a4dcf5 --- /dev/null +++ b/README.md @@ -0,0 +1,79 @@ +# Einleitung + +Mein Vorhaben umfasst die Integration einer Übersetzungsfunktion, die in der Lage ist, sowohl einzelne Wörter als auch vollständige Sätze oder umfangreichere Texte zu übersetzen. Zusätzlich besteht die Flexibilität, die Eingangssprache sowie die Ausgangssprache nach individuellem Bedarf anzupassen. Die herausragenden Übersetzungsfähigkeiten von ChatGPT machen diese Erweiterung zu einer besonders signifikanten Verbesserung. + +# Umsetzung + +## root_preferences.xml + +In der Datei root_preferences.xml wurden die erforderlichen Einstellungen vorgenommen. Für die Eingangssprache wurden folgende Konfigurationen vorgenommen: +**ListPreference für "language" (Sprache):** + +- `defaultValue="de"`: Standardwert ist auf "de" (Deutsch) gesetzt. +- `entries="@array/language_entries"`: Die Auswahlmöglichkeiten (Anzeigewerte) für den Benutzer sind in einem Ressourcen-Array mit dem Namen "language_entries" festgelegt. +- `entryValues="@array/language_values"`: Die tatsächlichen Werte, die im Hintergrund verwendet werden, wenn der Benutzer eine Auswahl trifft, sind in einem Ressourcen-Array mit dem Namen "language_values" festgelegt. +- `key="language"`: Der Schlüssel, unter dem dieser Wert in den Einstellungen gespeichert wird. +- `title="@string/language"`: Der Titel oder die Bezeichnung, die dem Benutzer angezeigt wird. +- `useSimpleSummaryProvider="true"`: Eine vereinfachte Zusammenfassung wird verwendet, um den ausgewählten Wert anzuzeigen. + +Für "Chaptgpt_language" sind die Änderungen hauptsächlich auf den Wechsel zu den entsprechenden Ressourcenarrays (`chatgpt_language_entries` und `chatgpt_language_values`) und den zugehörigen Zeichenkettenressourcen für Titel und Standardwert. + +## getChatgptLanguage + +Der Code ruft die ausgewählte ChatGPT-Sprache aus den Anwendungseinstellungen ab und verwendet dann einen Switch-Block, um verschiedene Beschreibungen für die Sprachauswahl zu generieren. Wenn die ausgewählte Sprache "German" ist, wird die Beschreibung "Übersetzt mir das auf deutsch:" zurückgegeben. Bei "English" lautet die Beschreibung "Translate it in English:", bei "Italian" "Translate the following to Italy:", und bei "French" "Translate the following to France:". Falls keine der vordefinierten Sprachen ausgewählt wurde, wird eine Laufzeit-Ausnahme mit dem Hinweis "Output Language not supported" ausgelöst. Der Standardwert für die Sprache ist "English". + +```java +public String getChatgptLanguage() { +String chatgpt_language = PreferenceManager.getDefaultSharedPreferences(context).getString + ("chatgpt_language", "English"); + switch(chatgpt_language) { + case "German": + return "Übersetzt mir das auf deutsch:"; + case "English": + return "Translate it in English:"; + case "Italian": + return "Translate the following to italy:"; + case "French": + return "Translate the following to france:"; + default: + throw new RuntimeException("Output Language not supported: " + chatgpt_language); + } +} +```` + +## getLocale + +Der Code ruft die ausgewählte Benutzersprache aus den Anwendungseinstellungen ab und verwendet einen Switch-Block, um die entsprechende `Locale` für die Sprache zurückzugeben. Wenn die ausgewählte Sprache "de" ist, wird `Locale.GERMAN` zurückgegeben. Für "en" wird `Locale.ENGLISH` zurückgegeben, für "ita" wird `Locale.ITALIAN` zurückgegeben und für "franc" wird `Locale.FRANCE` zurückgegeben. Falls keine der vordefinierten Sprachen ausgewählt wurde, wird eine Laufzeit-Ausnahme mit dem Hinweis "Locale not supported" ausgelöst. Der Standardwert für die Sprache ist "de" (Deutsch). + +```java +public Locale getLocale() { + String language = PreferenceManager.getDefaultSharedPreferences(context).getString("language", "de"); + switch (language) { + case "de": + return Locale.GERMAN; + case "en": + return Locale.ENGLISH; + case "ita": + return Locale.ITALIAN; + case "franc": + return Locale.FRANCE; + default: + throw new RuntimeException("Local not supported: " + language); + } +} +```` + +## getTextFromSpeech + +In der Klasse MainFragment.java wird die Funktion getChatgptLanguage() in die Variable getTextFromSpeech implementiert.: +``chat.addMessage(new Message(Author.System, prefs.getChatgptLanguage()));`` + +# Problem + +Ich stieß auf ein Problem, das ich glücklicherweise erfolgreich behoben habe. Ursprünglich musste man den Reset-Knopf verwenden, damit der Wechsel der Sprache für ChatGPT erkannt wurde. In der Methode createNewChat() hatte ich den folgenden Code: +``chat.addMessage(new Message(Author.System, prefs.getChatgptLanguage()));`` +Dieser Code befand sich jedoch an der falschen Stelle und wurde dann direkt in die Variable getTextFromSpeech eingefügt, siehe oben. + +# Fazit + +Es ist mir gelungen, alles wie geplant umzusetzen. Zunächst dachte ich, dass ich das Problem nicht lösen könnte, aber zum Glück konnte ich es schließlich doch bewältigen. Der zeitliche Aufwand war im Grunde genommen optimal. Am Anfang hatte ich einige Schwierigkeiten, weil ich nicht genau wusste, wie ich beginnen sollte. Nachdem ich jedoch wusste, wo ich was tun musste, ging es recht schnell voran, und bis auf das beschriebene Problem hat alles reibungslos funktioniert. diff --git a/app/src/main/java/de/fhdw/app_entwicklung/chatgpt/MainFragment.java b/app/src/main/java/de/fhdw/app_entwicklung/chatgpt/MainFragment.java index 3ac722f..3a191c9 100644 --- a/app/src/main/java/de/fhdw/app_entwicklung/chatgpt/MainFragment.java +++ b/app/src/main/java/de/fhdw/app_entwicklung/chatgpt/MainFragment.java @@ -14,13 +14,13 @@ import androidx.fragment.app.Fragment; import java.util.List; -import java.util.Locale; +import java.util.stream.Collectors; import de.fhdw.app_entwicklung.chatgpt.model.Author; import de.fhdw.app_entwicklung.chatgpt.model.Chat; import de.fhdw.app_entwicklung.chatgpt.model.Message; +import de.fhdw.app_entwicklung.chatgpt.openai.ChatGpt; import de.fhdw.app_entwicklung.chatgpt.openai.IChatGpt; -import de.fhdw.app_entwicklung.chatgpt.openai.MockChatGpt; import de.fhdw.app_entwicklung.chatgpt.speech.LaunchSpeechRecognition; import de.fhdw.app_entwicklung.chatgpt.speech.TextToSpeechTool; @@ -36,7 +36,8 @@ public class MainFragment extends Fragment { private final ActivityResultLauncher getTextFromSpeech = registerForActivityResult( new LaunchSpeechRecognition(), query -> { - Message userMessage = new Message(Author.User, query); + Message userMessage = new Message(Author.User, query); + chat.addMessage(new Message(Author.System, prefs.getChatgptLanguage())); chat.addMessage(userMessage); if (chat.getMessages().size() > 1) { getTextView().append(CHAT_SEPARATOR); @@ -46,7 +47,7 @@ public class MainFragment extends Fragment { MainActivity.backgroundExecutorService.execute(() -> { String apiToken = prefs.getApiToken(); - IChatGpt chatGpt = new MockChatGpt(apiToken); + IChatGpt chatGpt = new ChatGpt(apiToken); String answer = chatGpt.getChatCompletion(chat); Message answerMessage = new Message(Author.Assistant, answer); @@ -75,17 +76,20 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat super.onViewCreated(view, savedInstanceState); prefs = new PrefsFacade(requireContext()); - textToSpeech = new TextToSpeechTool(requireContext(), Locale.GERMAN); + textToSpeech = new TextToSpeechTool(requireContext(), prefs.getLocale()); chat = new Chat(); if (savedInstanceState != null) { chat = savedInstanceState.getParcelable(EXTRA_DATA_CHAT); + } else { + chat = createNewChat(); } getAskButton().setOnClickListener(v -> - getTextFromSpeech.launch(new LaunchSpeechRecognition.SpeechRecognitionArgs(Locale.GERMAN))); + getTextFromSpeech.launch(new LaunchSpeechRecognition.SpeechRecognitionArgs(prefs.getLocale()))); getResetButton().setOnClickListener(v -> { - chat = new Chat(); + chat = createNewChat(); updateTextView(); + }); updateTextView(); } @@ -111,9 +115,9 @@ public void onDestroy() { super.onDestroy(); } - private void updateTextView() { + public void updateTextView() { getTextView().setText(""); - List messages = chat.getMessages(); + List messages = chat.getMessages().stream().filter(message -> message.author != Author.System).collect(Collectors.toList()); if (!messages.isEmpty()) { getTextView().append(toString(messages.get(0))); for (int i = 1; i < messages.size(); i++) { @@ -132,6 +136,11 @@ private CharSequence toString(Message message) { return message.message; } + + private Chat createNewChat() { + Chat chat = new Chat(); + return chat; + } private TextView getTextView() { //noinspection ConstantConditions return getView().findViewById(R.id.textView); @@ -151,5 +160,11 @@ private ScrollView getScrollView() { //noinspection ConstantConditions return getView().findViewById(R.id.scrollview); } + public void resetChat(){ + getResetButton().setOnClickListener(v -> { + chat = createNewChat(); + updateTextView(); + }); + } } \ No newline at end of file diff --git a/app/src/main/java/de/fhdw/app_entwicklung/chatgpt/PrefsFacade.java b/app/src/main/java/de/fhdw/app_entwicklung/chatgpt/PrefsFacade.java index 58e130d..36c8f6e 100644 --- a/app/src/main/java/de/fhdw/app_entwicklung/chatgpt/PrefsFacade.java +++ b/app/src/main/java/de/fhdw/app_entwicklung/chatgpt/PrefsFacade.java @@ -5,10 +5,13 @@ import androidx.annotation.NonNull; import androidx.preference.PreferenceManager; -public class PrefsFacade { +import java.util.Locale; + +public class PrefsFacade { private final Context context; + public PrefsFacade(@NonNull Context context) { this.context = context; } @@ -17,4 +20,37 @@ public String getApiToken() { return PreferenceManager.getDefaultSharedPreferences(context).getString("api_token", ""); } + public Locale getLocale() { + String language = PreferenceManager.getDefaultSharedPreferences(context).getString("language", "de"); + switch (language) { + case "de": + return Locale.GERMAN; + case "en": + return Locale.ENGLISH; + case "ita": + return Locale.ITALIAN; + case "franc": + return Locale.FRANCE; + default: + throw new RuntimeException("Local not supported: " + language); + } + } + + public String getChatgptLanguage() { + String chatgpt_language = PreferenceManager.getDefaultSharedPreferences(context).getString + ("chatgpt_language", "English"); + switch(chatgpt_language) { + case "German": + return "Übersetzt mir das auf deutsch:"; + case "English": + return "Translate it in English:"; + case "Italian": + return "Translate the following to italy:"; + case "French": + return "Translate the following to france:"; + default: + throw new RuntimeException("Output Language not supported: " + chatgpt_language); + } + } + } \ No newline at end of file diff --git a/app/src/main/java/de/fhdw/app_entwicklung/chatgpt/openai/MockChatGpt.java b/app/src/main/java/de/fhdw/app_entwicklung/chatgpt/openai/MockChatGpt.java index 85cc01e..cd1235b 100644 --- a/app/src/main/java/de/fhdw/app_entwicklung/chatgpt/openai/MockChatGpt.java +++ b/app/src/main/java/de/fhdw/app_entwicklung/chatgpt/openai/MockChatGpt.java @@ -2,25 +2,13 @@ import androidx.annotation.NonNull; -import java.util.concurrent.ThreadLocalRandom; - import de.fhdw.app_entwicklung.chatgpt.model.Chat; public class MockChatGpt implements IChatGpt { - /** @noinspection unused*/ - public MockChatGpt(String apiToken) { - // ignore... - } - @Override public String getChatCompletion(@NonNull Chat chat) { - return MESSAGES[ThreadLocalRandom.current().nextInt(0, MESSAGES.length)]; - } - public static final String[] MESSAGES = { - "Let me tell you something, folks. John F. Kennedy, he was a guy. He was a guy, he was a president, and they say he was a pretty good president. People liked him, they really did. But you know what? I think I could have been a much better president than JFK, I really do. I mean, look at what I've done, the things I've accomplished. Nobody's accomplished more than me. So yeah, JFK, he was okay, but I don't think he can hold a candle to me. Not even close.", - "Look, I know a lot of great things, okay? And when it comes to JFK, I know he was born in Massachusetts. He was a Democrat, and let me tell you, I've dealt with a lot of Democrats, folks. They're not always the greatest, believe me. But JFK, he had some charm, some charisma. People were drawn to him. And apparently, he had this thing called the New Frontier, where he wanted to promote social welfare programs and space exploration. But you know what? I'm all about the America First agenda. I'm focused on jobs, the economy, and making America great again. So while JFK may have had his own ideas, I think my vision for the country is much better, folks. Just saying.", - "Let me tell you, I know a lot of things, okay? I've got a tremendous memory, the best memory there is. When it comes to JFK, he was the 35th president of the United States, and he served from 1961 until 1963. Now, during his presidency, there were some major events. There was the Cuban Missile Crisis, where he stood up to the Soviets and made it clear that America wouldn't back down. And let me tell you, that was a big deal. People thought we were on the brink of World War III, but JFK, he handled it like a boss. Now, I have to mention something else, folks. Unfortunately, JFK's presidency was cut short. He was assassinated in Dallas, Texas in November 1963. It's a tragic event, no doubt about it. And I know there are a lot of conspiracy theories surrounding his assassination, but hey, I'm not here to delve into that. I'm here to talk about what I know, and what I know is that JFK's presidency, for the short time it lasted, left an impact on this country. Whether you agree with his policies or not, he was a figure that people remember. And that's all I have to say about that." - }; -} \ No newline at end of file + return "test"; + } +} diff --git a/app/src/main/res/drawable/iconapp.xml b/app/src/main/res/drawable/iconapp.xml new file mode 100644 index 0000000..bfef0a2 --- /dev/null +++ b/app/src/main/res/drawable/iconapp.xml @@ -0,0 +1,14 @@ + + + + diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 78a6b27..03d8463 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -3,4 +3,7 @@ Fragen Einstellungen Reset + Übersetzer App + Sprache + Ausgabesprache \ No newline at end of file diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index e5f8fdc..48f9e9d 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -1,2 +1,30 @@ + + + German + English + Italian + French + + + + de + en + ita + franc + + + + German + English + Italian + French + + + + German + English + Italian + French + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 639b292..fb492a9 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -3,4 +3,7 @@ Ask Settings Reset + Translator App + Language + Output Language \ No newline at end of file diff --git a/app/src/main/res/xml/root_preferences.xml b/app/src/main/res/xml/root_preferences.xml index 9c31de1..29de3d4 100644 --- a/app/src/main/res/xml/root_preferences.xml +++ b/app/src/main/res/xml/root_preferences.xml @@ -1,6 +1,23 @@ - + + + + + + -