aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKazuki Yamaguchi <k@rhe.jp>2017-10-08 20:54:49 +0900
committerKazuki Yamaguchi <k@rhe.jp>2017-10-08 20:54:49 +0900
commitafb8ce292daabe75c11c094c1cd4d9a7a9a89c20 (patch)
treee1b893d1016be368d12faccb4676568348f1b2de
parent16fbf18a9273a1acea81a0200d6988b04b253303 (diff)
downloadSmileEssence-afb8ce292daabe75c11c094c1cd4d9a7a9a89c20.tar.gz
get intents back2017-10-08
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/IntentRouter.kt138
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/World.kt4
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/activity/MainActivity.kt87
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/activity/ManageAccountsActivity.kt91
4 files changed, 130 insertions, 190 deletions
diff --git a/app/src/main/java/net/lacolaco/smileessence/IntentRouter.kt b/app/src/main/java/net/lacolaco/smileessence/IntentRouter.kt
deleted file mode 100644
index 2c202f37..00000000
--- a/app/src/main/java/net/lacolaco/smileessence/IntentRouter.kt
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2012-2014 lacolaco.net
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package net.lacolaco.smileessence
-
-import android.app.Activity
-import android.content.Intent
-import android.net.Uri
-import android.os.Bundle
-import android.text.TextUtils
-import android.widget.Toast
-import net.lacolaco.smileessence.activity.MainActivity
-import net.lacolaco.smileessence.command.CommandOpenUserDetail
-import net.lacolaco.smileessence.entity.Tweet
-import net.lacolaco.smileessence.logging.Logger
-import net.lacolaco.smileessence.util.UIHandler
-import net.lacolaco.smileessence.view.DialogHelper
-import net.lacolaco.smileessence.view.dialog.StatusDetailDialogFragment
-
-import java.util.regex.Matcher
-import java.util.regex.Pattern
-
-object IntentRouter {
-
- // ------------------------------ FIELDS ------------------------------
-
- private val TWITTER_HOST = "twitter.com"
- private val TWITTER_STATUS_PATTERN = Pattern.compile("\\A(?:/#!)?/(?:\\w{1,15})/status(?:es)?/(\\d+)\\z", Pattern.CASE_INSENSITIVE)
- private val TWITTER_USER_PATTERN = Pattern.compile("\\A(?:/#!)?/(\\w{1,15})/?\\z", Pattern.CASE_INSENSITIVE)
- private val TWITTER_POST_PATTERN = Pattern.compile("\\A/(intent/tweet|share)\\z", Pattern.CASE_INSENSITIVE)
-
- // -------------------------- STATIC METHODS --------------------------
-
- fun onNewIntent(activity: MainActivity, intent: Intent) {
- Logger.debug("onNewIntent")
- val uri = intent.data
- if (uri != null) {
- onUriIntent(activity, uri)
- } else if (intent.action != null) {
- when (intent.action) {
- Intent.ACTION_SEND -> {
- if ("text/plain" == intent.type) {
- val extra = intent.extras
- if (extra != null) {
- val text = getText(extra)
- openPostPage(activity, text)
- }
- } else if (intent.type.startsWith("image/")) {
- val imageUri = intent.getParcelableExtra<Uri>(Intent.EXTRA_STREAM)
- openPostPageWithImage(activity, imageUri)
- }
- }
- }
- }
- }
-
- private fun onUriIntent(activity: MainActivity, uri: Uri) {
- Logger.debug(uri.toString())
-
- if (uri.host == TWITTER_HOST) {
- val postMatcher = TWITTER_POST_PATTERN.matcher(uri.path) // /share and /intent/tweet: don't accept status parameter
- if (postMatcher.find()) {
- openPostPage(activity, extractText(uri))
- return
- }
- val statusMatcher = TWITTER_STATUS_PATTERN.matcher(uri.path)
- if (statusMatcher.find()) {
- Tweet.fetchTask(java.lang.Long.parseLong(statusMatcher.group(1)), activity.world.account)
- .onDoneUI { tweet -> DialogHelper.showDialog(activity, StatusDetailDialogFragment.newInstance(tweet)) }
- .onFail { x -> Application.toast(R.string.error_intent_status_cannot_load) }
- .execute()
- return
- }
- val userMatcher = TWITTER_USER_PATTERN.matcher(uri.path)
- if (userMatcher.find()) {
- showUserDialog(activity, userMatcher.group(1))
- }
- }
- }
-
- private fun getText(extra: Bundle): String {
- val builder = StringBuilder()
- if (!TextUtils.isEmpty(extra.getCharSequence(Intent.EXTRA_SUBJECT))) {
- builder.append(extra.getCharSequence(Intent.EXTRA_SUBJECT)).append(" ")
- }
- builder.append(extra.getCharSequence(Intent.EXTRA_TEXT))
- return builder.toString()
- }
-
- private fun extractText(uri: Uri): String {
- var result = ""
- val text = uri.getQueryParameter("text")
- val url = uri.getQueryParameter("url")
- val via = uri.getQueryParameter("via")
- val hashtags = uri.getQueryParameter("hashtags")
-
- if (!TextUtils.isEmpty(text)) result += text
- if (!TextUtils.isEmpty(url)) result += " " + url
- if (!TextUtils.isEmpty(hashtags)) result += " " + hashtags.trim { it <= ' ' }.replace(",".toRegex(), " #")
- if (!TextUtils.isEmpty(via)) result += " via @" + via
-
- return result
- }
-
- private fun showUserDialog(activity: MainActivity, screenName: String) {
- val openUserDetail = CommandOpenUserDetail(activity, screenName)
- openUserDetail.execute()
- }
-
- private fun openPostPage(activity: MainActivity, str: String) {
- UIHandler().post { activity.world.postState.beginTransaction().setText(str).commitWithOpen(activity) }
- }
-
- private fun openPostPageWithImage(activity: MainActivity, imageUri: Uri) {
- UIHandler().post { activity.openPostPageWithImage(imageUri) }
- }
-}
diff --git a/app/src/main/java/net/lacolaco/smileessence/World.kt b/app/src/main/java/net/lacolaco/smileessence/World.kt
index 1522b465..638607d1 100644
--- a/app/src/main/java/net/lacolaco/smileessence/World.kt
+++ b/app/src/main/java/net/lacolaco/smileessence/World.kt
@@ -1,5 +1,6 @@
package net.lacolaco.smileessence
+import android.content.Intent
import android.support.annotation.StringRes
import de.keyboardsurfer.android.widget.crouton.Configuration
import de.keyboardsurfer.android.widget.crouton.Crouton
@@ -31,6 +32,9 @@ class World(val account: Account) {
private val resId: Int = 0 // XXX: Fetch from Account
// XXX: Move to MainActivity
val postState = PostState()
+ // XXX: Workaround for a bug in Android
+ @Deprecated("A temporary workaround")
+ var mainActivityIntent: Intent? = null
// Timelines
private val tweets = ArrayList<Tweet>()
private val tweetNotifiers = WeakHashMap<Any, (Tweet) -> Unit>()
diff --git a/app/src/main/java/net/lacolaco/smileessence/activity/MainActivity.kt b/app/src/main/java/net/lacolaco/smileessence/activity/MainActivity.kt
index 28a95a27..cdbc94d4 100644
--- a/app/src/main/java/net/lacolaco/smileessence/activity/MainActivity.kt
+++ b/app/src/main/java/net/lacolaco/smileessence/activity/MainActivity.kt
@@ -31,6 +31,7 @@ import android.net.Uri
import android.os.Bundle
import android.provider.MediaStore
import android.support.v4.view.ViewPager
+import android.text.TextUtils
import android.view.Menu
import android.view.MenuItem
import android.view.WindowManager
@@ -38,15 +39,21 @@ import android.widget.ImageView
import de.keyboardsurfer.android.widget.crouton.Crouton
import kotlinx.android.synthetic.main.layout_main.*
import net.lacolaco.smileessence.*
+import net.lacolaco.smileessence.command.CommandOpenUserDetail
import net.lacolaco.smileessence.data.ExtractionWord
+import net.lacolaco.smileessence.entity.Tweet
import net.lacolaco.smileessence.logging.Logger
import net.lacolaco.smileessence.twitter.task.Users
import net.lacolaco.smileessence.util.BitmapURLTask
+import net.lacolaco.smileessence.view.DialogHelper
import net.lacolaco.smileessence.view.adapter.PageListAdapter
import net.lacolaco.smileessence.view.dialog.ConfirmDialogFragment
+import net.lacolaco.smileessence.view.dialog.StatusDetailDialogFragment
+import net.lacolaco.smileessence.view.dialog.UserDetailDialogFragment
import net.lacolaco.smileessence.view.page.*
import org.jetbrains.anko.browse
import org.jetbrains.anko.startActivity;
+import java.util.regex.Pattern
class MainActivity : Activity(), ViewPager.OnPageChangeListener {
val world: World by lazy {
@@ -111,6 +118,65 @@ class MainActivity : Activity(), ViewPager.OnPageChangeListener {
BitmapURLTask(world.account.user.profileImageUrl, currentAccountIconImageView).execute()
}
+ private fun processIntent(intent: Intent) {
+ val uri = intent.getParcelableExtra<Uri>(KEY_ORIGINAL_DATA)
+ if (uri != null){
+ if (uri.host == "twitter.com") {
+ // /share and /intent/tweet: don't accept status parameter
+ val postMatcher = TWITTER_POST_PATTERN.matcher(uri.path)
+ if (postMatcher.find()) {
+ var text = uri.getQueryParameter("text") ?: ""
+ val url = uri.getQueryParameter("url")
+ if (!TextUtils.isEmpty(url))
+ text += " " + url
+ val hashtags = uri.getQueryParameter("hashtags")
+ if (!TextUtils.isEmpty(hashtags))
+ text += " " + hashtags.trim { it <= ' ' }.replace(",".toRegex(), " #")
+ val via = uri.getQueryParameter("via")
+ if (!TextUtils.isEmpty(via))
+ text += " via @" + via
+ world.postState.beginTransaction().setText(text).commitWithOpen(this)
+ return
+ }
+ val statusMatcher = TWITTER_STATUS_PATTERN.matcher(uri.path)
+ if (statusMatcher.find()) {
+ Tweet.fetchTask(java.lang.Long.parseLong(statusMatcher.group(1)), world.account)
+ .onDoneUI { tweet -> DialogHelper.showDialog(this, StatusDetailDialogFragment.newInstance(tweet)) }
+ .onFail { _ -> world.notifyError(R.string.error_intent_status_cannot_load) }
+ .execute()
+ return
+ }
+ val userMatcher = TWITTER_USER_PATTERN.matcher(uri.path)
+ if (userMatcher.find()) {
+ Users.GetTask(world.account, userMatcher.group(1))
+ .onDoneUI { user ->
+ DialogHelper.showDialog(this, UserDetailDialogFragment.newInstance(user))
+ }
+ .onFail { _ -> world.notifyError(R.string.notice_error_show_user) }
+ .execute()
+ return
+ }
+ }
+ } else when (intent.action) {
+ Intent.ACTION_SEND -> {
+ val type = intent.getStringExtra(KEY_ORIGINAL_TYPE)
+ if (type == "text/plain") {
+ val extra = intent.extras
+ if (extra != null) {
+ var text = extra.getCharSequence(Intent.EXTRA_TEXT).toString()
+ if (!TextUtils.isEmpty(extra.getCharSequence(Intent.EXTRA_SUBJECT))) {
+ text = extra.getCharSequence(Intent.EXTRA_SUBJECT).toString() + " " + text
+ }
+ world.postState.beginTransaction().setText(text).commitWithOpen(this)
+ return
+ }
+ } else if (type != null && type.startsWith("image/")) {
+ openPostPageWithImage(intent.getParcelableExtra(Intent.EXTRA_STREAM))
+ }
+ }
+ }
+ }
+
// ------------------------ OVERRIDE METHODS ------------------------
override fun onBackPressed() {
@@ -183,7 +249,7 @@ class MainActivity : Activity(), ViewPager.OnPageChangeListener {
setTitle()
// refresh all pages
- for (i in 0..pagerAdapter.count - 1) {
+ for (i in 0 until pagerAdapter.count) {
val pf = pagerAdapter.getCachedFragment(i)
if (pf != null && pf.isAdded) {
Logger.debug(String.format("PageFragment %s is already attached; refreshing", pf.javaClass.name))
@@ -194,7 +260,7 @@ class MainActivity : Activity(), ViewPager.OnPageChangeListener {
// start user stream
world.setupStreaming()
- window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+ window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
}
override fun onDestroy() {
@@ -248,6 +314,17 @@ class MainActivity : Activity(), ViewPager.OnPageChangeListener {
super.onResume()
Application.currentWorld = world
world.setMainActivityActive(true)
+ val intent = world.mainActivityIntent
+ if (intent != null) {
+ world.mainActivityIntent = null
+ processIntent(intent)
+ }
+ }
+
+ override fun onNewIntent(intent: Intent) {
+ super.onNewIntent(intent)
+ // With the current releases (~ 7) of Android, onNewIntent() doesn't seem to be called properly
+ if (false) processIntent(intent)
}
// --------------------- Interface OnPageChangeListener ---------------------
@@ -263,5 +340,11 @@ class MainActivity : Activity(), ViewPager.OnPageChangeListener {
companion object {
val REQUEST_GET_PICTURE_FROM_GALLERY = 11
+ val KEY_ORIGINAL_DATA = "originalData"
+ val KEY_ORIGINAL_TYPE = "originalType"
+ private val TWITTER_POST_PATTERN = Pattern.compile("\\A/(intent/tweet|share)\\z", Pattern.CASE_INSENSITIVE)
+ private val TWITTER_STATUS_PATTERN = Pattern.compile("\\A(?:/#!)?/(?:\\w{1,15})/status(?:es)?/(\\d+)\\z", Pattern.CASE_INSENSITIVE)
+ private val TWITTER_USER_PATTERN = Pattern.compile("\\A(?:/#!)?/(\\w{1,15})/?\\z", Pattern.CASE_INSENSITIVE)
+
}
}
diff --git a/app/src/main/java/net/lacolaco/smileessence/activity/ManageAccountsActivity.kt b/app/src/main/java/net/lacolaco/smileessence/activity/ManageAccountsActivity.kt
index 50cbe0aa..a279afed 100644
--- a/app/src/main/java/net/lacolaco/smileessence/activity/ManageAccountsActivity.kt
+++ b/app/src/main/java/net/lacolaco/smileessence/activity/ManageAccountsActivity.kt
@@ -25,12 +25,12 @@
package net.lacolaco.smileessence.activity
import android.app.Activity
+import android.content.ComponentName
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Bundle
-import android.support.v4.app.ActivityCompat
-import android.support.v4.content.ContextCompat
+import android.os.Process
import android.view.Menu
import android.view.MenuItem
import android.view.View
@@ -48,30 +48,30 @@ import kotlinx.android.synthetic.main.list_item_account.view.*
import kotlinx.coroutines.experimental.android.UI
import kotlinx.coroutines.experimental.async
import org.jetbrains.anko.coroutines.experimental.bg
-import org.jetbrains.anko.intentFor
import org.jetbrains.anko.startActivityForResult
import java.util.ArrayList
class ManageAccountsActivity : Activity() {
private val adapter by lazy { EditAccountsAdapter() }
+ private lateinit var receivedIntent: Intent
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- // Check if it is initiated from launcher
- if (!intent.getBooleanExtra(INTENT_KEY_NOINIT, false)) {
- val wextPermission = ContextCompat.checkSelfPermission(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
- if (wextPermission != PackageManager.PERMISSION_GRANTED) {
- ActivityCompat.requestPermissions(this, arrayOf(android.Manifest.permission.WRITE_EXTERNAL_STORAGE), REQUEST_WRITE_EXTERNAL_STORAGE_PERMISSION)
- }
+ // Save the received intent
+ receivedIntent = Intent(intent)
- // Skip this activity if app is already started
- val currentWorld = Application.currentWorld
- if (currentWorld != null) {
- goToWorld(currentWorld)
- return
- }
+ // Check if it is initiated from launcher
+ if (android.os.Build.VERSION.SDK_INT >= 23 &&
+ checkPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE, Process.myPid(),
+ Process.myUid()) != PackageManager.PERMISSION_GRANTED)
+ requestPermissions(arrayOf(android.Manifest.permission.WRITE_EXTERNAL_STORAGE), REQUEST_WRITE_EXTERNAL_STORAGE_PERMISSION)
+
+ // Skip this activity if app is already started
+ if (Application.currentWorld != null && !intent.getBooleanExtra(INTENT_KEY_NOINIT, false)) {
+ goToWorld(Application.currentWorld!!)
+ return
}
setContentView(R.layout.layout_edit_list)
@@ -97,10 +97,15 @@ class ManageAccountsActivity : Activity() {
}
}
+ override fun onNewIntent(intent: Intent) {
+ super.onNewIntent(intent)
+ receivedIntent = Intent(intent)
+ }
+
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
when (requestCode) {
REQUEST_WRITE_EXTERNAL_STORAGE_PERMISSION -> {
- if (grantResults.size > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+ if (grantResults.size == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// OK
val currentWorld = Application.currentWorld
if (currentWorld != null) {
@@ -117,10 +122,13 @@ class ManageAccountsActivity : Activity() {
private fun goToWorld(world: World) {
// Continue the existing MainActivity
- val intent = intentFor<MainActivity>()
- intent.data = Uri.parse("smileessence://mainactivity/?user_id=" + world.account.userId)
+ receivedIntent.component = ComponentName(this, MainActivity::class.java)
+ receivedIntent.putExtra(MainActivity.KEY_ORIGINAL_DATA, receivedIntent.data)
+ receivedIntent.putExtra(MainActivity.KEY_ORIGINAL_TYPE, receivedIntent.type)
+ receivedIntent.data = Uri.parse("smileessence://mainactivity/?user_id=" + world.account.userId)
finish()
- startActivity(intent)
+ world.mainActivityIntent = receivedIntent
+ startActivity(receivedIntent)
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
@@ -153,15 +161,9 @@ class ManageAccountsActivity : Activity() {
}
}
- override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
- when (requestCode) {
- REQUEST_OAUTH -> {
- receiveOAuth(requestCode, resultCode, data)
- }
- else -> {
- Logger.error("[BUG] unexpected activity result: reqCode=$requestCode, resCode=$resultCode")
- }
- }
+ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) = when (requestCode) {
+ REQUEST_OAUTH -> receiveOAuth(requestCode, resultCode, data)
+ else -> Logger.error("[BUG] unexpected activity result: reqCode=$requestCode, resCode=$resultCode")
}
private fun receiveOAuth(requestCode: Int, resultCode: Int, data: Intent?) {
@@ -183,23 +185,13 @@ class ManageAccountsActivity : Activity() {
}
private inner class EditAccountsAdapter : BaseAdapter() {
- private val accounts: MutableList<Account>
+ private val accounts: MutableList<Account> = ArrayList(Account.all())
- init {
- accounts = ArrayList(Account.all())
- }
+ override fun getCount(): Int = accounts.size
- override fun getCount(): Int {
- return accounts.size
- }
+ override fun getItem(position: Int): Account = accounts[position]
- override fun getItem(position: Int): Account {
- return accounts[position]
- }
-
- override fun getItemId(position: Int): Long {
- return accounts[position].userId
- }
+ override fun getItemId(position: Int): Long = accounts[position].userId
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
val view = convertView ?: layoutInflater.inflate(R.layout.list_item_account, parent, false)
@@ -209,14 +201,12 @@ class ManageAccountsActivity : Activity() {
return view
}
- fun add(account: Account): Int {
- if (!accounts.contains(account)) {
- accounts.add(account)
- notifyDataSetChanged()
- return accounts.size - 1
- } else {
- return accounts.indexOf(account)
- }
+ fun add(account: Account): Int = if (!accounts.contains(account)) {
+ accounts.add(account)
+ notifyDataSetChanged()
+ accounts.size - 1
+ } else {
+ accounts.indexOf(account)
}
fun removeAt(position: Int): Account? {
@@ -230,5 +220,6 @@ class ManageAccountsActivity : Activity() {
val INTENT_KEY_NOINIT = "noInit"
private val REQUEST_OAUTH = 10
private val REQUEST_WRITE_EXTERNAL_STORAGE_PERMISSION = 11
+
}
}