Google Assistant App Actions for AntennaPod (#4417)

This commit is contained in:
Margaret Borowiec 2021-01-24 14:41:55 +00:00 committed by GitHub
parent c32239be0e
commit cd23eccf95
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 113 additions and 2 deletions

View File

@ -84,6 +84,28 @@
android:windowSoftInputMode="stateAlwaysHidden" android:windowSoftInputMode="stateAlwaysHidden"
android:launchMode="singleTask" android:launchMode="singleTask"
android:label="@string/app_name"> android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="antennapod.org"
android:pathPrefix="/deeplink/main"
android:scheme="https" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="antennapod.org"
android:pathPrefix="/deeplink/search"
android:scheme="https" />
</intent-filter>
</activity> </activity>
<activity <activity
@ -312,6 +334,10 @@
android:name="android.support.FILE_PROVIDER_PATHS" android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/> android:resource="@xml/provider_paths"/>
</provider> </provider>
<meta-data
android:name="com.google.android.actions"
android:resource="@xml/actions" />
</application> </application>
</manifest> </manifest>

View File

@ -6,6 +6,7 @@ import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.media.AudioManager; import android.media.AudioManager;
import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
@ -51,6 +52,7 @@ import de.danoeh.antennapod.fragment.FeedItemlistFragment;
import de.danoeh.antennapod.fragment.NavDrawerFragment; import de.danoeh.antennapod.fragment.NavDrawerFragment;
import de.danoeh.antennapod.fragment.PlaybackHistoryFragment; import de.danoeh.antennapod.fragment.PlaybackHistoryFragment;
import de.danoeh.antennapod.fragment.QueueFragment; import de.danoeh.antennapod.fragment.QueueFragment;
import de.danoeh.antennapod.fragment.SearchFragment;
import de.danoeh.antennapod.fragment.SubscriptionFragment; import de.danoeh.antennapod.fragment.SubscriptionFragment;
import de.danoeh.antennapod.fragment.TransitionEffect; import de.danoeh.antennapod.fragment.TransitionEffect;
import de.danoeh.antennapod.preferences.PreferenceUpgrader; import de.danoeh.antennapod.preferences.PreferenceUpgrader;
@ -511,6 +513,8 @@ public class MainActivity extends CastEnabledActivity {
} else if (intent.getBooleanExtra(EXTRA_OPEN_PLAYER, false)) { } else if (intent.getBooleanExtra(EXTRA_OPEN_PLAYER, false)) {
sheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED); sheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
bottomSheetCallback.onSlide(null, 1.0f); bottomSheetCallback.onSlide(null, 1.0f);
} else if (Intent.ACTION_VIEW.equals(intent.getAction())) {
handleDeeplink(intent.getData());
} }
// to avoid handling the intent twice when the configuration changes // to avoid handling the intent twice when the configuration changes
setIntent(new Intent(MainActivity.this, MainActivity.class)); setIntent(new Intent(MainActivity.this, MainActivity.class));
@ -520,6 +524,7 @@ public class MainActivity extends CastEnabledActivity {
protected void onNewIntent(Intent intent) { protected void onNewIntent(Intent intent) {
super.onNewIntent(intent); super.onNewIntent(intent);
setIntent(intent); setIntent(intent);
handleNavIntent();
} }
public Snackbar showSnackbarAbovePlayer(CharSequence text, int duration) { public Snackbar showSnackbarAbovePlayer(CharSequence text, int duration) {
@ -540,6 +545,59 @@ public class MainActivity extends CastEnabledActivity {
return showSnackbarAbovePlayer(getResources().getText(text), duration); return showSnackbarAbovePlayer(getResources().getText(text), duration);
} }
/**
* Handles the deep link incoming via App Actions.
* Performs an in-app search or opens the relevant feature of the app
* depending on the query.
*
* @param uri incoming deep link
*/
private void handleDeeplink(Uri uri) {
if (uri == null || uri.getPath() == null) {
return;
}
Log.d(TAG, "Handling deeplink: " + uri.toString());
switch (uri.getPath()) {
case "/deeplink/search":
String query = uri.getQueryParameter("query");
if (query == null) {
return;
}
this.loadChildFragment(SearchFragment.newInstance(query));
break;
case "/deeplink/main":
String feature = uri.getQueryParameter("page");
if (feature == null) {
return;
}
switch (feature) {
case "DOWNLOADS":
loadFragment(DownloadsFragment.TAG, null);
break;
case "HISTORY":
loadFragment(PlaybackHistoryFragment.TAG, null);
break;
case "EPISODES":
loadFragment(EpisodesFragment.TAG, null);
break;
case "QUEUE":
loadFragment(QueueFragment.TAG, null);
break;
case "SUBSCRIPTIONS":
loadFragment(SubscriptionFragment.TAG, null);
break;
default:
showSnackbarAbovePlayer(getString(R.string.app_action_not_found, feature),
Snackbar.LENGTH_LONG);
return;
}
break;
default:
break;
}
}
//Hardware keyboard support //Hardware keyboard support
@Override @Override
public boolean onKeyUp(int keyCode, KeyEvent event) { public boolean onKeyUp(int keyCode, KeyEvent event) {
@ -592,5 +650,4 @@ public class MainActivity extends CastEnabledActivity {
} }
return super.onKeyUp(keyCode, event); return super.onKeyUp(keyCode, event);
} }
} }

View File

@ -0,0 +1,25 @@
<?xml version ="1.0" encoding ="utf-8"?>
<actions>
<action intentName="actions.intent.OPEN_APP_FEATURE">
<fulfillment urlTemplate="https://antennapod.org/deeplink/main{?page}">
<parameter-mapping intentParameter="feature" urlParameter="page" />
</fulfillment>
<parameter name="feature">
<entity-set-reference entitySetId="featureEntitySet" />
</parameter>
</action>
<action intentName="actions.intent.GET_THING">
<fulfillment urlTemplate="https://antennapod.org/deeplink/search{?query}">
<parameter-mapping intentParameter="thing.name" urlParameter="query"/>
</fulfillment>
</action>
<entity-set entitySetId="featureEntitySet">
<entity identifier="QUEUE" name="@string/queue_label" />
<entity identifier="EPISODES" name="@string/episodes_label" />
<entity identifier="DOWNLOADS" name="@string/downloads_label" />
<entity identifier="SUBSCRIPTIONS" name="@string/subscriptions_label" />
<entity identifier="HISTORY" name="@string/playback_history_label" />
</entity-set>
</actions>

View File

@ -11,6 +11,7 @@
<string name="statistics_label">Statistics</string> <string name="statistics_label">Statistics</string>
<string name="add_feed_label">Add Podcast</string> <string name="add_feed_label">Add Podcast</string>
<string name="episodes_label">Episodes</string> <string name="episodes_label">Episodes</string>
<string name="queue_label">Queue</string>
<string name="all_episodes_short_label">All</string> <string name="all_episodes_short_label">All</string>
<string name="new_episodes_label">New</string> <string name="new_episodes_label">New</string>
<string name="favorite_episodes_label">Favorites</string> <string name="favorite_episodes_label">Favorites</string>
@ -32,6 +33,9 @@
<string name="download_statistics_label">Downloads</string> <string name="download_statistics_label">Downloads</string>
<string name="notification_pref_fragment">Notifications</string> <string name="notification_pref_fragment">Notifications</string>
<!-- Google Assistant -->
<string name="app_action_not_found">\"%1$s\" not found</string>
<!-- Statistics fragment --> <!-- Statistics fragment -->
<string name="total_time_listened_to_podcasts">Total time of episodes played:</string> <string name="total_time_listened_to_podcasts">Total time of episodes played:</string>
<string name="statistics_details_dialog">%1$d out of %2$d episodes started.\n\nPlayed %3$s out of %4$s.</string> <string name="statistics_details_dialog">%1$d out of %2$d episodes started.\n\nPlayed %3$s out of %4$s.</string>
@ -367,7 +371,6 @@
<string name="storage_pref">Storage</string> <string name="storage_pref">Storage</string>
<string name="storage_sum">Episode auto delete, Import, Export</string> <string name="storage_sum">Episode auto delete, Import, Export</string>
<string name="project_pref">Project</string> <string name="project_pref">Project</string>
<string name="queue_label">Queue</string>
<string name="synchronization_pref">Synchronization</string> <string name="synchronization_pref">Synchronization</string>
<string name="synchronization_sum">Synchronize with other devices using gpodder.net</string> <string name="synchronization_sum">Synchronize with other devices using gpodder.net</string>
<string name="automation">Automation</string> <string name="automation">Automation</string>