Merge branch 'develop' into settings_icon_fix

This commit is contained in:
Martin Fietz 2018-10-21 11:22:07 +02:00 committed by GitHub
commit 4621a38a11
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
154 changed files with 935 additions and 340 deletions

View File

@ -33,6 +33,7 @@ trans.kn_IN = core/src/main/res/values-kn-rIN/strings.xml
trans.ko = core/src/main/res/values-ko/strings.xml
trans.ko_KR = core/src/main/res/values-ko-rKR/strings.xml
trans.lt = core/src/main/res/values-lt/strings.xml
trans.mk = core/src/main/res/values-mk/strings.xml
trans.nb = core/src/main/res/values-nb/strings.xml
trans.no = core/src/main/res/values-no/strings.xml
trans.nl = core/src/main/res/values-nl/strings.xml

View File

@ -1,10 +1,10 @@
Change Log
==========
Version 1.6.6
Version 1.7.0
-------------
* Experimental new media player (ExoPlayer)
* NEW ExoPlayer (experimental)
* Fix for Bluetooth Forward (Oreo)
* Preference redesign + search
* Notification improvements

View File

@ -150,6 +150,7 @@ dependencies {
implementation "com.android.support:gridlayout-v7:$supportVersion"
implementation "com.android.support:percent:$supportVersion"
implementation "com.android.support:recyclerview-v7:$supportVersion"
compileOnly 'com.google.android.wearable:wearable:2.2.0'
implementation "org.apache.commons:commons-lang3:$commonslangVersion"
implementation("org.shredzone.flattr4j:flattr4j-core:$flattr4jVersion") {
exclude group: "org.json", module: "json"

View File

@ -125,3 +125,13 @@
-keep class com.squareup.moshi.** { *; }
-keep interface com.squareup.moshi.** { *; }
-keep public class retrofit2.adapter.rxjava.RxJavaCallAdapterFactory { *; }
# awaitility
-dontwarn java.beans.BeanInfo
-dontwarn java.beans.Introspector
-dontwarn java.beans.IntrospectionException
-dontwarn java.beans.PropertyDescriptor
-dontwarn java.lang.management.ManagementFactory
-dontwarn java.lang.management.ThreadInfo
-dontwarn java.lang.management.ThreadMXBean

View File

@ -21,6 +21,7 @@ import de.danoeh.antennapod.core.util.flattr.FlattrStatus;
*/
class DBTestUtils {
private DBTestUtils(){}
/**
* Use this method when tests don't involve chapters.
*/

View File

@ -8,6 +8,7 @@ import java.io.IOException;
* Utility methods for FeedGenerator
*/
class GeneratorUtil {
private GeneratorUtil(){}
public static void addPaymentLink(XmlSerializer xml, String paymentLink, boolean withNamespace) throws IOException {
String ns = (withNamespace) ? "http://www.w3.org/2005/Atom" : null;

View File

@ -2,8 +2,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="de.danoeh.antennapod"
android:installLocation="auto"
android:versionCode="1060690"
android:versionName="1.6.6-RC1">
android:versionCode="1070000"
android:versionName="1.7.0">
<!--
Version code schema:
"1.2.3-SNAPSHOT" -> 1020300

View File

@ -20,7 +20,7 @@ public class PodcastApp extends Application {
try {
Class.forName("de.danoeh.antennapod.config.ClientConfigurator");
} catch (Exception e) {
throw new RuntimeException("ClientConfigurator not found");
throw new RuntimeException("ClientConfigurator not found", e);
}
}

View File

@ -69,22 +69,6 @@ public class FeedSettingsActivity extends AppCompatActivity {
private Subscription subscription;
private final View.OnClickListener copyUrlToClipboard = new View.OnClickListener() {
@Override
public void onClick(View v) {
if(feed != null && feed.getDownload_url() != null) {
String url = feed.getDownload_url();
ClipData clipData = ClipData.newPlainText(url, url);
android.content.ClipboardManager cm = (android.content.ClipboardManager) FeedSettingsActivity.this
.getSystemService(Context.CLIPBOARD_SERVICE);
cm.setPrimaryClip(clipData);
Toast t = Toast.makeText(FeedSettingsActivity.this, R.string.copied_url_msg, Toast.LENGTH_SHORT);
t.show();
}
}
};
private boolean authInfoChanged = false;
private final TextWatcher authTextWatcher = new TextWatcher() {

View File

@ -231,7 +231,6 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
Log.d(TAG, "onCreate()");
StorageUtils.checkStorageAvailability(this);
orientation = getResources().getConfiguration().orientation;
getWindow().setFormat(PixelFormat.TRANSPARENT);
}
@ -265,15 +264,10 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
private void onBufferUpdate(float progress) {
if (sbPosition != null) {
sbPosition.setSecondaryProgress((int) progress * sbPosition.getMax());
sbPosition.setSecondaryProgress((int) (progress * sbPosition.getMax()));
}
}
/**
* Current screen orientation.
*/
private int orientation;
@Override
protected void onStart() {
super.onStart();
@ -992,7 +986,7 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
}
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == REQUEST_CODE_STORAGE) {
if (grantResults.length <= 0 || grantResults[0] != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, R.string.needs_storage_permission, Toast.LENGTH_LONG).show();

View File

@ -357,7 +357,7 @@ public abstract class MediaplayerInfoActivity extends MediaplayerActivity implem
@Override
public boolean onOptionsItemSelected(MenuItem item) {
return drawerToggle != null && drawerToggle.onOptionsItemSelected(item) || super.onOptionsItemSelected(item);
return (drawerToggle != null && drawerToggle.onOptionsItemSelected(item)) || super.onOptionsItemSelected(item);
}
@Override

View File

@ -144,7 +144,7 @@ public class OnlineFeedViewActivity extends AppCompatActivity {
feedUrl = getIntent().getStringExtra(ARG_FEEDURL);
} else if (TextUtils.equals(getIntent().getAction(), Intent.ACTION_SEND)
|| TextUtils.equals(getIntent().getAction(), Intent.ACTION_VIEW)) {
feedUrl = (TextUtils.equals(getIntent().getAction(), Intent.ACTION_SEND))
feedUrl = TextUtils.equals(getIntent().getAction(), Intent.ACTION_SEND)
? getIntent().getStringExtra(Intent.EXTRA_TEXT) : getIntent().getDataString();
if (actionBar != null) {
actionBar.setTitle(R.string.add_feed_label);
@ -306,7 +306,7 @@ public class OnlineFeedViewActivity extends AppCompatActivity {
}
private void parseFeed() {
if (feed == null || feed.getFile_url() == null && feed.isDownloaded()) {
if (feed == null || (feed.getFile_url() == null && feed.isDownloaded())) {
throw new IllegalStateException("feed must be non-null and downloaded when parseFeed is called");
}
Log.d(TAG, "Parsing feed");

View File

@ -14,6 +14,8 @@ import de.danoeh.antennapod.core.export.opml.OpmlElement;
*/
public class OpmlImportHolder {
private OpmlImportHolder(){}
private static ArrayList<OpmlElement> readElements;
public static ArrayList<OpmlElement> getReadElements() {

View File

@ -45,8 +45,6 @@ import de.danoeh.antennapod.core.service.GpodnetSyncService;
public class GpodnetAuthenticationActivity extends AppCompatActivity {
private static final String TAG = "GpodnetAuthActivity";
private static final String CURRENT_STEP = "current_step";
private ViewFlipper viewFlipper;
private static final int STEP_DEFAULT = -1;

View File

@ -8,6 +8,8 @@ import de.danoeh.antennapod.core.ClientConfig;
*/
class ClientConfigurator {
private ClientConfigurator(){}
static {
ClientConfig.USER_AGENT = "AntennaPod/" + BuildConfig.VERSION_NAME;
ClientConfig.applicationCallbacks = new ApplicationCallbacksImpl();

View File

@ -1,5 +1,6 @@
package de.danoeh.antennapod.dialog;
import android.app.AlertDialog;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
@ -95,6 +96,28 @@ public class EpisodesApplyActionFragment extends Fragment {
}
refreshCheckboxes();
});
mListView.setOnItemLongClickListener((adapterView, view12, position, id) -> {
new AlertDialog.Builder(getActivity())
.setItems(R.array.batch_long_press_options, (dialogInterface, item) -> {
int direction;
if (item == 0) {
direction = -1;
} else {
direction = 1;
}
int currentPosition = position + direction;
while (currentPosition >= 0 && currentPosition < episodes.size()) {
long id1 = episodes.get(currentPosition).getId();
if (!checkedIds.contains(id1)) {
checkedIds.add(id1);
}
currentPosition += direction;
}
refreshCheckboxes();
}).show();
return true;
});
for(FeedItem episode : episodes) {
titles.add(episode.getTitle());

View File

@ -17,6 +17,9 @@ import de.danoeh.antennapod.core.preferences.GpodnetPreferences;
* Creates a dialog that lets the user change the hostname for the gpodder.net service.
*/
public class GpodnetSetHostnameDialog {
private GpodnetSetHostnameDialog(){}
private static final String TAG = "GpodnetSetHostnameDialog";
public static AlertDialog createDialog(final Context context) {

View File

@ -17,6 +17,8 @@ import de.danoeh.antennapod.R;
public class RatingDialog {
private RatingDialog(){}
private static final String TAG = RatingDialog.class.getSimpleName();
private static final int AFTER_DAYS = 7;

View File

@ -22,7 +22,6 @@ import de.danoeh.antennapod.core.util.playback.Playable;
public class CoverFragment extends Fragment implements MediaplayerInfoContentFragment {
private static final String TAG = "CoverFragment";
private static final String ARG_PLAYABLE = "arg.playable";
private Playable media;

View File

@ -20,10 +20,10 @@ import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.feed.MediaType;
import de.danoeh.antennapod.core.glide.ApGlideSettings;
import de.danoeh.antennapod.core.service.playback.PlaybackService;
import de.danoeh.antennapod.core.util.Converter;
import de.danoeh.antennapod.core.util.playback.Playable;
import de.danoeh.antennapod.core.util.playback.PlaybackController;
import rx.Single;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;
@ -41,6 +41,7 @@ public class ExternalPlayerFragment extends Fragment {
private TextView mFeedName;
private ProgressBar mProgressBar;
private PlaybackController controller;
private Subscription subscription;
public ExternalPlayerFragment() {
super();
@ -81,7 +82,7 @@ public class ExternalPlayerFragment extends Fragment {
super.onActivityCreated(savedInstanceState);
controller = setupPlaybackController();
butPlay.setOnClickListener(v -> {
if(controller != null) {
if (controller != null) {
controller.playPause();
}
});
@ -142,6 +143,9 @@ public class ExternalPlayerFragment extends Fragment {
if (controller != null) {
controller.release();
}
if (subscription != null) {
subscription.unsubscribe();
}
}
@Override
@ -162,7 +166,7 @@ public class ExternalPlayerFragment extends Fragment {
controller = setupPlaybackController();
if (butPlay != null) {
butPlay.setOnClickListener(v -> {
if(controller != null) {
if (controller != null) {
controller.playPause();
}
});
@ -177,7 +181,10 @@ public class ExternalPlayerFragment extends Fragment {
return false;
}
Single.create(subscriber -> subscriber.onSuccess(controller.getMedia()))
if (subscription != null) {
subscription.unsubscribe();
}
subscription = Single.create(subscriber -> subscriber.onSuccess(controller.getMedia()))
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(media -> updateUi((Playable) media));
@ -206,15 +213,10 @@ public class ExternalPlayerFragment extends Fragment {
butPlay.setVisibility(View.VISIBLE);
}
} else {
Log.w(TAG, "loadMediaInfo was called while the media object of playbackService was null!");
Log.w(TAG, "loadMediaInfo was called while the media object of playbackService was null!");
}
}
private String getPositionString(int position, int duration) {
return Converter.getDurationStringLong(position) + " / "
+ Converter.getDurationStringLong(duration);
}
public PlaybackController getPlaybackControllerTestingOnly() {
return controller;
}

View File

@ -417,13 +417,10 @@ public class ItemlistFragment extends ListFragment {
}
private boolean insideOnFragmentLoaded = false;
private void onFragmentLoaded() {
if(!isVisible()) {
return;
}
insideOnFragmentLoaded = true;
if (adapter == null) {
setListAdapter(null);
setupHeaderView();
@ -440,9 +437,6 @@ public class ItemlistFragment extends ListFragment {
if (feed != null && feed.getNextPageLink() == null && listFooter != null) {
getListView().removeFooterView(listFooter.getRoot());
}
insideOnFragmentLoaded = false;
}
private void refreshHeaderView() {

View File

@ -21,7 +21,6 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.yqritc.recyclerviewflexibledivider.HorizontalDividerItemDecoration;
@ -46,7 +45,6 @@ import de.danoeh.antennapod.core.service.download.Downloader;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBTasks;
import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.core.storage.DownloadRequestException;
import de.danoeh.antennapod.core.storage.DownloadRequester;
import de.danoeh.antennapod.core.util.Converter;
import de.danoeh.antennapod.core.util.FeedItemUtil;
@ -489,8 +487,8 @@ public class QueueFragment extends Fragment {
private void reallyMoved(int from, int to) {
// Write drag operation to database
Log.d(TAG, "Write to database move(" + dragFrom + ", " + dragTo + ")");
DBWriter.moveQueueItem(dragFrom, dragTo, true);
Log.d(TAG, "Write to database move(" + from + ", " + to + ")");
DBWriter.moveQueueItem(from, to, true);
}
}
);
@ -535,9 +533,12 @@ public class QueueFragment extends Fragment {
String info = queue.size() + getString(R.string.episodes_suffix);
if(queue.size() > 0) {
long timeLeft = 0;
float playbackSpeed = Float.valueOf(UserPreferences.getPlaybackSpeed());
for(FeedItem item : queue) {
if(item.getMedia() != null) {
timeLeft += item.getMedia().getDuration() - item.getMedia().getPosition();
timeLeft +=
(long) ((item.getMedia().getDuration() - item.getMedia().getPosition())
/ playbackSpeed);
}
}
info += " \u2022 ";

View File

@ -30,6 +30,9 @@ import de.danoeh.antennapod.core.util.ShareUtils;
* Handles interactions with the FeedItemMenu.
*/
public class FeedMenuHandler {
private FeedMenuHandler(){ }
private static final String TAG = "FeedMenuHandler";
public static boolean onCreateOptionsMenu(MenuInflater inflater, Menu menu) {

View File

@ -227,6 +227,9 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
return true;
});
if (Build.VERSION.SDK_INT >= 26) {
ui.findPreference(UserPreferences.PREF_EXPANDED_NOTIFICATION).setVisible(false);
}
}
private void setupStorageScreen() {

View File

@ -1,4 +1,4 @@
AntennaPod ist ein Podcast-Manager und -Player, der Dir unmittelbar Zugriff auf Millionen von freien und bezahlten Podcasts ermöglicht, angefangen von unabhängigen Podcastern zu großen Rundfunkanstalten oder Hörfunksendern wie BBC, NPR und CNN. Abonniere, importiere und exportiere deine Feeds mühelos mit Hilfe des iTunes-Verzeichnisses, OPML-Dateien oder einfachen RSS-URLs. Reduziere Aufwand, Stromverbrauch und Datenverbrauch durch die Kontrolle der Downloads (bestimmte Uhrzeiten, Intervalle, WiFi-Netze) und des Löschens von Episoden (basierend auf deinen Favoriten und weiteren Einstellungen).<br>
AntennaPod ist ein Podcast-Manager und -Player, der Dir unmittelbar Zugriff auf Millionen von freien und kostenpflichtigen Podcasts ermöglicht, angefangen von unabhängigen Podcastern bis hin zu großen Rundfunkanstalten wie BBC, NPR und CNN. Abonniere, importiere und exportiere deine Feeds mühelos mit Hilfe des iTunes-Verzeichnisses, OPML-Dateien oder einfachen RSS-URLs. Reduziere Aufwand, Stromverbrauch und Datenverbrauch durch die Kontrolle der Downloads (bestimmte Uhrzeiten, Intervalle, WiFi-Netze) und des Löschens von Episoden (basierend auf deinen Favoriten und weiteren Einstellungen).<br>
Aber am wichtigsten: Downloade, streame oder füge Episoden zur Abspielliste hinzu und genieße sie mit einstellbarer Abspielgeschwindigkeit, Unterstützung von Kapiteln und Schlummerfunktion. Mit Flattr kannst du den Podcastern sogar deine Wertschätzung zeigen.
AntennaPod ist, von Podcast-Enthusiasten gemacht, frei im Sinne des Wortes: Open Source, keine Kosten, keine Werbung.
@ -24,7 +24,7 @@ STEUER DAS SYSTEM<br>
&#8226; Passe das Aussehen mit dem hellen oder dunklen Theme an<br>
&#8226; Sichere deine Abonnements mit gPodder.net oder über den OPML-Export
<b>Trete der AntennaPod-Community bei!</b><br>
<b>Tritt der AntennaPod-Community bei!</b><br>
AntennaPod wird aktiv von Freiwilligen weiterentwickelt. Auch du kannst bei der Entwicklung mit Quellcode oder Kommentaren mitwirken!
Wir verwenden GitHub für Funktionswünsche (Feature Requests), Fehlerberichte (Bug Reports) und zum Beisteuern von Code (Code Contributions).

View File

@ -1,11 +1,11 @@
AntennaPod is a podcast manager and player that gives you instant access to millions of free and paid podcasts, from independent podcasters to large publishing houses such as the BBC, NPR and CNN. Add, import and export their feeds hassle-free using the iTunes podcast database, OPML files or simple RSS URLs. Save effort, battery power and mobile data usage with powerful automation controls for downloading episodes (specify times, intervals and WiFi networks) and deleting episodes (based your favourites and delay settings).<br>
But most importantly: Download, stream or queue episodes and enjoy them the way you like with adjustable playback speeds, chapter support and a sleep timer. You can even show your love to the content creators with our Flattr integration.
Το Antennapod είναι μία εφαρμογή διαχείρισης και εκτέλεσης podcasts που σας δίνει άμεση πρόσβαση σε εκατομμύρια δωρεάν και επί πληρωμή podcasts, από ανεξάρτητους podcasters έως μεγάλους εκδοτικούς οίκους όπως το BBC, NPR και CNN. Μπορείτε εύκολα να προσθέσετε, να εισάγετε και να εξάγετε τις ροές τους χρησιμοποιώντας τη βάση δεδομένων podcast του iTunes, αρχεία OPML ή απλά RSS URLs. Γλυτώστε προσπάθεια, μπαταρία και χρήση δεδομένων κινητής τηλεφωνίας με ισχυρές ρυθμίσεις αυτοματισμών για λήψη επεισοδίων (ορίστε τους χρόνους, τα διαστήματα και τα δίκτυα WiFi) και σβήστε επεισόδια (με βάση τα αγαπημένα σας και τις ρυθμίσεις καθυστέρησης).<br>
Αλλά το πλέον σημαντικό: Κατεβάστε, κάντε stream ή βάλτε στη σειρά επεισόδια και απολαύστε τα όπως επιθυμήτε με ρυθμιζόμενη ταχύτητα αναπαραγωγής, υποστήριξη κεφάλαιων και χρονόμετρο απενεργοποίησης. Μπορείτε ακόμη και να δείξετε την αγάπη σας στους δημιουργούς περιεχομένου μέσω της ενσωμάτωσης του Flattr.
Made by podcast-enthousiast, AntennaPod is free in all senses of the word: open source, no costs, no ads.
Φτιαγμένο από λάτρη των podcast, το AntennaPod είναι ελεύθερο με όλες τις έννοιες της λέξης: ανοικτού λογισμικού, χωρίς κόστη, χωρίς διαφημίσεις.
<b>All features:</b><br>
IMPORT, ORGANIZE AND PLAY<br>
&#8226; Add and import feeds via the iTunes and gPodder.net directories, OPML files and RSS or Atom links<br>
<b>Όλα τα χαρακτηριστικά:</b><br>
ΕΙΣΑΓΩΓΉ, ΟΡΓΆΝΩΣΗ ΚΑΙ ΕΚΤΈΛΕΣΗ<br>
&#8226; Προσθέστε και εισάγετε ροές μέσω των φακέλων του iTunes και του gPodder.net, αρχείων OPML και RSS ή συνδέσμους Atom<br>
&#8226; Manage playback from anywhere: homescreen widget, system notification and earplug and bluetooth controls<br>
&#8226; Enjoy listening your way with adjustable playback speed, chapter support (MP3, VorbisComment and Podlove), remembered playback position and an advanced sleep timer (shake to reset, lower volume and slow down playback)<br>
&#8226; Access password-protected feeds and episodes<br>
@ -24,20 +24,20 @@ CONTROL THE SYSTEM<br>
&#8226; Adapt to your environment using the light and dark theme<br>
&#8226; Back-up your subscriptions with the gPodder.net integration and OPML export
<b>Join the AntennaPod community!</b><br>
AntennaPod is under active development by volunteers. You can contribute too, with code or with comment!
<b>Ενταχθείτε στη κοινότητα του AntennaPod!</b><br>
Το AntennaPod βρίσκεται υπό ενεργή ανάπτυξη από εθελοντές. Μπορείτε και εσείς να συνεισφέρετε, με κώδικα ή με κάποιο σχόλιο.
GitHub is the place to go for feature requests, bug reports and code contributions:<br>
Το Github είναι το μέρος να επισκεφθείτε για να ζητήσετε καινούρια χαρακτηριστικά, να αναφέρετε σφάλματα και για συνεισφορά κώδικα:<br>
https://www.github.com/AntennaPod/AntennaPod
Our Google Group is the place to share your ideas, favourite podcasting moments and gratitude to all the volunteers:<br>
Το Google Group μας είναι το μέρος να μοιραστείτε τις ιδέες σας, τις αγαπημένες σας στιγμές ενασχόλησης με τα podcasts και ευγνωμοσύνη σε όλους τους εθελοντές:<br>
https://groups.google.com/forum/#!forum/antennapod
Have a question or want to give us feedback?
Έχετε κάποια ερώτηση ή θέλετε να μας δώσετε κάποια ανατροφοδότηση;
https://twitter.com/@AntennaPod
Transifex is the place to help with translations:<br>
Το Transifex είναι το μέρος για να βοηθήσετε με τις μεταφράσεις:<br>
https://www.transifex.com/antennapod/antennapod
Check out our Beta Testing programme to get the latest features first:<br>
Ελέγξτε το πρόγραμμά μας Beta Testing για να λαμβάνετε τα τελευταία χαρακτηριστικά πρώτοι:<br>
https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod

View File

@ -1,4 +1,4 @@
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 (a horas o intervalos específicos, o redes WiFi) y de borrado de episodios (basado en favoritos y ajustes de tiempo).<br>
AntennaPod es un gestor y reproductor de podcast que te da acceso instantáneo a millones de podcast gratuitos y pagos, 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. Ahorre esfuerzo, energía de la batería y uso de datos móviles con potentes controles de automatización para descargar episodios (especifique horarios, intervalos y redes WiFi) y elimine episodios (según sus preferencias y configuraciones de demora).<br>
Y lo más importante: descarga, escucha en stream y disfrutalos como quieras con velocidad de reproducción variable, soporte para capítulos y temporizador de sueño. Incluso puedes mostrar tu gratitud a los creadores de contenido mediante Flattr.
Hecho por entusiastas del podcasting, AntennaPod es libre, gratuito y sin publicidad.

View File

@ -38,16 +38,21 @@
<PreferenceCategory android:title="@string/project_pref">
<Preference
android:key="prefFaq"
android:title="@string/pref_faq"/>
android:title="@string/pref_faq"
android:icon="?attr/ic_question_answer" />
<Preference
android:key="prefKnownIssues"
android:title="@string/pref_known_issues"/>
android:title="@string/pref_known_issues"
android:icon="?attr/ic_known_issues" />
<Preference
android:key="prefSendCrashReport"
android:title="@string/crash_report_title"
android:summary="@string/crash_report_sum"/>
android:summary="@string/crash_report_sum"
android:icon="?attr/ic_bug" />
<Preference
android:key="prefAbout"
android:title="@string/about_pref"/>
android:title="@string/about_pref"
android:icon="?attr/action_about" />
</PreferenceCategory>
</PreferenceScreen>

View File

@ -0,0 +1,118 @@
package android.support.v4.app;
import android.app.job.JobParameters;
import android.app.job.JobServiceEngine;
import android.app.job.JobWorkItem;
import android.content.Intent;
import android.os.Build;
import android.os.IBinder;
import android.support.annotation.RequiresApi;
import android.util.Log;
public abstract class SafeJobIntentService extends JobIntentService {
@Override
public void onCreate() {
super.onCreate();
if (Build.VERSION.SDK_INT >= 26) {
mJobImpl = new SafeJobServiceEngineImpl(this);
}
}
/**
* Implementation of a safe JobServiceEngine for interaction with JobIntentService.
*/
@RequiresApi(26)
static final class SafeJobServiceEngineImpl extends JobServiceEngine
implements JobIntentService.CompatJobEngine {
static final String TAG = "JobServiceEngineImpl";
static final boolean DEBUG = false;
final JobIntentService mService;
final Object mLock = new Object();
JobParameters mParams;
final class WrapperWorkItem implements JobIntentService.GenericWorkItem {
final JobWorkItem mJobWork;
WrapperWorkItem(JobWorkItem jobWork) {
mJobWork = jobWork;
}
@Override
public Intent getIntent() {
return mJobWork.getIntent();
}
@Override
public void complete() {
synchronized (mLock) {
if (mParams != null) {
try {
mParams.completeWork(mJobWork);
} catch (SecurityException e) {
Log.e(TAG, Log.getStackTraceString(e));
}
}
}
}
}
SafeJobServiceEngineImpl(JobIntentService service) {
super(service);
mService = service;
}
@Override
public IBinder compatGetBinder() {
return getBinder();
}
@Override
public boolean onStartJob(JobParameters params) {
if (DEBUG) Log.d(TAG, "onStartJob: " + params);
mParams = params;
// We can now start dequeuing work!
mService.ensureProcessorRunningLocked(false);
return true;
}
@Override
public boolean onStopJob(JobParameters params) {
if (DEBUG) Log.d(TAG, "onStartJob: " + params);
boolean result = mService.doStopCurrentWork();
synchronized (mLock) {
// Once we return, the job is stopped, so its JobParameters are no
// longer valid and we should not be doing anything with them.
mParams = null;
}
return result;
}
/**
* Dequeue some work.
*/
@Override
public JobIntentService.GenericWorkItem dequeueWork() {
JobWorkItem work = null;
synchronized (mLock) {
if (mParams == null) {
return null;
}
try {
work = mParams.dequeueWork();
} catch (SecurityException e) {
Log.e(TAG, Log.getStackTraceString(e));
}
}
if (work != null) {
work.getIntent().setExtrasClassLoader(mService.getClassLoader());
return new WrapperWorkItem(work);
} else {
return null;
}
}
}
}

View File

@ -24,6 +24,8 @@ import de.danoeh.antennapod.core.storage.DBWriter;
*/
class UpdateManager {
private UpdateManager(){}
private static final String TAG = UpdateManager.class.getSimpleName();
private static final String PREF_NAME = "app_version";

View File

@ -19,11 +19,9 @@ import de.danoeh.antennapod.core.util.flattr.FlattrUtils;
public class FlattrStatusFetcher extends Thread {
private static final String TAG = "FlattrStatusFetcher";
private final Context context;
public FlattrStatusFetcher(Context context) {
super();
this.context = context;
}
@Override

View File

@ -50,7 +50,7 @@ public abstract class FeedComponent {
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (o == null || !(o instanceof FeedComponent)) return false;
FeedComponent that = (FeedComponent) o;
@ -62,4 +62,4 @@ public abstract class FeedComponent {
public int hashCode() {
return (int) (id ^ (id >>> 32));
}
}
}

View File

@ -194,7 +194,7 @@ public class FeedItem extends FeedComponent implements ShownotesProvider, Flattr
if (other.link != null) {
link = other.link;
}
if (other.pubDate != null && other.pubDate != pubDate) {
if (other.pubDate != null && other.pubDate.equals(pubDate)) {
pubDate = other.pubDate;
}
if (other.media != null) {

View File

@ -532,8 +532,8 @@ public class FeedMedia extends FeedFile implements Playable {
UserPreferences.isAutoFlattr() &&
item.getPaymentLink() != null &&
item.getFlattrStatus().getUnflattred() &&
(completed && autoFlattrThreshold <= 1.0f ||
played_duration >= autoFlattrThreshold * duration)) {
((completed && autoFlattrThreshold <= 1.0f) ||
(played_duration >= autoFlattrThreshold * duration))) {
DBTasks.flattrItemIfLoggedIn(context, item);
}
}
@ -626,6 +626,9 @@ public class FeedMedia extends FeedFile implements Playable {
@Override
public boolean equals(Object o) {
if (o == null) {
return false;
}
if (FeedMediaFlavorHelper.instanceOfRemoteMedia(o)) {
return o.equals(this);
}

View File

@ -6,6 +6,7 @@ import com.bumptech.glide.load.engine.DiskCacheStrategy;
* The settings that AntennaPod will use for various Glide options
*/
public class ApGlideSettings {
private ApGlideSettings(){}
public static final DiskCacheStrategy AP_DISK_CACHE_STRATEGY = DiskCacheStrategy.ALL;
}

View File

@ -169,7 +169,7 @@ public class GpodnetEpisodeAction {
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (o == null || !(o instanceof GpodnetEpisodeAction)) return false;
GpodnetEpisodeAction that = (GpodnetEpisodeAction) o;

View File

@ -24,6 +24,8 @@ import de.danoeh.antennapod.core.service.GpodnetSyncService;
*/
public class GpodnetPreferences {
private GpodnetPreferences(){}
private static final String TAG = "GpodnetPreferences";
private static final String PREF_NAME = "gpodder.net";

View File

@ -23,7 +23,6 @@ public class SleepTimerPreferences {
private static final String DEFAULT_VALUE = "15";
private static final int DEFAULT_TIME_UNIT = 1;
private static Context context;
private static SharedPreferences prefs;
/**

View File

@ -34,6 +34,7 @@ import java.util.concurrent.TimeUnit;
* when called.
*/
public class UserPreferences {
private UserPreferences(){}
private static final String IMPORT_DIR = "import/";
@ -44,7 +45,7 @@ public class UserPreferences {
public static final String PREF_HIDDEN_DRAWER_ITEMS = "prefHiddenDrawerItems";
private static final String PREF_DRAWER_FEED_ORDER = "prefDrawerFeedOrder";
private static final String PREF_DRAWER_FEED_COUNTER = "prefDrawerFeedIndicator";
private static final String PREF_EXPANDED_NOTIFICATION = "prefExpandNotify";
public static final String PREF_EXPANDED_NOTIFICATION = "prefExpandNotify";
private static final String PREF_PERSISTENT_NOTIFICATION = "prefPersistNotify";
public static final String PREF_COMPACT_NOTIFICATION_BUTTONS = "prefCompactNotificationButtons";
public static final String PREF_LOCKSCREEN_BACKGROUND = "prefLockscreenBackground";

View File

@ -6,8 +6,8 @@ import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.v4.app.JobIntentService;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.SafeJobIntentService;
import android.support.v4.util.ArrayMap;
import android.util.Log;
import android.util.Pair;
@ -44,7 +44,7 @@ import de.danoeh.antennapod.core.util.gui.NotificationUtils;
* Synchronizes local subscriptions with gpodder.net service. The service should be started with ACTION_SYNC as an action argument.
* This class also provides static methods for starting the GpodnetSyncService.
*/
public class GpodnetSyncService extends JobIntentService {
public class GpodnetSyncService extends SafeJobIntentService {
private static final String TAG = "GpodnetSyncService";

View File

@ -9,23 +9,24 @@ import android.content.ServiceConnection;
import android.os.Build;
import android.os.IBinder;
import android.support.annotation.NonNull;
import android.support.v4.app.JobIntentService;
import android.support.v4.app.SafeJobIntentService;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.widget.RemoteViews;
import de.danoeh.antennapod.core.R;
import de.danoeh.antennapod.core.receiver.MediaButtonReceiver;
import de.danoeh.antennapod.core.receiver.PlayerWidget;
import de.danoeh.antennapod.core.service.playback.PlaybackService;
import de.danoeh.antennapod.core.service.playback.PlayerStatus;
import de.danoeh.antennapod.core.util.Converter;
import de.danoeh.antennapod.core.util.playback.Playable;
import de.danoeh.antennapod.core.receiver.PlayerWidget;
/**
* Updates the state of the player widget
*/
public class PlayerWidgetJobService extends JobIntentService {
public class PlayerWidgetJobService extends SafeJobIntentService {
private static final String TAG = "PlayerWidgetJobService";

View File

@ -40,6 +40,9 @@ import okhttp3.internal.http.StatusLine;
* Provides access to a HttpClient singleton.
*/
public class AntennapodHttpClient {
private AntennapodHttpClient(){}
private static final String TAG = "AntennapodHttpClient";
private static final int CONNECTION_TIMEOUT = 30000;

View File

@ -124,7 +124,7 @@ public class DownloadRequest implements Parcelable {
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (o == null || !(o instanceof DownloadRequest)) return false;
DownloadRequest that = (DownloadRequest) o;

View File

@ -117,11 +117,6 @@ public class DownloadService extends Service {
private CompletionService<Downloader> downloadExecutor;
private FeedSyncThread feedSyncThread;
/**
* Number of threads of downloadExecutor.
*/
private static final int NUM_PARALLEL_DOWNLOADS = 6;
private DownloadRequester requester;
@ -862,22 +857,6 @@ public class DownloadService extends Service {
return true;
}
/**
* Delete files that aren't needed anymore
*/
private void cleanup(Feed feed) {
if (feed.getFile_url() != null) {
if (new File(feed.getFile_url()).delete()) {
Log.d(TAG, "Successfully deleted cache file.");
} else {
Log.e(TAG, "Failed to delete cache file.");
}
feed.setFile_url(null);
} else {
Log.d(TAG, "Didn't delete cache file: File url is not set.");
}
}
public void shutdown() {
isActive = false;
if (isCollectingRequests) {

View File

@ -304,7 +304,7 @@ public class HttpDownloader extends Downloader {
String encoded = ByteString.of(bytes).base64();
return "Basic " + encoded;
} catch (UnsupportedEncodingException e) {
throw new AssertionError();
throw new AssertionError(e);
}
}

View File

@ -602,14 +602,6 @@ public class PlaybackService extends MediaBrowserServiceCompat {
mediaPlayer.setVideoSurface(sh);
}
/**
* Called when the surface holder of the mediaplayer has to be changed.
*/
private void resetVideoSurface() {
taskManager.cancelPositionSaver();
mediaPlayer.resetVideoSurface();
}
public void notifyVideoSurfaceAbandoned() {
mediaPlayer.pause(true, false);
mediaPlayer.resetVideoSurface();

View File

@ -12,7 +12,7 @@ public enum PlayerStatus {
INITIALIZING(9), // playback service is loading the Playable's metadata
INITIALIZED(10); // playback service was started, data source of media player was set.
private int statusValue;
private final int statusValue;
private static final PlayerStatus[] fromOrdinalLookup;
static {

View File

@ -75,7 +75,7 @@ public final class DBReader {
cursor = adapter.getAllFeedsCursor();
List<Feed> feeds = new ArrayList<>(cursor.getCount());
while (cursor.moveToNext()) {
Feed feed = extractFeedFromCursorRow(adapter, cursor);
Feed feed = extractFeedFromCursorRow(cursor);
feeds.add(feed);
}
return feeds;
@ -243,7 +243,7 @@ public final class DBReader {
return result;
}
private static Feed extractFeedFromCursorRow(PodDBAdapter adapter, Cursor cursor) {
private static Feed extractFeedFromCursorRow(Cursor cursor) {
Feed feed = Feed.fromCursor(cursor);
FeedPreferences preferences = FeedPreferences.fromCursor(cursor);
feed.setPreferences(preferences);
@ -580,7 +580,7 @@ public final class DBReader {
try {
cursor = adapter.getFeedCursor(feedId);
if (cursor.moveToNext()) {
feed = extractFeedFromCursorRow(adapter, cursor);
feed = extractFeedFromCursorRow(cursor);
feed.setItems(getFeedItemList(feed));
} else {
Log.e(TAG, "getFeed could not find feed with id " + feedId);
@ -1007,7 +1007,7 @@ public final class DBReader {
Cursor feedCursor = adapter.getFeedsInFlattrQueueCursor();
if (feedCursor.moveToFirst()) {
do {
result.add(extractFeedFromCursorRow(adapter, feedCursor));
result.add(extractFeedFromCursorRow(feedCursor));
} while (feedCursor.moveToNext());
}
feedCursor.close();

View File

@ -777,10 +777,8 @@ public final class DBTasks {
*/
abstract static class QueryTask<T> implements Callable<T> {
private T result;
private final Context context;
public QueryTask(Context context) {
this.context = context;
}
@Override

View File

@ -19,6 +19,8 @@ import de.danoeh.antennapod.core.util.comparator.SearchResultValueComparator;
* Performs search on Feeds and FeedItems
*/
public class FeedSearcher {
private FeedSearcher(){}
private static final String TAG = "FeedSearcher";

View File

@ -22,9 +22,6 @@ public class NSRSS20 extends Namespace {
private static final String TAG = "NSRSS20";
private static final String NSTAG = "rss";
private static final String NSURI = "";
public static final String CHANNEL = "channel";
public static final String ITEM = "item";
private static final String GUID = "guid";

View File

@ -15,7 +15,6 @@ public abstract class Namespace {
public abstract SyndElement handleElementStart(String localName, HandlerState state, Attributes attributes);
/** Called by a Feedhandler when in endElement and it detects a namespace element
* @return true if namespace handled the element, false if it ignored it
* */
public abstract void handleElementEnd(String localName, HandlerState state);

View File

@ -47,8 +47,6 @@ public class NSAtom extends Namespace {
private static final String LINK_REL_ARCHIVES = "archives";
private static final String LINK_REL_ENCLOSURE = "enclosure";
private static final String LINK_REL_PAYMENT = "payment";
private static final String LINK_REL_RELATED = "related";
private static final String LINK_REL_SELF = "self";
private static final String LINK_REL_NEXT = "next";
// type-values
private static final String LINK_TYPE_ATOM = "application/atom+xml";

View File

@ -28,7 +28,6 @@ public final class Converter {
/** Determines the length of the number for best readability.*/
private static final int NUM_LENGTH = 1024;
private static final int DAYS_MIL = 86400000;
private static final int HOURS_MIL = 3600000;
private static final int MINUTES_MIL = 60000;
private static final int SECONDS_MIL = 1000;

View File

@ -17,7 +17,9 @@ import java.util.TimeZone;
*/
public class DateUtils {
private static final String TAG = "DateUtils";
private DateUtils(){}
private static final String TAG = "DateUtils";
private static final TimeZone defaultTimezone = TimeZone.getTimeZone("GMT");
@ -135,7 +137,7 @@ public class DateUtils {
if (parts.length >= 2) {
result += Integer.parseInt(parts[idx]) * 60000L;
idx++;
result += (Float.parseFloat(parts[idx])) * 1000L;
result += (long) (Float.parseFloat(parts[idx]) * 1000L);
}
return result;
}

View File

@ -5,6 +5,7 @@ import java.util.List;
import de.danoeh.antennapod.core.feed.FeedItem;
public class FeedItemUtil {
private FeedItemUtil(){}
public static int indexOfItemWithDownloadUrl(List<FeedItem> items, String downloadUrl) {
if(items == null) {

View File

@ -8,6 +8,7 @@ import android.content.pm.ResolveInfo;
import java.util.List;
public class IntentUtils {
private IntentUtils(){}
/*
* Checks if there is at least one exported activity that can be performed for the intent

View File

@ -5,6 +5,9 @@ import android.support.v4.util.ArrayMap;
import java.nio.charset.Charset;
public class LangUtils {
private LangUtils(){}
public static final Charset UTF_8 = Charset.forName("UTF-8");
private static final ArrayMap<String, String> languages;

View File

@ -27,6 +27,7 @@ import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;
public class NetworkUtils {
private NetworkUtils(){}
private static final String TAG = NetworkUtils.class.getSimpleName();

View File

@ -9,6 +9,7 @@ import java.util.concurrent.TimeUnit;
* Media file should be "rewinded" x seconds after user resumes the playback.
*/
public class RewindAfterPauseUtils {
private RewindAfterPauseUtils(){}
public static final long ELAPSED_TIME_FOR_SHORT_REWIND = TimeUnit.MINUTES.toMillis(1);
public static final long ELAPSED_TIME_FOR_MEDIUM_REWIND = TimeUnit.HOURS.toMillis(1);

View File

@ -14,6 +14,8 @@ import de.danoeh.antennapod.core.preferences.UserPreferences;
* Utility functions for handling storage errors
*/
public class StorageUtils {
private StorageUtils(){}
private static final String TAG = "StorageUtils";
public static boolean storageAvailable() {

View File

@ -11,6 +11,8 @@ import de.danoeh.antennapod.core.R;
import de.danoeh.antennapod.core.preferences.UserPreferences;
public class ThemeUtils {
private ThemeUtils(){}
private static final String TAG = "ThemeUtils";
public static int getSelectionBackgroundColor() {

View File

@ -11,7 +11,9 @@ import de.danoeh.antennapod.core.BuildConfig;
/** Ensures that only one instance of the FlattrService class exists at a time */
class FlattrServiceCreator {
private static final String TAG = "FlattrServiceCreator";
private FlattrServiceCreator(){}
public static final String TAG = "FlattrServiceCreator";
private static volatile FlattrService flattrService;

View File

@ -36,6 +36,8 @@ import de.danoeh.antennapod.core.storage.DBWriter;
*/
public class FlattrUtils {
private FlattrUtils(){}
private static final String TAG = "FlattrUtils";
private static final String HOST_NAME = "de.danoeh.antennapod";

View File

@ -7,6 +7,7 @@ import de.danoeh.antennapod.core.R;
/** Utility class for MediaPlayer errors. */
public class MediaPlayerError {
private MediaPlayerError(){}
/** Get a human-readable string for a specific error code. */
public static String getErrorString(Context context, int code) {

View File

@ -176,6 +176,8 @@ public interface Playable extends Parcelable,
* Provides utility methods for Playable objects.
*/
class PlayableUtils {
private PlayableUtils(){}
private static final String TAG = "PlayableUtils";
/**

View File

@ -702,7 +702,7 @@ public abstract class PlaybackController {
return org.antennapod.audio.MediaPlayer.isPrestoLibraryInstalled(activity.getApplicationContext())
|| UserPreferences.useSonic()
|| Build.VERSION.SDK_INT >= 23
|| playbackService != null && playbackService.canSetSpeed();
|| (playbackService != null && playbackService.canSetSpeed());
}
public void setPlaybackSpeed(float speed) {

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 813 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 653 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 492 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 459 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 601 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 663 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 529 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 423 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 406 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 488 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 960 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 710 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 504 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 462 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 602 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 276 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 926 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 631 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 594 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 310 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 738 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 666 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 900 B

View File

@ -1,17 +1,34 @@
<?xml version='1.0' encoding='UTF-8'?>
<resources xmlns:tools="http://schemas.android.com/tools">
<!--Activitiy and fragment titles-->
<string name="feeds_label">Feeds</string>
<string name="feed_update_receiver_name">تحديث التسجيل</string>
<string name="feeds_label">مغذيات</string>
<string name="statistics_label">إحصائيات</string>
<string name="add_feed_label">إضافة بودكاست</string>
<string name="episodes_label">حلقات</string>
<string name="all_episodes_short_label">الكل</string>
<string name="new_episodes_label">جديد</string>
<string name="favorite_episodes_label">المفضلات</string>
<string name="new_label">جديد</string>
<string name="settings_label">اعدادات</string>
<string name="settings_label">إعدادات</string>
<string name="downloads_label">تنزيل</string>
<string name="downloads_running_label">جارى التشغيل</string>
<string name="downloads_completed_label">اكتمل</string>
<string name="downloads_log_label">سجل</string>
<string name="subscriptions_label">تسجيلات</string>
<string name="subscriptions_list_label">لائحة التسجيلات</string>
<string name="cancel_download_label">الغاء التنزيل</string>
<string name="playback_history_label">أرشيف التشغيل</string>
<string name="gpodnet_main_label">gpodder.net</string>
<string name="gpodnet_summary">تزامن مع أجهزة أخرى</string>
<string name="gpodnet_auth_label">تسجيل الدخول لموقع gpodder</string>
<string name="free_space_label"> %1$s مجانا</string>
<string name="episode_cache_full_title">ذاكرة تخزين الحلقات ممتلئة</string>
<string name="episode_cache_full_message">لقد تم تجاوز الحد الأقصى لتخزين الحلقات. المرجو الرفع من قيمة التخزين في قائمة الإعدادات.</string>
<string name="synchronizing">المزامنة...</string>
<!--Statistics fragment-->
<string name="total_time_listened_to_podcasts">مجموع وقت تشغيل البودكاستات:</string>
<string name="statistics_mode">نمط الإحصائيات</string>
<!--Main activity-->
<string name="drawer_open">قائمة الفتح</string>
<string name="drawer_close">قائمة الاغلاف</string>
@ -27,11 +44,13 @@
<string name="copied_url_msg">تم نسخ الرابط للحافظة</string>
<string name="go_to_position_label">اذهب لهذا الموقع</string>
<!--Playback history-->
<string name="clear_history_label">مسح الأرشيف</string>
<!--Other-->
<string name="confirm_label">تأكيد</string>
<string name="cancel_label">الغاء</string>
<string name="yes">نعم</string>
<string name="no">لا</string>
<string name="reset">إعادة التعيين</string>
<string name="author_label">المؤلف</string>
<string name="language_label">لغة</string>
<string name="url_label">عنوان الموقع</string>
@ -61,7 +80,6 @@
<string name="show_info_label">اظهار المعلومات</string>
<string name="share_label">مشاركة</string>
<string name="share_link_label">مشاركة الرابط</string>
<string name="episode_actions">تطبيق الاجراء</string>
<string name="hide_unplayed_episodes_label">لم يتم تشغيله</string>
<string name="hide_paused_episodes_label">ايقاف مؤقت</string>
<string name="hide_downloaded_episodes_label">تم التنزيل</string>
@ -106,24 +124,73 @@
<!--Auto-Flattr dialog-->
<!--Search-->
<!--OPML import and export-->
<string name="opml_import_error_no_file">لم يتم اختيار أي ملف</string>
<string name="select_all_label">اختر الكل</string>
<string name="deselect_all_label">ألغ اختيار الكل</string>
<string name="select_options_label">اختر...</string>
<string name="choose_file_from_filesystem">عبر ملف نظام داخلي </string>
<string name="choose_file_from_external_application">إستخدام تطبيق خارجي</string>
<string name="opml_export_label">تصدير بصيغة OPML</string>
<string name="html_export_label">تصدير بصيغة HTML</string>
<string name="exporting_label">جار التصدير ...</string>
<string name="export_error_label">حدث خطأ أثناء التصدير</string>
<string name="export_success_title">تم التصدير بنجاح</string>
<!--Sleep timer-->
<string name="enter_time_here_label">أدخل التوقيت</string>
<string name="timer_vibration_label">تشغيل الهزاز</string>
<string name="time_seconds">ثواني</string>
<string name="time_minutes">دقائق</string>
<string name="time_hours">ساعات</string>
<!--gpodder.net-->
<string name="gpodnet_taglist_header">الفئات</string>
<string name="gpodnet_toplist_header">أقوى البودكاستات</string>
<string name="gpodnet_suggestions_header">إقتراحات</string>
<string name="gpodnetauth_login_title">تسجيل الدخول</string>
<string name="gpodnetauth_login_butLabel">تسجيل الدخول</string>
<string name="username_label">إسم المستخدم</string>
<string name="password_label">كلمة المرور</string>
<string name="gpodnetauth_device_title">اختيار الأجهزة:</string>
<string name="gpodnetauth_device_butCreateNewDevice">أدخل جهازا جديدا</string>
<string name="gpodnetauth_device_chooseExistingDevice">اختر جهازا من القائمة: </string>
<string name="gpodnetauth_device_butChoose">إختر</string>
<string name="gpodnetauth_finish_title">لقد تم تسجيل الدخول بنجاح!</string>
<string name="gpodnetauth_finish_butgomainscreen">إذهب إلى الصفحة الرئيسية</string>
<string name="gpodnetsync_auth_error_descr">خطأ في إسم المستخدم أو كلمة المرور</string>
<string name="gpodnetsync_pref_report_successful">تم بنجاح</string>
<!--Directory chooser-->
<string name="selected_folder_label">إختيار المستند:</string>
<string name="create_folder_label">أنشأ مستندا جديدا</string>
<string name="choose_data_directory">إختيار مستند البيانات</string>
<!--Online feed view-->
<string name="downloading_label">تحميل ...</string>
<!--Content descriptions for image buttons-->
<string name="media_type_audio_label">صوت</string>
<string name="media_type_video_label">فيديو</string>
<string name="load_next_page_label">تحميل الصفحة التالية</string>
<!--Feed information screen-->
<string name="authentication_label">تسجيل الدخول</string>
<!--Progress information-->
<!--AntennaPodSP-->
<!--Episodes apply actions-->
<string name="all_label">الكل</string>
<string name="selected_all_label">إختيار كل الحلقات</string>
<string name="unplayed_label">لم يتم تشغيله</string>
<string name="downloaded_label">تم التنزيل</string>
<string name="not_downloaded_label">لم يتم التنزيل</string>
<!--Sort-->
<!--Rating dialog-->
<!--Audio controls-->
<string name="volume">مستوى الصوت</string>
<!--proxy settings-->
<string name="proxy_type_label">النوع</string>
<!--Database import/export-->
<string name="label_import">استيراد</string>
<string name="label_export">تصدير</string>
<string name="export_ok">تم التصدير بنجاح</string>
<!--Casting-->
<!--<string name="cast_failed_to_connect">Could not connect to the device</string>-->
<!--Notification channels-->
<string name="notification_channel_downloading">تحميل</string>
<string name="notification_channel_playing">يشغل حاليا</string>
<string name="notification_channel_error">الأخطاء</string>
</resources>

View File

@ -165,7 +165,6 @@
<string name="deselect_all_label">Seçimi ləğv et</string>
<string name="opml_export_label">OPML ixraçı</string>
<string name="export_error_label">İxracın xətası</string>
<string name="opml_export_success_sum">OPML fayl:\u0020 yazılıb</string>
<!--Sleep timer-->
<string name="set_sleeptimer_label">Yuxu taymerini qoy</string>
<string name="disable_sleeptimer_label">Yuxu taymerini keçir</string>
@ -200,4 +199,5 @@
<!--Database import/export-->
<!--Casting-->
<!--<string name="cast_failed_to_connect">Could not connect to the device</string>-->
<!--Notification channels-->
</resources>

View File

@ -109,7 +109,6 @@
<string name="feed_remover_msg">Desaniciando fees</string>
<string name="load_complete_feed">Completóse\'l refrescu\'l feed</string>
<string name="hide_episodes_title">Anubrir episodios</string>
<string name="episode_actions">Aplicar aiciones</string>
<string name="hide_unplayed_episodes_label">Ensin reproducir</string>
<string name="hide_paused_episodes_label">Posóse</string>
<string name="hide_played_episodes_label">Reprodúxose</string>
@ -243,7 +242,6 @@
<!--Preferences-->
<string name="storage_pref">Almacenamientu</string>
<string name="project_pref">Proyeutu</string>
<string name="services_label">Servicios</string>
<string name="flattr_label">Flattr</string>
<string name="pref_episode_cleanup_title">Llimpieza d\'episodios</string>
<string name="pref_pauseOnDisconnect_sum">Posa la reproducción al desconeutase los auriculares o Bluetooth</string>
@ -378,4 +376,5 @@
<!--Database import/export-->
<!--Casting-->
<!--<string name="cast_failed_to_connect">Could not connect to the device</string>-->
<!--Notification channels-->
</resources>

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