アプリ設定でTLのフォント変更

This commit is contained in:
tateisu 2017-05-16 09:49:44 +09:00
parent 540b9e5f19
commit 3b435fec85
15 changed files with 292 additions and 51 deletions

View File

@ -9,8 +9,8 @@ android {
applicationId "jp.juggler.subwaytooter"
minSdkVersion 21
targetSdkVersion 25
versionCode 57
versionName "0.5.7"
versionCode 58
versionName "0.5.8"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}

View File

@ -2,12 +2,15 @@ package jp.juggler.subwaytooter;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Typeface;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.ColorInt;
import android.support.annotation.Nullable;
import android.support.v4.view.ViewCompat;
import android.support.v7.app.AppCompatActivity;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.View;
import android.widget.AdapterView;
@ -18,10 +21,19 @@ import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.Switch;
import android.widget.TextView;
import com.jrummyapps.android.colorpicker.ColorPickerDialog;
import com.jrummyapps.android.colorpicker.ColorPickerDialogListener;
import org.apache.commons.io.IOUtils;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import jp.juggler.subwaytooter.util.Utils;
public class ActAppSetting extends AppCompatActivity
implements CompoundButton.OnCheckedChangeListener
, AdapterView.OnItemSelectedListener
@ -85,6 +97,8 @@ public class ActAppSetting extends AppCompatActivity
EditText etColumnWidth;
EditText etMediaThumbHeight;
TextView tvTimelineFontUrl;
String timeline_font;
private void initUI(){
setContentView( R.layout.act_app_setting );
@ -197,6 +211,8 @@ public class ActAppSetting extends AppCompatActivity
findViewById( R.id.btnTabBackgroundColorReset ).setOnClickListener( this );
findViewById( R.id.btnTabDividerColorEdit ).setOnClickListener( this );
findViewById( R.id.btnTabDividerColorReset ).setOnClickListener( this );
findViewById( R.id.btnTimelineFontEdit ).setOnClickListener( this );
findViewById( R.id.btnTimelineFontReset ).setOnClickListener( this );
ivFooterToot = (ImageView) findViewById( R.id.ivFooterToot );
ivFooterMenu = (ImageView) findViewById( R.id.ivFooterMenu );
@ -207,6 +223,11 @@ public class ActAppSetting extends AppCompatActivity
etColumnWidth = (EditText) findViewById( R.id.etColumnWidth );
etMediaThumbHeight = (EditText) findViewById( R.id.etMediaThumbHeight );
tvTimelineFontUrl= (TextView) findViewById( R.id.tvTimelineFontUrl );
etColumnWidth.addTextChangedListener( this );
etMediaThumbHeight.addTextChangedListener( this );
}
boolean load_busy;
@ -243,14 +264,16 @@ public class ActAppSetting extends AppCompatActivity
etColumnWidth.setText( pref.getString( Pref.KEY_COLUMN_WIDTH, "" ) );
etMediaThumbHeight.setText( pref.getString( Pref.KEY_MEDIA_THUMB_HEIGHT, "" ) );
etColumnWidth.addTextChangedListener( this );
etMediaThumbHeight.addTextChangedListener( this );
timeline_font = pref.getString( Pref.KEY_TIMELINE_FONT, "" );
load_busy = false;
showFooterColor();
showTimelineFont();
}
private void saveUIToData(){
if( load_busy ) return;
pref.edit()
@ -282,6 +305,7 @@ public class ActAppSetting extends AppCompatActivity
.putString( Pref.KEY_COLUMN_WIDTH, etColumnWidth.getText().toString().trim() )
.putString( Pref.KEY_MEDIA_THUMB_HEIGHT, etMediaThumbHeight.getText().toString().trim() )
.putString( Pref.KEY_TIMELINE_FONT, timeline_font )
.apply();
@ -346,10 +370,42 @@ public class ActAppSetting extends AppCompatActivity
saveUIToData();
showFooterColor();
break;
case R.id.btnTimelineFontReset:
timeline_font = "";
saveUIToData();
showTimelineFont();
break;
case R.id.btnTimelineFontEdit:
try{
Intent intent = new Intent( Intent.ACTION_OPEN_DOCUMENT );
intent.addCategory( Intent.CATEGORY_OPENABLE );
intent.setType( "*/*" );
startActivityForResult( intent, REQUEST_CODE_TIMELINE_FONT );
}catch(Throwable ex){
Utils.showToast( this,ex,"could not open picker for font/*" );
}
break;
}
}
static final int REQUEST_CODE_TIMELINE_FONT = 1;
@Override protected void onActivityResult( int requestCode, int resultCode, Intent data ){
if( resultCode == RESULT_OK && requestCode == REQUEST_CODE_TIMELINE_FONT){
if( data != null ){
Uri uri = data.getData();
if( uri != null ){
getContentResolver().takePersistableUriPermission( uri, Intent.FLAG_GRANT_READ_URI_PERMISSION );
saveTimelineFont( uri);
}
}
}
super.onActivityResult( requestCode, resultCode, data );
}
void openColorPicker( int id, int color ){
ColorPickerDialog.Builder builder = ColorPickerDialog.newBuilder()
.setDialogType( ColorPickerDialog.TYPE_CUSTOM )
@ -444,4 +500,76 @@ public class ActAppSetting extends AppCompatActivity
@Override public void afterTextChanged( Editable s ){
saveUIToData();
}
private void showTimelineFont(){
try{
if( ! TextUtils.isEmpty( timeline_font ) ){
tvTimelineFontUrl.setTypeface( Typeface.DEFAULT );
Typeface face = Typeface.createFromFile( timeline_font );
tvTimelineFontUrl.setTypeface(face );
tvTimelineFontUrl.setText( timeline_font );
return;
}
}catch(Throwable ex){
ex.printStackTrace( );
}
// fallback
tvTimelineFontUrl.setText( getString( R.string.not_selected ) );
tvTimelineFontUrl.setTypeface( Typeface.DEFAULT );
}
static final String TIMELINE_FONT_FILE_NAME = "TimelineFont";
private void saveTimelineFont( Uri uri ){
try{
File dir = getFilesDir();
//noinspection ResultOfMethodCallIgnored
dir.mkdir();
File tmp_file = new File( dir, TIMELINE_FONT_FILE_NAME +".tmp" );
InputStream is = getContentResolver().openInputStream( uri );
if( is == null ){
Utils.showToast( this, false, "openInputStream returns null.");
return;
}
try{
FileOutputStream os = new FileOutputStream( tmp_file );
try{
IOUtils.copy( is,os );
}finally{
IOUtils.closeQuietly( os );
}
}finally{
IOUtils.closeQuietly( is );
}
Typeface face = Typeface.createFromFile( tmp_file );
if( face == null ){
Utils.showToast( this, false, "Typeface.createFromFile() failed.");
return;
}
File file = new File( dir, TIMELINE_FONT_FILE_NAME );
if(!tmp_file.renameTo( file ) ){
Utils.showToast( this, false, "File operation failed.");
return;
}
timeline_font = file.getAbsolutePath();
saveUIToData();
showTimelineFont();
}catch(Throwable ex){
ex.printStackTrace( );
Utils.showToast( this,ex,"saveTimelineFont failed.");
}
}
}

View File

@ -6,6 +6,7 @@ import android.content.ComponentName;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Typeface;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
@ -605,9 +606,23 @@ public class ActMain extends AppCompatActivity
static final int COLUMN_WIDTH_MIN_DP = 300;
Typeface timeline_font ;
void initUI(){
setContentView( R.layout.act_main );
String sv = pref.getString(Pref.KEY_TIMELINE_FONT,"");
if( ! TextUtils.isEmpty( sv ) ){
try{
timeline_font = Typeface.createFromFile( sv );
}catch(Throwable ex){
ex.printStackTrace();
}
}
llEmpty = findViewById( R.id.llEmpty );
// // toolbar
@ -636,7 +651,6 @@ public class ActMain extends AppCompatActivity
svColumnStrip.setHorizontalFadingEdgeEnabled( true );
String sv;
DisplayMetrics dm = getResources().getDisplayMetrics();
float density = dm.density;

View File

@ -73,7 +73,6 @@ import okhttp3.Request;
import okhttp3.RequestBody;
import okio.BufferedSink;
import static jp.juggler.subwaytooter.R.id.viewRoot;
public class ActPost extends AppCompatActivity implements View.OnClickListener, PostAttachment.Callback {
static final LogCategory log = new LogCategory( "ActPost" );
@ -510,7 +509,7 @@ public class ActPost extends AppCompatActivity implements View.OnClickListener,
Styler.fixHorizontalMargin(findViewById( R.id.llFooterBar ));
formRoot = findViewById( viewRoot );
formRoot = findViewById( R.id.viewRoot );
scrollView = (ScrollView) findViewById( R.id.scrollView );
btnAccount = (Button) findViewById( R.id.btnAccount );
btnVisibility = (ImageButton) findViewById( R.id.btnVisibility );

View File

@ -6,6 +6,7 @@ import android.os.AsyncTask;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.view.ViewCompat;
import android.support.v4.widget.TextViewCompat;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
@ -82,6 +83,21 @@ class ColumnViewHolder
ColumnViewHolder( ActMain arg_activity, View root ){
this.activity = arg_activity;
if( activity.timeline_font != null ){
Utils.scanView( root, new Utils.ScanViewCallback() {
@Override public void onScanView( View v ){
try{
if( v instanceof TextView ){
( (TextView) v ).setTypeface( activity.timeline_font );
}
}catch(Throwable ex){
ex.printStackTrace();
}
}
} );
}
flColumnBackground = root.findViewById( R.id.flColumnBackground );
ivColumnBackgroundImage = (ImageView) root.findViewById( R.id.ivColumnBackgroundImage );
llColumnHeader = root.findViewById( R.id.llColumnHeader );

View File

@ -13,6 +13,7 @@ import jp.juggler.subwaytooter.api.entity.TootStatus;
import jp.juggler.subwaytooter.table.SavedAccount;
import jp.juggler.subwaytooter.table.UserRelation;
import jp.juggler.subwaytooter.util.Emojione;
import jp.juggler.subwaytooter.util.Utils;
import jp.juggler.subwaytooter.view.MyLinkMovementMethod;
import jp.juggler.subwaytooter.view.MyNetworkImageView;
@ -36,13 +37,28 @@ class HeaderViewHolder implements View.OnClickListener, View.OnLongClickListener
private TootAccount who;
HeaderViewHolder( ActMain activity,Column column, ListView parent ){
this.activity = activity;
HeaderViewHolder( ActMain arg_activity,Column column, ListView parent ){
this.activity = arg_activity;
this.column = column;
this.access_info = column.access_info;
this.viewRoot = activity.getLayoutInflater().inflate( R.layout.lv_list_header, parent, false );
viewRoot.setTag( this);
if( activity.timeline_font != null ){
Utils.scanView( viewRoot, new Utils.ScanViewCallback() {
@Override public void onScanView( View v ){
try{
if( v instanceof TextView ){
( (TextView) v ).setTypeface( activity.timeline_font );
}
}catch(Throwable ex){
ex.printStackTrace();
}
}
} );
}
ivBackground = (MyNetworkImageView) viewRoot.findViewById( R.id.ivBackground );
tvCreated = (TextView) viewRoot.findViewById( R.id.tvCreated );
ivAvatar = (MyNetworkImageView) viewRoot.findViewById( R.id.ivAvatar );

View File

@ -1,5 +1,6 @@
package jp.juggler.subwaytooter;
import android.graphics.Typeface;
import android.support.v4.view.ViewCompat;
import android.text.TextUtils;
import android.view.View;
@ -84,22 +85,43 @@ class ItemViewHolder implements View.OnClickListener, View.OnLongClickListener {
private final boolean bSimpleList;
ItemViewHolder( ActMain activity, Column column, ItemListAdapter list_adapter, View view ,boolean bSimpleList ){
this.activity = activity;
ItemViewHolder( ActMain arg_activity, Column column, ItemListAdapter list_adapter, View view ,boolean bSimpleList ){
this.activity = arg_activity;
this.column = column;
this.access_info = column.access_info;
this.list_adapter = list_adapter;
this.bSimpleList = bSimpleList;
this.tvName = (TextView) view.findViewById( R.id.tvName );
this.tvFollowerName = (TextView) view.findViewById( R.id.tvFollowerName );
this.tvBoosted = (TextView) view.findViewById( R.id.tvBoosted );
if( activity.timeline_font != null ){
Utils.scanView( view, new Utils.ScanViewCallback() {
@Override public void onScanView( View v ){
try{
if( v instanceof TextView ){
( (TextView) v ).setTypeface( activity.timeline_font );
}
}catch(Throwable ex){
ex.printStackTrace();
}
}
} );
}else{
tvName.setTypeface( Typeface.DEFAULT_BOLD );
tvFollowerName.setTypeface( Typeface.DEFAULT_BOLD );
tvBoosted.setTypeface( Typeface.DEFAULT_BOLD );
}
this.llBoosted = view.findViewById( R.id.llBoosted );
this.ivBoosted = (ImageView) view.findViewById( R.id.ivBoosted );
this.tvBoosted = (TextView) view.findViewById( R.id.tvBoosted );
this.tvBoostedTime = (TextView) view.findViewById( R.id.tvBoostedTime );
this.tvBoostedAcct = (TextView) view.findViewById( R.id.tvBoostedAcct );
this.llFollow = view.findViewById( R.id.llFollow );
this.ivFollow = (MyNetworkImageView) view.findViewById( R.id.ivFollow );
this.tvFollowerName = (TextView) view.findViewById( R.id.tvFollowerName );
this.tvFollowerAcct = (TextView) view.findViewById( R.id.tvFollowerAcct );
this.btnFollow = (ImageButton) view.findViewById( R.id.btnFollow );
this.ivFollowedBy = (ImageView) view.findViewById( R.id.ivFollowedBy );
@ -107,7 +129,6 @@ class ItemViewHolder implements View.OnClickListener, View.OnLongClickListener {
this.llStatus = view.findViewById( R.id.llStatus );
this.ivThumbnail = (MyNetworkImageView) view.findViewById( R.id.ivThumbnail );
this.tvName = (TextView) view.findViewById( R.id.tvName );
this.tvTime = (TextView) view.findViewById( R.id.tvTime );
this.tvAcct = (TextView) view.findViewById( R.id.tvAcct );

View File

@ -44,6 +44,7 @@ public class Pref {
static final String KEY_COLUMN_WIDTH = "ColumnWidth";
static final String KEY_MEDIA_THUMB_HEIGHT = "MediaThumbHeight";
static final String KEY_TIMELINE_FONT = "timeline_font";
}

View File

@ -43,6 +43,7 @@ import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.webkit.MimeTypeMap;
import android.widget.Toast;
@ -777,6 +778,21 @@ public class Utils {
return null;
}
public interface ScanViewCallback {
void onScanView( View v );
}
public static void scanView( View v, ScanViewCallback callback ){
if( v == null ) return;
callback.onScanView( v );
if( v instanceof ViewGroup ){
ViewGroup vg = (ViewGroup) v;
for( int i = 0, ie = vg.getChildCount() ; i < ie ; ++ i ){
scanView( vg.getChildAt( i ), callback );
}
}
}
static class FileInfo {
Uri uri;
@ -884,10 +900,10 @@ public class Utils {
return resources.getString( string_id, args ) + String.format( " :%s %s", ex.getClass().getSimpleName(), ex.getMessage() );
}
public static boolean isMainThread( ){
public static boolean isMainThread(){
return Looper.getMainLooper().getThread() == Thread.currentThread();
}
public static void runOnMainThread( @NonNull Runnable proc ){
if( Looper.getMainLooper().getThread() == Thread.currentThread() ){
proc.run();
@ -1043,29 +1059,28 @@ public class Utils {
return null;
}
private static final char ALM = (char) 0x061c; // Arabic letter mark (ALM)
private static final char LRM = (char) 0x200E; // Left-to-right mark (LRM)
private static final char RLM = (char) 0x200F; // Right-to-left mark (RLM)
private static final char LRE = (char) 0x202A; // Left-to-right embedding (LRE)
private static final char RLE = (char) 0x202B; // Right-to-left embedding (RLE)
private static final char PDF = (char) 0x202C; // Pop directional formatting (PDF)
private static final char LRO = (char) 0x202D; // Left-to-right override (LRO)
private static final char RLO = (char) 0x202E; // Right-to-left override (RLO)
private static final char ALM = (char)0x061c; // Arabic letter mark (ALM)
private static final char LRM = (char)0x200E; // Left-to-right mark (LRM)
private static final char RLM = (char)0x200F; // Right-to-left mark (RLM)
private static final char LRE = (char)0x202A; // Left-to-right embedding (LRE)
private static final char RLE = (char)0x202B; // Right-to-left embedding (RLE)
private static final char PDF = (char)0x202C; // Pop directional formatting (PDF)
private static final char LRO = (char)0x202D; // Left-to-right override (LRO)
private static final char RLO = (char)0x202E; // Right-to-left override (RLO)
private static final String CHARS_MUST_PDF = String.valueOf( LRE ) + RLE + LRO + RLO;
private static final String CHARS_MUST_PDF = String.valueOf( LRE ) + RLE + LRO + RLO ;
private static final char LRI = (char) 0x2066; // Left-to-right isolate (LRI)
private static final char RLI = (char) 0x2067; // Right-to-left isolate (RLI)
private static final char FSI = (char) 0x2068; // First strong isolate (FSI)
private static final char PDI = (char) 0x2069; // Pop directional isolate (PDI)
private static final char LRI = (char)0x2066; // Left-to-right isolate (LRI)
private static final char RLI = (char)0x2067; // Right-to-left isolate (RLI)
private static final char FSI = (char)0x2068; // First strong isolate (FSI)
private static final char PDI = (char)0x2069; // Pop directional isolate (PDI)
private static final String CHARS_MUST_PDI = String.valueOf( LRI ) + RLI + FSI;
private static final String CHARS_MUST_PDI = String.valueOf( LRI ) + RLI + FSI ;
public static String sanitizeBDI(String src){
public static String sanitizeBDI( String src ){
LinkedList< Character > stack = null;
for( int i = 0, ie = src.length() ; i < ie ; ++ i ){
char c = src.charAt( i );
@ -1082,7 +1097,7 @@ public class Utils {
}
if( stack == null || stack.isEmpty() ) return src;
StringBuilder sb = new StringBuilder();
sb.append( src );
while( ! stack.isEmpty() ){

View File

@ -550,6 +550,40 @@
<View style="@style/setting_divider"/>
<TextView
style="@style/setting_row_label"
android:text="@string/timeline_font"
/>
<LinearLayout style="@style/setting_row_form">
<TextView
android:id="@+id/tvTimelineFontUrl"
style="@style/setting_horizontal_stretch"
/>
</LinearLayout>
<LinearLayout style="@style/setting_row_form">
<Button
android:id="@+id/btnTimelineFontEdit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/edit"
android:textAllCaps="false"
/>
<Button
android:id="@+id/btnTimelineFontReset"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/reset"
android:textAllCaps="false"
/>
</LinearLayout>
<View style="@style/setting_divider"/>
<!--<TextView-->
<!--style="@style/setting_row_label"-->
<!--android:text="@string/actions"-->

View File

@ -73,7 +73,6 @@
android:id="@+id/tvBoosted"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textStyle="bold"
tools:text="~にブーストされました"
/>
@ -111,7 +110,6 @@
android:id="@+id/tvFollowerName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textStyle="bold"
tools:text="Follower Name"
/>
@ -226,7 +224,6 @@
android:id="@+id/tvName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textStyle="bold"
tools:text="Displayname @username"
/>

View File

@ -70,7 +70,6 @@
android:id="@+id/tvBoosted"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textStyle="bold"
tools:text="~にブーストされました"
/>
@ -110,7 +109,6 @@
android:id="@+id/tvFollowerName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textStyle="bold"
tools:text="Follower Name"
/>
@ -223,7 +221,6 @@
android:id="@+id/tvName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textStyle="bold"
tools:text="Displayname @username"
/>

View File

@ -316,6 +316,7 @@
<string name="your_statuses">Vos statuts</string>
<string name="launcher_icon_by">Icone de l\'application créée par フタバ</string>
<string name="ssl_bug_7_0">Android 7.0 ne peut utiliser qu\'elliptic curve \"prime256v1\" pour les connexions sécurisées.\nL\'instance à laquelle vous voulez vous connecter semble ne pas le gérer.\n-Vous pouvez mettre à jour le système d\'exploitation vers Android 7.1.1.\n-Ou, demander au propriétaire de l\'instance de prendre en charge elliptic curve \"prime256v1\".\nPlus de détails ici: https://code.google.com/p/android/issues/detail?id=224438</string>
<string name="timeline_font">Timeline font (app restart required)</string>
<!--<string name="abc_action_bar_home_description">Revenir à l\'accueil</string>-->

View File

@ -604,4 +604,5 @@
<string name="launcher_icon_by">ランチャーアイコンはフタバさんがデザインしました</string>
<string name="ssl_bug_7_0">Android 7.0 には利用できる elliptic curve が \"prime256v1\" だけというバグがあります。\nしかし対象のインスタンスはこの elliptic curve に対応していないようです。\n可能ならOSバージョン 7.1.1以降にアップデートするとバグは修正されます。\nもしくは elliptic curve \"prime256v1\" に対応してもらうよう、あなたからインスタンスのオーナーに要望を出すことができます。\n関連情報 https://code.google.com/p/android/issues/detail?id=224438</string>
<string name="timeline_font">タイムラインのフォント(アプリ再起動が必要)</string>
</resources>

View File

@ -276,7 +276,7 @@
<string name="open_in_pseudo_account">Open in emulated account on %1$s</string>
<string name="color_and_background">Color and Background…</string>
<string name="column_background">Column's background</string>
<string name="column_background">Column\'s background</string>
<string name="pick_image">Pick an image</string>
<string name="image_alpha">Image alpha</string>
<string name="image">Image</string>
@ -291,11 +291,11 @@
<string name="muted_word">Banned words</string>
<string name="word_was_muted">The word was banned.</string>
<string name="copy_complete">Clipboard updated.</string>
<string name="footer_color">Footer's color</string>
<string name="button_background_color">Button's background color</string>
<string name="button_foreground_color">Button's foreground color</string>
<string name="tab_background_color">Tab's background color</string>
<string name="tab_divider_color">Tab's divider color</string>
<string name="footer_color">Footer\'s color</string>
<string name="button_background_color">Button\'s background color</string>
<string name="button_foreground_color">Button\'s foreground color</string>
<string name="tab_background_color">Tab\'s background color</string>
<string name="tab_divider_color">Tab\'s divider color</string>
<string name="open_status_from">Open status from</string>
<string name="help_translation">Help with the translation</string>
<string name="dont_use_streaming_api">Refresh manually the feeds</string>
@ -312,5 +312,6 @@
<string name="account_picker_reply">Which account do you reply from?</string>
<string name="reply_from_another_account">Reply from another account</string>
<string name="launcher_icon_by">Thanks to フタバ for the application icon.</string>
<string name="ssl_bug_7_0">Android 7.0 can only use the elliptic curve \"prime256v1\".\nUnfortunatly your instance seems to not support it.\nThis bug has been fixed in Android 7.1.1.\nYou can either upgrade your OS or ask the administrator of your instance to add support to the elliptic curve \"prime256v1\".\nSee also https://code.google.com/p/android/issues/detail?id=224438</string>
<string name="ssl_bug_7_0">Android 7.0 can only use the elliptic curve \"prime256v1\".\nUnfortunately your instance seems to not support it.\nThis bug has been fixed in Android 7.1.1.\nYou can either upgrade your OS or ask the administrator of your instance to add support to the elliptic curve \"prime256v1\".\nSee also https://code.google.com/p/android/issues/detail?id=224438</string>
<string name="timeline_font">Timeline font (app restart required)</string>
</resources>