diff --git a/app/build.gradle b/app/build.gradle
index 14e078e7..30cd1a9d 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -9,8 +9,8 @@ android {
applicationId "jp.juggler.subwaytooter"
minSdkVersion 21
targetSdkVersion 25
- versionCode 98
- versionName "0.9.8"
+ versionCode 99
+ versionName "0.9.9"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
diff --git a/app/src/main/java/jp/juggler/subwaytooter/ActAccountSetting.java b/app/src/main/java/jp/juggler/subwaytooter/ActAccountSetting.java
index 1844cc92..4ec1b65f 100644
--- a/app/src/main/java/jp/juggler/subwaytooter/ActAccountSetting.java
+++ b/app/src/main/java/jp/juggler/subwaytooter/ActAccountSetting.java
@@ -5,11 +5,11 @@ import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
+import android.media.RingtoneManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.Nullable;
-import android.support.v4.os.AsyncTaskCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
@@ -67,10 +67,25 @@ public class ActAccountSetting extends AppCompatActivity
}
static final int REQUEST_CODE_ACCT_CUSTOMIZE = 1;
+ static final int REQUEST_CODE_NOTIFICATION_SOUND = 2;
@Override protected void onActivityResult( int requestCode, int resultCode, Intent data ){
if( requestCode == REQUEST_CODE_ACCT_CUSTOMIZE && resultCode == RESULT_OK ){
showAcctColor();
+ }else if( resultCode == RESULT_OK && requestCode == REQUEST_CODE_NOTIFICATION_SOUND ){
+ // RINGTONE_PICKERからの選択されたデータを取得する
+ Uri uri = (Uri) data.getExtras().get( RingtoneManager.EXTRA_RINGTONE_PICKED_URI );
+ if( uri != null ){
+ notification_sound_uri = uri.toString();
+ saveUIToData();
+ // Ringtone ringtone = RingtoneManager.getRingtone(getApplicationContext(), uri);
+ // TextView ringView = (TextView) findViewById(R.id.ringtone);
+ // ringView.setText(ringtone.getTitle(getApplicationContext()));
+ // ringtone.setStreamType(AudioManager.STREAM_ALARM);
+ // ringtone.play();
+ // SystemClock.sleep(1000);
+ // ringtone.stop();
+ }
}
super.onActivityResult( requestCode, resultCode, data );
}
@@ -97,6 +112,11 @@ public class ActAccountSetting extends AppCompatActivity
View btnUserCustom;
String full_acct;
+ Button btnNotificationSoundEdit;
+ Button btnNotificationSoundReset;
+
+ String notification_sound_uri;
+
private void initUI(){
setContentView( R.layout.act_account_setting );
@@ -140,6 +160,11 @@ public class ActAccountSetting extends AppCompatActivity
cbConfirmUnfollow.setOnCheckedChangeListener( this );
cbConfirmBoost.setOnCheckedChangeListener( this );
cbConfirmToot.setOnCheckedChangeListener( this );
+
+ btnNotificationSoundEdit = (Button) findViewById( R.id.btnNotificationSoundEdit );
+ btnNotificationSoundReset = (Button) findViewById( R.id.btnNotificationSoundReset );
+ btnNotificationSoundEdit.setOnClickListener( this );
+ btnNotificationSoundReset.setOnClickListener( this );
}
boolean loading = false;
@@ -169,11 +194,17 @@ public class ActAccountSetting extends AppCompatActivity
cbConfirmBoost.setChecked( a.confirm_boost );
cbConfirmToot.setChecked( a.confirm_post );
+ notification_sound_uri = a.sound_uri;
+
loading = false;
boolean enabled = ! a.isPseudo();
btnAccessToken.setEnabled( enabled );
btnVisibility.setEnabled( enabled );
+ btnVisibility.setEnabled( enabled );
+ btnVisibility.setEnabled( enabled );
+ btnNotificationSoundEdit.setEnabled( enabled );
+ btnNotificationSoundReset.setEnabled( enabled );
cbNotificationMention.setEnabled( enabled );
cbNotificationBoost.setEnabled( enabled );
@@ -206,6 +237,8 @@ public class ActAccountSetting extends AppCompatActivity
account.notification_favourite = cbNotificationFavourite.isChecked();
account.notification_follow = cbNotificationFollow.isChecked();
+ account.sound_uri = notification_sound_uri == null ? "" : notification_sound_uri;
+
account.confirm_follow = cbConfirmFollow.isChecked();
account.confirm_follow_locked = cbConfirmFollowLockedUser.isChecked();
account.confirm_unfollow = cbConfirmUnfollow.isChecked();
@@ -237,7 +270,15 @@ public class ActAccountSetting extends AppCompatActivity
case R.id.btnUserCustom:
ActNickname.open( this, full_acct, REQUEST_CODE_ACCT_CUSTOMIZE );
break;
-
+
+ case R.id.btnNotificationSoundEdit:
+ openNotificationSoundPicker();
+ break;
+
+ case R.id.btnNotificationSoundReset:
+ notification_sound_uri = "";
+ saveUIToData();
+ break;
}
}
@@ -439,5 +480,23 @@ public class ActAccountSetting extends AppCompatActivity
task.executeOnExecutor( App1.task_executor );
}
+ private void openNotificationSoundPicker(){
+ Intent intent = new Intent( RingtoneManager.ACTION_RINGTONE_PICKER );
+ intent.putExtra( RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_NOTIFICATION );
+ intent.putExtra( RingtoneManager.EXTRA_RINGTONE_TITLE, R.string.notification_sound );
+ intent.putExtra( RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, false );
+ intent.putExtra( RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, false );
+ try{
+ Uri uri = TextUtils.isEmpty( notification_sound_uri ) ? null : Uri.parse( notification_sound_uri );
+ if( uri != null ){
+ intent.putExtra( RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, uri );
+ }
+ }catch( Throwable ignored ){
+ }
+
+ Intent chooser = Intent.createChooser( intent, getString( R.string.notification_sound ) );
+ startActivityForResult( chooser, REQUEST_CODE_NOTIFICATION_SOUND );
+ }
+
}
diff --git a/app/src/main/java/jp/juggler/subwaytooter/ActAppSetting.java b/app/src/main/java/jp/juggler/subwaytooter/ActAppSetting.java
index 7c697061..d4005eca 100644
--- a/app/src/main/java/jp/juggler/subwaytooter/ActAppSetting.java
+++ b/app/src/main/java/jp/juggler/subwaytooter/ActAppSetting.java
@@ -40,9 +40,11 @@ import org.apache.commons.io.output.FileWriterWithEncoding;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
+import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
+import java.util.Locale;
import jp.juggler.subwaytooter.table.AcctColor;
import jp.juggler.subwaytooter.table.SavedAccount;
@@ -127,10 +129,17 @@ public class ActAppSetting extends AppCompatActivity
EditText etMediaThumbHeight;
EditText etClientName;
-
TextView tvTimelineFontUrl;
String timeline_font;
+ EditText etTimelineFontSize;
+ EditText etAcctFontSize;
+ TextView tvTimelineFontSize;
+ TextView tvAcctFontSize;
+
+ static final float default_timeline_font_size = 14f;
+ static final float default_acct_font_size = 12f;
+
private void initUI(){
setContentView( R.layout.act_app_setting );
@@ -178,7 +187,6 @@ public class ActAppSetting extends AppCompatActivity
swPostButtonBarTop = (Switch) findViewById( R.id.swPostButtonBarTop );
swPostButtonBarTop.setOnCheckedChangeListener( this );
-
cbNotificationSound = (CheckBox) findViewById( R.id.cbNotificationSound );
cbNotificationVibration = (CheckBox) findViewById( R.id.cbNotificationVibration );
cbNotificationLED = (CheckBox) findViewById( R.id.cbNotificationLED );
@@ -277,13 +285,22 @@ public class ActAppSetting extends AppCompatActivity
etColumnWidth = (EditText) findViewById( R.id.etColumnWidth );
etColumnWidth.addTextChangedListener( this );
-
+
etMediaThumbHeight = (EditText) findViewById( R.id.etMediaThumbHeight );
etMediaThumbHeight.addTextChangedListener( this );
-
+
etClientName = (EditText) findViewById( R.id.etClientName );
etClientName.addTextChangedListener( this );
-
+
+ tvTimelineFontSize = (TextView) findViewById( R.id.tvTimelineFontSize );
+ tvAcctFontSize = (TextView) findViewById( R.id.tvAcctFontSize );
+
+ etTimelineFontSize = (EditText) findViewById( R.id.etTimelineFontSize );
+ etTimelineFontSize.addTextChangedListener( new SizeCheckTextWatcher( tvTimelineFontSize, etTimelineFontSize, default_timeline_font_size ) );
+
+ etAcctFontSize = (EditText) findViewById( R.id.etAcctFontSize );
+ etAcctFontSize.addTextChangedListener( new SizeCheckTextWatcher( tvAcctFontSize, etAcctFontSize, default_acct_font_size ) );
+
tvTimelineFontUrl = (TextView) findViewById( R.id.tvTimelineFontUrl );
}
@@ -332,12 +349,19 @@ public class ActAppSetting extends AppCompatActivity
etColumnWidth.setText( pref.getString( Pref.KEY_COLUMN_WIDTH, "" ) );
etMediaThumbHeight.setText( pref.getString( Pref.KEY_MEDIA_THUMB_HEIGHT, "" ) );
etClientName.setText( pref.getString( Pref.KEY_CLIENT_NAME, "" ) );
+
+ etTimelineFontSize.setText( formatFontSize( pref.getFloat( Pref.KEY_TIMELINE_FONT_SIZE, Float.NaN ) ) );
+ etAcctFontSize.setText( formatFontSize( pref.getFloat( Pref.KEY_ACCT_FONT_SIZE, Float.NaN ) ) );
+
timeline_font = pref.getString( Pref.KEY_TIMELINE_FONT, "" );
load_busy = false;
showFooterColor();
showTimelineFont();
+
+ showFontSize( tvTimelineFontSize, etTimelineFontSize, default_timeline_font_size );
+ showFontSize( tvAcctFontSize, etAcctFontSize, default_acct_font_size );
}
private void saveUIToData(){
@@ -357,7 +381,7 @@ public class ActAppSetting extends AppCompatActivity
.putBoolean( Pref.KEY_DONT_CROP_MEDIA_THUMBNAIL, swDontCropMediaThumb.isChecked() )
.putBoolean( Pref.KEY_PRIOR_CHROME, swPriorChrome.isChecked() )
.putBoolean( Pref.KEY_POST_BUTTON_BAR_AT_TOP, swPostButtonBarTop.isChecked() )
-
+
.putBoolean( Pref.KEY_NOTIFICATION_SOUND, cbNotificationSound.isChecked() )
.putBoolean( Pref.KEY_NOTIFICATION_VIBRATION, cbNotificationVibration.isChecked() )
.putBoolean( Pref.KEY_NOTIFICATION_LED, cbNotificationLED.isChecked() )
@@ -380,7 +404,9 @@ 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_CLIENT_NAME, etClientName.getText().toString().trim() )
-
+ .putFloat( Pref.KEY_TIMELINE_FONT_SIZE, parseFontSize( etTimelineFontSize.getText().toString().trim() ) )
+ .putFloat( Pref.KEY_ACCT_FONT_SIZE, parseFontSize( etAcctFontSize.getText().toString().trim() ) )
+
.apply();
}
@@ -496,6 +522,7 @@ public class ActAppSetting extends AppCompatActivity
AlarmService.startCheck( this );
Utils.showToast( this, false, getString( R.string.custom_stream_listener_was_reset ) );
break;
+
}
}
@@ -631,6 +658,65 @@ public class ActAppSetting extends AppCompatActivity
saveUIToData();
}
+ private class SizeCheckTextWatcher implements TextWatcher {
+ TextView sample;
+ EditText et;
+ float default_size_sp;
+
+ SizeCheckTextWatcher( TextView sample, EditText et, float default_size_sp ){
+ this.sample = sample;
+ this.et = et;
+ this.default_size_sp = default_size_sp;
+ }
+
+ @Override public void beforeTextChanged( CharSequence s, int start, int count, int after ){
+
+ }
+
+ @Override public void onTextChanged( CharSequence s, int start, int before, int count ){
+
+ }
+
+ @Override public void afterTextChanged( Editable s ){
+ saveUIToData();
+ showFontSize( sample, et, default_size_sp );
+ }
+ }
+
+ private String formatFontSize( float fv ){
+ if( Float.isNaN( fv ) ){
+ return "";
+ }else{
+ return String.format( Locale.getDefault(), "%.1f", fv );
+ }
+ }
+
+ private float parseFontSize( String src ){
+ try{
+ NumberFormat format = NumberFormat.getInstance( Locale.getDefault() );
+ Number number = format.parse( src );
+ float f = number.floatValue();
+ if( ! Float.isNaN( f ) ){
+ if( f < 0f ) f = 0f;
+ if( f > 999f ) f = 999f;
+ return f;
+ }
+ }catch( Throwable ex ){
+ ex.printStackTrace();
+ }
+ return Float.NaN;
+ }
+
+ private void showFontSize( TextView sample, EditText et, float default_sp ){
+ float fv = parseFontSize( et.getText().toString().trim() );
+ if( Float.isNaN( fv ) ){
+ sample.setTextSize( default_sp );
+ }else{
+ if( fv < 1f ) fv = 1f;
+ sample.setTextSize( fv );
+ }
+ }
+
private void showTimelineFont(){
try{
if( ! TextUtils.isEmpty( timeline_font ) ){
diff --git a/app/src/main/java/jp/juggler/subwaytooter/ActColumnCustomize.java b/app/src/main/java/jp/juggler/subwaytooter/ActColumnCustomize.java
index 53c44112..c8317298 100644
--- a/app/src/main/java/jp/juggler/subwaytooter/ActColumnCustomize.java
+++ b/app/src/main/java/jp/juggler/subwaytooter/ActColumnCustomize.java
@@ -225,7 +225,7 @@ public class ActColumnCustomize extends AppCompatActivity
if( ! fromUser ) return;
column.column_bg_image_alpha = progress / (float) PROGRESS_MAX;
ivColumnBackground.setAlpha( column.column_bg_image_alpha );
- etAlpha.setText( String.format( Locale.JAPAN, "%.4f", column.column_bg_image_alpha ) );
+ etAlpha.setText( String.format( Locale.getDefault() , "%.4f", column.column_bg_image_alpha ) );
}
} );
diff --git a/app/src/main/java/jp/juggler/subwaytooter/ActMain.java b/app/src/main/java/jp/juggler/subwaytooter/ActMain.java
index fb4fc740..0d5ccfd4 100644
--- a/app/src/main/java/jp/juggler/subwaytooter/ActMain.java
+++ b/app/src/main/java/jp/juggler/subwaytooter/ActMain.java
@@ -105,6 +105,15 @@ public class ActMain extends AppCompatActivity
String posted_acct;
long posted_status_id;
+ float timeline_font_size_sp = Float.NaN;
+ float acct_font_size_sp = Float.NaN;
+
+ float validateFloat( float fv){
+ if( Float.isNaN( fv ) ) return fv;
+ if( fv < 1f ) fv = 1f;
+ return fv;
+ }
+
@Override protected void onCreate( Bundle savedInstanceState ){
log.d( "onCreate" );
super.onCreate( savedInstanceState );
@@ -118,6 +127,9 @@ public class ActMain extends AppCompatActivity
this.density = app_state.density;
this.acct_pad_lr = (int) ( 0.5f + 4f * density );
+ timeline_font_size_sp = validateFloat( pref.getFloat( Pref.KEY_TIMELINE_FONT_SIZE, Float.NaN ) );
+ acct_font_size_sp = validateFloat( pref.getFloat( Pref.KEY_ACCT_FONT_SIZE, Float.NaN ) );
+
initUI();
updateColumnStrip();
@@ -3755,12 +3767,12 @@ public class ActMain extends AppCompatActivity
}
public void openTimelineFor( @NonNull String host ){
- final ArrayList< SavedAccount > account_list = new ArrayList<>( );
+ final ArrayList< SavedAccount > account_list = new ArrayList<>();
for( SavedAccount a : SavedAccount.loadAccountList( log ) ){
if( host.equalsIgnoreCase( a.host ) ) account_list.add( a );
}
if( account_list.isEmpty() ){
-
+
SavedAccount ai = addPseudoAccount( host );
if( ai != null ){
addColumn( getDefaultInsertPosition(), ai, Column.TYPE_LOCAL );
@@ -3768,7 +3780,7 @@ public class ActMain extends AppCompatActivity
}else{
AccountPicker.pick( this, false, false
- , getString( R.string.account_picker_add_timeline_of ,host )
+ , getString( R.string.account_picker_add_timeline_of, host )
, account_list, new AccountPicker.AccountPickerCallback() {
@Override public void onAccountPicked( @NonNull SavedAccount ai ){
addColumn( getDefaultInsertPosition(), ai, Column.TYPE_LOCAL );
diff --git a/app/src/main/java/jp/juggler/subwaytooter/AlarmService.java b/app/src/main/java/jp/juggler/subwaytooter/AlarmService.java
index f1686792..8c520e3e 100644
--- a/app/src/main/java/jp/juggler/subwaytooter/AlarmService.java
+++ b/app/src/main/java/jp/juggler/subwaytooter/AlarmService.java
@@ -7,6 +7,8 @@ import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
+import android.media.Ringtone;
+import android.media.RingtoneManager;
import android.net.Uri;
import android.os.PowerManager;
import android.os.SystemClock;
@@ -24,6 +26,7 @@ import org.hjson.JsonValue;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
+
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@@ -106,7 +109,6 @@ public class AlarmService extends IntentService {
Intent next_intent = new Intent( this, AlarmReceiver.class );
pi_next = PendingIntent.getBroadcast( this, PENDING_CODE_ALARM, next_intent, PendingIntent.FLAG_UPDATE_CURRENT );
-
}
@Override public void onDestroy(){
@@ -121,16 +123,16 @@ public class AlarmService extends IntentService {
String mCustomStreamListenerSecret;
String mCustomStreamListenerSettingString;
JsonObject mCustomStreamListenerSetting;
-
- void loadCustomStreamListenerSetting( ){
+
+ void loadCustomStreamListenerSetting(){
mCustomStreamListenerSetting = null;
mCustomStreamListenerSecret = null;
- mCustomStreamListenerSettingString = pref.getString(Pref.KEY_STREAM_LISTENER_CONFIG_DATA ,null);
- if(! TextUtils.isEmpty( mCustomStreamListenerSettingString ) ){
+ mCustomStreamListenerSettingString = pref.getString( Pref.KEY_STREAM_LISTENER_CONFIG_DATA, null );
+ if( ! TextUtils.isEmpty( mCustomStreamListenerSettingString ) ){
try{
mCustomStreamListenerSetting = JsonValue.readHjson( mCustomStreamListenerSettingString ).asObject();
- mCustomStreamListenerSecret = pref.getString(Pref.KEY_STREAM_LISTENER_SECRET ,null);
- }catch(Throwable ex){
+ mCustomStreamListenerSecret = pref.getString( Pref.KEY_STREAM_LISTENER_SECRET, null );
+ }catch( Throwable ex ){
ex.printStackTrace();
}
}
@@ -139,7 +141,7 @@ public class AlarmService extends IntentService {
// IntentService は onHandleIntent をワーカースレッドから呼び出す
// 同期処理を行って良い
@Override protected void onHandleIntent( @Nullable Intent intent ){
- bStreamListenerTest =false;
+ bStreamListenerTest = false;
// クラッシュレポートによると App1.onCreate より前にここを通る場合がある
// データベースへアクセスできるようにする
@@ -184,16 +186,16 @@ public class AlarmService extends IntentService {
// アプリサーバへの登録をやり直す
}else if( ACTION_RESET_LAST_LOAD.equals( action ) ){
boolean bDone = false;
- String tag = intent.getStringExtra(EXTRA_TAG);
+ String tag = intent.getStringExtra( EXTRA_TAG );
if( tag != null ){
- for(SavedAccount sa : SavedAccount.loadByTag(log,tag )){
+ for( SavedAccount sa : SavedAccount.loadByTag( log, tag ) ){
bDone = true;
- NotificationTracking.resetLastLoad( sa.db_id);
+ NotificationTracking.resetLastLoad( sa.db_id );
}
}
- if(!bDone){
+ if( ! bDone ){
// タグにマッチする情報がなかった場合、全部読み直す
- NotificationTracking.resetLastLoad( );
+ NotificationTracking.resetLastLoad();
}
}else if( ACTION_DATA_DELETED.equals( action ) ){
deleteCacheData( intent.getLongExtra( EXTRA_DB_ID, - 1L ) );
@@ -281,7 +283,7 @@ public class AlarmService extends IntentService {
ArrayList< Data > data_list = new ArrayList<>();
checkAccount( client, data_list, account, muted_app, muted_word );
- showNotification( account.db_id, data_list );
+ showNotification( account, data_list );
}catch( Throwable ex ){
ex.printStackTrace();
@@ -317,9 +319,8 @@ public class AlarmService extends IntentService {
String getInstallId(){
SharedPreferences prefDevice = PrefDevice.prefDevice( this );
-
- String sv = prefDevice.getString(PrefDevice.KEY_INSTALL_ID,null);
+ String sv = prefDevice.getString( PrefDevice.KEY_INSTALL_ID, null );
if( ! TextUtils.isEmpty( sv ) ) return sv;
// インストールIDを生成する前に、各データの通知登録キャッシュをクリアする
@@ -332,13 +333,13 @@ public class AlarmService extends IntentService {
// トークンがまだ生成されていない場合、このメソッドは null を返します。
device_token = FirebaseInstanceId.getInstance().getToken();
if( TextUtils.isEmpty( device_token ) ){
- log.e("getInstallId: missing device token.");
+ log.e( "getInstallId: missing device token." );
return null;
}else{
prefDevice.edit().putString( PrefDevice.KEY_DEVICE_TOKEN, device_token ).apply();
}
- }catch(Throwable ex2){
- log.e("getInstallId: could not get device token.");
+ }catch( Throwable ex2 ){
+ log.e( "getInstallId: could not get device token." );
ex2.printStackTrace();
return null;
}
@@ -353,13 +354,13 @@ public class AlarmService extends IntentService {
Response response = call.execute();
if( ! response.isSuccessful() ){
- log.e("getInstallId: get /counter failed. %s",response);
+ log.e( "getInstallId: get /counter failed. %s", response );
return null;
}
//noinspection ConstantConditions
sv = Utils.digestSHA256( device_token + UUID.randomUUID() + response.body().string() );
- prefDevice.edit().putString(PrefDevice.KEY_INSTALL_ID, sv).apply();
+ prefDevice.edit().putString( PrefDevice.KEY_INSTALL_ID, sv ).apply();
return sv;
@@ -369,24 +370,22 @@ public class AlarmService extends IntentService {
}
}
-
-
private void unregisterDeviceToken( @NonNull SavedAccount account ){
try{
if( SavedAccount.REGISTER_KEY_UNREGISTERED.equals( account.register_key ) ){
- log.d("unregisterDeviceToken: already unregistered.");
+ log.d( "unregisterDeviceToken: already unregistered." );
return;
}
-
+
// ネットワーク的な事情でインストールIDを取得できなかったのなら、何もしない
if( TextUtils.isEmpty( install_id ) ){
- log.d("unregisterDeviceToken: missing install_id");
+ log.d( "unregisterDeviceToken: missing install_id" );
return;
}
String tag = account.notification_tag;
if( TextUtils.isEmpty( tag ) ){
- log.d("unregisterDeviceToken: missing notification_tag");
+ log.d( "unregisterDeviceToken: missing notification_tag" );
return;
}
@@ -410,7 +409,7 @@ public class AlarmService extends IntentService {
account.register_time = 0L;
account.saveRegisterKey();
}
-
+
}catch( Throwable ex ){
ex.printStackTrace();
}
@@ -421,7 +420,7 @@ public class AlarmService extends IntentService {
try{
// ネットワーク的な事情でインストールIDを取得できなかったのなら、何もしない
if( TextUtils.isEmpty( install_id ) ){
- log.d("registerDeviceToken: missing install id");
+ log.d( "registerDeviceToken: missing install id" );
return false;
}
@@ -429,18 +428,18 @@ public class AlarmService extends IntentService {
String device_token = prefDevice.getString( PrefDevice.KEY_DEVICE_TOKEN, null );
if( TextUtils.isEmpty( device_token ) ){
- log.d("registerDeviceToken: missing device_token");
+ log.d( "registerDeviceToken: missing device_token" );
return false;
}
String access_token = Utils.optStringX( account.token_info, "access_token" );
if( TextUtils.isEmpty( access_token ) ){
- log.d("registerDeviceToken: missing access_token");
+ log.d( "registerDeviceToken: missing access_token" );
return false;
}
String tag = account.notification_tag;
-
+
if( SavedAccount.REGISTER_KEY_UNREGISTERED.equals( account.register_key ) ){
tag = null;
}
@@ -452,36 +451,36 @@ public class AlarmService extends IntentService {
String reg_key = Utils.digestSHA256(
tag
- + access_token
- + device_token
- + (mCustomStreamListenerSecret==null? "" :mCustomStreamListenerSecret)
- + (mCustomStreamListenerSettingString==null? "" :mCustomStreamListenerSettingString)
+ + access_token
+ + device_token
+ + ( mCustomStreamListenerSecret == null ? "" : mCustomStreamListenerSecret )
+ + ( mCustomStreamListenerSettingString == null ? "" : mCustomStreamListenerSettingString )
);
long now = System.currentTimeMillis();
if( reg_key.equals( account.register_key ) && now - account.register_time < 3600000 * 3 ){
// タグやトークンが同一なら、前回登録に成功してから一定時間は再登録しない
- log.d("registerDeviceToken: already registered.");
+ log.d( "registerDeviceToken: already registered." );
return false;
}
-
+
// サーバ情報APIを使う
- StringBuilder post_data = new StringBuilder( );
-
- post_data.append("instance_url=").append(Uri.encode( "https://" + account.host ));
-
- post_data.append("&app_id=").append(Uri.encode( getPackageName() ));
-
- post_data.append("&tag=").append(tag);
-
- post_data.append("&access_token=").append(Utils.optStringX( account.token_info, "access_token" ));
-
- post_data.append("&device_token=").append(device_token);
-
+ StringBuilder post_data = new StringBuilder();
+
+ post_data.append( "instance_url=" ).append( Uri.encode( "https://" + account.host ) );
+
+ post_data.append( "&app_id=" ).append( Uri.encode( getPackageName() ) );
+
+ post_data.append( "&tag=" ).append( tag );
+
+ post_data.append( "&access_token=" ).append( Utils.optStringX( account.token_info, "access_token" ) );
+
+ post_data.append( "&device_token=" ).append( device_token );
+
if( ! TextUtils.isEmpty( mCustomStreamListenerSettingString )
- && ! TextUtils.isEmpty( mCustomStreamListenerSecret )
+ && ! TextUtils.isEmpty( mCustomStreamListenerSecret )
){
- post_data.append("&user_config=").append(Uri.encode(mCustomStreamListenerSettingString));
- post_data.append("&app_secret=").append(Uri.encode(mCustomStreamListenerSecret));
+ post_data.append( "&user_config=" ).append( Uri.encode( mCustomStreamListenerSettingString ) );
+ post_data.append( "&app_secret=" ).append( Uri.encode( mCustomStreamListenerSecret ) );
}
Request request = new Request.Builder()
@@ -489,21 +488,21 @@ public class AlarmService extends IntentService {
.post( RequestBody.create( TootApiClient.MEDIA_TYPE_FORM_URL_ENCODED, post_data.toString() ) )
.build();
- Call call = App1.ok_http_client.newCall( request );
+ Call call = App1.ok_http_client.newCall( request );
Response response = call.execute();
- String body=null;
+ String body = null;
try{
//noinspection ConstantConditions
- body =response.body().string();
- }catch(Throwable ignored){
+ body = response.body().string();
+ }catch( Throwable ignored ){
}
- log.e( "registerDeviceToken: %s (%s)",response,(body==null?"":body) );
-
+ log.e( "registerDeviceToken: %s (%s)", response, ( body == null ? "" : body ) );
+
int code = response.code();
-
- if( response.isSuccessful() || (code >= 400 && code < 500) ){
+
+ if( response.isSuccessful() || ( code >= 400 && code < 500 ) ){
// 登録できた時も4xxエラーだった時もDBに記録する
account.register_key = reg_key;
account.register_time = now;
@@ -632,7 +631,7 @@ public class AlarmService extends IntentService {
return;
}
- TootNotification notification = TootNotification.parse( log, account,account.host ,src );
+ TootNotification notification = TootNotification.parse( log, account, account.host, src );
if( notification == null ){
return;
}
@@ -672,8 +671,8 @@ public class AlarmService extends IntentService {
return "- " + "?";
}
- private void showNotification( long account_db_id, @NonNull ArrayList< Data > data_list ){
- String notification_tag = Long.toString( account_db_id );
+ private void showNotification( @NonNull SavedAccount account, @NonNull ArrayList< Data > data_list ){
+ String notification_tag = Long.toString( account.db_id );
if( data_list.isEmpty() ){
notification_manager.cancel( notification_tag, NOTIFICATION_ID );
return;
@@ -691,7 +690,7 @@ public class AlarmService extends IntentService {
} );
Data item = data_list.get( 0 );
- NotificationTracking nt = NotificationTracking.load( account_db_id );
+ NotificationTracking nt = NotificationTracking.load( account.db_id );
if( item.notification.time_created_at == nt.post_time
&& item.notification.id == nt.post_id
){
@@ -703,21 +702,39 @@ public class AlarmService extends IntentService {
// 通知タップ
Intent intent_click = new Intent( this, AlarmReceiver.class );
- intent_click.putExtra( EXTRA_DB_ID, account_db_id );
+ intent_click.putExtra( EXTRA_DB_ID, account.db_id );
intent_click.setAction( ACTION_NOTIFICATION_CLICK );
Intent intent_delete = new Intent( this, AlarmReceiver.class );
- intent_click.putExtra( EXTRA_DB_ID, account_db_id );
+ intent_click.putExtra( EXTRA_DB_ID, account.db_id );
intent_delete.setAction( ACTION_NOTIFICATION_DELETE );
- PendingIntent pi_click = PendingIntent.getBroadcast( this, ( 256 + (int) account_db_id ), intent_click, PendingIntent.FLAG_UPDATE_CURRENT );
+ PendingIntent pi_click = PendingIntent.getBroadcast( this, ( 256 + (int) account.db_id ), intent_click, PendingIntent.FLAG_UPDATE_CURRENT );
// 通知を消去した時のPendingIntent
- PendingIntent pi_delete = PendingIntent.getBroadcast( this, ( Integer.MAX_VALUE - (int) account_db_id ), intent_delete, PendingIntent.FLAG_UPDATE_CURRENT );
+ PendingIntent pi_delete = PendingIntent.getBroadcast( this, ( Integer.MAX_VALUE - (int) account.db_id ), intent_delete, PendingIntent.FLAG_UPDATE_CURRENT );
+
+ NotificationCompat.Builder builder = new NotificationCompat.Builder( this )
+ .setContentIntent( pi_click )
+ .setDeleteIntent( pi_delete )
+ .setAutoCancel( false )
+ .setSmallIcon( R.drawable.ic_notification ) // ここは常に白テーマのアイコンを使う
+ .setColor( ContextCompat.getColor( this, R.color.Light_colorAccent ) ) // ここは常に白テーマの色を使う
+ .setWhen( item.notification.time_created_at );
int iv = 0;
if( pref.getBoolean( Pref.KEY_NOTIFICATION_SOUND, true ) ){
- iv |= NotificationCompat.DEFAULT_SOUND;
+ Uri sound_uri = null;
+ try{
+ String sv = account.sound_uri;
+ sound_uri = TextUtils.isEmpty( sv ) ? null : Uri.parse( sv );
+ }catch( Throwable ignored ){
+ }
+ if( sound_uri != null ){
+ builder.setSound( sound_uri );
+ }else{
+ iv |= NotificationCompat.DEFAULT_SOUND;
+ }
}
if( pref.getBoolean( Pref.KEY_NOTIFICATION_VIBRATION, true ) ){
iv |= NotificationCompat.DEFAULT_VIBRATE;
@@ -726,15 +743,7 @@ public class AlarmService extends IntentService {
if( pref.getBoolean( Pref.KEY_NOTIFICATION_LED, true ) ){
iv |= NotificationCompat.DEFAULT_LIGHTS;
}
-
- NotificationCompat.Builder builder = new NotificationCompat.Builder( this )
- .setContentIntent( pi_click )
- .setDeleteIntent( pi_delete )
- .setAutoCancel( false )
- .setSmallIcon( R.drawable.ic_notification ) // ここは常に白テーマのアイコンを使う
- .setColor( ContextCompat.getColor( this, R.color.Light_colorAccent ) ) // ここは常に白テーマの色を使う
- .setDefaults( iv )
- .setWhen( item.notification.time_created_at );
+ builder.setDefaults( iv );
String a = getNotificationLine( item.notification.type, item.notification.account.display_name );
String acct = item.access_info.acct + " " + getString( R.string.app_name );
@@ -772,11 +781,10 @@ public class AlarmService extends IntentService {
public static void onFirebaseMessage( @NonNull Context context, @Nullable String tag ){
Intent intent = new Intent( context, AlarmService.class );
intent.setAction( ACTION_RESET_LAST_LOAD );
- if(tag !=null) intent.putExtra( EXTRA_TAG,tag );
+ if( tag != null ) intent.putExtra( EXTRA_TAG, tag );
context.startService( intent );
}
-
private static class InjectData {
long account_db_id;
TootNotification.List list = new TootNotification.List();
diff --git a/app/src/main/java/jp/juggler/subwaytooter/App1.java b/app/src/main/java/jp/juggler/subwaytooter/App1.java
index f0c38d59..a75788b3 100644
--- a/app/src/main/java/jp/juggler/subwaytooter/App1.java
+++ b/app/src/main/java/jp/juggler/subwaytooter/App1.java
@@ -51,7 +51,7 @@ public class App1 extends Application {
static final LogCategory log = new LogCategory( "App1" );
static final String DB_NAME = "app_db";
- static final int DB_VERSION = 15;
+ static final int DB_VERSION = 16;
public static final String FILE_PROVIDER_AUTHORITY = "jp.juggler.subwaytooter.FileProvider";
// 2017/4/25 v10 1=>2 SavedAccount に通知設定を追加
// 2017/4/25 v10 1=>2 NotificationTracking テーブルを追加
@@ -66,6 +66,7 @@ public class App1 extends Application {
// 2017/5/23 v68 12=>13 SavedAccountに項目追加
// 2017/5/25 v69 13=>14 SavedAccountに項目追加
// 2017/5/27 v73 14=>15 TagSetテーブルの追加
+ // 2017/7/22 v99 15=>16 SavedAccountに項目追加
private static DBOpenHelper db_open_helper;
diff --git a/app/src/main/java/jp/juggler/subwaytooter/AppDataExporter.java b/app/src/main/java/jp/juggler/subwaytooter/AppDataExporter.java
index 957ed6a9..4acf716f 100644
--- a/app/src/main/java/jp/juggler/subwaytooter/AppDataExporter.java
+++ b/app/src/main/java/jp/juggler/subwaytooter/AppDataExporter.java
@@ -334,6 +334,13 @@ public class AppDataExporter {
e.putString( k, sv );
break;
+ // double
+ case Pref.KEY_TIMELINE_FONT_SIZE:
+ case Pref.KEY_ACCT_FONT_SIZE:
+ double dv = reader.nextDouble();
+ e.putFloat( k, (float)dv );
+ break;
+
// force reset
default:
case Pref.KEY_TIMELINE_FONT:
diff --git a/app/src/main/java/jp/juggler/subwaytooter/ItemViewHolder.java b/app/src/main/java/jp/juggler/subwaytooter/ItemViewHolder.java
index bcfb9d3d..055deb65 100644
--- a/app/src/main/java/jp/juggler/subwaytooter/ItemViewHolder.java
+++ b/app/src/main/java/jp/juggler/subwaytooter/ItemViewHolder.java
@@ -67,7 +67,7 @@ class ItemViewHolder implements View.OnClickListener, View.OnLongClickListener {
private final MyTextView tvContent;
private final View flMedia;
- private final View btnShowMedia;
+ private final TextView btnShowMedia;
private final MyNetworkImageView ivMedia1;
private final MyNetworkImageView ivMedia2;
@@ -150,7 +150,7 @@ class ItemViewHolder implements View.OnClickListener, View.OnLongClickListener {
this.buttons_for_status = bSimpleList ? null : new StatusButtons( activity, column, view, false );
this.flMedia = view.findViewById( R.id.flMedia );
- this.btnShowMedia = view.findViewById( R.id.btnShowMedia );
+ this.btnShowMedia = (TextView) view.findViewById( R.id.btnShowMedia );
this.ivMedia1 = (MyNetworkImageView) view.findViewById( R.id.ivMedia1 );
this.ivMedia2 = (MyNetworkImageView) view.findViewById( R.id.ivMedia2 );
this.ivMedia3 = (MyNetworkImageView) view.findViewById( R.id.ivMedia3 );
@@ -191,6 +191,26 @@ class ItemViewHolder implements View.OnClickListener, View.OnLongClickListener {
ViewGroup.LayoutParams lp = flMedia.getLayoutParams();
lp.height = activity.app_state.media_thumb_height;
+
+ if( ! Float.isNaN( activity.timeline_font_size_sp ) ){
+ tvBoosted.setTextSize( activity.timeline_font_size_sp );
+ tvFollowerName.setTextSize( activity.timeline_font_size_sp );
+ tvName.setTextSize( activity.timeline_font_size_sp );
+ tvMentions.setTextSize( activity.timeline_font_size_sp );
+ tvContentWarning.setTextSize( activity.timeline_font_size_sp );
+ tvContent.setTextSize( activity.timeline_font_size_sp );
+ btnShowMedia.setTextSize( activity.timeline_font_size_sp );
+ tvApplication.setTextSize( activity.timeline_font_size_sp );
+
+ }
+
+ if( ! Float.isNaN( activity.acct_font_size_sp ) ){
+ tvBoostedAcct.setTextSize( activity.acct_font_size_sp );
+ tvBoostedTime.setTextSize( activity.acct_font_size_sp );
+ tvFollowerAcct.setTextSize( activity.acct_font_size_sp );
+ tvAcct.setTextSize( activity.acct_font_size_sp );
+ tvTime.setTextSize( activity.acct_font_size_sp );
+ }
}
void bind( Object item ){
@@ -343,6 +363,7 @@ class ItemViewHolder implements View.OnClickListener, View.OnLongClickListener {
, access_info.supplyBaseUrl( status.account.avatar )
);
}
+
tvContent.setText( status.decoded_content );
// if( status.decoded_tags == null ){
diff --git a/app/src/main/java/jp/juggler/subwaytooter/Pref.java b/app/src/main/java/jp/juggler/subwaytooter/Pref.java
index 5de56693..528c954d 100644
--- a/app/src/main/java/jp/juggler/subwaytooter/Pref.java
+++ b/app/src/main/java/jp/juggler/subwaytooter/Pref.java
@@ -65,5 +65,8 @@ public class Pref {
static final String KEY_LAST_COLUMN_POS = "last_column_pos";
+ public static final String KEY_TIMELINE_FONT_SIZE = "timeline_font_size";
+ public static final String KEY_ACCT_FONT_SIZE = "acct_font_size";
+
// 項目を追加したらAppDataExporter#importPref のswitch文も更新すること
}
diff --git a/app/src/main/java/jp/juggler/subwaytooter/table/SavedAccount.java b/app/src/main/java/jp/juggler/subwaytooter/table/SavedAccount.java
index 98845416..51d7207b 100644
--- a/app/src/main/java/jp/juggler/subwaytooter/table/SavedAccount.java
+++ b/app/src/main/java/jp/juggler/subwaytooter/table/SavedAccount.java
@@ -52,6 +52,10 @@ public class SavedAccount extends TootAccount implements LinkClickContext {
public static final String COL_REGISTER_KEY = "register_key";
public static final String COL_REGISTER_TIME = "register_time";
+ // スキーマ16から
+ public static final String COL_SOUND_URI = "sound_uri";
+
+
public static final long INVALID_ID = - 1L;
// login information
@@ -66,6 +70,7 @@ public class SavedAccount extends TootAccount implements LinkClickContext {
public boolean notification_boost;
public boolean notification_favourite;
public boolean notification_follow;
+ @NonNull public String sound_uri ="";
public boolean confirm_follow;
public boolean confirm_follow_locked;
@@ -116,6 +121,9 @@ public class SavedAccount extends TootAccount implements LinkClickContext {
+ "," + COL_REGISTER_KEY + " text default ''"
+ "," + COL_REGISTER_TIME + " integer default 0"
+ // 以下はDBスキーマ16で更新
+ + "," + COL_SOUND_URI + " text default ''"
+
+ ")"
);
@@ -187,6 +195,13 @@ public class SavedAccount extends TootAccount implements LinkClickContext {
ex.printStackTrace();
}
}
+ if( oldVersion < 16 && newVersion >= 16 ){
+ try{
+ db.execSQL( "alter table " + table + " add column " + COL_SOUND_URI + " text default ''" );
+ }catch( Throwable ex ){
+ ex.printStackTrace();
+ }
+ }
}
private SavedAccount(){
@@ -250,6 +265,8 @@ public class SavedAccount extends TootAccount implements LinkClickContext {
dst.register_time = cursor.getLong( cursor.getColumnIndex( COL_REGISTER_TIME ));
dst.token_info = new JSONObject( cursor.getString( cursor.getColumnIndex( COL_TOKEN ) ) );
+
+ dst.sound_uri = cursor.getString( cursor.getColumnIndex( COL_SOUND_URI ) );
}
return dst;
}
@@ -308,6 +325,8 @@ public class SavedAccount extends TootAccount implements LinkClickContext {
cv.put( COL_CONFIRM_UNFOLLOW, confirm_unfollow ? 1 : 0 );
cv.put( COL_CONFIRM_POST, confirm_post ? 1 : 0 );
+ cv.put( COL_SOUND_URI, sound_uri );
+
// UIからは更新しない
// notification_tag
// register_key
@@ -360,6 +379,8 @@ public class SavedAccount extends TootAccount implements LinkClickContext {
this.notification_favourite = b.notification_favourite;
this.notification_follow = b.notification_follow;
this.notification_tag = b.notification_tag;
+
+ this.sound_uri = b.sound_uri;
}
public static @Nullable SavedAccount loadAccount( @NonNull LogCategory log, long db_id ){
diff --git a/app/src/main/res/layout/act_account_setting.xml b/app/src/main/res/layout/act_account_setting.xml
index f4c61586..d172bc83 100644
--- a/app/src/main/res/layout/act_account_setting.xml
+++ b/app/src/main/res/layout/act_account_setting.xml
@@ -262,6 +262,35 @@
/>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/act_app_setting.xml b/app/src/main/res/layout/act_app_setting.xml
index cb4097f7..14128067 100644
--- a/app/src/main/res/layout/act_app_setting.xml
+++ b/app/src/main/res/layout/act_app_setting.xml
@@ -78,6 +78,8 @@
/>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Account-Image-Header-Static
Open timeline of \"%1$s\"
Account-Url
+ Notification Sound
+ Timeline font size (unit:sp. leave empty to default. app restart required)
+ Acct font size (unit:sp. leave empty to default. app restart required)
-
+
diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml
index 702a0d19..9fdc29b9 100644
--- a/app/src/main/res/values-ja/strings.xml
+++ b/app/src/main/res/values-ja/strings.xml
@@ -671,5 +671,8 @@
Account-Image-Header-Static
Account-Url
\"%1$s\"のタイムラインを開く
+ 通知音
+ タイムラインのフォントサイズ(単位:sp。空欄でデフォルト。アプリ再起動が必要)
+ Acctのフォントサイズ(単位:sp。空欄でデフォルト。アプリ再起動が必要)
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 4055dac8..44ae5eba 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -379,5 +379,8 @@
Account-Image-Header
Account-Image-Header-Static
Open timeline of \"%1$s\"
+ Notification Sound
+ Timeline font size (unit:sp. leave empty to default. app restart required)
+ Acct font size (unit:sp. leave empty to default. app restart required)
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index e0bce4e6..a3bc3ab6 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -208,6 +208,8 @@
- 12dp
- 0dp
+
+ - 14sp