Merge branch 'develop' into extract-queue-item-view

This commit is contained in:
ByteHamster 2020-02-05 16:51:59 +01:00
commit d74b8d06b2
121 changed files with 1089 additions and 855 deletions

View File

@ -18,8 +18,8 @@ android {
// "1.2.3-SNAPSHOT" -> 1020300
// "1.2.3-RC4" -> 1020304
// "1.2.3" -> 1020395
versionCode 1080008
versionName "1.8.0-RC8"
versionCode 1080195
versionName "1.8.1"
testApplicationId "de.test.antennapod"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
generatedDensities = []

View File

@ -66,8 +66,8 @@ public class SpeedChangeTest {
List<FeedItem> queue = DBReader.getQueue();
PlaybackPreferences.writeMediaPlaying(queue.get(0).getMedia(), PlayerStatus.PAUSED, false);
UserPreferences.setPlaybackSpeedArray(new String[] {"1.00", "2.00", "3.00"});
availableSpeeds = UserPreferences.getPlaybackSpeedArray();
availableSpeeds = new String[] {"1.00", "2.00", "3.00"};
UserPreferences.setPlaybackSpeedArray(availableSpeeds);
EspressoTestUtils.tryKillPlaybackService();
activityRule.launchActivity(new Intent());

View File

@ -64,6 +64,7 @@ public class TextOnlyFeedsTest {
openNavDrawer();
onDrawerItem(withText(feed.getTitle())).perform(scrollTo(), click());
onView(withText(feed.getItemAtIndex(0).getTitle())).perform(click());
onView(isRoot()).perform(waitForView(withText(R.string.mark_read_no_media_label), 3000));
onView(withText(R.string.mark_read_no_media_label)).perform(click());
onView(isRoot()).perform(waitForView(allOf(withText(R.string.mark_read_no_media_label), not(isDisplayed())), 3000));
}

View File

@ -26,7 +26,7 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
/**
* Test class for timeline
* Test class for timeline.
*/
@SmallTest
public class TimelineTest {
@ -34,7 +34,7 @@ public class TimelineTest {
private Context context;
@Before
public void setUp() throws Exception {
public void setUp() {
context = InstrumentationRegistry.getTargetContext();
}
@ -49,128 +49,151 @@ public class TimelineTest {
}
@Test
public void testProcessShownotesAddTimecodeHHMMSSNoChapters() throws Exception {
public void testProcessShownotesAddTimecodeHHMMSSNoChapters() {
final String timeStr = "10:11:12";
final long time = 3600 * 1000 * 10 + 60 * 1000 * 11 + 12 * 1000;
Playable p = newTestPlayable(null, "<p> Some test text with a timecode " + timeStr + " here.</p>", Integer.MAX_VALUE);
Playable p = newTestPlayable(null, "<p> Some test text with a timecode "
+ timeStr + " here.</p>", Integer.MAX_VALUE);
Timeline t = new Timeline(context, p);
String res = t.processShownotes();
checkLinkCorrect(res, new long[]{time}, new String[]{timeStr});
}
@Test
public void testProcessShownotesAddTimecodeHHMMSSMoreThen24HoursNoChapters() throws Exception {
public void testProcessShownotesAddTimecodeHHMMSSMoreThen24HoursNoChapters() {
final String timeStr = "25:00:00";
final long time = 25 * 60 * 60 * 1000;
Playable p = newTestPlayable(null, "<p> Some test text with a timecode " + timeStr + " here.</p>", Integer.MAX_VALUE);
Playable p = newTestPlayable(null, "<p> Some test text with a timecode "
+ timeStr + " here.</p>", Integer.MAX_VALUE);
Timeline t = new Timeline(context, p);
String res = t.processShownotes();
checkLinkCorrect(res, new long[]{time}, new String[]{timeStr});
}
@Test
public void testProcessShownotesAddTimecodeHHMMNoChapters() throws Exception {
public void testProcessShownotesAddTimecodeHHMMNoChapters() {
final String timeStr = "10:11";
final long time = 3600 * 1000 * 10 + 60 * 1000 * 11;
Playable p = newTestPlayable(null, "<p> Some test text with a timecode " + timeStr + " here.</p>", Integer.MAX_VALUE);
Playable p = newTestPlayable(null, "<p> Some test text with a timecode "
+ timeStr + " here.</p>", Integer.MAX_VALUE);
Timeline t = new Timeline(context, p);
String res = t.processShownotes();
checkLinkCorrect(res, new long[]{time}, new String[]{timeStr});
}
@Test
public void testProcessShownotesAddTimecodeMMSSNoChapters() throws Exception {
public void testProcessShownotesAddTimecodeMMSSNoChapters() {
final String timeStr = "10:11";
final long time = 10 * 60 * 1000 + 11 * 1000;
Playable p = newTestPlayable(null, "<p> Some test text with a timecode " + timeStr + " here.</p>", 11 * 60 * 1000);
Playable p = newTestPlayable(null, "<p> Some test text with a timecode "
+ timeStr + " here.</p>", 11 * 60 * 1000);
Timeline t = new Timeline(context, p);
String res = t.processShownotes();
checkLinkCorrect(res, new long[]{time}, new String[]{timeStr});
}
@Test
public void testProcessShownotesAddTimecodeHMMSSNoChapters() throws Exception {
public void testProcessShownotesAddTimecodeHMMSSNoChapters() {
final String timeStr = "2:11:12";
final long time = 2 * 60 * 60 * 1000 + 11 * 60 * 1000 + 12 * 1000;
Playable p = newTestPlayable(null, "<p> Some test text with a timecode " + timeStr + " here.</p>", Integer.MAX_VALUE);
Playable p = newTestPlayable(null, "<p> Some test text with a timecode "
+ timeStr + " here.</p>", Integer.MAX_VALUE);
Timeline t = new Timeline(context, p);
String res = t.processShownotes();
checkLinkCorrect(res, new long[]{time}, new String[]{timeStr});
}
@Test
public void testProcessShownotesAddTimecodeMSSNoChapters() throws Exception {
public void testProcessShownotesAddTimecodeMSSNoChapters() {
final String timeStr = "1:12";
final long time = 60 * 1000 + 12 * 1000;
Playable p = newTestPlayable(null, "<p> Some test text with a timecode " + timeStr + " here.</p>", 2 * 60 * 1000);
Playable p = newTestPlayable(null, "<p> Some test text with a timecode "
+ timeStr + " here.</p>", 2 * 60 * 1000);
Timeline t = new Timeline(context, p);
String res = t.processShownotes();
checkLinkCorrect(res, new long[]{time}, new String[]{timeStr});
}
@Test
public void testProcessShownotesAddTimecodeMultipleFormatsNoChapters() throws Exception {
final String[] timeStrings = new String[]{ "10:12", "1:10:12" };
Playable p = newTestPlayable(null, "<p> Some test text with a timecode " + timeStrings[0] + " here. Hey look another one " + timeStrings[1] + " here!</p>", 2 * 60 * 60 * 1000);
public void testProcessShownotesAddNoTimecodeDuration() {
final String timeStr = "2:11:12";
final int time = 2 * 60 * 60 * 1000 + 11 * 60 * 1000 + 12 * 1000;
String originalText = "<p> Some test text with a timecode " + timeStr + " here.</p>";
Playable p = newTestPlayable(null, originalText, time);
Timeline t = new Timeline(context, p);
String res = t.processShownotes();
checkLinkCorrect(res, new long[]{ 10 * 60 * 1000 + 12 * 1000, 60 * 60 * 1000 + 10 * 60 * 1000 + 12 * 1000 }, timeStrings);
Document d = Jsoup.parse(res);
assertEquals("Should not parse time codes that equal duration", 0, d.body().getElementsByTag("a").size());
}
@Test
public void testProcessShownotesAddTimecodeMultipleShortFormatNoChapters() throws Exception {
public void testProcessShownotesAddTimecodeMultipleFormatsNoChapters() {
final String[] timeStrings = new String[]{ "10:12", "1:10:12" };
Playable p = newTestPlayable(null, "<p> Some test text with a timecode "
+ timeStrings[0] + " here. Hey look another one " + timeStrings[1] + " here!</p>", 2 * 60 * 60 * 1000);
Timeline t = new Timeline(context, p);
String res = t.processShownotes();
checkLinkCorrect(res, new long[]{ 10 * 60 * 1000 + 12 * 1000,
60 * 60 * 1000 + 10 * 60 * 1000 + 12 * 1000 }, timeStrings);
}
@Test
public void testProcessShownotesAddTimecodeMultipleShortFormatNoChapters() {
// One of these timecodes fits as HH:MM and one does not so both should be parsed as MM:SS.
final String[] timeStrings = new String[]{ "10:12", "2:12" };
Playable p = newTestPlayable(null, "<p> Some test text with a timecode " + timeStrings[0] + " here. Hey look another one " + timeStrings[1] + " here!</p>", 3 * 60 * 60 * 1000);
Playable p = newTestPlayable(null, "<p> Some test text with a timecode "
+ timeStrings[0] + " here. Hey look another one " + timeStrings[1] + " here!</p>", 3 * 60 * 60 * 1000);
Timeline t = new Timeline(context, p);
String res = t.processShownotes();
checkLinkCorrect(res, new long[]{ 10 * 60 * 1000 + 12 * 1000, 2 * 60 * 1000 + 12 * 1000 }, timeStrings);
}
@Test
public void testProcessShownotesAddTimecodeParentheses() throws Exception {
public void testProcessShownotesAddTimecodeParentheses() {
final String timeStr = "10:11";
final long time = 3600 * 1000 * 10 + 60 * 1000 * 11;
Playable p = newTestPlayable(null, "<p> Some test text with a timecode (" + timeStr + ") here.</p>", Integer.MAX_VALUE);
Playable p = newTestPlayable(null, "<p> Some test text with a timecode ("
+ timeStr + ") here.</p>", Integer.MAX_VALUE);
Timeline t = new Timeline(context, p);
String res = t.processShownotes();
checkLinkCorrect(res, new long[]{time}, new String[]{timeStr});
}
@Test
public void testProcessShownotesAddTimecodeBrackets() throws Exception {
public void testProcessShownotesAddTimecodeBrackets() {
final String timeStr = "10:11";
final long time = 3600 * 1000 * 10 + 60 * 1000 * 11;
Playable p = newTestPlayable(null, "<p> Some test text with a timecode [" + timeStr + "] here.</p>", Integer.MAX_VALUE);
Playable p = newTestPlayable(null, "<p> Some test text with a timecode ["
+ timeStr + "] here.</p>", Integer.MAX_VALUE);
Timeline t = new Timeline(context, p);
String res = t.processShownotes();
checkLinkCorrect(res, new long[]{time}, new String[]{timeStr});
}
@Test
public void testProcessShownotesAddTimecodeAngleBrackets() throws Exception {
public void testProcessShownotesAddTimecodeAngleBrackets() {
final String timeStr = "10:11";
final long time = 3600 * 1000 * 10 + 60 * 1000 * 11;
Playable p = newTestPlayable(null, "<p> Some test text with a timecode <" + timeStr + "> here.</p>", Integer.MAX_VALUE);
Playable p = newTestPlayable(null, "<p> Some test text with a timecode <"
+ timeStr + "> here.</p>", Integer.MAX_VALUE);
Timeline t = new Timeline(context, p);
String res = t.processShownotes();
checkLinkCorrect(res, new long[]{time}, new String[]{timeStr});
}
@Test
public void testProcessShownotesAndInvalidTimecode() throws Exception {
public void testProcessShownotesAndInvalidTimecode() {
final String[] timeStrs = new String[] {"2:1", "0:0", "000", "00", "00:000"};
StringBuilder shownotes = new StringBuilder("<p> Some test text with timecodes ");
@ -197,14 +220,15 @@ public class TimelineTest {
assertTrue(href.endsWith(String.valueOf(timecodes[countedLinks])));
assertEquals(timecodeStr[countedLinks], text);
countedLinks++;
assertTrue("Contains too many links: " + countedLinks + " > " + timecodes.length, countedLinks <= timecodes.length);
assertTrue("Contains too many links: " + countedLinks + " > "
+ timecodes.length, countedLinks <= timecodes.length);
}
}
assertEquals(timecodes.length, countedLinks);
}
@Test
public void testIsTimecodeLink() throws Exception {
public void testIsTimecodeLink() {
assertFalse(Timeline.isTimecodeLink(null));
assertFalse(Timeline.isTimecodeLink("http://antennapod/timecode/123123"));
assertFalse(Timeline.isTimecodeLink("antennapod://timecode/"));
@ -215,7 +239,7 @@ public class TimelineTest {
}
@Test
public void testGetTimecodeLinkTime() throws Exception {
public void testGetTimecodeLinkTime() {
assertEquals(-1, Timeline.getTimecodeLinkTime(null));
assertEquals(-1, Timeline.getTimecodeLinkTime("http://timecode/123"));
assertEquals(123, Timeline.getTimecodeLinkTime("antennapod://timecode/123"));

View File

@ -33,6 +33,7 @@
android:label="@string/app_name"
android:backupAgent=".core.backup.OpmlBackupAgent"
android:restoreAnyVersion="true"
android:theme="@style/Theme.AntennaPod.Splash"
android:usesCleartextTraffic="true"
android:logo="@mipmap/ic_launcher">
@ -53,12 +54,7 @@
<activity
android:name=".activity.SplashActivity"
android:label="@string/app_name"
android:configChanges="keyboardHidden|orientation|screenSize"
android:theme="@style/Theme.AntennaPod.Dark.Splash">
<!-- android:launchMode="singleTask" removed for #2948, so that
when app is launched again, the app will go to the last activity users use
(if the app has been used recently, e.g., last 30 minutes),
rather than always go to MainActivity (launched by SplashActivity here) -->
android:configChanges="keyboardHidden|orientation|screenSize">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>

View File

@ -35,7 +35,9 @@ public class CrashReportWriter implements Thread.UncaughtExceptionHandler {
PrintWriter out = null;
try {
out = new PrintWriter(new FileWriter(path));
out.println(getSystemInfo());
out.println("[ Crash info ]");
out.println("Time: " + new SimpleDateFormat("dd-MM-yyyy HH:mm:ss", Locale.getDefault()).format(new Date()));
out.println("AntennaPod version: " + BuildConfig.VERSION_NAME);
out.println();
out.println("[ StackTrace ]");
ex.printStackTrace(out);
@ -54,7 +56,6 @@ public class CrashReportWriter implements Thread.UncaughtExceptionHandler {
"\nAntennaPod version: " + BuildConfig.VERSION_NAME +
"\nModel: " + Build.MODEL +
"\nDevice: " + Build.DEVICE +
"\nProduct: " + Build.PRODUCT +
"\nTime: " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()).format(new Date()) + "\n";
"\nProduct: " + Build.PRODUCT;
}
}

View File

@ -1,28 +1,25 @@
package de.danoeh.antennapod.activity;
import android.content.Intent;
import androidx.core.view.ViewCompat;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.Locale;
import java.util.concurrent.atomic.AtomicBoolean;
import de.danoeh.antennapod.core.feed.MediaType;
import de.danoeh.antennapod.core.preferences.PlaybackPreferences;
import de.danoeh.antennapod.core.feed.util.PlaybackSpeedUtils;
import de.danoeh.antennapod.core.preferences.PlaybackPreferences;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.service.playback.PlaybackService;
import de.danoeh.antennapod.dialog.VariableSpeedDialog;
import java.text.DecimalFormat;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* Activity for playing audio files.
*/
public class AudioplayerActivity extends MediaplayerInfoActivity {
private static final String TAG = "AudioPlayerActivity";
private static final float EPSILON = 0.001f;
private final AtomicBoolean isSetup = new AtomicBoolean(false);
@ -33,8 +30,8 @@ public class AudioplayerActivity extends MediaplayerInfoActivity {
playExternalMedia(getIntent(), MediaType.AUDIO);
} else if (PlaybackService.isCasting()) {
Intent intent = PlaybackService.getPlayerActivityIntent(this);
if (intent.getComponent() != null &&
!intent.getComponent().getClassName().equals(AudioplayerActivity.class.getName())) {
if (intent.getComponent() != null
&& !intent.getComponent().getClassName().equals(AudioplayerActivity.class.getName())) {
saveCurrentFragment();
finish();
startActivity(intent);
@ -57,7 +54,7 @@ public class AudioplayerActivity extends MediaplayerInfoActivity {
@Override
protected void updatePlaybackSpeedButton() {
if(butPlaybackSpeed == null) {
if (butPlaybackSpeed == null) {
return;
}
if (controller == null) {
@ -66,14 +63,14 @@ public class AudioplayerActivity extends MediaplayerInfoActivity {
return;
}
updatePlaybackSpeedButtonText();
ViewCompat.setAlpha(butPlaybackSpeed, controller.canSetPlaybackSpeed() ? 1.0f : 0.5f);
butPlaybackSpeed.setAlpha(controller.canSetPlaybackSpeed() ? 1.0f : 0.5f);
butPlaybackSpeed.setVisibility(View.VISIBLE);
txtvPlaybackSpeed.setVisibility(View.VISIBLE);
}
@Override
protected void updatePlaybackSpeedButtonText() {
if(butPlaybackSpeed == null) {
if (butPlaybackSpeed == null) {
return;
}
if (controller == null) {
@ -82,7 +79,7 @@ public class AudioplayerActivity extends MediaplayerInfoActivity {
return;
}
float speed = 1.0f;
if(controller.canSetPlaybackSpeed()) {
if (controller.canSetPlaybackSpeed()) {
speed = PlaybackSpeedUtils.getCurrentPlaybackSpeed(controller.getMedia());
}
String speedStr = new DecimalFormat("0.00").format(speed);
@ -91,54 +88,40 @@ public class AudioplayerActivity extends MediaplayerInfoActivity {
@Override
protected void setupGUI() {
if(isSetup.getAndSet(true)) {
if (isSetup.getAndSet(true)) {
return;
}
super.setupGUI();
if(butCastDisconnect != null) {
if (butCastDisconnect != null) {
butCastDisconnect.setVisibility(View.GONE);
}
if(butPlaybackSpeed != null) {
if (butPlaybackSpeed != null) {
butPlaybackSpeed.setOnClickListener(v -> {
if (controller == null) {
return;
}
if (controller.canSetPlaybackSpeed()) {
String[] availableSpeeds = UserPreferences.getPlaybackSpeedArray();
DecimalFormatSymbols format = new DecimalFormatSymbols(Locale.US);
format.setDecimalSeparator('.');
float[] availableSpeeds = UserPreferences.getPlaybackSpeedArray();
float currentSpeed = controller.getCurrentPlaybackSpeedMultiplier();
float currentSpeedValue = controller.getCurrentPlaybackSpeedMultiplier();
String currentSpeed = new DecimalFormat("0.00", format).format(currentSpeedValue);
int newSpeedIndex = 0;
while (newSpeedIndex < availableSpeeds.length
&& availableSpeeds[newSpeedIndex] < currentSpeed + EPSILON) {
newSpeedIndex++;
}
// Provide initial value in case the speed list has changed
// out from under us
// and our current speed isn't in the new list
String newSpeed;
if (availableSpeeds.length > 0) {
float newSpeed;
if (availableSpeeds.length == 0) {
newSpeed = 1.0f;
} else if (newSpeedIndex == availableSpeeds.length) {
newSpeed = availableSpeeds[0];
} else {
newSpeed = "1.00";
newSpeed = availableSpeeds[newSpeedIndex];
}
for (int i = 0; i < availableSpeeds.length; i++) {
if (availableSpeeds[i].equals(currentSpeed)) {
if (i == availableSpeeds.length - 1) {
newSpeed = availableSpeeds[0];
} else {
newSpeed = availableSpeeds[i + 1];
}
break;
}
}
try {
PlaybackPreferences.setCurrentlyPlayingTemporaryPlaybackSpeed(Float.parseFloat(newSpeed));
} catch (NumberFormatException e) {
// Well this was awkward...
}
PlaybackPreferences.setCurrentlyPlayingTemporaryPlaybackSpeed(newSpeed);
UserPreferences.setPlaybackSpeed(newSpeed);
controller.setPlaybackSpeed(Float.parseFloat(newSpeed));
controller.setPlaybackSpeed(newSpeed);
onPositionObserverUpdate();
} else {
VariableSpeedDialog.showGetPluginDialog(this);

View File

@ -30,16 +30,17 @@ public class BugReportActivity extends AppCompatActivity {
getSupportActionBar().setDisplayShowHomeEnabled(true);
setContentView(R.layout.bug_report);
TextView crashDetailsText = findViewById(R.id.crash_report_logs);
String crashDetailsText = CrashReportWriter.getSystemInfo() + "\n\n";
TextView crashDetailsTextView = findViewById(R.id.crash_report_logs);
try {
File crashFile = CrashReportWriter.getFile();
String crashReportContent = IOUtils.toString(new FileInputStream(crashFile), Charset.forName("UTF-8"));
crashDetailsText.setText(crashReportContent);
crashDetailsText += IOUtils.toString(new FileInputStream(crashFile), Charset.forName("UTF-8"));
} catch (IOException e) {
e.printStackTrace();
crashDetailsText.setText("No crash report recorded\n" + CrashReportWriter.getSystemInfo());
crashDetailsText += "No crash report recorded";
}
crashDetailsTextView.setText(crashDetailsText);
findViewById(R.id.btn_open_bug_tracker).setOnClickListener(v -> {
IntentUtils.openInBrowser(BugReportActivity.this, "https://github.com/AntennaPod/AntennaPod/issues");
@ -47,7 +48,7 @@ public class BugReportActivity extends AppCompatActivity {
findViewById(R.id.btn_copy_log).setOnClickListener(v -> {
ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText(getString(R.string.bug_report_title), crashDetailsText.getText());
ClipData clip = ClipData.newPlainText(getString(R.string.bug_report_title), crashDetailsTextView.getText());
clipboard.setPrimaryClip(clip);
Snackbar.make(findViewById(android.R.id.content), R.string.copied_to_clipboard, Snackbar.LENGTH_SHORT).show();
});

View File

@ -274,7 +274,7 @@ public abstract class MediaplayerInfoActivity extends MediaplayerActivity implem
@Override
boolean loadMediaInfo() {
if (controller != null) {
if (controller != null && controller.getMedia() != null) {
List<Chapter> chapters = controller.getMedia().getChapters();
boolean hasChapters = chapters != null && !chapters.isEmpty();
pageIndicator.setDisabledPage(hasChapters ? -1 : 2);

View File

@ -7,11 +7,6 @@ import android.content.Intent;
import android.graphics.LightingColorFilter;
import android.os.Build;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.UiThread;
import androidx.core.app.NavUtils;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import android.text.TextUtils;
import android.util.Log;
import android.view.MenuItem;
@ -24,26 +19,18 @@ import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.Spinner;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.UiThread;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.NavUtils;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import de.danoeh.antennapod.core.event.FeedListUpdateEvent;
import org.apache.commons.lang3.StringUtils;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.adapter.FeedItemlistDescriptionAdapter;
import de.danoeh.antennapod.core.dialog.DownloadRequestErrorDialogCreator;
import de.danoeh.antennapod.core.event.DownloadEvent;
import de.danoeh.antennapod.core.event.FeedListUpdateEvent;
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedPreferences;
@ -73,6 +60,16 @@ import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import org.apache.commons.lang3.StringUtils;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* Downloads a feed from a feed URL and parses it. Subclasses can display the
@ -368,8 +365,6 @@ public class OnlineFeedViewActivity extends AppCompatActivity {
findViewById(R.id.feedDisplay).setVisibility(View.VISIBLE);
this.feed = feed;
this.selectedDownloadUrl = feed.getDownload_url();
listView.setSelector(android.R.color.transparent);
listView.setAdapter(new FeedItemlistDescriptionAdapter(this, 0, feed.getItems()));
ImageView cover = findViewById(R.id.imgvCover);
ImageView headerBackground = findViewById(R.id.imgvBackground);
@ -382,6 +377,9 @@ public class OnlineFeedViewActivity extends AppCompatActivity {
View header = View.inflate(this, R.layout.onlinefeedview_header, null);
listView.addHeaderView(header);
listView.setSelector(android.R.color.transparent);
listView.setAdapter(new FeedItemlistDescriptionAdapter(this, 0, feed.getItems()));
TextView description = header.findViewById(R.id.txtvDescription);
subscribeButton = findViewById(R.id.butSubscribe);

View File

@ -9,15 +9,12 @@ import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.feed.FeedComponent;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.SearchResult;
import de.danoeh.antennapod.core.glide.ApGlideSettings;
/**
@ -40,7 +37,7 @@ public class SearchlistAdapter extends BaseAdapter {
}
@Override
public SearchResult getItem(int position) {
public FeedComponent getItem(int position) {
return itemAccess.getItem(position);
}
@ -52,8 +49,7 @@ public class SearchlistAdapter extends BaseAdapter {
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final Holder holder;
SearchResult result = getItem(position);
FeedComponent component = result.getComponent();
FeedComponent component = getItem(position);
// Inflate Layout
if (convertView == null) {
@ -93,7 +89,7 @@ public class SearchlistAdapter extends BaseAdapter {
} else if (component.getClass() == FeedItem.class) {
final FeedItem item = (FeedItem) component;
holder.title.setText(item.getTitle());
holder.subtitle.setText(result.getLocation().getDescription());
holder.subtitle.setVisibility(View.VISIBLE);
convertView.setAlpha(item.isPlayed() ? 0.5f : 1.0f);
@ -121,7 +117,7 @@ public class SearchlistAdapter extends BaseAdapter {
public interface ItemAccess {
int getCount();
SearchResult getItem(int position);
FeedComponent getItem(int position);
}
}

View File

@ -34,7 +34,7 @@ public abstract class ItemActionButton {
}
@NonNull
public static ItemActionButton forItem(@NonNull FeedItem item, boolean isInQueue) {
public static ItemActionButton forItem(@NonNull FeedItem item, boolean isInQueue, boolean allowStream) {
final FeedMedia media = item.getMedia();
if (media == null) {
return new MarkAsPlayedActionButton(item);
@ -45,9 +45,10 @@ public abstract class ItemActionButton {
return new PlayActionButton(item);
} else if (isDownloadingMedia) {
return new CancelDownloadActionButton(item);
} else if (UserPreferences.streamOverDownload()) {
} else if (UserPreferences.streamOverDownload() && allowStream) {
return new StreamActionButton(item);
} else if (MobileDownloadHelper.userAllowedMobileDownloads() || !MobileDownloadHelper.userChoseAddToQueue() || isInQueue) {
} else if (MobileDownloadHelper.userAllowedMobileDownloads()
|| !MobileDownloadHelper.userChoseAddToQueue() || isInQueue) {
return new DownloadActionButton(item, isInQueue);
} else {
return new AddToQueueActionButton(item);

View File

@ -10,7 +10,6 @@ import android.widget.CheckBox;
import android.widget.SeekBar;
import android.widget.TextView;
import de.danoeh.antennapod.core.preferences.PlaybackPreferences;
import java.util.Locale;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.feed.util.PlaybackSpeedUtils;
import de.danoeh.antennapod.core.preferences.UserPreferences;
@ -102,13 +101,12 @@ public class PlaybackControlsDialog extends DialogFragment {
if (controller != null && controller.canSetPlaybackSpeed()) {
float playbackSpeed = (progress + 10) / 20.0f;
controller.setPlaybackSpeed(playbackSpeed);
String speedPref = String.format(Locale.US, "%.2f", playbackSpeed);
PlaybackPreferences.setCurrentlyPlayingTemporaryPlaybackSpeed(playbackSpeed);
if (isPlayingVideo) {
UserPreferences.setVideoPlaybackSpeed(speedPref);
UserPreferences.setVideoPlaybackSpeed(playbackSpeed);
} else {
UserPreferences.setPlaybackSpeed(speedPref);
UserPreferences.setPlaybackSpeed(playbackSpeed);
}
String speedStr = String.format("%.2fx", playbackSpeed);

View File

@ -6,8 +6,12 @@ import androidx.appcompat.app.AlertDialog;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
public class VariableSpeedDialog {
@ -43,15 +47,22 @@ public class VariableSpeedDialog {
}
private static void showSpeedSelectorDialog(final Context context) {
DecimalFormatSymbols format = new DecimalFormatSymbols(Locale.US);
format.setDecimalSeparator('.');
DecimalFormat speedFormat = new DecimalFormat("0.00", format);
final String[] speedValues = context.getResources().getStringArray(
R.array.playback_speed_values);
// According to Java spec these get initialized to false on creation
final boolean[] speedChecked = new boolean[speedValues.length];
// Build the "isChecked" array so that multiChoice dialog is
// populated correctly
List<String> selectedSpeedList = Arrays.asList(UserPreferences
.getPlaybackSpeedArray());
// Build the "isChecked" array so that multiChoice dialog is populated correctly
List<String> selectedSpeedList = new ArrayList<>();
float[] selectedSpeeds = UserPreferences.getPlaybackSpeedArray();
for (float speed : selectedSpeeds) {
selectedSpeedList.add(speedFormat.format(speed));
}
for (int i = 0; i < speedValues.length; i++) {
speedChecked[i] = selectedSpeedList.contains(speedValues[i]);
}

View File

@ -1,6 +1,8 @@
package de.danoeh.antennapod.discovery;
import android.content.Context;
import android.util.Log;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.ClientConfig;
import de.danoeh.antennapod.core.service.download.AntennapodHttpClient;
@ -21,6 +23,7 @@ import java.util.List;
import java.util.Locale;
public class ItunesTopListLoader {
private static final String TAG = "ITunesTopListLoader";
private final Context context;
public ItunesTopListLoader(Context context) {
@ -29,11 +32,11 @@ public class ItunesTopListLoader {
public Single<List<PodcastSearchResult>> loadToplist(int limit) {
return Single.create((SingleOnSubscribe<List<PodcastSearchResult>>) emitter -> {
String lang = Locale.getDefault().getLanguage();
String country = Locale.getDefault().getCountry();
OkHttpClient client = AntennapodHttpClient.getHttpClient();
String feedString;
try {
feedString = getTopListFeed(client, lang, limit);
feedString = getTopListFeed(client, country, limit);
} catch (IOException e) {
feedString = getTopListFeed(client, "us", limit);
}
@ -74,11 +77,12 @@ public class ItunesTopListLoader {
.observeOn(AndroidSchedulers.mainThread());
}
private String getTopListFeed(OkHttpClient client, String language, int limit) throws IOException {
String url = "https://itunes.apple.com/%s/rss/toppodcasts/limit="+limit+"/explicit=true/json";
private String getTopListFeed(OkHttpClient client, String country, int limit) throws IOException {
String url = "https://itunes.apple.com/%s/rss/toppodcasts/limit=" + limit + "/explicit=true/json";
Log.d(TAG, "Feed URL " + String.format(url, country));
Request.Builder httpReq = new Request.Builder()
.header("User-Agent", ClientConfig.USER_AGENT)
.url(String.format(url, language));
.url(String.format(url, country));
try (Response response = client.newCall(httpReq.build()).execute()) {
if (response.isSuccessful()) {
@ -95,7 +99,7 @@ public class ItunesTopListLoader {
JSONArray entries = feed.getJSONArray("entry");
List<PodcastSearchResult> results = new ArrayList<>();
for (int i=0; i < entries.length(); i++) {
for (int i = 0; i < entries.length(); i++) {
JSONObject json = entries.getJSONObject(i);
results.add(PodcastSearchResult.fromItunesToplist(json));
}

View File

@ -169,7 +169,7 @@ public abstract class EpisodesListFragment extends Fragment {
MenuItem searchItem = menu.findItem(R.id.action_search);
final SearchView sv = (SearchView) MenuItemCompat.getActionView(searchItem);
sv.setQueryHint(getString(R.string.search_hint));
sv.setQueryHint(getString(R.string.search_label));
sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String s) {

View File

@ -179,7 +179,7 @@ public class FeedItemlistFragment extends ListFragment {
MenuItem searchItem = menu.findItem(R.id.action_search);
final SearchView sv = (SearchView) MenuItemCompat.getActionView(searchItem);
sv.setQueryHint(getString(R.string.search_hint));
sv.setQueryHint(getString(R.string.search_label));
searchItem.setOnActionExpandListener(new MenuItem.OnActionExpandListener() {
@Override
public boolean onMenuItemActionExpand(MenuItem item) {

View File

@ -117,8 +117,7 @@ public class FeedSettingsFragment extends PreferenceFragmentCompat {
private void setupPlaybackSpeedPreference() {
ListPreference feedPlaybackSpeedPreference = findPreference(PREF_FEED_PLAYBACK_SPEED);
String[] speeds = UserPreferences.getPlaybackSpeedArray();
final String[] speeds = getResources().getStringArray(R.array.playback_speed_values);
String[] values = new String[speeds.length + 1];
values[0] = SPEED_FORMAT.format(SPEED_USE_GLOBAL);

View File

@ -94,8 +94,12 @@ public class ItemFragment extends Fragment {
private ImageView imgvCover;
private ProgressBar progbarDownload;
private ProgressBar progbarLoading;
private Button butAction1;
private Button butAction2;
private TextView butAction1Text;
private TextView butAction2Text;
private ImageView butAction1Icon;
private ImageView butAction2Icon;
private View butAction1;
private View butAction2;
private Disposable disposable;
private PlaybackController controller;
@ -141,12 +145,16 @@ public class ItemFragment extends Fragment {
progbarLoading = layout.findViewById(R.id.progbarLoading);
butAction1 = layout.findViewById(R.id.butAction1);
butAction2 = layout.findViewById(R.id.butAction2);
butAction1Icon = layout.findViewById(R.id.butAction1Icon);
butAction2Icon = layout.findViewById(R.id.butAction2Icon);
butAction1Text = layout.findViewById(R.id.butAction1Text);
butAction2Text = layout.findViewById(R.id.butAction2Text);
butAction1.setOnClickListener(v -> {
if (item == null) {
return;
}
ItemActionButton actionButton = ItemActionButton.forItem(item, item.isTagged(FeedItem.TAG_QUEUE));
ItemActionButton actionButton = ItemActionButton.forItem(item, item.isTagged(FeedItem.TAG_QUEUE), false);
actionButton.onClick(getActivity());
FeedMedia media = item.getMedia();
@ -267,22 +275,22 @@ public class ItemFragment extends Fragment {
}
FeedMedia media = item.getMedia();
@AttrRes int butAction1Icon = 0;
@StringRes int butAction1Text = 0;
@AttrRes int butAction2Icon = 0;
@StringRes int butAction2Text = 0;
@AttrRes int butAction1IconRes = 0;
@StringRes int butAction1TextRes = 0;
@AttrRes int butAction2IconRes = 0;
@StringRes int butAction2TextRes = 0;
if (media == null) {
if (!item.isPlayed()) {
butAction1Icon = R.attr.navigation_accept;
butAction1IconRes = R.attr.navigation_accept;
if (item.hasMedia()) {
butAction1Text = R.string.mark_read_label;
butAction1TextRes = R.string.mark_read_label;
} else {
butAction1Text = R.string.mark_read_no_media_label;
butAction1TextRes = R.string.mark_read_no_media_label;
}
}
if (item.getLink() != null) {
butAction2Icon = R.attr.location_web_site;
butAction2Text = R.string.visit_website_label;
butAction2IconRes = R.attr.location_web_site;
butAction2TextRes = R.string.visit_website_label;
}
} else {
if (media.getDuration() > 0) {
@ -290,40 +298,40 @@ public class ItemFragment extends Fragment {
}
boolean isDownloading = DownloadRequester.getInstance().isDownloadingFile(media);
if (!media.isDownloaded()) {
butAction2Icon = R.attr.action_stream;
butAction2Text = R.string.stream_label;
butAction2IconRes = R.attr.action_stream;
butAction2TextRes = R.string.stream_label;
} else {
butAction2Icon = R.attr.content_discard;
butAction2Text = R.string.delete_label;
butAction2IconRes = R.attr.content_discard;
butAction2TextRes = R.string.delete_label;
}
if (isDownloading) {
butAction1Icon = R.attr.navigation_cancel;
butAction1Text = R.string.cancel_label;
butAction1IconRes = R.attr.navigation_cancel;
butAction1TextRes = R.string.cancel_label;
} else if (media.isDownloaded()) {
butAction1Icon = R.attr.av_play;
butAction1Text = R.string.play_label;
butAction1IconRes = R.attr.av_play;
butAction1TextRes = R.string.play_label;
} else {
butAction1Icon = R.attr.av_download;
butAction1Text = R.string.download_label;
butAction1IconRes = R.attr.av_download;
butAction1TextRes = R.string.download_label;
}
}
if (butAction1Icon != 0 && butAction1Text != 0) {
butAction1.setText(butAction1Text);
butAction1.setTransformationMethod(null);
if (butAction1IconRes != 0 && butAction1TextRes != 0) {
butAction1Text.setText(butAction1TextRes);
butAction1Text.setTransformationMethod(null);
TypedValue typedValue = new TypedValue();
getContext().getTheme().resolveAttribute(butAction1Icon, typedValue, true);
butAction1.setCompoundDrawablesWithIntrinsicBounds(typedValue.resourceId, 0, 0, 0);
getContext().getTheme().resolveAttribute(butAction1IconRes, typedValue, true);
butAction1Icon.setImageResource(typedValue.resourceId);
butAction1.setVisibility(View.VISIBLE);
} else {
butAction1.setVisibility(View.INVISIBLE);
}
if (butAction2Icon != 0 && butAction2Text != 0) {
butAction2.setText(butAction2Text);
butAction2.setTransformationMethod(null);
if (butAction2IconRes != 0 && butAction2TextRes != 0) {
butAction2Text.setText(butAction2TextRes);
butAction2Text.setTransformationMethod(null);
TypedValue typedValue = new TypedValue();
getContext().getTheme().resolveAttribute(butAction2Icon, typedValue, true);
butAction2.setCompoundDrawablesWithIntrinsicBounds(typedValue.resourceId, 0, 0, 0);
getContext().getTheme().resolveAttribute(butAction2IconRes, typedValue, true);
butAction2Icon.setImageResource(typedValue.resourceId);
butAction2.setVisibility(View.VISIBLE);
} else {
butAction2.setVisibility(View.INVISIBLE);

View File

@ -16,6 +16,7 @@ import androidx.viewpager.widget.ViewPager;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.CastEnabledActivity;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.core.event.FeedItemEvent;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.util.Flavors;
@ -24,6 +25,9 @@ import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
/**
* Displays information about a list of FeedItems.
@ -104,12 +108,14 @@ public class ItemPagerFragment extends Fragment {
}
});
EventBus.getDefault().register(this);
return layout;
}
@Override
public void onDestroyView() {
super.onDestroyView();
EventBus.getDefault().unregister(this);
if (disposable != null) {
disposable.dispose();
}
@ -162,6 +168,17 @@ public class ItemPagerFragment extends Fragment {
}
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEventMainThread(FeedItemEvent event) {
for (FeedItem item : event.items) {
if (this.item != null && this.item.getId() == item.getId()) {
this.item = item;
getActivity().invalidateOptionsMenu();
return;
}
}
}
private void openPodcast() {
Fragment fragment = FeedItemlistFragment.newInstance(item.getFeedId());
((MainActivity) getActivity()).loadChildFragment(fragment);

View File

@ -288,7 +288,7 @@ public class QueueFragment extends Fragment {
MenuItem searchItem = menu.findItem(R.id.action_search);
final SearchView sv = (SearchView) MenuItemCompat.getActionView(searchItem);
sv.setQueryHint(getString(R.string.search_hint));
sv.setQueryHint(getString(R.string.search_label));
sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String s) {
@ -471,15 +471,19 @@ public class QueueFragment extends Fragment {
return super.onContextItemSelected(item);
}
int position = FeedItemUtil.indexOfItemWithId(queue, selectedItem.getId());
if (position < 0) {
Log.i(TAG, "Selected item no longer exist, ignoring selection");
return super.onContextItemSelected(item);
}
switch(item.getItemId()) {
case R.id.move_to_top_item:
int position = FeedItemUtil.indexOfItemWithId(queue, selectedItem.getId());
queue.add(0, queue.remove(position));
recyclerAdapter.notifyItemMoved(position, 0);
DBWriter.moveQueueItemToTop(selectedItem.getId(), true);
return true;
case R.id.move_to_bottom_item:
position = FeedItemUtil.indexOfItemWithId(queue, selectedItem.getId());
queue.add(queue.size()-1, queue.remove(position));
recyclerAdapter.notifyItemMoved(position, queue.size()-1);
DBWriter.moveQueueItemToBottom(selectedItem.getId(), true);

View File

@ -25,7 +25,6 @@ import de.danoeh.antennapod.core.event.UnreadItemsUpdateEvent;
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.feed.FeedComponent;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.SearchResult;
import de.danoeh.antennapod.core.storage.FeedSearcher;
import de.danoeh.antennapod.view.EmptyViewHandler;
import io.reactivex.Observable;
@ -47,9 +46,8 @@ public class SearchFragment extends Fragment implements AdapterView.OnItemClickL
private static final String ARG_FEED = "feed";
private SearchlistAdapter searchAdapter;
private List<SearchResult> searchResults = new ArrayList<>();
private List<FeedComponent> searchResults = new ArrayList<>();
private Disposable disposable;
private ListView listView;
private ProgressBar progressBar;
private EmptyViewHandler emptyViewHandler;
@ -57,7 +55,9 @@ public class SearchFragment extends Fragment implements AdapterView.OnItemClickL
* Create a new SearchFragment that searches all feeds.
*/
public static SearchFragment newInstance(String query) {
if (query == null) query = "";
if (query == null) {
query = "";
}
SearchFragment fragment = new SearchFragment();
Bundle args = new Bundle();
args.putString(ARG_QUERY, query);
@ -103,7 +103,7 @@ public class SearchFragment extends Fragment implements AdapterView.OnItemClickL
((AppCompatActivity) getActivity()).getSupportActionBar().setTitle(R.string.search_label);
View layout = inflater.inflate(R.layout.search_fragment, container, false);
listView = layout.findViewById(R.id.listview);
ListView listView = layout.findViewById(R.id.listview);
progressBar = layout.findViewById(R.id.progressBar);
searchAdapter = new SearchlistAdapter(getActivity(), itemAccess);
listView.setAdapter(searchAdapter);
@ -125,15 +125,12 @@ public class SearchFragment extends Fragment implements AdapterView.OnItemClickL
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
SearchResult result = (SearchResult) listView.getAdapter().getItem(position);
FeedComponent comp = result.getComponent();
FeedComponent comp = searchAdapter.getItem(position);
if (comp.getClass() == Feed.class) {
((MainActivity) getActivity()).loadFeedFragmentById(comp.getId(), null);
} else {
if (comp.getClass() == FeedItem.class) {
FeedItem item = (FeedItem) comp;
((MainActivity) getActivity()).loadChildFragment(ItemPagerFragment.newInstance(item.getId()));
}
} else if (comp.getClass() == FeedItem.class) {
FeedItem item = (FeedItem) comp;
((MainActivity) getActivity()).loadChildFragment(ItemPagerFragment.newInstance(item.getId()));
}
}
@ -143,7 +140,7 @@ public class SearchFragment extends Fragment implements AdapterView.OnItemClickL
MenuItem item = menu.add(Menu.NONE, R.id.search_item, Menu.NONE, R.string.search_label);
MenuItemCompat.setShowAsAction(item, MenuItemCompat.SHOW_AS_ACTION_IF_ROOM);
final SearchView sv = new SearchView(getActivity());
sv.setQueryHint(getString(R.string.search_hint));
sv.setQueryHint(getString(R.string.search_label));
sv.setQuery(getArguments().getString(ARG_QUERY), false);
sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
@ -167,7 +164,7 @@ public class SearchFragment extends Fragment implements AdapterView.OnItemClickL
search();
}
private void onSearchResults(List<SearchResult> results) {
private void onSearchResults(List<FeedComponent> results) {
progressBar.setVisibility(View.GONE);
searchResults = results;
searchAdapter.notifyDataSetChanged();
@ -182,7 +179,7 @@ public class SearchFragment extends Fragment implements AdapterView.OnItemClickL
}
@Override
public SearchResult getItem(int position) {
public FeedComponent getItem(int position) {
if (0 <= position && position < searchResults.size()) {
return searchResults.get(position);
} else {
@ -204,7 +201,7 @@ public class SearchFragment extends Fragment implements AdapterView.OnItemClickL
}
@NonNull
private List<SearchResult> performSearch() {
private List<FeedComponent> performSearch() {
Bundle args = getArguments();
String query = args.getString(ARG_QUERY);
long feed = args.getLong(ARG_FEED);

View File

@ -304,12 +304,12 @@ public class SubscriptionFragment extends Fragment {
dialog.createNewDialog().show();
}
@Subscribe
@Subscribe(threadMode = ThreadMode.MAIN)
public void onFeedListChanged(FeedListUpdateEvent event) {
loadSubscriptions();
}
@Subscribe
@Subscribe(threadMode = ThreadMode.MAIN)
public void onUnreadItemsChanged(UnreadItemsUpdateEvent event) {
loadSubscriptions();
}

View File

@ -216,8 +216,8 @@ public class ImportExportPreferencesFragment extends PreferenceFragmentCompat {
private void showExportErrorDialog(final Throwable error) {
progressDialog.dismiss();
final AlertDialog.Builder alert = new AlertDialog.Builder(getContext())
.setNeutralButton(android.R.string.ok, (dialog, which) -> dialog.dismiss());
final AlertDialog.Builder alert = new AlertDialog.Builder(getContext());
alert.setPositiveButton(android.R.string.ok, (dialog, which) -> dialog.dismiss());
alert.setTitle(R.string.export_error_label);
alert.setMessage(error.getMessage());
alert.show();

View File

@ -84,5 +84,8 @@ public class PreferenceUpgrader {
UserPreferences.setEnqueueLocation(enqueueLocation);
}
}
if (oldVersion < 1080100) {
prefs.edit().putString(UserPreferences.PREF_VIDEO_BEHAVIOR, "pip").apply();
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 757 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 984 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 484 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 595 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 881 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 490 KiB

View File

@ -1,31 +1,31 @@
AntennaPod is un gestor y reproductor de podcast que te da acceso instantáneo a millones de podcast gratuitos y de pago, desde podcasters independientes a grandes estaciones como la BBC, NPR y CNN. Agrega, importa y exporta las fuentes de manera sencilla usando el listado de iTunes, archivos OPML o las URL de tipo RSS. Ahorra esfuerzo, batería y datos con los controles de descarga y de borrado de episodios (basado en favoritos y ajustes de tiempo).
Descarga, escucha en stream, o añade la cola episodios y disfrútalos como quieras con velocidad de reproducción ajustable, soporte para capítulos y temporizador de sueño.
Ahorra esuferzo, batería y consumo de datos con los potentes controles de automatización para descarga (especifica a qué horas y desde qué redes Wi-Fi) y borrado de episodios antiguos (basado en tus preferencias).
AntennaPod es un gestor y reproductor de podcasts que te da acceso instantáneo a millones de podcast gratuitos y de pago; desde podcasters independientes a grandes estaciones como la BBC, NPR y CNN. Agrega, importa y exporta las fuentes de manera sencilla usando el listado de iTunes, archivos OPML o las URL de tipo RSS. Ahorra esfuerzo, batería y datos con los controles de descarga y de borrado de episodios (basado en favoritos y ajustes de tiempo).
Descarga, escucha en stream o añade a la cola episodios y disfrútalos como quieras con velocidad de reproducción ajustable, soporte para capítulos y temporizador de sueño.
Ahorra esfuerzo, batería y consumo de datos con los potentes controles de automatización para descarga (especifica la hora y desde qué redes Wi-Fi) y el borrado de episodios antiguos (basado en tus preferencias).
Creado por entusiastas del pódcast, AntennaPod es libre en todos los sentidos: código abierto, gratuito y sin publicidad.
<b>Importar, organizar y reproducir</b>
• Administra la reproducción desde cualquier parte: control en pantalla de inicio, notificación del sistema y controles de auricular y bluetooth
• Administra la reproducción desde cualquier parte: control en la pantalla de inicio, las notificaciones del sistema y los controles de auriculares y bluetooth
• Añade e importa fuentes mediante los directorios de iTunes y gPodder.net, archivos OPML y enlaces RSS o Atom
• Disfruta escuchando a tu manera con velocidad de reproducción ajustable, soporte de capítulos (MP3, VorbisComment y Podlove), recordatorio del punto de reproducción y el temporizador de sueño avanzado (agita para restablecer, bajar el volumen y disminuir la velocidad de reproducción)
• Disfruta escuchando a tu manera, con velocidad de reproducción ajustable, soporte de capítulos (MP3, VorbisComment y Podlove), marcador del punto de reproducción y temporizador de sueño avanzado (agita para restablecer, bajar el volumen y disminuir la velocidad de reproducción)
• Accede a fuentes y episodios protegidos con contraseña
<b>Seguir, valorar y compartir </b>
• Haz un seguimiento de lo mejor de lo mejor marcando episodios como favoritos
• Busca ese episodio en el historial o busca por título y notas
• Comparte episodios y fuentes a través de las avanzadas redes sociales y opciones de correo electrónico, los servicios de gPodder.net y la exportación OPML
• Comparte episodios y fuentes a través de las opciones avanzadas de redes sociales y correo electrónico, los servicios de gPodder.net y exportando a OPML
<b>Control del sistema</b>
• Controla las descargas automáticas: elige las fuentes, excluye las redes móviles, selecciona redes wifi específicas, o solo cuando el teléfono se esté cargando y establece horarios o intervalos
• Gestiona el almacenamiento configurando la cantidad de episodios en caché, configura borrado inteligente y eligiendo tu ubicación favorita
• Controla las descargas automáticas: elige las fuentes, excluye las redes móviles, selecciona redes WiFi específicas, cuando el teléfono se cargue, establece horarios o intervalos
• Gestiona el almacenamiento configurando la cantidad de episodios en caché, borrado inteligente y eligiendo tu ubicación favorita
• Adáptate a tu entorno usando el tema claro u oscuro
• Haz una copia de seguridad de tus suscripciones con la integración de gPodder.net y la exportación OPML
• Haz una copia de seguridad de tus suscripciones con la integración de gPodder.net y exportando a OPML
<b>¡Únete a la comunidad AntennaPod!</b>
AntennaPod está en continuo desarrollo por voluntarios. ¡Tú también puedes contribuir, con tu código o con tus comentarios!
AntennaPod es desarrollado por voluntarios. ¡Tú también puedes contribuir, con tu código o con tus comentarios!
GitHub es el sitio que debes visitar para solicitar características nuevas, reportar fallos y contribuir con código:
Visita GitHub para solicitar características nuevas, reportar fallos y contribuir con código:
https://www.github.com/AntennaPod/AntennaPod
Para ayudar con las traducciones en Transifex:
Ayuda con las traducciones en Transifex:
https://www.transifex.com/antennapod/antennapod

View File

@ -0,0 +1,31 @@
AntennaPod on taskuhäälingu haldur ja esitaja, millega saad kohese ligipääsu miljonitele tasuta ja tasulistele saadetele nii ise- kui suurtegijatelt nagu BBC, NPR ja CNN. Lisa, impordi ja ekspordi nende voogusid ilma muredeta kasutades iTunes'i taskuhäälingute andmebaasi, OPML fail või lihtsalt RSS URL-e.
Laadi alla, voogedasta või lisa kuulamise järjekorda saateid ning naudi neid täpselt nii, nagu sina tahad, kasutades muudetavat taasesituse kiirust, peatükkide tuge ja unetaimerit.
Säästa pingutuselt, aku kestuselt ja mobiilse andmeside kasutuselt võimekate automatiseerimise vahenditega saadete allalaadimiseks (määra millal, mis sagedusega ja millistest WiFi võrkudes) ning kustutamiseks (vastavalt sinu lemmikutele ja viivituse sätetele).
Kuna AntennaPod on tehtud taskuhäälingu entusiastide poolt, on AntennaPod vaba selle sõna igas tähenduses: vaba lähtekoodiga, tasuta ja ilma mingi reklaamita.
<b>Impordi, korrasta ja kuula</b>
• Halda esitust kust tahes: avaekraani vidina abil, süsteemi teate kaudu või kõrvaklappide või bluetoothi nuppude abil
• Lisa ja impordi voogusid iTunesi ja gPodder.net kaustadest, OPML failidest ja RSS või Atom linkide kaudu
• Naudi kuulamist just sinu moodi tänu muudetavale esituskiirusele, peatükkide toele, meeldejäetavale asukohale ning unetaimerile (raputamine, valjuse vähendamine)
• Ligipääs parooliga kaitstud voogudele ja saadetele
<b>Talleta ja jaga, et avaldada tunnustust</b>
• Talleta parimatest parimaid märkides saateid lemmikuteks
• Leia see üks saade otsides esitatute ajaloost pealkirjade või kirjelduste järgi
• Jaga saateid ja voogusid suurepäraste sotsiaalmeedia ja e-posti valikute abil, gPodder.neti kaudu ja OPML failide abil
<b>Oma kontrolli</b>
• Võta kontroll automaatse allalaadimise üle enda kätte: vali vood, keela mobiilivõrk, vali õiged WiFi võrgud, ütle, kui telefon peaks allalaadimise ajal laadima või määra millal ja kui tihti saateid alla laadida
• Halda ruumikasutust, määrates mitu saadet varuks hoida, luba nutikas kustutamine ja failide eelistatud asukoha määramine
• Kohanda keskonnaga heleda ja tumeda kujundusega
• Varunda oma tellimused gPodder.net keskkonda ja OPML faili eksportides
<b>Liitu AntennaPodi kogukonnaga!</b>
AntennaPod on vabatahtlike poolt aktiivselt arendamisel. Ka sina võid anda oma osa, kirjutades koodi või andes tagasisidet!
GitHub on koht, kus esitada uute võimaluste soove, vearaporteid ja kooditäiendusi:
https://www.github.com/AntennaPod/AntennaPod
Transifex on koht, kus saab aidata tõlgetega:
https://www.transifex.com/antennapod/antennapod

View File

@ -0,0 +1 @@
Lihtne, paindlik ja avatud lähtekoodiga taskuhäälingu haldur ja esitaja

View File

@ -0,0 +1 @@
AntennaPod

View File

@ -12,20 +12,20 @@ Conçu par des fans de podcast, AntennaPod est gratuit, open source et sans publ
<b>Suivez, partagez et appréciez</b>
• Enregistrez les meilleurs épisodes en tant que favoris
• Retrouvez un épisode à partir de l'historique de lecture ou en recherchant les noms et commentaires des épisodes
• Retrouvez un épisode à partir de l'historique de lecture ou en recherchant les titres et commentaires des épisodes
• Partagez vos épisodes et flux sur les réseaux sociaux, par email, sur gPodder.net ou en les exportant au format OPML
<b>Contrôlez</b>
• Prenez le contrôle en automatisant vos téléchargements : flux spécifiques, restriction de la connexion mobile, réseaux WIFI autorisés, seulement pendant la recharge, fréquence de mise à jour
• Prenez le contrôle en automatisant vos téléchargements : flux spécifiques, restriction de la connexion mobile, réseaux WIFI autorisés, seulement pendant la recharge, fréquence ou heure de mise à jour
• Gérez l'espace de stockage en réglant le nombre d'épisodes à garder, quand les supprimer et où les enregistrer
Choisissez le thème de l'interface
Adaptez l'interface selon vos préférences avec le thème clair ou sombre
• Sauvegardez vos abonnements avec gPodder.net ou des exports OPML
<b>Rejoignez la communauté d'AntennaPod !</b>
AntennaPod est développé activement par des volontaires. Vous pouvez aussi contribuer avec du code, des traductions ou des commentaires !
Allez sur GitHub pour demander de nouvelles options, signaler des bugs ou pour contribuer au développement :
Rendez-vous sur GitHub pour demander de nouvelles options, signaler des bugs ou pour contribuer au développement :
https://www.github.com/AntennaPod/AntennaPod
Allez sur Transifex pour aider la traduction :
Rendez-vous sur Transifex pour aider la traduction :
https://www.transifex.com/antennapod/antennapod

Binary file not shown.

Before

Width:  |  Height:  |  Size: 500 KiB

View File

@ -1 +1 @@
Un lecteur de podcast facile à utiliser et flexible
Un lecteur de podcast facile et souple à utiliser

View File

@ -1,42 +1,31 @@
AntenaPod é un xestor de podcast e reprodutor que lle da acceso a millóns de podcast tanto gratuítos como de pagamento, desde podcasters independentes a grandes productores como BBC, NPR e CNN. Engada, importe e exporte as súas fontes de xeito doado utilizando a base de datos de iTunes, ficheiros OPML ou URLs RSS. Aforre traballo, enerxía da batería e datos móbiles co sistema automatizado de control das descargas de episodios (indicando horario, intervalos e redes WiFi) e borrando episodios (baseado nos seus favoritos e axustes de retardo).<br>
O máis importante: Descarga, reproduce ou pon en cola os episodios e desfrútaos do xeito en que máis che conveña axustando a velocidade de reprodución, o soporte de capítulos e o apagado programable.
AntennaPod é un xestor de podcast e reprodutor que che permite acceder a millóns de contidos gratuítos e de pagamento, desde produtores independentes a grandes empresas de contidos como BBC, NPR ou CNN. Engade, importa e exporta as súas fontes sen complicacións utilizando a base de datos de iTunes, ficheiros OPML ou URL de RSS.
Descarga, difunde ou pon e cola episodios e desfrutaos do xeito que prefiras, con velocidade de reprodución axustable, soporte de capítulos e apagado programable.
De xeito doado, aforrando batería e datos móbiles e con ferramentas potentes para a automatización das descargas (indicando horarios, intervalos e redes WiFi) e borrado de ficheiros (baseado nos favoritos e axustes temporais).
Escrito por namorados dos podcast, AntennaPod é gratuíto e libre: open source, sen custos, sen publicidade.
Feita por entusiastas do podcast, AntennaPod é libre en todos os sentidos da palabra: código aberto, gratuíto e sen anuncios.
<b>Características:</b><br>
IMPORTAR, ORGANIZAR E REPRODUCIR<br>
&#8226; Engada e importe fontes a través dos directorios de iTunes e gPodder.net, ficheiros OPML e RSS ou ligazóns Atom<br>
&#8226; Xestione as opcións de reprodución desde calquer lugar: widget na pantalla de inicio, barra de notificacións e tamén desde os controis de auriculares e bluetooth<br>
&#8226; Goce escoitando ao seu xeito coa velocidade de reprodución axustable, soporte de capítulos (MP3, VorbisComment e Podlove), recordo da posición de reprodución e apagado configurable (axitar para reiniciar, baixar volume e diminuir velocidade de reprodución)<br>
&#8226; Acceso protexido con contrasinal a episodios e fontes<br>
&#8226; Benefíciese das fontes paxinadas (www.podlove.org/paged-feeds)
<b>Importar, organizar e reproducir</b>
• Controlar a reprodución desde calquera lugar: widget na pantalla, sistema de notificacións e controis de auriculares e por bluetooth.
• Engade e importa fontes vía directorios de iTunes e gPodder.net, ficheiros OPML e ligazóns RSS ou Atom.
• Desfruta escoitando ao teu xeito, con velocidade axustable, soporte de capítulos, lembra a posición de reprodución e programa a hora de apagado (axita para restablecer, volume máis baixo)
• Acceso protexido con contrasinal para fontes e episodios
SIGA, COMPARTA E VALORE <br>
&#8226; Garde o melloriño de cada casa marcando episodios como favoritos<br>
&#8226; Atope ese episodio especial no historial de reprodución ou buscando (títulos e notas do episodio)<br>
&#8226; Comparta episodios e fontes a través das opcións de redes sociais e correro electrónico, os servizos de gPodder.net e exportando a OPML<br>
<b>Leva un rexistro, comparte e promociona</b>
• Mantén un rexistro dos mellores episodios marcándoos como favoritos
• Atopa un episodio no histórico de reprodución ou buscando por títulos e notas do episodio
• Comparte episodios e fontes a través da web social, correo electrónico, o servizo gPodder.net e exportándoos como OPML.
CONTROL DO SISTEMA <br>
&#8226; Tome control sobre as descargas automáticas: escolla fontes, exclúa redes móbiles, redes WIFI concretas, requerir que o móbil esté a cargar e horarios e intervalos<br>
&#8226; Xestione o almacenamento establecendo o volume almacenado de episodios, borrado intelixente (baseándose nos favoritos e situación de reprodución) e selecionando a localización preferida<br>
&#8226; Utilice AntennaPod no seu idioma (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH, GL)<br>
&#8226; Adápteo a contorna utilizando o decorado claro ou oscuro<br>
&#8226; Respalde as súas suscricións coa integración en gPodder.net e exportando a OPML
<b>Xestiona o sistema</b>
• Toma o control das descargas automáticas: escolle fontes, exclúe redes móbiles, redes Wifi específicas, que o móbil esté cargando ou establece horarios para a descarga
• Xestiona o almacenaxe establecendo a número de episodios gardados, borrado intelixente e escollendo a localización preferida.
• Adáptase ao teu entorno utilizando os decorados claro ou escuro
• Respalda as túas subscricións con gPodder.net e a exportación OPML
<b>Únase a comunidade AntennaPod!</b><br>
<b>Participa na comunidade AntennaPod!</b>
AntennaPod está baixo continuo desenvolvemento grazas a voluntarios. Vostede tamén pode contribuir, con código ou con comentarios!
En GitHub pode solicitar novas características, informar de erros e contribuir ao código:<br>
Podes solicitar novas características utilizando GitHub, así como informe de fallos ou contribuír ao código:
https://www.github.com/AntennaPod/AntennaPod
No noso Google Group pode compartir ideas, momentos favoritos dos podcast e agradecer o traballo dos voluntarios:<br>
https://groups.google.com/forum/#!forum/antennapod
Ten algunha pregunta ou quere facernos algún comentario?
https://twitter.com/@AntennaPod
Para axudar na tradución vaia a Transifex:<br>
https://www.transifex.com/antennapod/antennapod
Mire o noso programa Beta de Probas para ter os últimos avances:<br>
https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod
As traducións fanse en Transifex:
https://www.transifex.com/antennapod/antennapod

View File

@ -0,0 +1,31 @@
Az AntennaPod egy podcastkezelő és -lejátszó, amely azonnali hozzáférést nyújt ingyenes és fizetős podcastok millióihoz: a független podcastkészítőktől kezdve a nagy kiadókig, mint a BBC, NPR és a CNN. Adjon hozzá, importáljon és exportáljon csatornákat az iTunes podcast adatbázis, OPML fájlok vagy egyszerű RSS URL-ek segítségével.
Töltsön le, hallgassa élőben vagy állítsa sorba az epizódokat, és elvezze azokat, ahogy szeretné az állítható lejátszási sebességgel, a fejezettámogatással és az alvási időzítővel.
Spóroljon az idejével, az akkumulátorral és a mobiladat-keretével a sokoldalú automatizálási beállításokkal, melyek letöltik az epizódokat (adjon meg időket, intervallumokat és WiFi-hálózatokat), és törlik is azokat (a kedvencei vagy a késleltetési beállításai alapján).
Podcast-rajongók készítésében, az AntennaPod teljesen szabad, nyílt forráskódú, ingyenes, és hirdetésektől mentes.
<b>Importálás, rendszerezés és lejátszás</b>
• Lejátszás kezelése bárhonnan: a kezdőképernyőről, fülhallgatóról és bluetoothos vezérlőkről
• Csatornák hozzáadása és importálása iTunesból, gPodder.net könyvtárakból, OPML-fájlokból és RSS/Atom hivatkozásokból
• Hallgasson saját ízlése szerint az állítható lejátszási sebességgel, fejezettámogatással, megjegyzett lejátszási pozícióval és egy nagy tudású alvási időzítővel (rázás az újraindításhoz, hangerő csökkentéshez)
• Jelszóval védett csatornák és epizódok elérése
<b>Kövesse, ossza meg és élvezze</b>
• Kövesse a legjobbak legjobbját azáltal, hogy kedvencként jelöli meg az epizódokat
• Találja meg azt a bizonyos epizódot a lejátszási előzményekkel vagy kereséssel (cím és adásjegyzetek alapján)
• Osszon meg epizódokat és csatornákat továbbfejlesztett közösségi média és e-mail lehetőségekkel, a gPodder.net szolgáltatásokkal és OPML exportálás segítségével
<b>Vezérelje a rendszert</b>
• Vegye át az irányítást az automatikus letöltés felett: válasszon csatornákat, mellőzze a mobilhálózatokat, válasszon specifikus WiFi-hálózatokat, követelje meg a telefon töltését és adjon meg időpontokat vagy időszakokat
• Kezelje a tárhelyet a tárolandó epizódok számának megadásával, az okos törléssel és az előnyben részesített hely megadásával
• Alkalmazkodjon a környezethez a világos és sötét téma használatával
• Mentse el a feliratkozásait a gPodder.net integrációval és az OPML exporttal
<b>Csatlakozzon az AntennaPod közösséghez!</b>
Az AntennaPodot aktívan fejlesztik az önkéntesek. Ön is közreműködhet: kóddal vagy megjegyzésekkel!
A GitHub a funkciókérések, hibajelentések és a kódbeküldés helye:
https://www.github.com/AntennaPod/AntennaPod
A Transifexen segíthet a fordításokban:
https://www.transifex.com/antennapod/antennapod

View File

@ -0,0 +1 @@
Könnyen használható, rugalmas és nyílt forráskódú podcastkezelő és -lejátszó

View File

@ -0,0 +1 @@
AntennaPod

View File

@ -1,43 +1,31 @@
AntennaPod è un riproduttore e gestore di podcast che ti da accesso immediato a milioni di podcast gratuiti e a pagamento, dai podcaster indipendenti alle più grandi emittenti come BBC, NPR e CNN. Aggiungi, importa e esporta in modo semplice usando il database di podcast di iTunes, un file OPML o i semplici URL RSS. Risparmia fatica, batteria e dati con il potente controllo automatizzato per il download di episodi (orari specifici, intervalli e reti WiFi) e dell'eliminazione degli episodi (basata sui preferiti e le impostazioni di eliminazione personali).<br>
Ancora più importante: scarica, ascolta in streaming o metti in coda gli episodi e goditeli quando e come vuoi grazie alla velocità di riproduzione personalizzabile, al supporto per i capitoli e al timer di spegnimento. Puoi anche ringraziare i creatori di contenuti grazie all'integrazione con Flattr.
AntennaPod è un riproduttore e gestore di podcast che permette l'accesso immediato a milioni di podcast gratuiti e a pagamento, dai podcaster indipendenti alle più grandi emittenti come BBC, NPR e CNN. Aggiungi, importa e esporta in modo semplice usando il database di podcast di iTunes, un file OPML o i semplici URL RSS.
Scarica, ascolta in streaming o accoda gli episodi e goditeli come preferisci grazie alla velocità di riproduzione modificabile, al supporto ai capitoli e al timer di spegnimento.
Risparmia fatica, carica della batteria e dati con i potenti controlli automatizzati per il download degli episodi (orari specifici, intervalli di tempo e reti WiFi selezionate) e l'eliminazione degli episodi (gestione dei preferiti e i tempi di cancellazione).
Creato da amanti dei podcast, AntennaPod è libero in tutti i sensi: open source, gratis, senza pubblicità.
Creato da appassionati di podcast, AntennaPod è libero in tutti i sensi: open source, gratuito e senza pubblicità.
<b>Funzioni:</b><br>
IMPORTA, ORGANIZZA E RIPRODUCI<br>
&#8226; Aggiungi e importa feed via iTunes, gPodder.net, file OPML e link RSS o Atom<br>
&#8226; Gestisci la riproduzione da dove vuoi: widget sulla schermata Home, notifiche di sistema e controlli sugli auricolari e via bluetooth. <br>
&#8226; Divertiti ad ascoltare nel modo che preferisci grazie alla velocità di riproduzione variabile, il supporto ai capitoli (MP3, VorbisComment e Podlove), la memorizzazione dell'avanzamento di riproduzione e un timer di spegnimento avanzato (scuoti per resettare, volume basso e rallentamento della velocità)<br>
&#8226; Accedi a feed e episodi protetti da password<br>
&#8226; Sfrutta i vantaggi dei paged feeds (www.podlove.org/paged-feeds)
<b>Importa, organizza e riproduci</b>
• Gestisci la riproduzione ovunque: widget nella schermata home, tendina delle notifiche, cuffie e controlli bluetooth.
• Aggiungi e importa le sottoscrizioni tramite iTunes e gPodder, o anche tramite file OPML, collegamenti RSS o Atom.
• Goditi l'ascolto nel modo che preferisci grazie alla velocità di riproduzione modificabile, il supporto ai capitoli, la memorizzazione dello stato di riproduzione e un timer di spegnimento avanzato (scuoti per riavviare o riduci il volume)
• Accedi ai feed e agli episodi protetti tramite utente e password
TIENI TRACCIA, CONDIVIDI & APPREZZA<br>
&#8226; Tieni traccia del meglio del meglio segnando gli episodi come Preferiti<br>
&#8226; Trova l'episodio specifico grazie alla cronologia di riproduzione o al sistema di ricerca (titoli e note dell'episodio)<br>
&#8226; Condividi gli episodi e i feed tramite le avanzate opzioni social ed email, il servizio gPodder.net e l'esportazione in OPML<br>
&#8226; Supporta i creatori di contenuti tramite l'integrazione con Flattr e il flattring automatico
<b>Tieni traccia, condividi & ricerca</b>
• Tieni traccia dei migliori episodi di sempre segnandoli come preferiti
• Trova proprio l'episodio che cercavi grazie alla ricerca nella cronologia, nei titoli e nelle note degli episodi
• Condividi gli episodi e i feed tramite opzioni avanzate di condivisione via social o email, i servizi di gPodder.net o l'esportazione OPML.
CONTROLLA IL SISTEMA<br>
&#8226; Prendi il controllo grazie ai download automatici: scegli i feed, escludi le reti mobili, seleziona reti WiFi specifiche, richiedi che il telefono sia in carica e imposta tempi e intervalli di aggiornamento<br>
&#8226; Gestisci lo spazio impostando l'occupazione massima, la cancellazione intelligente (basata sui Preferiti e sullo stato di riproduzione) e selezionando la posizione che preferisci <br>
&#8226; Usa AntennaPod nella tua lingua (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br>
&#8226; Adattati all'ambiente in cui ti trovi con i temi Chiaro e Scuro.<br>
&#8226; Salva le sottoscrizioni grazie all'integrazione con gPodder.net e l'esportazione OPML
<b>Controlla il sistema</b>
• Gestisci il download automatico: puoi selezionare i feed, escludere le reti mobili, utilizzare reti WiFi specifiche, impostare il download solo se in carica e scaricare in orari o intervalli selezionati.
• Gestisci lo spazio impostando l'occupazione massima degli episodi, la cancellazione intelligente e il percorso in cui scaricare i file.
• Adattati alle tue preferenze grazie ai temi chiaro o scuro.
• Effettua il backup delle sottoscrizioni grazie all'integrazione di gPodder.net e all'esportazione in OPML
<b>Entra nella community di AntennaPod!</b><br>
<b>Partecipa alla community di AntennaPod!</b>
AntennaPod è sviluppato da volontari. Anche tu puoi contribuire, con il codice o con dei commenti!
GitHub è il posto nel quale fare richieste, segnalare bug e contribuire allo sviluppo:<br>
GitHub è la piattaforma usata per le richieste di funzionalità, le segnalazioni di bug o i contributi al codice:
https://www.github.com/AntennaPod/AntennaPod
Il nostro gruppo Google è il luogo ideale dove condividere le idee, stimolare momenti di podcasting e ringraziare tutti i volontari:<br>
https://groups.google.com/forum/#!forum/antennapod
Hai una domanda o vuoi darci un feedback?
https://twitter.com/@AntennaPod
Transifex è il posto dove puoi contribuire alla traduzione di AntennaPod:<br>
https://www.transifex.com/antennapod/antennapod
Dai un'occhiata al nostro programma di Beta Testing per avere accesso in anticipo alle nuove features:<br>
https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod
Transifex è dove puoi contribuire alla traduzione:
https://www.transifex.com/antennapod/antennapod

View File

@ -1,42 +1,31 @@
AntennaPodは、独自のポッドキャスターから、BBC、NPR、CNNなどの大規模な放送まで、数百万の無料や有料ポッドキャストに瞬時にアクセスすることができる、ポッドキャストマネージャーおよびプレーヤーです。フィードは手間のかからないiTunesのPodcastのデータベース、OPMLファイルや簡単なRSSのURLを使用して追加、インポート、エクスポートします。エピソードのダウンロード (時間、間隔およびWiFiネットワークを指定) とエピソードの削除 (お気に入りと遅延設定に基づいて) をするために強力な自動コントロールで、手間、バッテリ消費、モバイルデータ使用量を節約します。<br>
しかし最も重要なこと: エピソードをダウンロード、ストリーム再生、またはキューに入れて、そして再生速度の調整、チャプターのサポート、スリープタイマーで好きなように楽しんでください。
AntennaPod は、独立したポッドキャスターから BBC、NPR、CNN などの大規模な出版社まで、数百万の無料および有料のポッドキャストに即座にアクセスできるポッドキャストマネージャーおよびプレーヤーです。 iTunes ポッドキャストデータベース、OPML ファイル、または簡単な RSS URL を使用して、フィードを簡単に追加、インポート、エクスポートできます。
エピソードをダウンロード、ストリーミング、またはキューに入れて、調整可能な再生速度、チャプターサポート、スリープタイマーで、お好きな方法でお楽しみください。
エピソードのダウンロード (時間、間隔、WiFi ネットワークの指定) とエピソードの削除 (お気に入りと遅延設定に基づく) の強力な自動化コントロールにより、労力、バッテリー消費量、モバイルデータ通信使用量を節約できます。
ポッドキャスト愛好家が作成した AntennaPod はすべての意味でフリー自由です: オープンソース、コスト不要、広告はありません
ポッドキャスト愛好家によって作られた AntennaPod は、オープンソース、無料、広告なしなど、あらゆる意味でフリーです
<b>すべての機能:</b><br>
インポート、整理、再生<br>
&#8226; iTunesや、gPodder.netディレクトリ、OPMLファイル、RSSまたはAtom経由でフィードを追加およびインポートします<br>
&#8226; 様々な場所で再生を管理します: ホーム画面ウィジェット、システム通知、イヤホン、Bluetoothコントロール<br>
&#8226; 再生速度の調整、チャプターのサポート (MP3、VorbisCommentとPodlove)、再生位置の保存、高度なスリープタイマー (シェイクしてリセット、音量を小さく、再生速度を遅く) で、お好みの聞き方でお楽しみください<br>
&#8226; アクセスパスワードで保護されたフィードとエピソード<br>
&#8226; ページフィードをご利用ください (www.podlove.org/paged-feeds)
<b>インポート、整理、再生</b>
• どこからでも再生を管理: ホームスクリーンウィジェット、システム通知、イヤホン、Bluetooth コントロール
• iTunes および gPodder.net ディレクトリー、OPMLファイル、RSS または Atom リンク経由でフィードを追加およびインポートします
• 調整可能な再生速度、チャプターサポート、記憶した再生位置、高度なスリープタイマー (シェイクしてリセット、音量を下げる) でお好みの方法でお楽しみください
• パスワードで保護されたフィードとエピソードのアクセス
記録、共有 & 感謝<br>
&#8226; エピソードをお気に入りとしてマークして、一番の中の一番を保存してください<br>
&#8226; 再生履歴から、または検索 (タイトルとショーノート) して目的のエピソードを見つけてください<br>
&#8226; 高度なソーシャルメディアとメールオプション、gPodder.netサービス、OPMLエクスポートからエピソードやフィードを共有してください<br>
<b>追跡、共有、感謝</b>
• エピソードをお気に入りとしてマークすることにより、ベストを追跡します
• 再生履歴から、またはタイトルとショーノートを検索して、エピソードを見つけます
• 高度なソーシャルメディア、メールオプション、gPodder.net サービス、OPML エクスポートを介してエピソードとフィードを共有します
システムのコントロール
&#8226; 自動ダウンロードの制御: フィードを選択、モバイルネットワークを除外、特定のWiFiネットワークを選択、電話を充電する必要、時間や間隔を設定<br>
&#8226; キャッシュされるエピソードの量の設定、スマート削除 (お気に入りやプレイ状況に基づいて) と、お好みの場所を選択して、ストレージを管理します<br>
&#8226; AntennaPod をあなたの言語でご利用ください (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br>
&#8226; ライトとダーク テーマを使用して環境に適応します<br>
&#8226; gPodder.net統合とOPMLのエクスポートで、購読をバックアップします
<b>システムをコントロール</b>
• 自動ダウンロードの制御: フィードの選択、モバイル通信ネットワークの除外、特定の WiFi ネットワークの選択、充電が必要な時間または間隔の設定
• キャッシュされるエピソードの量を設定、スマート削除、お好みの場所を選択してストレージを管理します
• ライトとダークのテーマを使用して環境に適応します
• gPodder.net 統合と OPML エクスポートを使用して購読をバックアップします
<b>AntennaPod のコミュニティに参加してください!</b><br>
<b>AntennaPod コミュニティに参加しましょう!</b>
AntennaPod はボランティアによって活発に開発中です。コードやコメントで、あなたもも貢献することができます!
GitHubは、機能のリクエスト、バグ報告、コードの貢献のための場所です:<br>
GitHub は、機能のリクエスト、バグ報告、およびコードの貢献のための場所です:
https://www.github.com/AntennaPod/AntennaPod
私たちのGoogleグループは、あなたのアイデア、お気に入りのポッドキャスティングモーメント、感謝を、すべてのボランティアと共有するための場所です:<br>
https://groups.google.com/forum/#!forum/antennapod
質問や、私たちへのフィードバックがありませんか?
https://twitter.com/@AntennaPod
Transifexは翻訳を支援するための場所です:<br>
https://www.transifex.com/antennapod/antennapod
私たちのベータテストプログラムをチェックして、最新機能を最初に入手してください:<br>
https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod
Transifex は翻訳を支援する場所です:
https://www.transifex.com/antennapod/antennapod

View File

@ -1,42 +1,31 @@
Met AntennaPod speel en beheer je al je podcasts en krijg je directe toegang tot duizenden gratis en betaalde podcasts - van onafhankelijke makers tot grote merken zoals BBC, CNN en NPO. Via de iTunes-databank, OPML-bestanden en simpele RSS-linkjes voeg je deze podcasts gemakkelijk toe. Dankzij simpele maar slimme automatische controle van het downloaden en verwijderen van afleveringen bespaar je de accu, hoef je je favoriete podcast niet meer handmatig te volgen en verbruik je geen onnodige mobiele gegevens.<br>
Maar belangrijker: download, stream of voeg afleveringen toe aan de wachtrij en geniet ervan! Je hebt beschikking over afspeelsnelheden, hoofdstukondersteuning en een slaaptimer.
Met AntennaPod speel en beheer je al je podcasts en krijg je directe toegang tot duizenden gratis en betaalde podcasts - van onafhankelijke makers tot grote merken zoals BBC, CNN en NPO. Via de iTunes-database, OPML-bestanden en simpele RSS-linkjes voeg je deze podcasts makkelijk toe.
Download, stream of voeg afleveringen toe aan de wachtrij. Met instelbare afspeelsnelheden, hoofdstukondersteuning en een slaaptimer luister je podcasts op de manier die jij prettig vindt.
Spaar moeite, je batterij en je databundel met slimme automatische controle op het downloaden nieuwe afleveringen. En AntennaPod verwijdert ook je oude afleveringen, afhankelijk van je instellingen.
Gemaakt door podcast-enthousiastelingen, AntennaPod is vrij in de breedste zin van het woord: vrij van advertenties, open source en gratis.
AntennaPod is gemaakt door podcast-enthousiastelingen. Het team van vrijwilligers bieden je het gratis aan - vrij van advertenties en open source.
<b>Alle features:</b><br>
IMPORTEREN, ORGANISEREN, AFSPELEN<br>
&#8226; Voeg feeds toe via iTunes and gPodder.net database, OPML-bestanden and RSS of Atom linkjes<br>
&#8226; Beheer het afspelen overal: met een homescreen widget, in je Android meldingen en de knoppen op je koptelefoon en bluetooth-apparaat<br>
&#8226; Bepaal zelf hoe je luistert met aanpasbare afspeelsnelheden, ondersteuning van hoofdstukken (MP3, VorbisComment en Podlove), afspeelpositie voor elke aflevering en een handige 'slaap timer' (schudden om te resetten, volume langzaam zachter en herstel naar normale afspeelsnelheid)<br>
&#8226; Toegang tot wachtwoord-beveiligde podcasts en afleveringen<br>
&#8226; Doe je voordeel met 'paged feeds' (www.podlove.org/paged-feeds)
<b>Importeren, organiseren en afspelen</b>
• Beheer het afspelen op elke manier: met een homescreen widget, in je Android meldingen en via de knoppen op je koptelefoon en bluetooth-apparaat
• Voeg podcasts toe via iTunes- en gPodder.net-databases, OPML-bestanden en RSS- of Atom-links
• Bepaal zelf hoe je luistert met aanpasbare afspeelsnelheden, ondersteuning van hoofdstukken, opslag van afspeelpositie voor elke aflevering en een handige 'slaap timer' (schudden om te resetten, volume langzaam zachter)
• Toegang tot wachtwoord-beveiligde podcasts en afleveringen
DEEL & WAARDEER<br>
&#8226; Hou het beste van het beste bij door afleveringen als favoriet te markeren<br>
&#8226; Vindt die ene aflevering terug in de afspeelgeschiedenis of door te zoeken (in titels, shownotes en makers)<br>
&#8226; Deel podcasts en afleveringen via uitgebreide opties voor sociale media, WhatsApp, email en gPodder.net<br>
<b>Hou bij, deel en waardeer</b>
Hou het beste van het beste bij door afleveringen als favoriet te markeren
• Vindt die ene aflevering terug via de afspeelgeschiedenis of door te zoeken in titels en shownotes
• Deel podcasts en afleveringen via uitgebreide opties voor sociale media, email, gPodder.net of een OPML-bestand
HOUD DE CONTROLE
&#8226; Beheer automatische downloads: kies je podcasts, sluit mobiele netwerken uit, selecteer specifieke WiFi-verbindingen, eis dat de telefoon wordt opgeladen and bepaal tijden of intervals<br>
&#8226; Controleer geheugengebruik: stel een maximumaantal gedownloade afleveringen in, laat afleveringen automatisch verwijderen (maar sluit je favorieten en niet-afgespeelde afleveringen uit) en selecteer zelf je opslaglocatie<br>
&#8226; Gebruik AntennaPod in jouw taal: Nederlands! (Of in het Engels, Zweeds, Frans, Duits, Spaans, enz)<br>
&#8226; Voel je een kameleon: kies voor een licht of donker uiterlijk<br>
&#8226; Back-up je abonnementen via gPodder.net en geëxporteerde OPML-bestanden
<b>Hou de controle</b>
• Beheer automatische downloads: kies je podcasts, sluit mobiele netwerken uit, selecteer specifieke WiFi-verbindingen, vereis dat de telefoon wordt opgeladen en bepaal tijden of intervals
• Controleer geheugengebruik: stel een maximumaantal gedownloade afleveringen in, laat afleveringen automatisch verwijderen en selecteer zelf je opslaglocatie
• Voel je een kameleon: kies voor een licht of donker uiterlijk
• Back-up je abonnementen via gPodder.net en geëxporteerde OPML-bestanden
<b>Doe mee met de AntennaPod gemeenschap!</b><br>
<b>Doe mee met de AntennaPod-gemeenschap!</b>
AntennaPod wordt regelmatig geüpdatet door vrijwilligers. En jij kan ook helpen, met code of commentaar!
GitHub is de beste plek voor foutmeldingen, verzoekjes voor nieuwe functies en bijdragen aan de code:<br>
Je kunt op GitHub terecht voor foutmeldingen, verzoekjes voor nieuwe functies en bijdragen aan de code:
https://www.github.com/AntennaPod/AntennaPod
Onze Google Group is de beste plek om je ideeën, favoriete podcast-momenten en waardering naar alle vrijwilligers te delen:<br>
https://groups.google.com/forum/#!forum/antennapod
Heb je een vraag of wil je feedback geven?
https://twitter.com/@AntennaPod
Transifex is de beste plek om te helpen met vertalen:<br>
https://www.transifex.com/antennapod/antennapod
Check het Beta Testprogramma om de laatste features als eerst te krijgen:<br>
https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod
Transifex is de beste plek om te helpen met vertalen:
https://www.transifex.com/antennapod/antennapod

View File

@ -0,0 +1,31 @@
AntennaPod to menedżer i odtwarzacz podcastów, który pozwala na natychmiastowy dostęp do milionów darmowych i płatnych podcastów, od niezależnych twórców po wielkie wydawnictwa takie jak BBC, NPR i CNN. Bezproblemowo dodawaj, importuj i eksportuj ich kanały używając bazy danych podcastów iTunes, plików OPML lub zwykłych adresów RSS.
Pobieraj, streamuj lub dodawaj do kolejki odcinki i korzystaj z nich jak chcesz, przy pomocy konfigurowalnej prędkości odtwarzania, wsparcia rozdziałów i wyłącznika czasowego.
Oszczędź czas, baterię i ilość pobranych danych komórkowych dzięki wielu możliwościom automatyzacji pobierania odcinków (określanie czasu, interwałów i sieci WiFi) i kasowania odcinków (na podstawie twoich ulubionych i ustawień opóźnienia)
Stworzony przez miłośników podcastów, AntennaPod jest darmowy w każdym znaczeniu tego słowa: otwarty kod, bez opłat, bez reklam.
<b>Importuj, organizuj i odtwarzaj</b>
• Zarządzaj odtwarzaniem z dowolnego miejsca: widgetu na ekranie głównym, powiadomienia systemowego, pilota na kablu słuchawkowym, urządzeń bluetooth
Dodawaj i importuj kanały z iTunes i gPodder.net, plików OPML oraz z adresów RSS lub Atom
• Ciesz się słuchaniem podcastów po swojemu, dzięki konfigurowalnej prędkości odtwarzania, obsłudze rozdziałów, zapamiętywanej pozycji odtwarzania i zaawansowanemu wyłącznikowi czasowemu (potrząśnij aby zresetować, zmniejszanie głośności)
• Wsparcie dla kanałów i odcinków zabezpieczonych hasłem
<b>Śledź i dziel się</b>
• Zachowaj najlepsze z najlepszych oznaczając odcinki jako ulubione
• Odnajdź ten jedyny odcinek dzięki historii odtwarzania lub przez wyszukiwanie po tytułach i opisach
• Udostępniaj odcinki i kanały dzięki zaawansowanym opcjom mediów społecznościowych i email, usłudze gPodder.net oraz eksporcie OPML
<b>Kontroluj</b>
• Kontroluj automatyczne pobieranie: wybierz kanały, oszczędzaj dane komórkowe, wybierz określone sieci WiFi, pobieraj tylko podczas ładowania, ustaw czas dnia lub częstotliwość
• Kontroluj użycie pamięci poprzez ustawienie ilości zachowywanych odcinków, inteligentne kasowanie oraz wybranie domyślnej lokalizacji
• Dostosuj wygląd dzięki motywom: ciemny, jasny, czarny (dla ekranów AMOLED)
• Twórz kopie zapasowe swoich subskrypcji dzięki integracji gPodder.net lub eksportuj je do pliku OPML
<b>Dołącz do społeczności AntennaPod</b>
AntennaPod jest ciągle rozwijane przez ochotników. Ty też możesz pomóc, kodem lub komentarzem!
Chcesz zgłosić błąd lub brakuje Ci jakiejś funkcji, a może programujesz? Odwiedź nasz GitHub:
https://www.github.com/AntennaPod/AntennaPod
Chcesz pomóc tłumaczyć AntennaPod - możesz to zrobić na Transifex:
https://www.transifex.com/antennapod/antennapod

View File

@ -0,0 +1 @@
Łatwy w użyciu, konfigurowalny opensource'owy menedżer i odtwarzacz podcastów

View File

@ -0,0 +1 @@
AntennaPod

View File

@ -0,0 +1,31 @@
AntennaPod — менеджер и проигрыватель подкастов, который обеспечит Вас мгновенным доступом к миллионам бесплатных и платных подкастов, как от независимых подкастеров, так и крупных издательских домов. С лёгкостью добавляйте, импортируйте и экспортируйте их каналы используя каталог подкастов iTunes, файлы OPML или адреса каналов RSS.
Загружайте, транслируйте по сети или добавляйте выпуски в очередь и наслаждайтесь ими так, как вам нравится, с регулируемой скоростью воспроизведения, поддержкой оглавления и таймером сна.
Экономьте время, заряд батареи и мобильный трафик при помощи мощных средств автоматизации загрузки выпусков (фильтрация, указание времени и интервалов, а также сетей WiFi) и их удаления (избранные и настройки хранения).
Созданное поклонниками подкастов, AntennaPod — бесплатное и свободное приложение без рекламы и платежей.
<b>Импортируйте, систематизируйте и слушайте</b>
• Всевозможное управление воспроизведением: виджетом, системным уведомлением и кнопками проводных и беспроводных гарнитур
• Добавление и импорт каналов через каталоги iTunes и gPodder.net, файлы OPML и ссылки на каналы в RSS или Atom
• Приятное Вам прослушивание с регулировкой скорости воспроизведения, оглавлениями, запоминанием места воспроизведения и продвинутым таймером сна (со сбросом при встряхивании, снижением громкости)
• Доступ к каналам и выпускам защищённым паролем
<b>Отслеживайте, делитесь и благодарите</b>
• Отслеживайте лучших из лучших, помещая выпуски в избранное
• Поиск того самого выпуска в истории воспроизведения или по заголовкам и примечаниям
• Разнообразие способов поделиться выпусками и каналами через социальные сети и e-mail, услуги gPodder.net и экспорт в OPML
<b>Управляйте системой</b>
• Управление автоматической загрузкой: выбор отдельных каналов, запрет на использование мобильных сетей, выбор определённых точек доступа WiFi, только во время зарядки телефона и в заданное время или интервалы
• Управление хранением путём задания количества выпусков в кэше, автоудаление и выбор предпочтительного размещения
• Приспосабливается к Вашему окружению посредством светлого или тёмного оформления
• Резервирование Ваших подписок путём интеграции с gPodder.net и экпорта в OPML
<b>Присоединяйтесь к сообществу AntennaPod!</b>
AntennaPod постоянно развивается силами добровольцев. Вы тоже можете сделать свой вклад при помощи кода или комментария!
Посещайте GitHub для запроса новых возможностей, уведомления об ошибках и внесения кода:
https://www.github.com/AntennaPod/AntennaPod
Помогайте с переводом приложения на Transifex:
https://www.transifex.com/antennapod/antennapod

View File

@ -0,0 +1 @@
Удобный и гибкий менеджер и проигрыватель подкастов с открытым исходным кодом

View File

@ -0,0 +1 @@
AntennaPod

View File

@ -1,42 +1,31 @@
AntennaPod är en podcasthanterare och spelare som ger dig omedelbar tillgång till miljoner av gratis och betalda podcasts, från oberoende podcastare till stora publiceringshus så som BBC, NPR och CNN. Lägg till, importera och exportera enkelt deras flöden med iTunes podcastdatabas, OPML-filer eller vanliga RSS URL:er. Spara möda, batterikraft och mobildata med kraftfulla automatiseringskontroller för nedladdning (välj tider, intervall och WiFi-nätverk) och borttagning av episoder (baserat på dina favoriter och fördröjningsinställningar).
Men viktigast av allt: Ladda ner, strömma eller köa episoder och avnjut dem på det sätt du gillar med justerbar uppspelningshastighet, kapitelstöd och insomningstimer.
Antennapod är en podcasthanterare och spelare som ger dig omedelbar tillgång till millioner av gratis och betalda podcasts, allt ifrån oberoende podcasters till publiceringsjättar som BBC, NPR och CNN. Lägg till, importera och exportera enkelt deras flöden med hjälp av Itunes-podcastdatabas, OPML filer eller enkla RSS URL:er.
Ladda ner, strömma eller köa episoder och avnjut dem på det sätt du gillar med justerbar uppspelningshastighet, kapitelstöd och sömntimer.
Spara tid, batteri och mobildata med kraftfulla automatiseringskontroller för nedladdning av episoder (specifera tider, intervall och Wi-Fi nätverk) och borttagning av episoder (baserat på dina favoriseringar och fördröjningsinställningar).
Gjord av podcastenthusiaster, AntennaPod är fri i alla ordets bemärkelser: öppen källkod, inga kostnader, ingen reklam.
<b>Alla funktioner:</b><br>
IMPORTERA, ORGANISERA OCH SPELA<br>
&#8226; Lägg till och importera flöden via iTunes och gPodder.net, OPML filer och RSS eller Atom länkar<br>
&#8226; Hantera uppspelningen från vartsomhelst: hemskärmswidget, aviseringsfältet och hörlurs/bluetoth-kontroller<br>
&#8226; Njut av att lyssna på ditt sätt med justerbar uppspelningshastighet, kapitelstöd (MP4, VorbisComment och Podlove), ihågkommen uppspelningsposition och en avancerad sömntimer (skaka för återställaning, sänk volymen och sänk hastigheten)<br>
&#8226; Kom åt lösenordsskyddade flöden och episoder<br>
&#8226; Dra nytta av siduppdelade flöden (www.podlove.ord/paged-feeds)
<b>Importera, organisera och spela</b>
• Hantera uppspelningen från vartsomhelst: hemskärmswidget, aviseringsfältet och hörlurs/bluetoth-kontroller
• Lägg till och importera flöden via iTunes och gPodder.net, OPML filer och RSS eller Atom länkar
• Njut av att lyssna på ditt sätt med justerbar uppspelningshastighet, kapitelstöd (MP3, VorbisComment och Podlove), ihågkommen uppspelningsposition och en avancerad sömntimer (skaka för återställaning, sänk volymen och sänk hastigheten)
• Kom åt lösenordsskyddade flöden och episoder
SPÅRA, DELA & UPPSKATTA<br>
&#8226; Håll ordning på de bästa av de bästa med favoritmarkering av episoder<br>
&#8226; Hitta just den där episoden i uppspelningshistoriken eller genom sökning (titel och shownotes)<br>
&#8226; Dela episoder och flöden med avancerade vald för social media och och email, tjänsten gPodder.net och via OPML export<br>
<b>Håll reda på, dela & uppskatta</b>
Håll ordning på de bästa av de bästa med favoritmarkering av episoder
Hitta just den där episoden i uppspelningshistoriken eller genom sökning (titel och shownotes)
Dela episoder och flöden med avancerade vald för social media och och email, tjänsten gPodder.net och via OPML export
KONTROLLERA SYSTEMET<br>
&#8226; Ta kontroll över automatisk nedladdning: välj flöden, exkludera mobilnätverk, välj specifika WiFi nätverk, kräv att telefonen är inkopplad för laddning och sätt tider eller intervall för körning<br>
&#8226; Hantera lagringsutrymme genom att välja antalet cachade episoder, smart borttagning (baserat på dina favoriter och uppspelningsstatus) och välj den lagringsplats du föredrar<br>
&#8226; Använd AntennaPod på ditt språk (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br>
&#8226; Anpassa till din omgivning med det ljusa och mörka temat<br>
&#8226; Ta backup av dina prenumerationer med integreringen av gPodder.net och OPML exportering
<b>Kontroller systemet</b>
• Ta kontroll över automatisk nedladdning: välj flöden, exkludera mobilnätverk, välj specifika Wi-Fi nätverk, kräv att telefonen är inkopplad för laddning och sätt tider eller intervall för körning
• Hantera lagring med inställningar för antalet episoder i cachen, smart borttagning (med hänsyn till dina favoriter och uppspelningsstatus) och välj din föredragna plats
• Anpassa till din omgivning med det ljusa och mörka temat
• Ta backup av dina prenumerationer med integreringen av gPodder.net och OPML exportering
<b>Gå med i AntennaPods gemenskap!</b><br>
<b>Gå med i AntennaPods gemenskap!</b>
AntennaPod är under aktiv utveckling av volontärer. Du kan också bidra, med kod eller kommentarer!
GitHub är platsen att gå till för att be om funktioner, skapa buggrapporter eller bidra med kod:<br>
GitHub är platsen att gå till för att be om funktioner, skapa buggrapporter eller bidra med kod:
https://www.github.com/AntennaPod/AntennaPod
Vår Google Group är platsen för att dela idéer, dina favoritögonblick med podcasting och din uppskattning till volontärerna:<br>
https://groups.google.com/forum/#!forum/antennapod
Har du frågor eller vill ge feedback?
https://twitter.com/@AntennaPod
Transifex är platsen att gå till för att hjälpa till med översättningen:<br>
https://www.transifex.com/antennapod/antennapod
Kolla in vårat Beta Testing program för att få de senaste funktionerna först:<br>
https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod
Transifex är platsen att gå till för att hjälpa till med översättningen:
https://www.transifex.com/antennapod/antennapod

View File

@ -1,42 +1,31 @@
AntennaPod 是一款播客管理器和播放器可让您即时收听数百万免费和付费的播客从独立播客到大型出版商如BBCNPR和CNN使用 iTunes 播客数据库OPML文件或简单的RSS URL轻松添加导入和导出 feeds ;通过强大的自动化控制功能节省工作量,电池电量和移动数据使用情况,以便下载剧集(指定时间,间隔和 WiFi 网络)和删除剧集(根据您的收藏和延迟设置)。
但最重要的是:下载,串流或安排节目并用可调节回放速度,章节支持和睡眠定时器以您喜欢的方式享受它们。
AntennaPod是一个播客管理器和播放器可以让你即时访问数以百万计的免费和付费播客从独立播主到大型新闻机构出版社如BBC、NPR和CNN。使用iTunes podcast数据库、OPML文件或简单的RSS地址轻而易举地添加、导入和导出它们的提要Feed
下载,在线播放或对音频进行排队,并借助可调节的回放速度、章节支持及睡眠定时器以您喜爱的方式享用它们。
通过针对音频下载(指定时间、间隔和WiFi网络)和音频删除(根据您的喜好和延迟设置)的强大自动控制功能,节省精力、电池电量和移动数据使用量。
AntennaPod由播客爱好者开发在任意方面上都是自由的开源免费无广告。
由播客爱好者制作的AntennaPod在任何意义上都是免费的开源、无成本、无广告。
<b>所有功能:</b><br>
导入、整理与播放<br>
&#8226; 通过 iTunes、gPodder.net、OPML 文件、RSS 或 Atom 链接添加和导入订阅
&#8226从任意地点管理回放主屏widget系统通知耳塞和蓝牙控制装置
&#8226借助可调节回放速度章节支持Mp3、Vorbis注释和Podlove记忆的回放位置和一个高级的睡眠定时器 (摇动设备来重置、调低音量并减慢回放)以您自己的方式享受收听播客节目
#8226; 访问受密码保护的 feeds 和剧集
&#8226; 充分利用分页 feeds (www.podlove.org/paged-feeds)
<b>导入、组织和播放</b>
•从任何地方管理播放:主屏幕小部件、系统通知、耳塞和蓝牙控制
•通过iTunes和gPodder.net目录、OPML文件和RSS或Atom链接添加和导入提要
•通过可调整的回放速度、章节支持、记忆回放位置及高级睡眠定时器(晃动手机重置、调低音量)以您的方式享受收听
•访问有密码保护的提要和音频
保持更新,分享&欣赏
8226; 通过将剧集标记为收藏来追踪最佳的剧集
&#8226; 通过回放历史或搜索(标题和节目笔记)找到您需要的那期节目
&#8226; 通过高级社交媒体和电邮选项gPodder.net服务和导出OPML文件来分享节目和源
<b>保持跟踪、分享和欣赏</b>
•把剧集标记为最爱
•通过回放历史或通过搜索标题和shownotes找到某期节目
•通过高级社交媒体和电子邮件选项、gPodder.net服务和导出OPML分享剧集和提要
一切尽在掌控<br>
&#8226; 控制自动下载:选择源,排除移动网络,选择特定无线网络,要求手机充电并设定次数或间隔
&#8226; 通过设定缓存节目的数量管理存储,智能删除(基于您的喜好和播放状态)并选择您偏好的存储位置
&#8226; 使用对应您的语言的 AntennaPod (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br>
8226; 使用浅色和深色主题以适应您的环境
8226; 使用 gPodder.net 集成功能和 OPML 导出以备份您的订阅
<b>控制系统</b>
•控制自动下载选择订阅源、排除移动网络、选择特定的WiFi网络、要求手机充电设置次数或间隔
•通过设置缓存的剧集数量、智能删除和选择您的首选位置来管理存储
•使用浅色和深色主题适应你的环境
• 使用gPodder.net集成和OPML导出备份订阅
<b>加入 AntennaPod 社区</b><br>
<b>加入AntennaPod社区</b>
志愿者正在积极开发 AntennaPod 。您也可以通过代码或评论做出贡献!
GitHub 是申请增加功能,报告错误和贡献代码的地方:
前往Github请求功能、报告错误和贡献代码
https://www.github.com/AntennaPod/AntennaPod
对于所有志愿者来说,我们的谷歌社群是分享你的创意,收藏的播客瞬间和表达感激的地方:
https://groups.google.com/forum/#!forum/antennapod
抱有疑问或者想要向我们提供反馈?
https://twitter.com/@AntennaPod
Transifex 是与翻译者帮助项目的网站:
https://www.transifex.com/antennapod/antennapod
查看我们的测试程序以获得最新的功能列表:
https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod
要帮忙翻译请前往Transifex
https://www.transifex.com/antennapod/antennapod

View File

@ -1,7 +1,3 @@
- Added per-feed playback speed setting (by @spacecowboy)
- Support sorting in Podcast screen (by @orionlee)
- Option to show stream button rather than download in lists (by @dsmith47)
- Option to replace Episode cover with Podcast cover (by @xgouchet)
- Transparent widget (by @M-arcel)
- User interface tweaks (by @ByteHamster)
- Tons of bug fixes and improvements
- Enabled picture-in-picture for video podcasts by default (by @ByteHamster)
- Fixed podcast discovery not showing local trends (by @tonytamsf)
- Various bug fixes and improvements (by @ByteHamster)

View File

@ -105,50 +105,55 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginStart="16dp"
android:layout_marginRight="16dp"
android:layout_marginEnd="16dp"
android:orientation="horizontal"
android:gravity="center_vertical"
tools:background="@android:color/holo_blue_bright">
<View
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_weight="1" />
<Button
android:id="@+id/butAction1"
style="?attr/buttonBarButtonStyle"
android:layout_width="wrap_content"
android:layout_height="48dp"
android:ellipsize="end"
android:drawablePadding="8dp"
android:textColor="?android:attr/textColorPrimary"
tools:text="Button 1"
tools:background="@android:color/holo_red_light" />
<View
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_weight="1" />
<Button
android:id="@+id/butAction2"
style="?attr/buttonBarButtonStyle"
android:layout_width="wrap_content"
android:layout_height="48dp"
android:drawablePadding="8dp"
android:ellipsize="end"
android:textColor="?android:attr/textColorPrimary"
tools:text="Button 2"
tools:background="@android:color/holo_orange_dark" />
<View
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_weight="1" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:id="@+id/butAction1"
android:orientation="horizontal"
android:background="?android:attr/selectableItemBackground"
android:gravity="center">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:id="@+id/butAction1Icon"
android:layout_margin="12dp"
tools:src="@drawable/ic_settings_grey600_24dp"/>
<TextView
android:textAppearance="@style/TextAppearance.AppCompat.Button"
android:id="@+id/butAction1Text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="?android:attr/textColorPrimary"
tools:text="Button 1"/>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:id="@+id/butAction2"
android:orientation="horizontal"
android:background="?android:attr/selectableItemBackground"
android:gravity="center">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:id="@+id/butAction2Icon"
android:layout_margin="12dp"
tools:src="@drawable/ic_settings_grey600_24dp"/>
<TextView
android:textAppearance="@style/TextAppearance.AppCompat.Button"
android:id="@+id/butAction2Text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="?android:attr/textColorPrimary"
tools:text="Button 2"/>
</LinearLayout>
</LinearLayout>
<View

View File

@ -37,6 +37,7 @@
android:layout_toLeftOf="@id/horizontal_divider"
android:layout_toStartOf="@id/horizontal_divider"
android:background="?android:attr/selectableItemBackground"
android:textColor="?android:attr/textColorPrimary"
android:text="@string/cancel_label" />
<Button
@ -50,6 +51,7 @@
android:layout_toRightOf="@id/horizontal_divider"
android:layout_toEndOf="@id/horizontal_divider"
android:background="?android:attr/selectableItemBackground"
android:textColor="?android:attr/textColorPrimary"
android:text="@string/confirm_label" />
</RelativeLayout>

View File

@ -35,7 +35,7 @@
android:summary="@string/pref_resumeAfterCall_sum"
android:title="@string/pref_resumeAfterCall_title"/>
<ListPreference
android:defaultValue="stop"
android:defaultValue="pip"
android:entries="@array/video_background_behavior_options"
android:entryValues="@array/video_background_behavior_values"
android:key="prefVideoBehavior"

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:hint="@string/search_hint"
android:hint="@string/search_label"
android:label="@string/app_name"/>

View File

@ -0,0 +1,53 @@
#!/bin/sh
function generateText() {
echo "$1"
convert -size 1698x750 xc:none -gravity Center -pointsize 150 -fill white -font Lato-Regular \
-annotate 0 "$1" /tmp/text.png
}
function simplePhone() {
generateText "$1"
convert templates/phone.png \
$2 -geometry +306+989 -composite \
/tmp/text.png -geometry +0+0 -composite \
$3
}
function addLayer() {
convert $2 $1 -composite $2
}
function generateScreenshots() {
language=$1
mkdir output/$1 2>/dev/null
text0=`cat raw/$language/texts.txt | head -1 | tail -1`
text1=`cat raw/$language/texts.txt | head -2 | tail -1`
text2=`cat raw/$language/texts.txt | head -3 | tail -1`
text3=`cat raw/$language/texts.txt | head -4 | tail -1`
text4=`cat raw/$language/texts.txt | head -5 | tail -1`
text5=`cat raw/$language/texts.txt | head -6 | tail -1`
simplePhone "$text0" raw/$language/00.png output/$language/00.png
simplePhone "$text1" raw/$language/01.png output/$language/01.png
simplePhone "$text2" raw/$language/02.png output/$language/02.png
generateText "$text3"
convert templates/twophones.png \
templates/twophones-a.png -geometry +0+0 -composite \
raw/$language/03a.png -geometry +119+984 -composite \
templates/twophones-b.png -geometry +0+0 -composite \
raw/$language/03b.png -geometry +479+1540 -composite \
/tmp/text.png -geometry +0+0 -composite \
output/$language/03.png
simplePhone "$text4" raw/$language/04.png output/$language/04.png
simplePhone "$text5" raw/$language/05.png output/$language/05.png
addLayer templates/suggestions.png output/$language/05.png
optipng output/$language/*.png
}
mkdir output 2>/dev/null
generateScreenshots "de-DE"
generateScreenshots "en-US"
rm /tmp/text.png

View File

Before

Width:  |  Height:  |  Size: 966 KiB

After

Width:  |  Height:  |  Size: 966 KiB

View File

Before

Width:  |  Height:  |  Size: 972 KiB

After

Width:  |  Height:  |  Size: 972 KiB

View File

Before

Width:  |  Height:  |  Size: 248 KiB

After

Width:  |  Height:  |  Size: 248 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 385 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 387 KiB

View File

Before

Width:  |  Height:  |  Size: 462 KiB

After

Width:  |  Height:  |  Size: 462 KiB

View File

Before

Width:  |  Height:  |  Size: 688 KiB

After

Width:  |  Height:  |  Size: 688 KiB

View File

@ -0,0 +1,6 @@
Abonniere deine\nLieblings-Podcasts
Player mit\nSchlummerfunktion
Automatisches\nHerunterladen
Wähle dein\nLieblings-Theme
Passe AntennaPod\nan deine Wünsche an
Entdecke tausende\nneuer Podcasts

View File

Before

Width:  |  Height:  |  Size: 930 KiB

After

Width:  |  Height:  |  Size: 930 KiB

View File

Before

Width:  |  Height:  |  Size: 95 KiB

After

Width:  |  Height:  |  Size: 95 KiB

View File

Before

Width:  |  Height:  |  Size: 245 KiB

After

Width:  |  Height:  |  Size: 245 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 385 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 387 KiB

View File

Before

Width:  |  Height:  |  Size: 371 KiB

After

Width:  |  Height:  |  Size: 371 KiB

View File

Before

Width:  |  Height:  |  Size: 742 KiB

After

Width:  |  Height:  |  Size: 742 KiB

View File

@ -0,0 +1,6 @@
Subscribe to all of your\nfavorite podcasts
Powerful player\nwith sleep timer
Save time with\nautomatic downloads
Select the theme\nthat fits best to you
Adapt AntennaPod\nto your needs
Discover thousands\nof great podcasts

View File

Before

Width:  |  Height:  |  Size: 929 KiB

After

Width:  |  Height:  |  Size: 929 KiB

View File

Before

Width:  |  Height:  |  Size: 94 KiB

After

Width:  |  Height:  |  Size: 94 KiB

View File

Before

Width:  |  Height:  |  Size: 248 KiB

After

Width:  |  Height:  |  Size: 248 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 387 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 389 KiB

View File

Before

Width:  |  Height:  |  Size: 370 KiB

After

Width:  |  Height:  |  Size: 370 KiB

View File

Before

Width:  |  Height:  |  Size: 710 KiB

After

Width:  |  Height:  |  Size: 710 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 442 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 548 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 532 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 467 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

@ -0,0 +1,37 @@
@font-face {
font-family: 'Roboto-Light';
src: url('file:///android_asset/Roboto-Light.ttf');
}
* {
color: %s;
font-family: roboto-Light;
font-size: 13pt;
overflow-wrap: break-word;
}
a {
font-style: normal;
text-decoration: none;
font-weight: normal;
color: #00A8DF;
}
a.timecode {
color: #669900;
}
img, iframe {
display: block;
margin: 10 auto;
max-width: 100%%;
height: auto;
}
body {
margin: %dpx %dpx %dpx %dpx;
}
p#apNoShownotes {
position: fixed;
top: 50%%;
left: 50%%;
transform: translate(-50%%, -50%%);
text-align: center;
-webkit-text-size-adjust: none;
font-size: 80%%;
}

View File

@ -1,22 +0,0 @@
package de.danoeh.antennapod.core.feed;
import de.danoeh.antennapod.core.storage.SearchLocation;
public class SearchResult {
private final FeedComponent component;
private SearchLocation location;
public SearchResult(FeedComponent component, SearchLocation location) {
super();
this.component = component;
this.location = location;
}
public FeedComponent getComponent() {
return component;
}
public SearchLocation getLocation() {
return location;
}
}

View File

@ -389,7 +389,7 @@ public class UserPreferences {
return Float.parseFloat(prefs.getString(PREF_PLAYBACK_SPEED, "1.00"));
} catch (NumberFormatException e) {
Log.e(TAG, Log.getStackTraceString(e));
UserPreferences.setPlaybackSpeed("1.00");
UserPreferences.setPlaybackSpeed(1.0f);
return 1.0f;
}
}
@ -399,7 +399,7 @@ public class UserPreferences {
return Float.parseFloat(prefs.getString(PREF_VIDEO_PLAYBACK_SPEED, "1.00"));
} catch (NumberFormatException e) {
Log.e(TAG, Log.getStackTraceString(e));
UserPreferences.setVideoPlaybackSpeed("1.00");
UserPreferences.setVideoPlaybackSpeed(1.0f);
return 1.0f;
}
}
@ -408,7 +408,7 @@ public class UserPreferences {
return prefs.getBoolean(PREF_PLAYBACK_SKIP_SILENCE, false);
}
public static String[] getPlaybackSpeedArray() {
public static float[] getPlaybackSpeedArray() {
return readPlaybackSpeedArray(prefs.getString(PREF_PLAYBACK_SPEED_ARRAY, null));
}
@ -638,15 +638,15 @@ public class UserPreferences {
.apply();
}
public static void setPlaybackSpeed(String speed) {
public static void setPlaybackSpeed(float speed) {
prefs.edit()
.putString(PREF_PLAYBACK_SPEED, speed)
.putString(PREF_PLAYBACK_SPEED, String.valueOf(speed))
.apply();
}
public static void setVideoPlaybackSpeed(String speed) {
public static void setVideoPlaybackSpeed(float speed) {
prefs.edit()
.putString(PREF_VIDEO_PLAYBACK_SPEED, speed)
.putString(PREF_VIDEO_PLAYBACK_SPEED, String.valueOf(speed))
.apply();
}
@ -769,24 +769,22 @@ public class UserPreferences {
}
}
private static String[] readPlaybackSpeedArray(String valueFromPrefs) {
String[] selectedSpeeds = null;
// If this preference hasn't been set yet, return the default options
if (valueFromPrefs == null) {
selectedSpeeds = new String[] { "0.75", "1.00", "1.25", "1.50", "1.75", "2.00" };
} else {
private static float[] readPlaybackSpeedArray(String valueFromPrefs) {
if (valueFromPrefs != null) {
try {
JSONArray jsonArray = new JSONArray(valueFromPrefs);
selectedSpeeds = new String[jsonArray.length()];
float[] selectedSpeeds = new float[jsonArray.length()];
for (int i = 0; i < jsonArray.length(); i++) {
selectedSpeeds[i] = jsonArray.getString(i);
selectedSpeeds[i] = (float) jsonArray.getDouble(i);
}
return selectedSpeeds;
} catch (JSONException e) {
Log.e(TAG, "Got JSON error when trying to get speeds from JSONArray");
e.printStackTrace();
}
}
return selectedSpeeds;
// If this preference hasn't been set yet, return the default options
return new float[] { 0.75f, 1.0f, 1.25f, 1.5f, 1.75f, 2.0f };
}
public static String getMediaPlayer() {
@ -816,11 +814,11 @@ public class UserPreferences {
}
public static VideoBackgroundBehavior getVideoBackgroundBehavior() {
switch (prefs.getString(PREF_VIDEO_BEHAVIOR, "stop")) {
switch (prefs.getString(PREF_VIDEO_BEHAVIOR, "pip")) {
case "stop": return VideoBackgroundBehavior.STOP;
case "pip": return VideoBackgroundBehavior.PICTURE_IN_PICTURE;
case "continue": return VideoBackgroundBehavior.CONTINUE_PLAYING;
default: return VideoBackgroundBehavior.STOP;
default: return VideoBackgroundBehavior.PICTURE_IN_PICTURE;
}
}

View File

@ -646,6 +646,7 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
float retVal = 1;
if ((playerStatus == PlayerStatus.PLAYING
|| playerStatus == PlayerStatus.PAUSED
|| playerStatus == PlayerStatus.INITIALIZED
|| playerStatus == PlayerStatus.PREPARED) && mediaPlayer.canSetSpeed()) {
retVal = mediaPlayer.getCurrentSpeedMultiplier();
}

View File

@ -54,10 +54,10 @@ import de.danoeh.antennapod.core.event.settings.SpeedPresetChangedEvent;
import de.danoeh.antennapod.core.event.settings.VolumeAdaptionChangedEvent;
import de.danoeh.antennapod.core.feed.Chapter;
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.feed.FeedComponent;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.feed.MediaType;
import de.danoeh.antennapod.core.feed.SearchResult;
import de.danoeh.antennapod.core.glide.ApGlideSettings;
import de.danoeh.antennapod.core.preferences.PlaybackPreferences;
import de.danoeh.antennapod.core.preferences.SleepTimerPreferences;
@ -574,6 +574,7 @@ public class PlaybackService extends MediaBrowserServiceCompat {
} else if (mediaPlayer.getPlayable() == null) {
startPlayingFromPreferences();
}
taskManager.restartSleepTimer();
return true;
case KeyEvent.KEYCODE_MEDIA_PLAY:
if (status == PlayerStatus.PAUSED || status == PlayerStatus.PREPARED) {
@ -584,6 +585,7 @@ public class PlaybackService extends MediaBrowserServiceCompat {
} else if (mediaPlayer.getPlayable() == null) {
startPlayingFromPreferences();
}
taskManager.restartSleepTimer();
return true;
case KeyEvent.KEYCODE_MEDIA_PAUSE:
if (status == PlayerStatus.PLAYING) {
@ -833,9 +835,6 @@ public class PlaybackService extends MediaBrowserServiceCompat {
@Override
public void onPlaybackStart(@NonNull Playable playable, int position) {
if (taskManager.isSleepTimerActive()) {
taskManager.restartSleepTimer();
}
taskManager.startWidgetUpdater();
if (position != PlaybackServiceMediaPlayer.INVALID_TIME) {
playable.setPosition(position);
@ -1468,10 +1467,12 @@ public class PlaybackService extends MediaBrowserServiceCompat {
public void resume() {
mediaPlayer.resume();
taskManager.restartSleepTimer();
}
public void prepare() {
mediaPlayer.prepare();
taskManager.restartSleepTimer();
}
public void pause(boolean abandonAudioFocus, boolean reinit) {
@ -1634,16 +1635,17 @@ public class PlaybackService extends MediaBrowserServiceCompat {
public void onPlayFromSearch(String query, Bundle extras) {
Log.d(TAG, "onPlayFromSearch query=" + query + " extras=" + extras.toString());
List<SearchResult> results = FeedSearcher.performSearch(getBaseContext(), query, 0);
for (SearchResult result : results) {
try {
FeedMedia p = ((FeedItem) (result.getComponent())).getMedia();
mediaPlayer.playMediaObject(p, !p.localFileAvailable(), true, true);
return;
} catch (Exception e) {
Log.d(TAG, e.getMessage());
e.printStackTrace();
continue;
List<FeedComponent> results = FeedSearcher.performSearch(getBaseContext(), query, 0);
for (FeedComponent result : results) {
if (result instanceof FeedItem) {
try {
FeedMedia media = ((FeedItem) result).getMedia();
mediaPlayer.playMediaObject(media, !media.localFileAvailable(), true, true);
return;
} catch (Exception e) {
Log.d(TAG, e.getMessage());
e.printStackTrace();
}
}
}
onPlay();

Some files were not shown because too many files have changed in this diff Show More