Android11分區(qū)存儲(chǔ),圖片分頁(yè)加載適配

Android11正式版已經(jīng)推出,我們將targetSdkVersion和compileSdkVersion都升級(jí)到30输硝,并升級(jí)pixel4到Android11,發(fā)現(xiàn)分區(qū)存儲(chǔ)讀取圖片失敗程梦。經(jīng)過(guò)分析点把,發(fā)現(xiàn)問(wèn)題如下:

context.contentResolver.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI
                        , getPhotoProjectionSQL(bucketId)
                        , getMediaSelectionSQL(true, bucketId)
                        , null
                        , getMediaOrderBySQL(start, count + 20))
 
 
private fun getMediaOrderBySQL(start: Int = 0, count: Int = Int.MAX_VALUE) = "${MediaStore.MediaColumns.DATE_MODIFIED} DESC limit $count offset $start"

getMediaOrderBySQL()方法拋出異常:


WechatIMG1.jpeg

從log上看橘荠,是SQL語(yǔ)句出了問(wèn)題,指向limit郎逃。經(jīng)過(guò)各種嘗試哥童,發(fā)現(xiàn)sortOrder這個(gè)參數(shù)在Android11中只支持排序方式,不再支持limit等查詢限制褒翰。但是通常我們加載相冊(cè)圖片/視頻等是需要分頁(yè)的贮懈,從官方文檔中沒(méi)有找到相應(yīng)的例子說(shuō)明。在閱讀query()方法的源碼优训,我們發(fā)現(xiàn)query()的實(shí)現(xiàn)如下:

public final @Nullable Cursor query(@RequiresPermission.Read @NonNull Uri uri,
        @Nullable String[] projection, @Nullable String selection,
        @Nullable String[] selectionArgs, @Nullable String sortOrder,
        @Nullable CancellationSignal cancellationSignal) {
    Bundle queryArgs = createSqlQueryBundle(selection, selectionArgs, sortOrder);
    return query(uri, projection, queryArgs, cancellationSignal);
}

將selection, selectionArgs, sortOrder封裝成一個(gè)Bundle對(duì)象傳給query()方法:

* @param uri The URI, using the content:// scheme, for the content to
 *         retrieve.
 * @param projection A list of which columns to return. Passing null will
 *         return all columns, which is inefficient.
 * @param queryArgs A Bundle containing additional information necessary for
 *            the operation. Arguments may include SQL style arguments, such
 *            as {@link ContentResolver#QUERY_ARG_SQL_LIMIT}, but note that
 *            the documentation for each individual provider will indicate
 *            which arguments they support.
 * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
 * If the operation is canceled, then {@link OperationCanceledException} will be thrown
 * when the query is executed.
 * @return A Cursor object, which is positioned before the first entry. May return
 *         <code>null</code> if the underlying content provider returns <code>null</code>,
 *         or if it crashes.
 * @see Cursor
 */
@Override
public final @Nullable Cursor query(final @RequiresPermission.Read @NonNull Uri uri,
        @Nullable String[] projection, @Nullable Bundle queryArgs,
        @Nullable CancellationSignal cancellationSignal)

不看這段代碼具體的實(shí)現(xiàn)朵你,主要是看注釋對(duì)于queryArgs這個(gè)參數(shù)的說(shuō)明:

 * @param queryArgs A Bundle containing additional information necessary for
 *            the operation. Arguments may include SQL style arguments, such
 *            as {@link ContentResolver#QUERY_ARG_SQL_LIMIT}, but note that
 *            the documentation for each individual provider will indicate
 *            which arguments they support.

such as這句:such as {@link ContentResolver#QUERY_ARG_SQL_LIMIT},猜測(cè)QUERY_ARG_SQL_LIMIT可能跟我們需要的limit有關(guān)揣非。往回看Bundle的創(chuàng)建過(guò)程:

Bundle queryArgs = createSqlQueryBundle(selection, selectionArgs, sortOrder);
 
public static @Nullable Bundle createSqlQueryBundle(
            @Nullable String selection,
            @Nullable String[] selectionArgs,
            @Nullable String sortOrder) {
 
        if (selection == null && selectionArgs == null && sortOrder == null) {
            return null;
        }
 
        Bundle queryArgs = new Bundle();
        if (selection != null) {
            queryArgs.putString(QUERY_ARG_SQL_SELECTION, selection);
        }
        if (selectionArgs != null) {
            queryArgs.putStringArray(QUERY_ARG_SQL_SELECTION_ARGS, selectionArgs);
        }
        if (sortOrder != null) {
            queryArgs.putString(QUERY_ARG_SQL_SORT_ORDER, sortOrder);
        }
        return queryArgs;
    }

QUERY_ARG_SQL_SELECTION抡医,QUERY_ARG_SQL_SELECTION_ARGS,QUERY_ARG_SQL_SORT_ORDER都是我們的傳參早敬。猜測(cè)是否可以為queryArgs增加QUERY_ARG_SQL_LIMIT來(lái)實(shí)現(xiàn)limit呢忌傻?于是把createSqlQueryBundle()方法copy到我們的代碼中,并增加QUERY_ARG_SQL_LIMIT搁嗓,如下:

val bundle = createSqlQueryBundle(getMediaSelectionSQL(true, bucketId)
                        , null
                        , getMediaOrderBySQLNoLimit(), count + 20, start)
                context.contentResolver.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI
                        , getPhotoProjectionSQL(bucketId)
                        , bundle
                        , null)
 
 
private fun createSqlQueryBundle(
            selection: String?,
            selectionArgs: Array<String?>?,
            sortOrder: String?, limitCount: Int = 0, offset: Int = 0): Bundle? {
        if (selection == null && selectionArgs == null && sortOrder == null) {
            return null
        }
        val queryArgs = Bundle()
        if (selection != null) {
            queryArgs.putString(ContentResolver.QUERY_ARG_SQL_SELECTION, selection)
        }
        if (selectionArgs != null) {
            queryArgs.putStringArray(ContentResolver.QUERY_ARG_SQL_SELECTION_ARGS, selectionArgs)
        }
        if (sortOrder != null) {
            queryArgs.putString(ContentResolver.QUERY_ARG_SQL_SORT_ORDER, sortOrder)
        }
        queryArgs.putString(ContentResolver.QUERY_ARG_SQL_LIMIT, "$limitCount offset $offset")
        return queryArgs
    }

調(diào)用如下:

val bundle = createSqlQueryBundle(getMediaSelectionSQL(false, bucketId)
                        , null
                        , getMediaOrderBySQLNoLimit(), count + 20, start)
                context.contentResolver.query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI
                        , getVideoProjectionSQL(bucketId)
                        , bundle
                        , null)

經(jīng)測(cè)試分頁(yè)加載成功芯勘。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市腺逛,隨后出現(xiàn)的幾起案子荷愕,更是在濱河造成了極大的恐慌,老刑警劉巖棍矛,帶你破解...
    沈念sama閱讀 212,599評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件安疗,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡够委,警方通過(guò)查閱死者的電腦和手機(jī)荐类,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,629評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)茁帽,“玉大人玉罐,你說(shuō)我怎么就攤上這事∨瞬Γ” “怎么了吊输?”我有些...
    開(kāi)封第一講書人閱讀 158,084評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)铁追。 經(jīng)常有香客問(wèn)我季蚂,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 56,708評(píng)論 1 284
  • 正文 為了忘掉前任扭屁,我火速辦了婚禮算谈,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘料滥。我一直安慰自己然眼,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,813評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布幔欧。 她就那樣靜靜地躺著罪治,像睡著了一般丽声。 火紅的嫁衣襯著肌膚如雪礁蔗。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 50,021評(píng)論 1 291
  • 那天雁社,我揣著相機(jī)與錄音浴井,去河邊找鬼。 笑死霉撵,一個(gè)胖子當(dāng)著我的面吹牛磺浙,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播徒坡,決...
    沈念sama閱讀 39,120評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼撕氧,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了喇完?” 一聲冷哼從身側(cè)響起伦泥,我...
    開(kāi)封第一講書人閱讀 37,866評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎锦溪,沒(méi)想到半個(gè)月后不脯,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,308評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡刻诊,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,633評(píng)論 2 327
  • 正文 我和宋清朗相戀三年防楷,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片则涯。...
    茶點(diǎn)故事閱讀 38,768評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡复局,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出粟判,到底是詐尸還是另有隱情亿昏,我是刑警寧澤,帶...
    沈念sama閱讀 34,461評(píng)論 4 333
  • 正文 年R本政府宣布浮入,位于F島的核電站龙优,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜彤断,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,094評(píng)論 3 317
  • 文/蒙蒙 一野舶、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧宰衙,春花似錦平道、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,850評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至袋哼,卻和暖如春冀墨,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背涛贯。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,082評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工诽嘉, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人弟翘。 一個(gè)月前我還...
    沈念sama閱讀 46,571評(píng)論 2 362
  • 正文 我出身青樓虫腋,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親稀余。 傳聞我的和親對(duì)象是個(gè)殘疾皇子悦冀,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,666評(píng)論 2 350