Firebase Cloud Messagingの組み込み
This commit is contained in:
parent
0d9b7c1750
commit
e99872fe4d
|
@ -6,6 +6,7 @@
|
||||||
<w>emojione</w>
|
<w>emojione</w>
|
||||||
<w>enty</w>
|
<w>enty</w>
|
||||||
<w>favourited</w>
|
<w>favourited</w>
|
||||||
|
<w>firebase</w>
|
||||||
<w>hashtag</w>
|
<w>hashtag</w>
|
||||||
<w>hashtags</w>
|
<w>hashtags</w>
|
||||||
<w>idempotency</w>
|
<w>idempotency</w>
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
<ConfirmationsSetting value="0" id="Add" />
|
<ConfirmationsSetting value="0" id="Add" />
|
||||||
<ConfirmationsSetting value="0" id="Remove" />
|
<ConfirmationsSetting value="0" id="Remove" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectType">
|
<component name="ProjectType">
|
||||||
|
|
|
@ -9,8 +9,8 @@ android {
|
||||||
applicationId "jp.juggler.subwaytooter"
|
applicationId "jp.juggler.subwaytooter"
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 25
|
targetSdkVersion 25
|
||||||
versionCode 67
|
versionCode 68
|
||||||
versionName "0.6.7"
|
versionName "0.6.8"
|
||||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,6 +55,9 @@ dependencies {
|
||||||
compile 'com.android.support:customtabs:25.3.1'
|
compile 'com.android.support:customtabs:25.3.1'
|
||||||
compile 'com.android.support:support-v4:25.3.1'
|
compile 'com.android.support:support-v4:25.3.1'
|
||||||
|
|
||||||
|
compile 'com.google.firebase:firebase-core:10.0.1'
|
||||||
|
compile 'com.google.firebase:firebase-messaging:10.0.1'
|
||||||
|
|
||||||
// compile 'com.android.support.constraint:constraint-layout:1.0.2'
|
// compile 'com.android.support.constraint:constraint-layout:1.0.2'
|
||||||
|
|
||||||
testCompile 'junit:junit:4.12'
|
testCompile 'junit:junit:4.12'
|
||||||
|
@ -74,3 +77,5 @@ dependencies {
|
||||||
// annotationProcessor 'com.github.bumptech.glide:compiler:3.8.0'
|
// annotationProcessor 'com.github.bumptech.glide:compiler:3.8.0'
|
||||||
compile 'com.github.bumptech.glide:okhttp3-integration:1.5.0'
|
compile 'com.github.bumptech.glide:okhttp3-integration:1.5.0'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
apply plugin: 'com.google.gms.google-services'
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
{
|
||||||
|
"project_info": {
|
||||||
|
"project_number": "433682361381",
|
||||||
|
"firebase_url": "https://subway-tooter.firebaseio.com",
|
||||||
|
"project_id": "subway-tooter",
|
||||||
|
"storage_bucket": "subway-tooter.appspot.com"
|
||||||
|
},
|
||||||
|
"client": [
|
||||||
|
{
|
||||||
|
"client_info": {
|
||||||
|
"mobilesdk_app_id": "1:433682361381:android:7ae4daf10abb936c",
|
||||||
|
"android_client_info": {
|
||||||
|
"package_name": "jp.juggler.subwaytooter"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"oauth_client": [
|
||||||
|
{
|
||||||
|
"client_id": "433682361381-33pqgervqgcehbm9hup1g6qu967vs427.apps.googleusercontent.com",
|
||||||
|
"client_type": 3
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"api_key": [
|
||||||
|
{
|
||||||
|
"current_key": "AIzaSyDVF995DFPjoY3ynGjGiI-5KDs8_BemE98"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"services": {
|
||||||
|
"analytics_service": {
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"appinvite_service": {
|
||||||
|
"status": 1,
|
||||||
|
"other_platform_oauth_client": []
|
||||||
|
},
|
||||||
|
"ads_service": {
|
||||||
|
"status": 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"configuration_version": "1"
|
||||||
|
}
|
|
@ -171,6 +171,32 @@
|
||||||
<!--android:name="com.bumptech.glide.integration.okhttp3.OkHttpGlideModule"-->
|
<!--android:name="com.bumptech.glide.integration.okhttp3.OkHttpGlideModule"-->
|
||||||
<!--android:value="GlideModule" />-->
|
<!--android:value="GlideModule" />-->
|
||||||
|
|
||||||
|
<service
|
||||||
|
android:name=".MyFirebaseMessagingService">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
|
||||||
|
</intent-filter>
|
||||||
|
</service>
|
||||||
|
|
||||||
|
<service
|
||||||
|
android:name=".MyFirebaseInstanceIDService">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
|
||||||
|
</intent-filter>
|
||||||
|
</service>
|
||||||
|
|
||||||
|
<!-- Set custom default icon. This is used when no icon is set for incoming notification messages.
|
||||||
|
See README(https://goo.gl/l4GJaQ) for more. -->
|
||||||
|
<meta-data
|
||||||
|
android:name="com.google.firebase.messaging.default_notification_icon"
|
||||||
|
android:resource="@drawable/ic_notification" />
|
||||||
|
|
||||||
|
<!-- Set color used with incoming notification messages. This is used when no color is set for the incoming
|
||||||
|
notification message. See README(https://goo.gl/6BKBk7) for more. -->
|
||||||
|
<meta-data
|
||||||
|
android:name="com.google.firebase.messaging.default_notification_color"
|
||||||
|
android:resource="@color/Light_colorAccent" />
|
||||||
|
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
|
@ -56,7 +56,7 @@ public class ActAccountSetting extends AppCompatActivity
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override protected void onStop(){
|
@Override protected void onStop(){
|
||||||
AlarmService.startCheck( this );
|
AlarmService.startCheck( this ,false);
|
||||||
super.onStop();
|
super.onStop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -128,7 +128,7 @@ public class ActMain extends AppCompatActivity
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AlarmService.startCheck( this );
|
AlarmService.startCheck( this ,false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override protected void onDestroy(){
|
@Override protected void onDestroy(){
|
||||||
|
@ -1192,7 +1192,7 @@ public class ActMain extends AppCompatActivity
|
||||||
account.saveSetting();
|
account.saveSetting();
|
||||||
}
|
}
|
||||||
Utils.showToast( ActMain.this, false, R.string.account_confirmed );
|
Utils.showToast( ActMain.this, false, R.string.account_confirmed );
|
||||||
AlarmService.startCheck( ActMain.this );
|
AlarmService.startCheck( ActMain.this ,false);
|
||||||
long count = SavedAccount.getCount();
|
long count = SavedAccount.getCount();
|
||||||
if( count > 1 ){
|
if( count > 1 ){
|
||||||
addColumn( getDefaultInsertPosition(), account, Column.TYPE_HOME );
|
addColumn( getDefaultInsertPosition(), account, Column.TYPE_HOME );
|
||||||
|
|
|
@ -15,6 +15,7 @@ import android.support.annotation.Nullable;
|
||||||
import android.support.v4.app.NotificationCompat;
|
import android.support.v4.app.NotificationCompat;
|
||||||
import android.support.v4.content.ContextCompat;
|
import android.support.v4.content.ContextCompat;
|
||||||
import android.support.v4.content.WakefulBroadcastReceiver;
|
import android.support.v4.content.WakefulBroadcastReceiver;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
|
@ -25,6 +26,7 @@ import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
@ -39,6 +41,10 @@ import jp.juggler.subwaytooter.table.SavedAccount;
|
||||||
import jp.juggler.subwaytooter.util.LogCategory;
|
import jp.juggler.subwaytooter.util.LogCategory;
|
||||||
import jp.juggler.subwaytooter.util.Utils;
|
import jp.juggler.subwaytooter.util.Utils;
|
||||||
import jp.juggler.subwaytooter.util.WordTrieTree;
|
import jp.juggler.subwaytooter.util.WordTrieTree;
|
||||||
|
import okhttp3.Call;
|
||||||
|
import okhttp3.Request;
|
||||||
|
import okhttp3.RequestBody;
|
||||||
|
import okhttp3.Response;
|
||||||
|
|
||||||
public class AlarmService extends IntentService {
|
public class AlarmService extends IntentService {
|
||||||
|
|
||||||
|
@ -61,6 +67,10 @@ public class AlarmService extends IntentService {
|
||||||
public static final AtomicBoolean mBusyAppDataImportBefore = new AtomicBoolean( false );
|
public static final AtomicBoolean mBusyAppDataImportBefore = new AtomicBoolean( false );
|
||||||
public static final AtomicBoolean mBusyAppDataImportAfter = new AtomicBoolean( false );
|
public static final AtomicBoolean mBusyAppDataImportAfter = new AtomicBoolean( false );
|
||||||
public static final String ACTION_APP_DATA_IMPORT_AFTER = "app_data_import_after";
|
public static final String ACTION_APP_DATA_IMPORT_AFTER = "app_data_import_after";
|
||||||
|
public static final String ACTION_DEVICE_TOKEN = "device_token";
|
||||||
|
private static final String ACTION_RESET_LAST_LOAD = "reset_last_load";
|
||||||
|
|
||||||
|
static final String APP_SERVER = "https://mastodon-msg.juggler.jp";
|
||||||
|
|
||||||
public AlarmService(){
|
public AlarmService(){
|
||||||
// name: Used to name the worker thread, important only for debugging.
|
// name: Used to name the worker thread, important only for debugging.
|
||||||
|
@ -92,6 +102,7 @@ public class AlarmService extends IntentService {
|
||||||
Intent next_intent = new Intent( this, AlarmReceiver.class );
|
Intent next_intent = new Intent( this, AlarmReceiver.class );
|
||||||
pi_next = PendingIntent.getBroadcast( this, PENDING_CODE_ALARM, next_intent, PendingIntent.FLAG_UPDATE_CURRENT );
|
pi_next = PendingIntent.getBroadcast( this, PENDING_CODE_ALARM, next_intent, PendingIntent.FLAG_UPDATE_CURRENT );
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void onDestroy(){
|
@Override public void onDestroy(){
|
||||||
|
@ -101,6 +112,8 @@ public class AlarmService extends IntentService {
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String install_id;
|
||||||
|
|
||||||
// IntentService は onHandleIntent をワーカースレッドから呼び出す
|
// IntentService は onHandleIntent をワーカースレッドから呼び出す
|
||||||
// 同期処理を行って良い
|
// 同期処理を行って良い
|
||||||
@Override protected void onHandleIntent( @Nullable Intent intent ){
|
@Override protected void onHandleIntent( @Nullable Intent intent ){
|
||||||
|
@ -109,6 +122,10 @@ public class AlarmService extends IntentService {
|
||||||
// データベースへアクセスできるようにする
|
// データベースへアクセスできるようにする
|
||||||
App1.prepareDB( this.getApplicationContext() );
|
App1.prepareDB( this.getApplicationContext() );
|
||||||
|
|
||||||
|
|
||||||
|
install_id = getInstallId();
|
||||||
|
|
||||||
|
|
||||||
if( intent != null ){
|
if( intent != null ){
|
||||||
String action = intent.getAction();
|
String action = intent.getAction();
|
||||||
log.d( "onHandleIntent action=%s", action );
|
log.d( "onHandleIntent action=%s", action );
|
||||||
|
@ -138,10 +155,19 @@ public class AlarmService extends IntentService {
|
||||||
if( intent != null ){
|
if( intent != null ){
|
||||||
String action = intent.getAction();
|
String action = intent.getAction();
|
||||||
|
|
||||||
if( ACTION_DATA_DELETED.equals( action ) ){
|
if( ACTION_DEVICE_TOKEN.equals( action ) ){
|
||||||
|
// デバイストークンが更新された
|
||||||
|
// TODO 過去に中継サーバに登録したものは登録解除して登録しなおす必要がある
|
||||||
|
|
||||||
|
}else if( ACTION_RESET_LAST_LOAD.equals( action ) ){
|
||||||
|
NotificationTracking.resetLastLoad();
|
||||||
|
|
||||||
|
}else if( ACTION_DATA_DELETED.equals( action ) ){
|
||||||
deleteCacheData( intent.getLongExtra( EXTRA_DB_ID, - 1L ) );
|
deleteCacheData( intent.getLongExtra( EXTRA_DB_ID, - 1L ) );
|
||||||
|
|
||||||
}else if( ACTION_DATA_INJECTED.equals( action ) ){
|
}else if( ACTION_DATA_INJECTED.equals( action ) ){
|
||||||
processInjectedData();
|
processInjectedData();
|
||||||
|
|
||||||
}else if( AlarmReceiver.ACTION_FROM_RECEIVER.equals( action ) ){
|
}else if( AlarmReceiver.ACTION_FROM_RECEIVER.equals( action ) ){
|
||||||
WakefulBroadcastReceiver.completeWakefulIntent( intent );
|
WakefulBroadcastReceiver.completeWakefulIntent( intent );
|
||||||
//
|
//
|
||||||
|
@ -192,11 +218,21 @@ public class AlarmService extends IntentService {
|
||||||
@Override public void run(){
|
@Override public void run(){
|
||||||
|
|
||||||
try{
|
try{
|
||||||
if( account.notification_mention
|
if( account.isPseudo() ) return;
|
||||||
|| account.notification_boost
|
|
||||||
|| account.notification_favourite
|
if( ! account.notification_mention
|
||||||
|| account.notification_follow
|
&& ! account.notification_boost
|
||||||
|
&& ! account.notification_favourite
|
||||||
|
&& ! account.notification_follow
|
||||||
){
|
){
|
||||||
|
unregisterDeviceToken( account );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( registerDeviceToken( account ) ){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
bAlarmRequired.set( true );
|
bAlarmRequired.set( true );
|
||||||
|
|
||||||
TootApiClient client = new TootApiClient( AlarmService.this, new TootApiClient.Callback() {
|
TootApiClient client = new TootApiClient( AlarmService.this, new TootApiClient.Callback() {
|
||||||
|
@ -211,7 +247,7 @@ public class AlarmService extends IntentService {
|
||||||
ArrayList< Data > data_list = new ArrayList<>();
|
ArrayList< Data > data_list = new ArrayList<>();
|
||||||
checkAccount( client, data_list, account, muted_app, muted_word );
|
checkAccount( client, data_list, account, muted_app, muted_word );
|
||||||
showNotification( account.db_id, data_list );
|
showNotification( account.db_id, data_list );
|
||||||
}
|
|
||||||
}catch( Throwable ex ){
|
}catch( Throwable ex ){
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
}
|
}
|
||||||
|
@ -244,6 +280,118 @@ public class AlarmService extends IntentService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String getInstallId(){
|
||||||
|
String sv = pref.getString(Pref.KEY_INSTALL_ID,null);
|
||||||
|
if( ! TextUtils.isEmpty( sv ) ) return sv;
|
||||||
|
|
||||||
|
try{
|
||||||
|
String device_token = pref.getString( Pref.KEY_DEVICE_TOKEN, null );
|
||||||
|
if( TextUtils.isEmpty( device_token ) ) return null;
|
||||||
|
|
||||||
|
Request request = new Request.Builder()
|
||||||
|
.url( APP_SERVER + "/counter" )
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Call call = App1.ok_http_client.newCall( request );
|
||||||
|
|
||||||
|
Response response = call.execute();
|
||||||
|
|
||||||
|
if( ! response.isSuccessful() ){
|
||||||
|
log.e("getInstallId: get /counter failed. %s",response);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
//noinspection ConstantConditions
|
||||||
|
sv = Utils.digestSHA256( device_token + UUID.randomUUID() + response.body().string() );
|
||||||
|
pref.edit().putString(Pref.KEY_INSTALL_ID, sv).apply();
|
||||||
|
|
||||||
|
return sv;
|
||||||
|
|
||||||
|
}catch( Throwable ex ){
|
||||||
|
ex.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void unregisterDeviceToken( @NonNull SavedAccount account ){
|
||||||
|
try{
|
||||||
|
// ネットワーク的な事情でインストールIDを取得できなかったのなら、何もしない
|
||||||
|
if( TextUtils.isEmpty( install_id ) ) return;
|
||||||
|
|
||||||
|
String device_token = pref.getString( Pref.KEY_DEVICE_TOKEN, null );
|
||||||
|
if( TextUtils.isEmpty( device_token ) ) return;
|
||||||
|
|
||||||
|
String tag = account.notification_tag;
|
||||||
|
if( TextUtils.isEmpty( tag ) ) return;
|
||||||
|
|
||||||
|
String post_data = "instance_url=" + Uri.encode( "https://" + account.host )
|
||||||
|
+ "&app_id=" + Uri.encode( getPackageName() )
|
||||||
|
+ "&tag=" + tag;
|
||||||
|
|
||||||
|
Request request = new Request.Builder()
|
||||||
|
.url( APP_SERVER + "/unregister" )
|
||||||
|
.post( RequestBody.create( TootApiClient.MEDIA_TYPE_FORM_URL_ENCODED, post_data ) )
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Call call = App1.ok_http_client.newCall( request );
|
||||||
|
|
||||||
|
Response response = call.execute();
|
||||||
|
|
||||||
|
log.e( "unregisterDeviceToken:%s", response );
|
||||||
|
|
||||||
|
}catch( Throwable ex ){
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 定期的な通知更新が不要なら真を返す
|
||||||
|
private boolean registerDeviceToken( @NonNull SavedAccount account ){
|
||||||
|
try{
|
||||||
|
// ネットワーク的な事情でインストールIDを取得できなかったのなら、何もしない
|
||||||
|
if( TextUtils.isEmpty( install_id ) ) return false;
|
||||||
|
|
||||||
|
String device_token = pref.getString( Pref.KEY_DEVICE_TOKEN, null );
|
||||||
|
if( TextUtils.isEmpty( device_token ) ) return false;
|
||||||
|
|
||||||
|
String tag = account.notification_tag;
|
||||||
|
if( TextUtils.isEmpty( tag ) ){
|
||||||
|
tag = account.notification_tag = Utils.digestSHA256( install_id + account.db_id + account.acct );
|
||||||
|
account.saveNotificationTag();
|
||||||
|
}
|
||||||
|
|
||||||
|
// サーバ情報APIを使う
|
||||||
|
String post_data = "instance_url=" +
|
||||||
|
Uri.encode( "https://" + account.host ) +
|
||||||
|
"&app_id=" +
|
||||||
|
Uri.encode( getPackageName() ) +
|
||||||
|
"&tag=" +
|
||||||
|
tag +
|
||||||
|
"&access_token=" +
|
||||||
|
Utils.optStringX( account.token_info, "access_token" ) +
|
||||||
|
"&device_token=" +
|
||||||
|
device_token;
|
||||||
|
|
||||||
|
Request request = new Request.Builder()
|
||||||
|
.url( APP_SERVER + "/register" )
|
||||||
|
.post( RequestBody.create( TootApiClient.MEDIA_TYPE_FORM_URL_ENCODED, post_data ) )
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Call call = App1.ok_http_client.newCall( request );
|
||||||
|
|
||||||
|
Response response = call.execute();
|
||||||
|
|
||||||
|
log.e( "registerDeviceToken:%s", response );
|
||||||
|
|
||||||
|
// TODO 登録結果をDBに記録する
|
||||||
|
// 登録してから一定時間は再登録しない
|
||||||
|
|
||||||
|
}catch( Throwable ex ){
|
||||||
|
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private static class Data {
|
private static class Data {
|
||||||
SavedAccount access_info;
|
SavedAccount access_info;
|
||||||
TootNotification notification;
|
TootNotification notification;
|
||||||
|
@ -492,9 +640,11 @@ public class AlarmService extends IntentService {
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
// Activity との連携
|
// Activity との連携
|
||||||
|
|
||||||
public static void startCheck( @NonNull Context context ){
|
public static void startCheck( @NonNull Context context, boolean bResetLastLoad ){
|
||||||
Intent intent = new Intent( context, AlarmReceiver.class );
|
Intent intent = new Intent( context, AlarmService.class );
|
||||||
context.sendBroadcast( intent );
|
if( bResetLastLoad ) intent.setAction( ACTION_RESET_LAST_LOAD );
|
||||||
|
|
||||||
|
context.startService( intent );
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class InjectData {
|
private static class InjectData {
|
||||||
|
|
|
@ -50,7 +50,7 @@ public class App1 extends Application {
|
||||||
static final LogCategory log = new LogCategory( "App1" );
|
static final LogCategory log = new LogCategory( "App1" );
|
||||||
|
|
||||||
static final String DB_NAME = "app_db";
|
static final String DB_NAME = "app_db";
|
||||||
static final int DB_VERSION = 12;
|
static final int DB_VERSION = 13;
|
||||||
// 2017/4/25 v10 1=>2 SavedAccount に通知設定を追加
|
// 2017/4/25 v10 1=>2 SavedAccount に通知設定を追加
|
||||||
// 2017/4/25 v10 1=>2 NotificationTracking テーブルを追加
|
// 2017/4/25 v10 1=>2 NotificationTracking テーブルを追加
|
||||||
// 2017/4/29 v20 2=>5 MediaShown,ContentWarningのインデクスが間違っていたので貼り直す
|
// 2017/4/29 v20 2=>5 MediaShown,ContentWarningのインデクスが間違っていたので貼り直す
|
||||||
|
@ -61,11 +61,11 @@ public class App1 extends Application {
|
||||||
// 2017/5/04 v33 9=>10 SavedAccountに項目追加
|
// 2017/5/04 v33 9=>10 SavedAccountに項目追加
|
||||||
// 2017/5/08 v41 10=>11 MutedWord テーブルの追加
|
// 2017/5/08 v41 10=>11 MutedWord テーブルの追加
|
||||||
// 2017/5/17 v59 11=>12 PostDraft テーブルの追加
|
// 2017/5/17 v59 11=>12 PostDraft テーブルの追加
|
||||||
|
// 2017/5/23 v68 12=>13 SavedAccountに項目追加
|
||||||
|
|
||||||
private static DBOpenHelper db_open_helper;
|
private static DBOpenHelper db_open_helper;
|
||||||
|
|
||||||
public static SQLiteDatabase getDB(){
|
public static SQLiteDatabase getDB(){
|
||||||
|
|
||||||
return db_open_helper.getWritableDatabase();
|
return db_open_helper.getWritableDatabase();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -314,6 +314,13 @@ public class AppDataExporter {
|
||||||
reader.skipValue();
|
reader.skipValue();
|
||||||
e.remove( k );
|
e.remove( k );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// just ignore
|
||||||
|
case Pref.KEY_DEVICE_TOKEN:
|
||||||
|
case Pref.KEY_INSTALL_ID:
|
||||||
|
reader.skipValue();
|
||||||
|
e.remove( k );
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
reader.endObject();
|
reader.endObject();
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
package jp.juggler.subwaytooter;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
|
|
||||||
|
import com.google.firebase.iid.FirebaseInstanceId;
|
||||||
|
import com.google.firebase.iid.FirebaseInstanceIdService;
|
||||||
|
|
||||||
|
import jp.juggler.subwaytooter.util.LogCategory;
|
||||||
|
|
||||||
|
public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService {
|
||||||
|
static final LogCategory log = new LogCategory("MyFirebaseInstanceIDService");
|
||||||
|
|
||||||
|
// Called when the system determines that the tokens need to be refreshed.
|
||||||
|
@Override public void onTokenRefresh(){
|
||||||
|
super.onTokenRefresh();
|
||||||
|
|
||||||
|
try{
|
||||||
|
String token = FirebaseInstanceId.getInstance().getToken();
|
||||||
|
log.d("onTokenRefresh: instance_token=%s",token);
|
||||||
|
|
||||||
|
Pref.pref(this).edit().putString(Pref.KEY_DEVICE_TOKEN,token).apply();
|
||||||
|
|
||||||
|
|
||||||
|
Intent intent = new Intent(this,AlarmService.class);
|
||||||
|
intent.setAction( AlarmService.ACTION_DEVICE_TOKEN );
|
||||||
|
startService( intent );
|
||||||
|
|
||||||
|
}catch(Throwable ex){
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package jp.juggler.subwaytooter;
|
||||||
|
|
||||||
|
import com.google.firebase.messaging.FirebaseMessagingService;
|
||||||
|
import com.google.firebase.messaging.RemoteMessage;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import jp.juggler.subwaytooter.util.LogCategory;
|
||||||
|
|
||||||
|
public class MyFirebaseMessagingService extends FirebaseMessagingService {
|
||||||
|
static final LogCategory log = new LogCategory("MyFirebaseMessagingService");
|
||||||
|
|
||||||
|
@Override public void onMessageReceived( RemoteMessage remoteMessage ){
|
||||||
|
super.onMessageReceived( remoteMessage );
|
||||||
|
|
||||||
|
Map< String, String > data = remoteMessage.getData();
|
||||||
|
if( data != null ){
|
||||||
|
for( Map.Entry< String, String > entry : data.entrySet() ){
|
||||||
|
log.d( "onMessageReceived: %s=%s", entry.getKey(), entry.getValue() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AlarmService.startCheck( getApplicationContext() ,true);
|
||||||
|
}
|
||||||
|
}
|
|
@ -47,6 +47,8 @@ public class Pref {
|
||||||
static final String KEY_MEDIA_THUMB_HEIGHT = "MediaThumbHeight";
|
static final String KEY_MEDIA_THUMB_HEIGHT = "MediaThumbHeight";
|
||||||
static final String KEY_TIMELINE_FONT = "timeline_font";
|
static final String KEY_TIMELINE_FONT = "timeline_font";
|
||||||
static final String KEY_DONT_CROP_MEDIA_THUMBNAIL = "DontCropMediaThumb";
|
static final String KEY_DONT_CROP_MEDIA_THUMBNAIL = "DontCropMediaThumb";
|
||||||
|
static final String KEY_DEVICE_TOKEN = "device_token";
|
||||||
|
static final String KEY_INSTALL_ID = "install_id";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@ public class NotificationTracking {
|
||||||
|
|
||||||
// 最後に表示した通知のID
|
// 最後に表示した通知のID
|
||||||
private static final String COL_POST_ID = "pi";
|
private static final String COL_POST_ID = "pi";
|
||||||
|
|
||||||
// 最後に表示した通知の作成時刻
|
// 最後に表示した通知の作成時刻
|
||||||
private static final String COL_POST_TIME = "pt";
|
private static final String COL_POST_TIME = "pt";
|
||||||
|
|
||||||
|
@ -187,7 +188,19 @@ public class NotificationTracking {
|
||||||
App1.getDB().update( table, cv,null,null);
|
App1.getDB().update( table, cv,null,null);
|
||||||
|
|
||||||
}catch( Throwable ex ){
|
}catch( Throwable ex ){
|
||||||
log.e( ex, "save failed." );
|
log.e( ex, "resetPostAll failed." );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void resetLastLoad(){
|
||||||
|
try{
|
||||||
|
ContentValues cv = new ContentValues();
|
||||||
|
cv.put( COL_LAST_LOAD, 0 );
|
||||||
|
App1.getDB().update( table, cv,null,null);
|
||||||
|
|
||||||
|
}catch( Throwable ex ){
|
||||||
|
log.e( ex, "resetLastLoad failed." );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ public class SavedAccount extends TootAccount implements LinkClickContext {
|
||||||
|
|
||||||
public static final String table = "access_info";
|
public static final String table = "access_info";
|
||||||
|
|
||||||
public static final String COL_ID = BaseColumns._ID;
|
private static final String COL_ID = BaseColumns._ID;
|
||||||
private static final String COL_HOST = "h";
|
private static final String COL_HOST = "h";
|
||||||
private static final String COL_USER = "u";
|
private static final String COL_USER = "u";
|
||||||
private static final String COL_ACCOUNT = "a";
|
private static final String COL_ACCOUNT = "a";
|
||||||
|
@ -45,6 +45,9 @@ public class SavedAccount extends TootAccount implements LinkClickContext {
|
||||||
private static final String COL_CONFIRM_UNFOLLOW = "confirm_unfollow";
|
private static final String COL_CONFIRM_UNFOLLOW = "confirm_unfollow";
|
||||||
private static final String COL_CONFIRM_POST = "confirm_post";
|
private static final String COL_CONFIRM_POST = "confirm_post";
|
||||||
|
|
||||||
|
// スキーマ13から
|
||||||
|
private static final String COL_NOTIFICATION_TAG = "notification_server";
|
||||||
|
|
||||||
public static final long INVALID_ID = - 1L;
|
public static final long INVALID_ID = - 1L;
|
||||||
|
|
||||||
// login information
|
// login information
|
||||||
|
@ -65,6 +68,8 @@ public class SavedAccount extends TootAccount implements LinkClickContext {
|
||||||
public boolean confirm_unfollow;
|
public boolean confirm_unfollow;
|
||||||
public boolean confirm_post;
|
public boolean confirm_post;
|
||||||
|
|
||||||
|
public String notification_tag;
|
||||||
|
|
||||||
// アプリデータのインポート時に呼ばれる
|
// アプリデータのインポート時に呼ばれる
|
||||||
public static void onDBDelete( SQLiteDatabase db ){
|
public static void onDBDelete( SQLiteDatabase db ){
|
||||||
try{
|
try{
|
||||||
|
@ -97,6 +102,11 @@ public class SavedAccount extends TootAccount implements LinkClickContext {
|
||||||
+ "," + COL_CONFIRM_FOLLOW_LOCKED + " integer default 1"
|
+ "," + COL_CONFIRM_FOLLOW_LOCKED + " integer default 1"
|
||||||
+ "," + COL_CONFIRM_UNFOLLOW + " integer default 1"
|
+ "," + COL_CONFIRM_UNFOLLOW + " integer default 1"
|
||||||
+ "," + COL_CONFIRM_POST + " integer default 1"
|
+ "," + COL_CONFIRM_POST + " integer default 1"
|
||||||
|
|
||||||
|
// 以下はDBスキーマ13で更新
|
||||||
|
+ "," + COL_NOTIFICATION_TAG + " text default ''"
|
||||||
|
|
||||||
|
|
||||||
+ ")"
|
+ ")"
|
||||||
);
|
);
|
||||||
db.execSQL( "create index if not exists " + table + "_user on " + table + "(u)" );
|
db.execSQL( "create index if not exists " + table + "_user on " + table + "(u)" );
|
||||||
|
@ -148,6 +158,13 @@ public class SavedAccount extends TootAccount implements LinkClickContext {
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if( oldVersion < 13 && newVersion >= 13 ){
|
||||||
|
try{
|
||||||
|
db.execSQL( "alter table " + table + " add column " + COL_NOTIFICATION_TAG + " text default ''" );
|
||||||
|
}catch( Throwable ex ){
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private SavedAccount(){
|
private SavedAccount(){
|
||||||
|
@ -178,6 +195,9 @@ public class SavedAccount extends TootAccount implements LinkClickContext {
|
||||||
dst.confirm_unfollow = ( 0 != cursor.getInt( cursor.getColumnIndex( COL_CONFIRM_UNFOLLOW ) ) );
|
dst.confirm_unfollow = ( 0 != cursor.getInt( cursor.getColumnIndex( COL_CONFIRM_UNFOLLOW ) ) );
|
||||||
dst.confirm_post = ( 0 != cursor.getInt( cursor.getColumnIndex( COL_CONFIRM_POST ) ) );
|
dst.confirm_post = ( 0 != cursor.getInt( cursor.getColumnIndex( COL_CONFIRM_POST ) ) );
|
||||||
|
|
||||||
|
int idx_notification_tag = cursor.getColumnIndex( COL_NOTIFICATION_TAG );
|
||||||
|
dst.notification_tag = cursor.isNull(idx_notification_tag) ? null : cursor.getString( idx_notification_tag );
|
||||||
|
|
||||||
dst.token_info = new JSONObject( cursor.getString( cursor.getColumnIndex( COL_TOKEN ) ) );
|
dst.token_info = new JSONObject( cursor.getString( cursor.getColumnIndex( COL_TOKEN ) ) );
|
||||||
}
|
}
|
||||||
return dst;
|
return dst;
|
||||||
|
@ -237,6 +257,18 @@ public class SavedAccount extends TootAccount implements LinkClickContext {
|
||||||
cv.put( COL_CONFIRM_UNFOLLOW, confirm_unfollow ? 1 : 0 );
|
cv.put( COL_CONFIRM_UNFOLLOW, confirm_unfollow ? 1 : 0 );
|
||||||
cv.put( COL_CONFIRM_POST, confirm_post ? 1 : 0 );
|
cv.put( COL_CONFIRM_POST, confirm_post ? 1 : 0 );
|
||||||
|
|
||||||
|
if( notification_tag != null ) cv.put( COL_NOTIFICATION_TAG, notification_tag );
|
||||||
|
|
||||||
|
App1.getDB().update( table, cv, COL_ID + "=?", new String[]{ Long.toString( db_id ) } );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void saveNotificationTag(){
|
||||||
|
if( db_id == INVALID_ID )
|
||||||
|
throw new RuntimeException( "SavedAccount.saveSetting missing db_id" );
|
||||||
|
|
||||||
|
ContentValues cv = new ContentValues();
|
||||||
|
cv.put( COL_NOTIFICATION_TAG, notification_tag );
|
||||||
|
|
||||||
App1.getDB().update( table, cv, COL_ID + "=?", new String[]{ Long.toString( db_id ) } );
|
App1.getDB().update( table, cv, COL_ID + "=?", new String[]{ Long.toString( db_id ) } );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,6 +286,7 @@ public class SavedAccount extends TootAccount implements LinkClickContext {
|
||||||
this.notification_boost = b.notification_boost;
|
this.notification_boost = b.notification_boost;
|
||||||
this.notification_favourite = b.notification_favourite;
|
this.notification_favourite = b.notification_favourite;
|
||||||
this.notification_follow = b.notification_follow;
|
this.notification_follow = b.notification_follow;
|
||||||
|
this.notification_tag = b.notification_tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static @Nullable SavedAccount loadAccount( @NonNull LogCategory log, long db_id ){
|
public static @Nullable SavedAccount loadAccount( @NonNull LogCategory log, long db_id ){
|
||||||
|
@ -370,4 +403,5 @@ public class SavedAccount extends TootAccount implements LinkClickContext {
|
||||||
return 0L;
|
return 0L;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,8 @@ buildscript {
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:2.3.2'
|
classpath 'com.android.tools.build:gradle:2.3.2'
|
||||||
|
|
||||||
|
classpath 'com.google.gms:google-services:3.0.0'
|
||||||
|
|
||||||
// NOTE: Do not place your application dependencies here; they belong
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
// in the individual module build.gradle files
|
// in the individual module build.gradle files
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue