アプリを終了して履歴から開きなおした際に前回の通知タップの影響を受けないようにする https://gist.github.com/tateisu/fa382f751080fa1c7b94a3d34a48f59d

This commit is contained in:
tateisu 2018-11-02 09:09:31 +09:00
parent 3053b287b0
commit de57629ec3
7 changed files with 87 additions and 66 deletions

View File

@ -26,35 +26,50 @@ class ActCallback : AppCompatActivity() {
internal val last_uri = AtomicReference<Uri>(null)
internal val sent_intent = AtomicReference<Intent>(null)
}
override fun onCreate(savedInstanceState : Bundle?) {
log.d("onCreate flags=%x", intent.flags)
super.onCreate(savedInstanceState)
var intent : Intent? = intent
if(intent != null) {
val action = intent.action
val type = intent.type
if(
// ACTION_SEND か ACTION_SEND_MULTIPLE
Intent.ACTION_SEND == action
|| Intent.ACTION_SEND_MULTIPLE == action
// ACTION_VIEW かつ type が 画像かビデオ
|| Intent.ACTION_VIEW == action && type != null && (type.startsWith("image/") || type.startsWith("video/"))) {
// Google Photo などから送られるIntentに含まれるuriの有効期間はActivityが閉じられるまで
// http://qiita.com/pside/items/a821e2fe9ae6b7c1a98c
// 有効期間を延長する
intent = remake(intent)
if(intent != null) {
sent_intent.set(intent)
}
} else {
val uri = intent.data
if(uri != null) {
last_uri.set(uri)
when {
intent == null -> {
// 多分起きないと思う
}
(intent.flags and Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0 -> {
// 履歴から開いた場合はIntentの中味を読まない
}
else -> {
val action = intent.action
val type = intent.type
if(
// ACTION_SEND か ACTION_SEND_MULTIPLE
Intent.ACTION_SEND == action
|| Intent.ACTION_SEND_MULTIPLE == action
// ACTION_VIEW かつ type が 画像かビデオ
|| Intent.ACTION_VIEW == action && type != null && (type.startsWith("image/") || type.startsWith(
"video/"
))) {
// Google Photo などから送られるIntentに含まれるuriの有効期間はActivityが閉じられるまで
// http://qiita.com/pside/items/a821e2fe9ae6b7c1a98c
// 有効期間を延長する
intent = remake(intent)
if(intent != null) {
sent_intent.set(intent)
}
} else {
val uri = intent.data
if(uri != null) {
last_uri.set(uri)
}
}
}
}
// どうであれメイン画面に戻る
intent = Intent(this, ActMain::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY or Intent.FLAG_ACTIVITY_NEW_TASK)
@ -62,14 +77,14 @@ class ActCallback : AppCompatActivity() {
finish()
}
private fun copyExtraTexts(dst:Intent,src:Intent){
var sv:String?
private fun copyExtraTexts(dst : Intent, src : Intent) {
var sv : String?
//
sv = src.getStringExtra(Intent.EXTRA_TEXT)
if(sv!=null) dst.putExtra(Intent.EXTRA_TEXT,sv)
if(sv != null) dst.putExtra(Intent.EXTRA_TEXT, sv)
//
sv = src.getStringExtra(Intent.EXTRA_SUBJECT)
if(sv!=null) dst.putExtra(Intent.EXTRA_SUBJECT,sv)
if(sv != null) dst.putExtra(Intent.EXTRA_SUBJECT, sv)
}
private fun remake(src : Intent) : Intent? {
@ -87,7 +102,7 @@ class ActCallback : AppCompatActivity() {
val uri = saveToCache(uriOriginal)
val dst = Intent(action)
dst.setDataAndType(uri, type)
copyExtraTexts(dst,src)
copyExtraTexts(dst, src)
return dst
} catch(ex : Throwable) {
log.trace(ex)
@ -107,7 +122,7 @@ class ActCallback : AppCompatActivity() {
val dst = Intent(action)
dst.type = type
dst.putExtra(Intent.EXTRA_STREAM, uri)
copyExtraTexts(dst,src)
copyExtraTexts(dst, src)
return dst
} catch(ex : Throwable) {
log.trace(ex)
@ -115,7 +130,8 @@ class ActCallback : AppCompatActivity() {
}
} else if(Intent.ACTION_SEND_MULTIPLE == action) {
val list_uri = src.getParcelableArrayListExtra<Uri>(Intent.EXTRA_STREAM) ?: return null
val list_uri =
src.getParcelableArrayListExtra<Uri>(Intent.EXTRA_STREAM) ?: return null
val list_dst = ArrayList<Uri>()
for(uriOriginal in list_uri) {
if(uriOriginal != null) {
@ -132,7 +148,7 @@ class ActCallback : AppCompatActivity() {
val dst = Intent(action)
dst.type = type
dst.putParcelableArrayListExtra(Intent.EXTRA_STREAM, list_dst)
copyExtraTexts(dst,src)
copyExtraTexts(dst, src)
return dst
}
} else if(Intent.ACTION_SEND == action) {
@ -141,10 +157,10 @@ class ActCallback : AppCompatActivity() {
// EXTRA_TEXT の存在を確認してからtypeがnullもしくは text/plain なら受け取る
val sv = src.getStringExtra(Intent.EXTRA_TEXT)
if( sv?.isNotEmpty() == true && (type == null || type.startsWith("text/"))) {
if(sv?.isNotEmpty() == true && (type == null || type.startsWith("text/"))) {
val dst = Intent(action)
dst.type = "text/plain"
copyExtraTexts(dst,src)
copyExtraTexts(dst, src)
return dst
}
@ -164,13 +180,14 @@ class ActCallback : AppCompatActivity() {
cache_dir.mkdirs()
val name = "img." + System.currentTimeMillis().toString() + "." + uri.toString().digestSHA256Hex()
val name =
"img." + System.currentTimeMillis().toString() + "." + uri.toString().digestSHA256Hex()
val dst = File(cache_dir, name)
FileOutputStream(dst).use { outStream ->
val source = contentResolver.openInputStream(uri)
?:throw RuntimeException("getContentResolver.openInputStream returns null.")
?: throw RuntimeException("getContentResolver.openInputStream returns null.")
source.use { inStream ->
IOUtils.copy(inStream, outStream)
}

View File

@ -83,6 +83,7 @@ class ActMain : AppCompatActivity()
const val STATE_CURRENT_PAGE = "current_page"
// 外部からインテントを受信した後、アカウント選択中に画面回転したらアカウント選択からやり直す
internal var sent_intent2 : Intent? = null
internal val reUrlHashTag =
@ -1507,7 +1508,9 @@ class ActMain : AppCompatActivity()
// ActOAuthCallbackで受け取ったUriを処理する
private fun handleIntentUri(uri : Uri) {
log.d("handleIntentUri ${uri}")
when(uri.scheme) {
"subwaytooter", "misskeyclientproto" -> return try {
handleOAuth2CallbackUri(uri)

View File

@ -1674,7 +1674,7 @@ class Column(
add(n.accountRef)
add(n.status)
}
internal fun update(client : TootApiClient, parser : TootParser) {
var n : Int

View File

@ -996,6 +996,7 @@ class PollingWorker private constructor(contextArg : Context) {
// 通知タップ時のPendingIntent
val intent_click = Intent(context, ActCallback::class.java)
// FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY を付与してはいけない
intent_click.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
val pi_click = PendingIntent.getActivity(
context,
@ -1546,6 +1547,7 @@ class PollingWorker private constructor(contextArg : Context) {
intent_click.action = ActCallback.ACTION_NOTIFICATION_CLICK
intent_click.data =
Uri.parse("subwaytooter://notification_click/?db_id=" + account.db_id)
// FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY を付与してはいけない
intent_click.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
val pi_click = PendingIntent.getActivity(
context,

View File

@ -5,6 +5,7 @@ import android.net.Uri
import android.text.Spannable
import jp.juggler.subwaytooter.api.TootParser
import jp.juggler.subwaytooter.table.UserRelation
import jp.juggler.subwaytooter.table.UserRelationMisskey
import jp.juggler.subwaytooter.util.*
import org.json.JSONArray
@ -249,16 +250,8 @@ open class TootAccount(parser : TootParser, src : JSONObject) {
}
// プロフカラムで ユーザのプロフ(A)とアカウントTL(B)を順に取得すると
// (A)ではisBlockingに情報が入っているが、(B)では情報が入っていない
// 対策として(A)でリレーションを取得済みのユーザは(B)のタイミングではリレーションを読み捨てる
val map = parser.misskeyUserRelationMap
if(map[id] == null) {
val relation = UserRelation.parseMisskeyUser(src)
if( relation != null) {
map[id] = relation
}
}
UserRelationMisskey.fromAccount(parser,src,id)
} else {

View File

@ -239,24 +239,5 @@ class UserRelation {
}
return null
}
// Misskey用
fun parseMisskeyUser(src : JSONObject) :UserRelation? {
// リレーションを返さない場合がある
src.opt("isFollowing") ?: return null
return UserRelation().apply {
following = src.optBoolean("isFollowing")
followed_by = src.optBoolean("isFollowed")
muting = src.optBoolean("isMuted")
blocking = src.optBoolean("isBlocking")
blocked_by = src.optBoolean("isBlocked")
endorsed = false
requested = src.optBoolean("hasPendingFollowRequestFromYou")
requested_by = src.optBoolean("hasPendingFollowRequestToYou")
}
}
}
}

View File

@ -3,10 +3,12 @@ package jp.juggler.subwaytooter.table
import android.content.ContentValues
import android.database.sqlite.SQLiteDatabase
import jp.juggler.subwaytooter.App1
import jp.juggler.subwaytooter.api.TootParser
import jp.juggler.subwaytooter.api.entity.EntityId
import jp.juggler.subwaytooter.api.entity.TootRelationShip
import jp.juggler.subwaytooter.util.LogCategory
import jp.juggler.subwaytooter.util.getInt
import org.json.JSONObject
object UserRelationMisskey : TableCompanion {
@ -244,5 +246,28 @@ object UserRelationMisskey : TableCompanion {
}
}
// MisskeyはUserエンティティにユーザリレーションが含まれたり含まれなかったりする
fun fromAccount(parser: TootParser, src : JSONObject,id:EntityId) {
// アカウントのjsonがユーザリレーションを含まないなら何もしない
src.opt("isFollowing") ?:return
// プロフカラムで ユーザのプロフ(A)とアカウントTL(B)を順に取得すると
// (A)ではisBlockingに情報が入っているが、(B)では情報が入っていない
// 対策として(A)でリレーションを取得済みのユーザは(B)のタイミングではリレーションを読み捨てる
val map = parser.misskeyUserRelationMap
if( map.containsKey(id) ) return
map[id] = UserRelation().apply {
following = src.optBoolean("isFollowing")
followed_by = src.optBoolean("isFollowed")
muting = src.optBoolean("isMuted")
blocking = src.optBoolean("isBlocking")
blocked_by = src.optBoolean("isBlocked")
endorsed = false
requested = src.optBoolean("hasPendingFollowRequestFromYou")
requested_by = src.optBoolean("hasPendingFollowRequestToYou")
}
}
}