Skip to content

Commit ddd1f62

Browse files
feat: add tts, intent filter and handle errors
1 parent ca81218 commit ddd1f62

File tree

6 files changed

+80
-21
lines changed

6 files changed

+80
-21
lines changed

.idea/deploymentTargetDropDown.xml

Lines changed: 1 addition & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/src/main/AndroidManifest.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
<uses-permission android:name="android.permission.WRITE_CALENDAR"/>
1212
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
1313

14+
1415
<application
1516
android:allowBackup="true"
1617
android:dataExtractionRules="@xml/data_extraction_rules"
@@ -33,6 +34,11 @@
3334

3435
<category android:name="android.intent.category.LAUNCHER" />
3536
</intent-filter>
37+
<intent-filter>
38+
<action android:name="android.intent.action.SEND" />
39+
<category android:name="android.intent.category.DEFAULT" />
40+
<data android:mimeType="text/plain" />
41+
</intent-filter>
3642
</activity>
3743

3844
<provider

app/src/main/java/com/luka/anidroid/activity/AnimeDetailsActivity.java

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import android.provider.CalendarContract;
2020
import android.provider.MediaStore;
2121
import android.provider.Settings;
22+
import android.speech.tts.TextToSpeech;
2223
import android.util.Log;
2324
import android.view.View;
2425
import android.webkit.URLUtil;
@@ -57,6 +58,7 @@
5758
import java.io.OutputStream;
5859
import java.util.ArrayList;
5960
import java.util.List;
61+
import java.util.Locale;
6062
import java.util.concurrent.ExecutorService;
6163
import java.util.concurrent.Executors;
6264
import java.util.concurrent.TimeUnit;
@@ -74,6 +76,7 @@ public class AnimeDetailsActivity extends AppCompatActivity {
7476
OkHttpClient client = new OkHttpClient();
7577
ObjectMapper objectMapper = new ObjectMapper();
7678
MusicVideoAdapter musicVideoAdapter;
79+
private TextToSpeech textToSpeech;
7780
private static final int WRITE_EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE = 1;
7881
private static final int WRITE_CALENDAR_PERMISSION_REQUEST_CODE = 2;
7982

@@ -86,6 +89,12 @@ protected void onCreate(Bundle savedInstanceState) {
8689
favoritesManager = new FavoritesManager(this);
8790
anime = (Anime) getIntent().getSerializableExtra("anime");
8891

92+
textToSpeech = new TextToSpeech(getApplicationContext(), status -> {
93+
if (status != TextToSpeech.ERROR) {
94+
textToSpeech.setLanguage(Locale.US);
95+
}
96+
});
97+
8998
ImageView imageView = findViewById(R.id.anime_image);
9099
imageView.setOnClickListener(new View.OnClickListener() {
91100
@Override
@@ -146,6 +155,16 @@ public void onLoadCleared(@Nullable Drawable placeholder) {
146155
});
147156

148157
TextView descriptionTextView = findViewById(R.id.anime_description);
158+
descriptionTextView.setOnClickListener(v -> {
159+
if (textToSpeech.isSpeaking()) {
160+
textToSpeech.stop();
161+
} else {
162+
String description = descriptionTextView.getText().toString();
163+
textToSpeech.setLanguage(Locale.US);
164+
textToSpeech.speak(description, TextToSpeech.QUEUE_FLUSH, null, null);
165+
}
166+
});
167+
149168
TextView scoreTextView = findViewById(R.id.anime_score);
150169
scoreTextView.setOnClickListener(new View.OnClickListener() {
151170
@Override
@@ -180,6 +199,15 @@ public void onClick(View v) {
180199
TextView durationTextView = findViewById(R.id.anime_duration);
181200
TextView popularityTextView = findViewById(R.id.anime_popularity);
182201
TextView titleNativeTextView = findViewById(R.id.anime_title_native);
202+
titleNativeTextView.setOnClickListener(v -> {
203+
if (textToSpeech.isSpeaking()) {
204+
textToSpeech.stop();
205+
} else {
206+
String titleNative = titleNativeTextView.getText().toString();
207+
textToSpeech.setLanguage(Locale.JAPANESE);
208+
textToSpeech.speak(titleNative, TextToSpeech.QUEUE_FLUSH, null, null);
209+
}
210+
});
183211
TextView seasonTextView = findViewById(R.id.anime_season);
184212
TextView statusTextView = findViewById(R.id.anime_status);
185213
TextView typeTextView = findViewById(R.id.anime_type);
@@ -276,6 +304,11 @@ private void fetchMusicVideos(int id) {
276304
handler.post(() -> {
277305
Toast.makeText(this, "Failed to fetch music videos", Toast.LENGTH_SHORT).show();
278306
});
307+
} catch (Exception e) {
308+
e.printStackTrace();
309+
handler.post(() -> {
310+
Toast.makeText(this, "Failed to fetch music videos", Toast.LENGTH_SHORT).show();
311+
});
279312
}
280313
});
281314
}
@@ -382,4 +415,13 @@ private int getBroadcastDay(String broadcastDay) {
382415
return -1; // Invalid broadcast day
383416
}
384417
}
418+
419+
@Override
420+
protected void onDestroy() {
421+
if (textToSpeech != null) {
422+
textToSpeech.stop();
423+
textToSpeech.shutdown();
424+
}
425+
super.onDestroy();
426+
}
385427
}

app/src/main/java/com/luka/anidroid/activity/MainActivity.java

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
package com.luka.anidroid.activity;
22

3+
import android.content.Intent;
34
import android.hardware.Sensor;
45
import android.hardware.SensorEvent;
56
import android.hardware.SensorEventListener;
67
import android.hardware.SensorManager;
78
import android.os.Bundle;
9+
import android.widget.EditText;
810

911
import androidx.appcompat.app.AppCompatActivity;
1012
import androidx.appcompat.app.AppCompatDelegate;
@@ -30,16 +32,12 @@ public class MainActivity extends AppCompatActivity implements SensorEventListen
3032
@Override
3133
protected void onSaveInstanceState(Bundle outState) {
3234
super.onSaveInstanceState(outState);
33-
// Save the state of your activity or any data you want to retain
34-
// For example, you can save the selected item id of the BottomNavigationView
3535
outState.putInt("selectedItemId", bottomNavigationView.getSelectedItemId());
3636
}
3737

3838
@Override
3939
protected void onRestoreInstanceState(Bundle savedInstanceState) {
4040
super.onRestoreInstanceState(savedInstanceState);
41-
// Restore the saved state of your activity or any data
42-
// For example, you can restore the selected item id of the BottomNavigationView
4341
int selectedItemId = savedInstanceState.getInt("selectedItemId");
4442
bottomNavigationView.setSelectedItemId(selectedItemId);
4543
}
@@ -55,12 +53,22 @@ protected void onCreate(Bundle savedInstanceState) {
5553
setContentView(R.layout.activity_main);
5654

5755
// Set HomeFragment as default fragment
58-
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new HomeFragment()).commit();
56+
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, favoritesFragment).commit();
5957

6058
bottomNavigationView = findViewById(R.id.bottom_navigation);
6159

6260
// Set home item as selected
63-
bottomNavigationView.setSelectedItemId(R.id.navigation_home);
61+
bottomNavigationView.setSelectedItemId(R.id.navigation_favorites);
62+
63+
Intent intent = getIntent();
64+
String action = intent.getAction();
65+
String type = intent.getType();
66+
67+
if (Intent.ACTION_SEND.equals(action) && type != null) {
68+
if ("text/plain".equals(type)) {
69+
handleSendText(intent); // Handle text being sent
70+
}
71+
}
6472

6573
bottomNavigationView.setOnItemSelectedListener(item -> {
6674
Fragment selectedFragment = null;
@@ -114,6 +122,18 @@ public void onSensorChanged(SensorEvent event) {
114122
}
115123
}
116124

125+
void handleSendText(Intent intent) {
126+
String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
127+
if (sharedText != null) {
128+
129+
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, searchFragment).commit();
130+
bottomNavigationView.setSelectedItemId(R.id.action_search);
131+
EditText searchEditText = findViewById(R.id.search_view);
132+
133+
searchFragment.searchAnime(sharedText);
134+
}
135+
}
136+
117137
@Override
118138
public void onAccuracyChanged(Sensor sensor, int accuracy) {
119139

app/src/main/java/com/luka/anidroid/fragment/HomeFragment.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,8 @@ private void fetchAnimeData(List<Anime> animeList, int page) {
112112
jsonArray = new JSONArray(data.toString());
113113
} catch (JSONException e) {
114114
throw new RuntimeException(e);
115+
} catch (NullPointerException e) {
116+
return;
115117
}
116118

117119
for (int i = 0; i < jsonArray.length(); i++) {

app/src/main/java/com/luka/anidroid/fragment/SearchFragment.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ public boolean onQueryTextChange(String newText) {
8383
return view;
8484
}
8585

86-
private void searchAnime(String query) {
86+
public void searchAnime(String query) {
8787
ExecutorService executor = Executors.newSingleThreadExecutor();
8888
Handler handler = new Handler(Looper.getMainLooper());
8989

@@ -111,6 +111,8 @@ private void searchAnime(String query) {
111111
jsonArray = new JSONArray(data.toString());
112112
} catch (JSONException e) {
113113
throw new RuntimeException(e);
114+
} catch (NullPointerException e) {
115+
return;
114116
}
115117

116118
for (int i = 0; i < jsonArray.length(); i++) {

0 commit comments

Comments
 (0)