1
0
mirror of https://github.com/tateisu/SubwayTooter synced 2024-12-25 08:31:38 +01:00

アプリ設定に自動消灯しないを追加。クライアント情報を認証の度に作り直す

This commit is contained in:
tateisu 2017-05-11 23:33:11 +09:00
parent c13b92d7f8
commit d2c44518fd
9 changed files with 112 additions and 88 deletions

View File

@ -1,6 +1,7 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="AndroidLintButtonStyle" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="AndroidLintSetTextI18n" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="EmptyStatementBody" enabled="false" level="WARNING" enabled_by_default="false">
<option name="m_reportEmptyBlocks" value="true" />

View File

@ -52,7 +52,7 @@ public class ActAppSetting extends AppCompatActivity
Switch swDontRound;
Switch swDontUseStreaming;
Switch swDontRefreshOnResume;
Switch swDontScreenOff;
Spinner spBackButtonAction;
Spinner spUITheme;
@ -108,6 +108,10 @@ public class ActAppSetting extends AppCompatActivity
swDontRefreshOnResume = (Switch) findViewById( R.id.swDontRefreshOnResume );
swDontRefreshOnResume.setOnCheckedChangeListener( this );
swDontScreenOff= (Switch) findViewById( R.id.swDontScreenOff );
swDontScreenOff.setOnCheckedChangeListener( this );
cbNotificationSound = (CheckBox) findViewById( R.id.cbNotificationSound );
cbNotificationVibration = (CheckBox) findViewById( R.id.cbNotificationVibration );
cbNotificationLED = (CheckBox) findViewById( R.id.cbNotificationLED );
@ -201,7 +205,8 @@ public class ActAppSetting extends AppCompatActivity
swDontRound.setChecked( pref.getBoolean( Pref.KEY_DONT_ROUND, false ) );
swDontUseStreaming.setChecked( pref.getBoolean( Pref.KEY_DONT_USE_STREAMING, false ) );
swDontRefreshOnResume.setChecked( pref.getBoolean( Pref.KEY_DONT_REFRESH_ON_RESUME , false ) );
swDontScreenOff.setChecked( pref.getBoolean( Pref.KEY_DONT_SCREEN_OFF , false ) );
cbNotificationSound.setChecked( pref.getBoolean( Pref.KEY_NOTIFICATION_SOUND, true ) );
cbNotificationVibration.setChecked( pref.getBoolean( Pref.KEY_NOTIFICATION_VIBRATION, true ) );
cbNotificationLED.setChecked( pref.getBoolean( Pref.KEY_NOTIFICATION_LED, true ) );
@ -233,6 +238,8 @@ public class ActAppSetting extends AppCompatActivity
.putBoolean( Pref.KEY_DONT_ROUND, swDontRound.isChecked() )
.putBoolean( Pref.KEY_DONT_USE_STREAMING, swDontUseStreaming.isChecked() )
.putBoolean( Pref.KEY_DONT_REFRESH_ON_RESUME, swDontRefreshOnResume.isChecked() )
.putBoolean( Pref.KEY_DONT_SCREEN_OFF, swDontScreenOff.isChecked() )
.putBoolean( Pref.KEY_NOTIFICATION_SOUND, cbNotificationSound.isChecked() )
.putBoolean( Pref.KEY_NOTIFICATION_VIBRATION, cbNotificationVibration.isChecked() )

View File

@ -26,6 +26,7 @@ import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.Window;
import android.view.WindowManager;
import android.widget.HorizontalScrollView;
import android.widget.ImageButton;
import android.widget.ImageView;
@ -129,6 +130,12 @@ public class ActMain extends AppCompatActivity
MyClickableSpan.link_callback = link_click_listener;
if( pref.getBoolean( Pref.KEY_DONT_SCREEN_OFF,false )){
getWindow().addFlags( WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}else{
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
// アカウント設定から戻ってきたらカラムを消す必要があるかもしれない
{

View File

@ -39,6 +39,7 @@ public class Pref {
static final String KEY_DONT_USE_STREAMING = "dont_use_streaming";
static final String KEY_DONT_REFRESH_ON_RESUME = "dont_refresh_on_resume";
static final String KEY_DONT_SCREEN_OFF = "dont_screen_off";

View File

@ -9,11 +9,11 @@ import org.json.JSONArray;
import org.json.JSONObject;
import jp.juggler.subwaytooter.App1;
import jp.juggler.subwaytooter.table.ClientInfo;
import jp.juggler.subwaytooter.table.SavedAccount;
import jp.juggler.subwaytooter.util.LogCategory;
import jp.juggler.subwaytooter.R;
import jp.juggler.subwaytooter.util.Utils;
import jp.juggler.subwaytooter.table.ClientInfo;
import okhttp3.Call;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
@ -236,96 +236,83 @@ public class TootApiClient {
public TootApiResult authorize1(){
JSONObject client_info = null;
JSONObject client_info;
// サーバ側がクライアント情報を消した場合今の認証フローではアプリがそれを知ることができない
// 毎回クライアント情報を作ることでしか対策できない
callback.publishApiProgress( context.getString( R.string.register_app_to_server, instance ) );
// OAuth2 クライアント登録
String client_name = "SubwayTooter"; // + UUID.randomUUID().toString();
for( ; ; ){
if( callback.isApiCancelled() ) return null;
if( client_info == null ){
// DBからまず探す
client_info = ClientInfo.load( instance );
if( client_info != null && client_info.optInt( KEY_AUTH_VERSION, 0 ) < AUTH_VERSION ){
// このトークンは形式が古くて使えないよ
client_info = null;
}
if( client_info != null ) continue;
callback.publishApiProgress( context.getString( R.string.register_app_to_server, instance ) );
// OAuth2 クライアント登録
String client_name = "SubwayTooter"; // + UUID.randomUUID().toString();
Request request = new Request.Builder()
.url( "https://" + instance + "/api/v1/apps" )
.post( RequestBody.create( MEDIA_TYPE_FORM_URL_ENCODED
, "client_name=" + Uri.encode( client_name )
+ "&redirect_uris=" + Uri.encode( REDIRECT_URL )
+ "&scopes=read write follow"
) )
.build();
Call call = ok_http_client.newCall( request );
Response response;
try{
response = call.execute();
}catch( Throwable ex ){
ex.printStackTrace( );
return new TootApiResult( Utils.formatError( ex, context.getResources(), R.string.network_error ) );
}
if( callback.isApiCancelled() ) return null;
if( ! response.isSuccessful() ){
return new TootApiResult( context.getString( R.string.network_error_arg, response ) );
}
try{
String json = response.body().string();
if( TextUtils.isEmpty( json ) || json.startsWith( "<" ) ){
return new TootApiResult( context.getString( R.string.response_not_json ) + "\n" + json );
}
// {"id":999,"redirect_uri":"urn:ietf:wg:oauth:2.0:oob","client_id":"******","client_secret":"******"}
client_info = new JSONObject( json );
String error = Utils.optStringX( client_info, "error" );
if( ! TextUtils.isEmpty( error ) ){
return new TootApiResult( context.getString( R.string.api_error, error ) );
}
client_info.put( KEY_AUTH_VERSION, AUTH_VERSION );
ClientInfo.save( instance, client_info.toString() );
continue;
}catch( Throwable ex ){
ex.printStackTrace();
return new TootApiResult( Utils.formatError( ex, "API data error" ) );
}
}
// 認証ページURLを作る
final String browser_url = "https://" + instance + "/oauth/authorize"
+ "?client_id=" + Uri.encode( Utils.optStringX( client_info, "client_id" ) )
// この段階では要らない + "&client_secret=" + Uri.encode( Utils.optStringX( client_info, "client_secret" ) )
+ "&response_type=code"
+ "&redirect_uri=" + Uri.encode( REDIRECT_URL )
+ "&scope=read write follow"
+ "&scopes=read write follow"
+ "&state=" + ( account != null ? "db:" + account.db_id : "host:" + instance )
+ "&grant_type=authorization_code"
// + "&username=" + Uri.encode( user_mail )
// + "&password=" + Uri.encode( password )
+ "&approval_prompt=force"
// +"&access_type=offline"
;
// APIリクエストは失敗?する
// URLをエラーとして返す
return new TootApiResult( browser_url );
Request request = new Request.Builder()
.url( "https://" + instance + "/api/v1/apps" )
.post( RequestBody.create( MEDIA_TYPE_FORM_URL_ENCODED
, "client_name=" + Uri.encode( client_name )
+ "&redirect_uris=" + Uri.encode( REDIRECT_URL )
+ "&scopes=read write follow"
) )
.build();
Call call = ok_http_client.newCall( request );
Response response;
try{
response = call.execute();
}catch( Throwable ex ){
ex.printStackTrace( );
return new TootApiResult( Utils.formatError( ex, context.getResources(), R.string.network_error ) );
}
if( callback.isApiCancelled() ) return null;
if( ! response.isSuccessful() ){
return new TootApiResult( context.getString( R.string.network_error_arg, response ) );
}
try{
String json = response.body().string();
if( TextUtils.isEmpty( json ) || json.startsWith( "<" ) ){
return new TootApiResult( context.getString( R.string.response_not_json ) + "\n" + json );
}
// {"id":999,"redirect_uri":"urn:ietf:wg:oauth:2.0:oob","client_id":"******","client_secret":"******"}
client_info = new JSONObject( json );
String error = Utils.optStringX( client_info, "error" );
if( ! TextUtils.isEmpty( error ) ){
return new TootApiResult( context.getString( R.string.api_error, error ) );
}
client_info.put( KEY_AUTH_VERSION, AUTH_VERSION );
// authorize2 で使う
ClientInfo.save( instance, client_info.toString() );
}catch( Throwable ex ){
ex.printStackTrace();
return new TootApiResult( Utils.formatError( ex, "API data error" ) );
}
// 認証ページURLを作る
final String browser_url = "https://" + instance + "/oauth/authorize"
+ "?client_id=" + Uri.encode( Utils.optStringX( client_info, "client_id" ) )
// この段階では要らない + "&client_secret=" + Uri.encode( Utils.optStringX( client_info, "client_secret" ) )
+ "&response_type=code"
+ "&redirect_uri=" + Uri.encode( REDIRECT_URL )
+ "&scope=read write follow"
+ "&scopes=read write follow"
+ "&state=" + ( account != null ? "db:" + account.db_id : "host:" + instance )
+ "&grant_type=authorization_code"
// + "&username=" + Uri.encode( user_mail )
// + "&password=" + Uri.encode( password )
+ "&approval_prompt=force"
// +"&access_type=offline"
;
// APIリクエストは失敗?する
// URLをエラーとして返す
return new TootApiResult( browser_url );
}
public TootApiResult authorize2( String code ){
JSONObject client_info = ClientInfo.load( instance );
if( client_info != null && client_info.optInt( KEY_AUTH_VERSION, 0 ) < AUTH_VERSION ){
client_info = null;
}
if( client_info == null ){
return new TootApiResult( "missing client id" );
}

View File

@ -2,9 +2,12 @@
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:ignore="TooManyViews"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:clipToPadding="false"
android:fillViewport="true"
@ -14,7 +17,6 @@
android:paddingStart="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:scrollbarStyle="outsideOverlay"
>
@ -392,7 +394,8 @@
</LinearLayout>
<LinearLayout style="@style/setting_row_form">
<LinearLayout style="@style/setting_row_form"
>
<TextView
style="@style/setting_row_label"
@ -479,6 +482,21 @@
<View style="@style/setting_divider"/>
<TextView
style="@style/setting_row_label"
android:text="@string/dont_screen_off"
/>
<LinearLayout style="@style/setting_row_form">
<Switch
android:id="@+id/swDontScreenOff"
style="@style/setting_horizontal_stretch"
/>
</LinearLayout>
<View style="@style/setting_divider"/>
<!--<TextView-->
<!--style="@style/setting_row_label"-->

View File

@ -307,5 +307,6 @@
<string name="already_boosted">Already boosted.</string>
<string name="already_favourited">Already favourited.</string>
<string name="status_id_conversion_failed">Status id conversion failed.</string>
<string name="dont_screen_off">Don\'t screen off while main activity is shown</string>
</resources>

View File

@ -593,4 +593,5 @@
<string name="already_boosted">既にブースト済みです</string>
<string name="already_favourited">既にお気に入り済みです</string>
<string name="status_id_conversion_failed">ステータスIDを変換できませんでした</string>
<string name="dont_screen_off">メイン画面表示中は自動消灯無効</string>
</resources>

View File

@ -303,4 +303,5 @@
<string name="status_id_conversion_failed">Status id conversion failed.</string>
<string name="already_favourited">Already favourited.</string>
<string name="already_boosted">Already boosted.</string>
<string name="dont_screen_off">Don\'t screen off while main activity is shown</string>
</resources>