- アプリ設定でタイムラインとAcctのフォントサイズを指定できる。
- アカウント設定で通知音を選べる。カスタム通知音の作成は別アプリで行ってください。
-- (例) 着メロメーカー https://play.google.com/store/apps/details?id=com.herman.ringtone&hl=ja&rdid=com.herman.ringtone
This commit is contained in:
tateisu 2017-07-22 05:21:55 +09:00
parent 1297393b00
commit 33220676b1
18 changed files with 401 additions and 101 deletions

View File

@ -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"
}

View File

@ -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 );
}
}

View File

@ -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 ) ){

View File

@ -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 ) );
}
} );

View File

@ -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 );

View File

@ -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();

View File

@ -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;

View File

@ -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:

View File

@ -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 ){

View File

@ -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文も更新すること
}

View File

@ -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 ){

View File

@ -262,6 +262,35 @@
/>
</LinearLayout>
<View style="@style/setting_divider"/>
<TextView
style="@style/setting_row_label"
android:text="@string/notification_sound"
/>
<LinearLayout style="@style/setting_row_form">
<Button
android:id="@+id/btnNotificationSoundEdit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/edit"
android:textAllCaps="false"
/>
<Button
android:id="@+id/btnNotificationSoundReset"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/reset"
android:textAllCaps="false"
/>
</LinearLayout>
<View style="@style/setting_divider"/>
<!--<View style="@style/setting_divider"/>-->
<!--<TextView-->

View File

@ -78,6 +78,8 @@
/>
</LinearLayout>
<View style="@style/setting_divider"/>
<TextView
@ -784,6 +786,46 @@
<View style="@style/setting_divider"/>
<TextView
style="@style/setting_row_label"
android:labelFor="@+id/etTimelineFontSize"
android:text="@string/timeline_font_size"
android:id="@+id/tvTimelineFontSize"
/>
<LinearLayout style="@style/setting_row_form">
<EditText
android:id="@+id/etTimelineFontSize"
style="@style/setting_horizontal_stretch"
android:gravity="center"
android:inputType="numberDecimal"
/>
</LinearLayout>
<View style="@style/setting_divider"/>
<TextView
style="@style/setting_row_label"
android:labelFor="@+id/etAcctFontSize"
android:text="@string/acct_font_size"
android:id="@+id/tvAcctFontSize"
/>
<LinearLayout style="@style/setting_row_form">
<EditText
android:id="@+id/etAcctFontSize"
style="@style/setting_horizontal_stretch"
android:gravity="center"
android:inputType="numberDecimal"
/>
</LinearLayout>
<View style="@style/setting_divider"/>
<!-- =============================================== -->
<TextView
style="@style/setting_group_header"

View File

@ -224,7 +224,7 @@
android:id="@+id/tvName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:text="Displayname @username"
tools:text="Displayname"
/>
<LinearLayout

View File

@ -384,8 +384,11 @@
<string name="send_header_account_image_header_static">Account-Image-Header-Static</string>
<string name="open_local_timeline_for">Open timeline of \"%1$s\"</string>
<string name="send_header_account_url">Account-Url</string>
<string name="notification_sound">Notification Sound</string>
<string name="timeline_font_size">Timeline font size (unit:sp. leave empty to default. app restart required)</string>
<string name="acct_font_size">Acct font size (unit:sp. leave empty to default. app restart required)</string>
<!--<string name="abc_action_bar_home_description">Revenir à l\'accueil</string>-->
<!--<string name="abc_action_bar_home_description">Revenir à l\'accueil</string>-->
<!--<string name="abc_action_bar_home_description_format">%1$s, %2$s</string>-->
<!--<string name="abc_action_bar_home_subtitle_description_format">%1$s, %2$s, %3$s</string>-->
<!--<string name="abc_action_bar_up_description">Revenir en haut de la page</string>-->

View File

@ -671,5 +671,8 @@
<string name="send_header_account_image_header_static">Account-Image-Header-Static</string>
<string name="send_header_account_url">Account-Url</string>
<string name="open_local_timeline_for">\"%1$s\"のタイムラインを開く</string>
<string name="notification_sound">通知音</string>
<string name="timeline_font_size">タイムラインのフォントサイズ(単位:sp。空欄でデフォルト。アプリ再起動が必要)</string>
<string name="acct_font_size">Acctのフォントサイズ(単位:sp。空欄でデフォルト。アプリ再起動が必要)</string>
</resources>

View File

@ -379,5 +379,8 @@
<string name="send_header_account_image_header">Account-Image-Header</string>
<string name="send_header_account_image_header_static">Account-Image-Header-Static</string>
<string name="open_local_timeline_for">Open timeline of \"%1$s\"</string>
<string name="notification_sound">Notification Sound</string>
<string name="timeline_font_size">Timeline font size (unit:sp. leave empty to default. app restart required)</string>
<string name="acct_font_size">Acct font size (unit:sp. leave empty to default. app restart required)</string>
</resources>

View File

@ -208,6 +208,8 @@
<item name="android:paddingStart" tools:ignore="NewApi">12dp</item>
<item name="android:paddingEnd" tools:ignore="NewApi">0dp</item>
<item name="android:textSize">14sp</item>
</style>
<style name="setting_row_form">