improved draft deletion
This commit is contained in:
parent
4e47cbb387
commit
ce4d921d7a
|
@ -34,8 +34,8 @@ android {
|
|||
applicationId "org.mariotaku.twidere"
|
||||
minSdkVersion 14
|
||||
targetSdkVersion 25
|
||||
versionCode 256
|
||||
versionName '3.3.38'
|
||||
versionCode 257
|
||||
versionName '3.3.39'
|
||||
multiDexEnabled true
|
||||
|
||||
buildConfigField 'boolean', 'LEAK_CANARY_ENABLED', 'Boolean.parseBoolean("true")'
|
||||
|
|
|
@ -36,7 +36,6 @@ import android.support.v4.app.LoaderManager.LoaderCallbacks
|
|||
import android.support.v4.content.CursorLoader
|
||||
import android.support.v4.content.Loader
|
||||
import android.text.TextUtils
|
||||
import android.util.Log
|
||||
import android.view.*
|
||||
import android.widget.AbsListView.MultiChoiceModeListener
|
||||
import android.widget.AdapterView
|
||||
|
@ -44,7 +43,6 @@ import android.widget.AdapterView.OnItemClickListener
|
|||
import android.widget.ListView
|
||||
import kotlinx.android.synthetic.main.fragment_drafts.*
|
||||
import org.mariotaku.kpreferences.get
|
||||
import org.mariotaku.ktextension.toStringArray
|
||||
import org.mariotaku.sqliteqb.library.Columns.Column
|
||||
import org.mariotaku.sqliteqb.library.Expression
|
||||
import org.mariotaku.sqliteqb.library.RawItemArray
|
||||
|
@ -59,14 +57,13 @@ import org.mariotaku.twidere.extension.selectAll
|
|||
import org.mariotaku.twidere.extension.selectNone
|
||||
import org.mariotaku.twidere.extension.updateSelectionItems
|
||||
import org.mariotaku.twidere.model.Draft
|
||||
import org.mariotaku.twidere.model.ParcelableMediaUpdate
|
||||
import org.mariotaku.twidere.model.draft.SendDirectMessageActionExtras
|
||||
import org.mariotaku.twidere.model.util.ParcelableStatusUpdateUtils
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.Drafts
|
||||
import org.mariotaku.twidere.service.LengthyOperationsService
|
||||
import org.mariotaku.twidere.util.AsyncTaskUtils
|
||||
import org.mariotaku.twidere.util.JsonSerializer
|
||||
import java.io.File
|
||||
import org.mariotaku.twidere.util.deleteDrafts
|
||||
import java.lang.ref.WeakReference
|
||||
import java.util.*
|
||||
|
||||
class DraftsFragment : BaseFragment(), LoaderCallbacks<Cursor?>, OnItemClickListener, MultiChoiceModeListener {
|
||||
|
@ -264,43 +261,19 @@ class DraftsFragment : BaseFragment(), LoaderCallbacks<Cursor?>, OnItemClickList
|
|||
}
|
||||
|
||||
private class DeleteDraftsTask(
|
||||
private val activity: FragmentActivity,
|
||||
activity: FragmentActivity,
|
||||
private val ids: LongArray
|
||||
) : AsyncTask<Any, Any, Unit>() {
|
||||
private val notificationManager = activity.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
|
||||
private val activityRef = WeakReference(activity)
|
||||
|
||||
override fun doInBackground(vararg params: Any) {
|
||||
val resolver = activity.contentResolver
|
||||
val where = Expression.inArgs(Column(Drafts._ID), ids.size)
|
||||
val projection = arrayOf(Drafts.MEDIA)
|
||||
val selection = where.sql
|
||||
val selectionArgs = ids.toStringArray()
|
||||
val c = resolver.query(Drafts.CONTENT_URI, projection, selection, selectionArgs, null) ?: return
|
||||
@Suppress("ConvertTryFinallyToUseCall")
|
||||
try {
|
||||
val idxMedia = c.getColumnIndex(Drafts.MEDIA)
|
||||
c.moveToFirst()
|
||||
while (!c.isAfterLast) {
|
||||
val mediaArray = JsonSerializer.parseArray(c.getString(idxMedia), ParcelableMediaUpdate::class.java)
|
||||
mediaArray?.forEach { media ->
|
||||
val uri = Uri.parse(media.uri)
|
||||
if ("file" == uri.scheme) {
|
||||
val file = File(uri.path)
|
||||
if (!file.delete()) {
|
||||
Log.w(LOGTAG, String.format("Unable to delete %s", file))
|
||||
}
|
||||
}
|
||||
}
|
||||
c.moveToNext()
|
||||
}
|
||||
} finally {
|
||||
c.close()
|
||||
}
|
||||
resolver.delete(Drafts.CONTENT_URI, selection, selectionArgs)
|
||||
val activity = activityRef.get() ?: return
|
||||
deleteDrafts(activity, ids)
|
||||
}
|
||||
|
||||
override fun onPreExecute() {
|
||||
super.onPreExecute()
|
||||
val activity = activityRef.get() ?: return
|
||||
(activity as IExtendedActivity<*>).executeAfterFragmentResumed { activity ->
|
||||
val f = ProgressDialogFragment.show(activity.supportFragmentManager, FRAGMENT_TAG_DELETING_DRAFTS)
|
||||
f.isCancelable = false
|
||||
|
@ -308,7 +281,7 @@ class DraftsFragment : BaseFragment(), LoaderCallbacks<Cursor?>, OnItemClickList
|
|||
}
|
||||
|
||||
override fun onPostExecute(result: Unit) {
|
||||
super.onPostExecute(result)
|
||||
val activity = activityRef.get() ?: return
|
||||
(activity as IExtendedActivity<*>).executeAfterFragmentResumed { activity ->
|
||||
val fm = activity.supportFragmentManager
|
||||
val f = fm.findFragmentByTag(FRAGMENT_TAG_DELETING_DRAFTS)
|
||||
|
@ -316,6 +289,7 @@ class DraftsFragment : BaseFragment(), LoaderCallbacks<Cursor?>, OnItemClickList
|
|||
f.dismiss()
|
||||
}
|
||||
}
|
||||
val notificationManager = activity.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
ids.forEach { id ->
|
||||
val tag = Uri.withAppendedPath(Drafts.CONTENT_URI, id.toString()).toString()
|
||||
notificationManager.cancel(tag, NOTIFICATION_ID_DRAFTS)
|
||||
|
|
|
@ -26,7 +26,6 @@ import android.app.Service
|
|||
import android.content.ContentValues
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.Point
|
||||
import android.net.Uri
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
|
@ -41,6 +40,8 @@ import android.widget.Toast
|
|||
import edu.tsinghua.hotmobi.HotMobiLogger
|
||||
import edu.tsinghua.hotmobi.model.TimelineType
|
||||
import edu.tsinghua.hotmobi.model.TweetEvent
|
||||
import nl.komponents.kovenant.task
|
||||
import nl.komponents.kovenant.ui.successUi
|
||||
import org.mariotaku.abstask.library.ManualTaskStarter
|
||||
import org.mariotaku.ktextension.configure
|
||||
import org.mariotaku.ktextension.toLong
|
||||
|
@ -70,8 +71,8 @@ import org.mariotaku.twidere.task.twitter.UpdateStatusTask
|
|||
import org.mariotaku.twidere.util.ContentValuesCreator
|
||||
import org.mariotaku.twidere.util.NotificationManagerWrapper
|
||||
import org.mariotaku.twidere.util.Utils
|
||||
import org.mariotaku.twidere.util.deleteDrafts
|
||||
import org.mariotaku.twidere.util.io.ContentLengthInputStream.ReadListener
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
|
@ -147,12 +148,17 @@ class LengthyOperationsService : BaseIntentService("lengthy_operations") {
|
|||
}
|
||||
}
|
||||
|
||||
@SuppressLint("Recycle")
|
||||
private fun handleDiscardDraftIntent(intent: Intent) {
|
||||
val data = intent.data ?: return
|
||||
task {
|
||||
if (deleteDrafts(this, longArrayOf(data.lastPathSegment.toLong(-1))) < 1) {
|
||||
throw IOException()
|
||||
}
|
||||
return@task data
|
||||
}.successUi { uri ->
|
||||
notificationManager.cancel(data.toString(), NOTIFICATION_ID_DRAFTS)
|
||||
val id = data.lastPathSegment.toLong(-1)
|
||||
val where = Expression.equals(Drafts._ID, id)
|
||||
contentResolver.delete(Drafts.CONTENT_URI, where.sql, null)
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleSendDirectMessageIntent(intent: Intent) {
|
||||
|
|
|
@ -1,13 +1,18 @@
|
|||
package org.mariotaku.twidere.util
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import android.net.Uri
|
||||
import org.mariotaku.kpreferences.get
|
||||
import org.mariotaku.ktextension.useCursor
|
||||
import org.mariotaku.pickncrop.library.PNCUtils
|
||||
import org.mariotaku.sqliteqb.library.*
|
||||
import org.mariotaku.twidere.constant.filterPossibilitySensitiveStatusesKey
|
||||
import org.mariotaku.twidere.constant.filterUnavailableQuoteStatusesKey
|
||||
import org.mariotaku.twidere.model.DraftCursorIndices
|
||||
import org.mariotaku.twidere.model.ParcelableStatus.FilterFlags
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.Filters
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.Statuses
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.*
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 2016/12/24.
|
||||
|
@ -76,3 +81,27 @@ fun buildStatusFilterWhereClause(preferences: SharedPreferences,
|
|||
}
|
||||
return filterExpression
|
||||
}
|
||||
|
||||
@SuppressLint("Recycle")
|
||||
fun deleteDrafts(context: Context, draftIds: LongArray): Int {
|
||||
val where = Expression.inArgs(Drafts._ID, draftIds.size).sql
|
||||
val whereArgs = draftIds.map(Long::toString).toTypedArray()
|
||||
|
||||
context.contentResolver.query(Drafts.CONTENT_URI, Drafts.COLUMNS, where, whereArgs,
|
||||
null).useCursor { cursor ->
|
||||
val indices = DraftCursorIndices(cursor)
|
||||
cursor.moveToFirst()
|
||||
while (!cursor.isAfterLast) {
|
||||
val draft = indices.newObject(cursor)
|
||||
draft.media?.forEach { item ->
|
||||
try {
|
||||
PNCUtils.deleteMedia(context, Uri.parse(item.uri))
|
||||
} catch (e: SecurityException) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
cursor.moveToNext()
|
||||
}
|
||||
}
|
||||
return context.contentResolver.delete(Drafts.CONTENT_URI, where, whereArgs)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue