Google Assistant App Actions for AntennaPod (#4417)
This commit is contained in:
parent
c32239be0e
commit
cd23eccf95
|
@ -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>
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
|
@ -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>
|
||||||
|
|
Loading…
Reference in New Issue