diff --git a/twidere.component.common/src/main/aidl/org/mariotaku/twidere/IStatusShortener.aidl b/twidere.component.common/src/main/aidl/org/mariotaku/twidere/IStatusShortener.aidl index 83991b897..a12ec6b42 100644 --- a/twidere.component.common/src/main/aidl/org/mariotaku/twidere/IStatusShortener.aidl +++ b/twidere.component.common/src/main/aidl/org/mariotaku/twidere/IStatusShortener.aidl @@ -18,16 +18,10 @@ */ package org.mariotaku.twidere; -import org.mariotaku.twidere.model.ParcelableAccount; -import org.mariotaku.twidere.model.ParcelableStatus; -import org.mariotaku.twidere.model.ParcelableStatusUpdate; -import org.mariotaku.twidere.model.StatusShortenResult; - interface IStatusShortener { - StatusShortenResult shorten(in ParcelableStatusUpdate status,in ParcelableAccount currentAccount, - String overrideStatusText); + String shorten(String statusJson, long currentAccountId, String overrideStatusText); - boolean callback(in StatusShortenResult result, in ParcelableStatus status); + boolean callback(String resultJson, String statusJson); } diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/TwidereConstants.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/TwidereConstants.java index f273b44a8..630fdbcf6 100644 --- a/twidere.component.common/src/main/java/org/mariotaku/twidere/TwidereConstants.java +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/TwidereConstants.java @@ -231,6 +231,8 @@ public interface TwidereConstants extends SharedPreferenceConstants, IntentConst String METADATA_KEY_EXTENSION_SETTINGS = "org.mariotaku.twidere.extension.settings"; String METADATA_KEY_EXTENSION_ICON = "org.mariotaku.twidere.extension.icon"; String METADATA_KEY_EXTENSION_USE_JSON = "org.mariotaku.twidere.extension.use_json"; + String METADATA_KEY_EXTENSION_VERSION_STATUS_SHORTENER = "org.mariotaku.twidere.extension.version.status_shortener"; + String METADATA_KEY_EXTENSION_VERSION_MEDIA_UPLOADER = "org.mariotaku.twidere.extension.version.media_uploader"; char SEPARATOR_PERMISSION = '|'; String SEPARATOR_PERMISSION_REGEX = "\\" + SEPARATOR_PERMISSION; diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/constant/SharedPreferenceConstants.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/constant/SharedPreferenceConstants.java index af8db3b29..ef9da22ba 100644 --- a/twidere.component.common/src/main/java/org/mariotaku/twidere/constant/SharedPreferenceConstants.java +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/constant/SharedPreferenceConstants.java @@ -302,6 +302,8 @@ public interface SharedPreferenceConstants { String KEY_API_LAST_CHANGE = "api_last_change"; @Preference(type = LONG, exportable = false) String KEY_DEFAULT_ACCOUNT_ID = "default_account_id"; + @Preference(type = BOOLEAN, exportable = true, defaultBoolean = true) + String KEY_RETRY_ON_NETWORK_ISSUE = "retry_on_network_issue"; @Preference(type = BOOLEAN, hasDefault = true, defaultBoolean = false) diff --git a/twidere.component.common/src/main/res/values/values.xml b/twidere.component.common/src/main/res/values/values.xml new file mode 100644 index 000000000..5072f4ab0 --- /dev/null +++ b/twidere.component.common/src/main/res/values/values.xml @@ -0,0 +1,5 @@ + + + 2 + 2 + \ No newline at end of file diff --git a/twidere.extension.shortener.gist/build.gradle b/twidere.extension.shortener.gist/build.gradle index 54a9a36e4..6f7aa5a0e 100644 --- a/twidere.extension.shortener.gist/build.gradle +++ b/twidere.extension.shortener.gist/build.gradle @@ -39,7 +39,7 @@ android { dependencies { apt 'com.bluelinelabs:logansquare-compiler:1.3.4' - compile 'com.github.mariotaku.RestFu:urlconnection:0.9.23' + compile 'com.github.mariotaku.RestFu:urlconnection:0.9.24' compile project(':twidere.library.extension') compile fileTree(dir: 'libs', include: ['*.jar']) } diff --git a/twidere.extension.shortener.gist/src/main/AndroidManifest.xml b/twidere.extension.shortener.gist/src/main/AndroidManifest.xml index bd4c641a4..3039356f0 100644 --- a/twidere.extension.shortener.gist/src/main/AndroidManifest.xml +++ b/twidere.extension.shortener.gist/src/main/AndroidManifest.xml @@ -50,6 +50,11 @@ + + + diff --git a/twidere.extension.shortener.gist/src/main/java/org/mariotaku/twidere/extension/shortener/gist/GistStatusShortenerService.java b/twidere.extension.shortener.gist/src/main/java/org/mariotaku/twidere/extension/shortener/gist/GistStatusShortenerService.java index 4d1ac1bdd..881e8338f 100644 --- a/twidere.extension.shortener.gist/src/main/java/org/mariotaku/twidere/extension/shortener/gist/GistStatusShortenerService.java +++ b/twidere.extension.shortener.gist/src/main/java/org/mariotaku/twidere/extension/shortener/gist/GistStatusShortenerService.java @@ -34,7 +34,7 @@ import org.mariotaku.twidere.service.StatusShortenerService; public class GistStatusShortenerService extends StatusShortenerService { @Override - protected StatusShortenResult shorten(ParcelableStatusUpdate status, ParcelableAccount currentAccount, String overrideStatusText) { + protected StatusShortenResult shorten(ParcelableStatusUpdate status, long currentAccountId, String overrideStatusText) { final Github github = GithubFactory.getInstance(getApiKey()); final NewGist newGist = new NewGist(); newGist.setDescription("long tweet"); diff --git a/twidere.extension.twitlonger/build.gradle b/twidere.extension.twitlonger/build.gradle index 05aae5507..8b4e75963 100644 --- a/twidere.extension.twitlonger/build.gradle +++ b/twidere.extension.twitlonger/build.gradle @@ -38,7 +38,7 @@ android { dependencies { apt 'com.bluelinelabs:logansquare-compiler:1.3.4' - compile 'com.github.mariotaku.RestFu:urlconnection:0.9.23' + compile 'com.github.mariotaku.RestFu:urlconnection:0.9.24' compile project(':twidere.library.extension') compile fileTree(dir: 'libs', include: ['*.jar']) } diff --git a/twidere.extension.twitlonger/src/main/AndroidManifest.xml b/twidere.extension.twitlonger/src/main/AndroidManifest.xml index 2d743f2af..dac539926 100644 --- a/twidere.extension.twitlonger/src/main/AndroidManifest.xml +++ b/twidere.extension.twitlonger/src/main/AndroidManifest.xml @@ -73,6 +73,11 @@ + + + diff --git a/twidere.extension.twitlonger/src/main/java/org/mariotaku/twidere/extension/twitlonger/TwitLongerStatusShortenerService.java b/twidere.extension.twitlonger/src/main/java/org/mariotaku/twidere/extension/twitlonger/TwitLongerStatusShortenerService.java index c2fadb07d..de6a6ea40 100644 --- a/twidere.extension.twitlonger/src/main/java/org/mariotaku/twidere/extension/twitlonger/TwitLongerStatusShortenerService.java +++ b/twidere.extension.twitlonger/src/main/java/org/mariotaku/twidere/extension/twitlonger/TwitLongerStatusShortenerService.java @@ -9,7 +9,6 @@ import android.support.annotation.Nullable; import android.util.Log; import org.mariotaku.twidere.Twidere; -import org.mariotaku.twidere.model.ParcelableAccount; import org.mariotaku.twidere.model.ParcelableCredentials; import org.mariotaku.twidere.model.ParcelableStatus; import org.mariotaku.twidere.model.ParcelableStatusUpdate; @@ -31,7 +30,7 @@ public class TwitLongerStatusShortenerService extends StatusShortenerService imp */ @Override protected StatusShortenResult shorten(final ParcelableStatusUpdate status, - final ParcelableAccount currentAccount, + final long currentAccountId, final String overrideStatusText) { final int granted = Twidere.isPermissionGranted(this); if (granted == Twidere.Permission.DENIED) { @@ -57,7 +56,7 @@ public class TwitLongerStatusShortenerService extends StatusShortenerService imp } final ParcelableCredentials credentials; try { - credentials = getOAuthCredentials(currentAccount.account_id); + credentials = getOAuthCredentials(currentAccountId); } catch (SecurityException e) { if (BuildConfig.DEBUG) { Log.w(LOGTAG, e); diff --git a/twidere.library.extension/src/main/java/org/mariotaku/twidere/service/StatusShortenerService.java b/twidere.library.extension/src/main/java/org/mariotaku/twidere/service/StatusShortenerService.java index 9c8ce5fe2..2bd78bbda 100644 --- a/twidere.library.extension/src/main/java/org/mariotaku/twidere/service/StatusShortenerService.java +++ b/twidere.library.extension/src/main/java/org/mariotaku/twidere/service/StatusShortenerService.java @@ -2,15 +2,17 @@ package org.mariotaku.twidere.service; import android.app.Service; import android.content.Intent; +import android.os.Build; import android.os.IBinder; import android.os.RemoteException; import org.mariotaku.twidere.IStatusShortener; -import org.mariotaku.twidere.model.ParcelableAccount; import org.mariotaku.twidere.model.ParcelableStatus; import org.mariotaku.twidere.model.ParcelableStatusUpdate; import org.mariotaku.twidere.model.StatusShortenResult; +import org.mariotaku.twidere.util.LoganSquareMapperFinder; +import java.io.IOException; import java.lang.ref.WeakReference; /** @@ -24,7 +26,7 @@ public abstract class StatusShortenerService extends Service { } protected abstract StatusShortenResult shorten(ParcelableStatusUpdate status, - ParcelableAccount currentAccount, + long currentAccountId, String overrideStatusText); protected abstract boolean callback(StatusShortenResult result, ParcelableStatus status); @@ -43,16 +45,38 @@ public abstract class StatusShortenerService extends Service { } @Override - public StatusShortenResult shorten(final ParcelableStatusUpdate status, - final ParcelableAccount currentAccount, - final String overrideStatusText) + public String shorten(final String statusJson, final long currentAccountId, + final String overrideStatusText) throws RemoteException { - return mService.get().shorten(status, currentAccount, overrideStatusText); + try { + final ParcelableStatusUpdate statusUpdate = LoganSquareMapperFinder.mapperFor(ParcelableStatusUpdate.class) + .parse(statusJson); + final StatusShortenResult shorten = mService.get().shorten(statusUpdate, currentAccountId, overrideStatusText); + return LoganSquareMapperFinder.mapperFor(StatusShortenResult.class).serialize(shorten); + } catch (IOException e) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) { + throw new RemoteException(e.getMessage()); + } else { + throw new RemoteException(); + } + } } @Override - public boolean callback(StatusShortenResult result, ParcelableStatus status) throws RemoteException { - return mService.get().callback(result, status); + public boolean callback(String resultJson, String statusJson) throws RemoteException { + try { + final StatusShortenResult result = LoganSquareMapperFinder.mapperFor(StatusShortenResult.class) + .parse(resultJson); + final ParcelableStatus status = LoganSquareMapperFinder.mapperFor(ParcelableStatus.class) + .parse(statusJson); + return mService.get().callback(result, status); + } catch (IOException e) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) { + throw new RemoteException(e.getMessage()); + } else { + throw new RemoteException(); + } + } } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/app/TwidereApplication.java b/twidere/src/main/java/org/mariotaku/twidere/app/TwidereApplication.java index d908bd922..d866d0ee4 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/app/TwidereApplication.java +++ b/twidere/src/main/java/org/mariotaku/twidere/app/TwidereApplication.java @@ -212,17 +212,19 @@ public class TwidereApplication extends MultiDexApplication implements Constants break; } case KEY_ENABLE_PROXY: - case KEY_CONNECTION_TIMEOUT: case KEY_PROXY_HOST: case KEY_PROXY_PORT: case KEY_PROXY_TYPE: case KEY_PROXY_USERNAME: - case KEY_PROXY_PASSWORD: { + case KEY_PROXY_PASSWORD: + case KEY_CONNECTION_TIMEOUT: + case KEY_RETRY_ON_NETWORK_ISSUE: { HttpClientFactory.reloadConnectivitySettings(this); break; } case KEY_DNS_SERVER: - case KEY_TCP_DNS_QUERY: { + case KEY_TCP_DNS_QUERY: + case KEY_BUILTIN_DNS_RESOLVER: { reloadDnsSettings(); break; } diff --git a/twidere/src/main/java/org/mariotaku/twidere/service/BackgroundOperationService.java b/twidere/src/main/java/org/mariotaku/twidere/service/BackgroundOperationService.java index 35368a0e3..39a87892a 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/service/BackgroundOperationService.java +++ b/twidere/src/main/java/org/mariotaku/twidere/service/BackgroundOperationService.java @@ -30,9 +30,11 @@ import android.content.pm.PackageManager; import android.database.Cursor; import android.graphics.BitmapFactory; import android.net.Uri; +import android.os.Bundle; import android.os.Handler; import android.os.Parcelable; import android.provider.BaseColumns; +import android.support.annotation.Nullable; import android.support.v4.app.NotificationCompat; import android.support.v4.app.NotificationCompat.Builder; import android.text.TextUtils; @@ -84,6 +86,7 @@ import org.mariotaku.twidere.preference.ServicePickerPreference; import org.mariotaku.twidere.provider.TwidereDataStore.CachedHashtags; import org.mariotaku.twidere.provider.TwidereDataStore.DirectMessages; import org.mariotaku.twidere.provider.TwidereDataStore.Drafts; +import org.mariotaku.twidere.util.AbsServiceInterface; import org.mariotaku.twidere.util.AsyncTwitterWrapper; import org.mariotaku.twidere.util.BitmapUtils; import org.mariotaku.twidere.util.ContentValuesCreator; @@ -519,6 +522,23 @@ public class BackgroundOperationService extends IntentService implements Constan if (!ServicePickerPreference.isNoneValue(shortenerComponent)) { shortener = StatusShortenerInterface.getInstance(app, shortenerComponent); if (shortener == null) throw new ShortenerNotFoundException(this); + try { + shortener.checkService(new AbsServiceInterface.CheckServiceAction() { + @Override + public void check(@Nullable Bundle metaData) throws AbsServiceInterface.CheckServiceException { + if (metaData == null) throw new ExtensionVersionMismatchException(); + final String extensionVersion = metaData.getString(METADATA_KEY_EXTENSION_VERSION_STATUS_SHORTENER); + if (!TextUtils.equals(extensionVersion, getString(R.string.status_shortener_service_interface_version))) { + throw new ExtensionVersionMismatchException(); + } + } + }); + } catch (AbsServiceInterface.CheckServiceException e) { + if (e instanceof ExtensionVersionMismatchException) { + throw new ShortenException(getString(R.string.shortener_version_incompatible)); + } + throw new ShortenException(e); + } } final boolean hasMedia = statusUpdate.media != null && statusUpdate.media.length > 0; @@ -581,7 +601,8 @@ public class BackgroundOperationService extends IntentService implements Constan StatusShortenResult shortenedResult = null; if (shouldShorten && shortener != null) { try { - shortenedResult = shortener.shorten(statusUpdate, account, statusText); + shortenedResult = shortener.shorten(statusUpdate, account.account_id, + statusText); } catch (final Exception e) { throw new ShortenException(getString(R.string.error_message_tweet_shorten_failed), e); } @@ -910,4 +931,8 @@ public class BackgroundOperationService extends IntentService implements Constan super(message); } } + + static class ExtensionVersionMismatchException extends AbsServiceInterface.CheckServiceException { + + } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/AbsServiceInterface.java b/twidere/src/main/java/org/mariotaku/twidere/util/AbsServiceInterface.java index 2ac306fe6..93ad2327b 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/AbsServiceInterface.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/AbsServiceInterface.java @@ -23,8 +23,10 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; +import android.os.Bundle; import android.os.IBinder; import android.os.IInterface; +import android.support.annotation.Nullable; import android.util.Log; import org.mariotaku.twidere.Constants; @@ -37,6 +39,8 @@ public abstract class AbsServiceInterface implements Const private final Context mContext; private final String mShortenerName; + @Nullable + private final Bundle mMetaData; private I mIInterface; private ServiceToken mToken; @@ -56,9 +60,10 @@ public abstract class AbsServiceInterface implements Const protected abstract I onServiceConnected(ComponentName service, IBinder obj); - protected AbsServiceInterface(final Context context, final String shortenerName) { + protected AbsServiceInterface(final Context context, final String componentName, @Nullable final Bundle metaData) { mContext = context; - mShortenerName = shortenerName; + mShortenerName = componentName; + mMetaData = metaData; } public final I getInterface() { @@ -89,4 +94,15 @@ public abstract class AbsServiceInterface implements Const } } + public final void checkService(CheckServiceAction action) throws CheckServiceException { + action.check(mMetaData); + } + + public interface CheckServiceAction { + void check(@Nullable Bundle metaData) throws CheckServiceException; + } + + public static class CheckServiceException extends Exception { + + } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/HttpClientFactory.java b/twidere/src/main/java/org/mariotaku/twidere/util/HttpClientFactory.java index d8c8e6920..28c9c3932 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/HttpClientFactory.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/HttpClientFactory.java @@ -2,7 +2,6 @@ package org.mariotaku.twidere.util; import android.annotation.SuppressLint; import android.content.Context; -import android.content.SharedPreferences; import android.text.TextUtils; import org.apache.commons.lang3.math.NumberUtils; @@ -10,9 +9,11 @@ import org.mariotaku.restfu.http.RestHttpClient; import org.mariotaku.restfu.okhttp3.OkHttpRestClient; import org.mariotaku.twidere.Constants; import org.mariotaku.twidere.util.dagger.DependencyHolder; +import org.mariotaku.twidere.util.net.TwidereDns; import org.mariotaku.twidere.util.net.TwidereProxySelector; import java.io.IOException; +import java.net.InetSocketAddress; import java.net.Proxy; import java.util.concurrent.TimeUnit; @@ -33,14 +34,14 @@ import static android.text.TextUtils.isEmpty; public class HttpClientFactory implements Constants { public static RestHttpClient createRestHttpClient(final Context context, - final SharedPreferences prefs, final Dns dns, + final SharedPreferencesWrapper prefs, final Dns dns, final ConnectionPool connectionPool) { final OkHttpClient.Builder builder = new OkHttpClient.Builder(); initOkHttpClient(context, prefs, builder, dns, connectionPool); return new OkHttpRestClient(builder.build()); } - public static void initOkHttpClient(final Context context, final SharedPreferences prefs, + public static void initOkHttpClient(final Context context, final SharedPreferencesWrapper prefs, final OkHttpClient.Builder builder, final Dns dns, final ConnectionPool connectionPool) { updateHttpClientConfiguration(context, builder, prefs, dns, connectionPool); @@ -50,11 +51,11 @@ public class HttpClientFactory implements Constants { @SuppressLint("SSLCertificateSocketFactoryGetInsecure") public static void updateHttpClientConfiguration(final Context context, final OkHttpClient.Builder builder, - final SharedPreferences prefs, final Dns dns, + final SharedPreferencesWrapper prefs, final Dns dns, final ConnectionPool connectionPool) { final boolean enableProxy = prefs.getBoolean(KEY_ENABLE_PROXY, false); builder.connectTimeout(prefs.getInt(KEY_CONNECTION_TIMEOUT, 10), TimeUnit.SECONDS); - builder.retryOnConnectionFailure(true); + builder.retryOnConnectionFailure(prefs.getBoolean(KEY_RETRY_ON_NETWORK_ISSUE)); builder.connectionPool(connectionPool); if (enableProxy) { final String proxyType = prefs.getString(KEY_PROXY_TYPE, null); @@ -64,7 +65,11 @@ public class HttpClientFactory implements Constants { TwidereMathUtils.RANGE_INCLUSIVE_INCLUSIVE)) { final Proxy.Type type = getProxyType(proxyType); if (type != Proxy.Type.DIRECT) { - builder.proxySelector(new TwidereProxySelector(context, type, proxyHost, proxyPort)); + if (TwidereDns.isValidIpAddress(proxyHost)) { + builder.proxy(new Proxy(type, InetSocketAddress.createUnresolved(proxyHost, proxyPort))); + } else { + builder.proxySelector(new TwidereProxySelector(context, type, proxyHost, proxyPort)); + } } } final String username = prefs.getString(KEY_PROXY_USERNAME, null); diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/MediaUploaderInterface.java b/twidere/src/main/java/org/mariotaku/twidere/util/MediaUploaderInterface.java index e178b7cc0..9f9efc9e0 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/MediaUploaderInterface.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/MediaUploaderInterface.java @@ -23,6 +23,9 @@ import android.app.Application; import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; @@ -32,9 +35,11 @@ import org.mariotaku.twidere.model.MediaUploadResult; import org.mariotaku.twidere.model.ParcelableStatusUpdate; import org.mariotaku.twidere.model.UploaderMediaItem; +import java.util.List; + public final class MediaUploaderInterface extends AbsServiceInterface implements IMediaUploader { - protected MediaUploaderInterface(Context context, String shortenerName) { - super(context, shortenerName); + protected MediaUploaderInterface(Context context, String uploaderName, Bundle metaData) { + super(context, uploaderName, metaData); } public static MediaUploaderInterface getInstance(final Application application, final String uploaderName) { @@ -42,8 +47,10 @@ public final class MediaUploaderInterface extends AbsServiceInterface services = pm.queryIntentServices(intent, PackageManager.GET_META_DATA); + if (services.size() != 1) return null; + return new MediaUploaderInterface(application, uploaderName, services.get(0).serviceInfo.metaData); } @Override diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/StatusShortenerInterface.java b/twidere/src/main/java/org/mariotaku/twidere/util/StatusShortenerInterface.java index e42d843fe..8a3719b43 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/StatusShortenerInterface.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/StatusShortenerInterface.java @@ -23,19 +23,23 @@ import android.app.Application; import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; import org.mariotaku.twidere.IStatusShortener; -import org.mariotaku.twidere.model.ParcelableAccount; import org.mariotaku.twidere.model.ParcelableStatus; import org.mariotaku.twidere.model.ParcelableStatusUpdate; import org.mariotaku.twidere.model.StatusShortenResult; -public final class StatusShortenerInterface extends AbsServiceInterface implements IStatusShortener { +import java.util.List; - protected StatusShortenerInterface(Context context, String shortenerName) { - super(context, shortenerName); +public final class StatusShortenerInterface extends AbsServiceInterface { + + protected StatusShortenerInterface(Context context, String shortenerName, Bundle metaData) { + super(context, shortenerName, metaData); } @Override @@ -43,37 +47,41 @@ public final class StatusShortenerInterface extends AbsServiceInterface services = pm.queryIntentServices(intent, PackageManager.GET_META_DATA); + if (services.size() != 1) return null; + return new StatusShortenerInterface(application, shortenerName, services.get(0).serviceInfo.metaData); } } diff --git a/twidere/src/main/res/values/strings.xml b/twidere/src/main/res/values/strings.xml index eff291e56..e17c39302 100644 --- a/twidere/src/main/res/values/strings.xml +++ b/twidere/src/main/res/values/strings.xml @@ -742,6 +742,8 @@ Start Builtin DNS resolver Bandwidth saving mode + Retry on network issue + Try recover from network issue automatically Disable media preview on metered network Recent media Reply to %1$s: %2$s @@ -750,4 +752,5 @@ %1$s: %2$s Translate from %s Translation + Incompatible shortener \ No newline at end of file diff --git a/twidere/src/main/res/xml/preferences_advanced_network.xml b/twidere/src/main/res/xml/preferences_advanced_network.xml index b45c01a56..91e836fb1 100644 --- a/twidere/src/main/res/xml/preferences_advanced_network.xml +++ b/twidere/src/main/res/xml/preferences_advanced_network.xml @@ -33,6 +33,12 @@ android:key="custom_host_mapping" android:summary="@string/custom_host_mapping_summary" android:title="@string/custom_host_mapping"/> + +