Android適配:小米手機(jī) Unable to load resource 0x00000000 from pkg=com.android.systemui

近期在梳理項目中的 手機(jī)圖片處理荠商、文件處理皆撩、APK文件在線升級等功能時扣墩,發(fā)現(xiàn)了在個別小米手機(jī)上總是報錯:
Unable to load resource 0x00000000 from pkg=com.android.systemui

Unable to load resource 0x00000000 from pkg=com.android.systemui
android.content.res.Resources$NotFoundException: Resource ID #0x0
at android.content.res.ResourcesImpl.getValue(ResourcesImpl.java:201)
at android.content.res.MiuiResourcesImpl.getValue(MiuiResourcesImpl.java:94)
at android.content.res.Resources.getDrawable(Resources.java:788)
at android.graphics.drawable.Icon.loadDrawableInner(Icon.java:316)
at android.graphics.drawable.Icon.loadDrawable(Icon.java:272)
at android.graphics.drawable.Icon.loadDrawableAsUser(Icon.java:380)
at com.android.systemui.statusbar.ExpandedIcon.getDrawable(ExpandedIcon.java:59)
at com.android.systemui.statusbar.StatusBarIconView.getIcon(StatusBarIconView.java:179)
at com.android.systemui.statusbar.StatusBarIconView.setIcon(StatusBarIconView.java:138)
at com.android.systemui.statusbar.StatusBarIconView.updateDarkMode(StatusBarIconView.java:271)
at com.android.systemui.statusbar.phone.SimpleStatusBar.updateDarkMode(SimpleStatusBar.java:291)
at com.android.systemui.statusbar.phone.PhoneStatusBar$19.run(PhoneStatusBar.java:3730)
at android.os.Handler.handleCallback(Handler.java:754)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:163)
at android.app.ActivityThread.main(ActivityThread.java:6363)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:794)

關(guān)于該問題,網(wǎng)上討論的帖子很多扛吞,也有很多的解釋呻惕。

該異常恐怕只有小米系統(tǒng)開發(fā)人員才知道:在哪些具體條件下滥比,會報出來亚脆。
而我們的問題,主要是處理文件時出現(xiàn)的守呜。那么型酥,此文章也只是針對手機(jī)文件處理時給出一些解決方案。


分析:

  1. 經(jīng)測試查乒,小米個別機(jī)型高低版本(Android版本弥喉,如android7.1.2等)都有可能出現(xiàn)該問題。
  2. 問題的主要原因:使用Intent傳遞參數(shù)時玛迄,直接把大的數(shù)據(jù)作為了參數(shù)進(jìn)行傳遞由境,如文件。
 調(diào)用系統(tǒng)程序蓖议,裁切指定的圖片虏杰,小米手機(jī)報此異常
   // 裁切圖
    public void cutimage(Uri imageUri) {
        Intent intent= new Intent("com.android.camera.action.CROP");
        intent.setDataAndType(imageUri, "image/*");
        ......
        ......
        intent.putExtra("outputFormat", "JPEG");
        intent.putExtra("noFaceDetection", true);
        intent.putExtra("return-data", true);
        startActivityForResult(intent, AppConstants.REQUEST_CODE_CROP);
    }

調(diào)用系統(tǒng)程序,安裝下載的apk文件時勒虾,小米手機(jī)報此異常
 /**
     * apk安裝
     */
    public static void InstallApk(Context context, File apkFile){      
        Intent intent = new Intent();
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setAction(android.content.Intent.ACTION_VIEW);
        intent.setDataAndType(FileProviderUtils.uriFromFile(context, apkFile),
 "application/vnd.android.package-archive");
        context.startActivity(intent);
    }

setDataAndType方法傳遞了安裝包數(shù)據(jù)時纺阔,報異常;

除此之外修然,還有很多例子笛钝,此處不再羅列。


原因:

通過網(wǎng)上查詢資料愕宋、代碼實驗玻靡,這個問題應(yīng)該是:因為小米個別機(jī)型使用Intent傳遞過大的數(shù)據(jù)導(dǎo)致的。

intent.setDataAndType(imageUri, "image/*");
該方法傳遞的是uri中贝,不是文件囤捻,沒有問題;
Intent.putExtra("return-data",true)邻寿;
該方法是指否回傳數(shù)據(jù)蝎土。
如果設(shè)置為true视哑,當(dāng)處理完畢后,結(jié)果會通過intent進(jìn)行回傳誊涯,如果處理的是大文件黎炉,那就要小心了!4着 !
小米系統(tǒng)問題可能就是出在這里淀弹,return-data的方式只適用于小數(shù)據(jù)丹壕,小米手機(jī)有可能處理完的數(shù)據(jù)仍然過大,導(dǎo)致的異常薇溃。

解決方案

Intent傳參時菌赖,不直接傳遞大的文件數(shù)據(jù)。

重點1:
那么沐序,我們的數(shù)據(jù)應(yīng)該如何傳遞呢琉用? --以上面的例子為參考,我們進(jìn)行分析策幼。
如果我們需要處理后的數(shù)據(jù)(如裁切后的圖片)邑时,可以使用URI回傳,而非實際的數(shù)據(jù)特姐;
如果我們不需要處理好的數(shù)據(jù)晶丘,直接設(shè)置不需要回傳即可。
但是這兩種方式唐含,都需要明確設(shè)置Intent.putExtra("return-data",false)浅浮;

重點2:
我們?nèi)魏畏较騻鬟f文件都需要使用URI,但是使用時捷枯,要小心一個坑滚秩,即android7.0傳遞uri時,應(yīng)注意權(quán)限安全淮捆。
即:針對URI郁油,我們要分版本適配,網(wǎng)上有很多處理方案争剿,也可參考已艰,我之前寫的文章:
http://www.reibang.com/p/bec4497c2a63


代碼實現(xiàn)

代碼也同樣以上面的例子為參考,給予解決:

代碼1:
URI 適配封裝類:

package com.iwangzhe.app.util.android7.urifit;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.support.v4.content.FileProvider;
import java.io.File;

/**
 * 類:FileProviderUtils Uri適配幫助類
 * 從APP向外共享的文件URI時蚕苇,必須使用該類進(jìn)行適配哩掺,否則在7.0以上系統(tǒng),會報錯:FileUriExposedException(文件Uri暴露異常)
 * 作者: qxc
 * 日期:2018/2/23.
 */
public class FileProviderUtils {
    /**
     * 從文件獲得URI
     * @param context 上下文
     * @param file 文件
     * @return 文件對應(yīng)的URI
     */
    public static Uri uriFromFile(Context context, File file) {
        Uri fileUri;
        //7.0以上進(jìn)行適配
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            String p = context.getPackageName() + ".FileProvider";
            fileUri = FileProvider.getUriForFile(
                    context,
                    p,
                    file);
        } else {
            fileUri = Uri.fromFile(file);
        }
        return fileUri;
    }

    /**
     * 設(shè)置Intent的data和類型涩笤,并賦予目標(biāo)程序臨時的URI讀寫權(quán)限
     * @param context 上下文
     * @param intent 意圖
     * @param type 類型
     * @param file 文件
     * @param writeAble 是否賦予可寫URI的權(quán)限
     */
    public static void setIntentDataAndType(Activity context,
                                            Intent intent,
                                            String type,
                                            File file,
                                            boolean writeAble) {
        //7.0以上進(jìn)行適配
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            intent.setDataAndType(uriFromFile(context, file), type);
            //臨時賦予讀寫Uri的權(quán)限
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            if (writeAble) {
                intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
            }
        } else {
            intent.setDataAndType(Uri.fromFile(file), type);
        }
    }

    /**
     * 設(shè)置Intent的data和類型嚼吞,并賦予目標(biāo)程序臨時的URI讀寫權(quán)限
     * @param context 上下文
     * @param intent 意圖
     * @param type 類型
     * @param fileUri 文件uri
     * @param writeAble 是否賦予可寫URI的權(quán)限
     */
    public static void setIntentDataAndType(Context context,
                                            Intent intent,
                                            String type,
                                            Uri fileUri,
                                            boolean writeAble) {
        //7.0以上進(jìn)行適配
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            intent.setDataAndType(fileUri, type);
            //臨時賦予讀寫Uri的權(quán)限
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            if (writeAble) {
                intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
            }
        } else {
            intent.setDataAndType(fileUri, type);
        }
    }
}

代碼2:
系統(tǒng)程序交互類(調(diào)用裁切盒件、執(zhí)行安裝包等等)

package com.iwangzhe.app.util.android7.systemprogram;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.provider.MediaStore;
import com.iwangzhe.app.util.android7.urifit.FileProviderUtils;
import com.iwangzhe.app.util.log.collect.exception.ExceptionProxy;
import java.io.File;
/**
 * 類:SystemProgramUtils 系統(tǒng)程序適配幫助類
 * 1. 拍照
 * 2. 相冊
 * 3. 裁切
 * 4. apk安裝
 * 作者: qxc
 * 日期:2018/2/23.
 */
public class SystemProgramUtils {
    public static final int REQUEST_CODE_PAIZHAO = 1;
    public static final int REQUEST_CODE_ZHAOPIAN = 2;
    public static final int REQUEST_CODE_CAIQIE = 3;

    /**
     * 打開相機(jī)拍照
     */
    public static void paizhao(Activity activity, File outputFile){
        Intent intent = new Intent();
        intent.setAction("android.media.action.IMAGE_CAPTURE");
        intent.addCategory("android.intent.category.DEFAULT");
        Uri uri = FileProviderUtils.uriFromFile(activity, outputFile);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
        activity.startActivityForResult(intent, REQUEST_CODE_PAIZHAO);
    }

    /**
     * 打開相冊
     */
    public static void zhaopian(Activity activity){
        Intent intent = new Intent();
        intent.setType("image/*");
        intent.setAction("android.intent.action.PICK");
        intent.addCategory("android.intent.category.DEFAULT");
        activity.startActivityForResult(intent, REQUEST_CODE_ZHAOPIAN);
    }

    /**
     * 打開圖片裁切
     */
    public static void Caiqie(Activity activity, Uri uri, File outputFile) {
        Intent intent = new Intent("com.android.camera.action.CROP");
        FileProviderUtils.setIntentDataAndType(activity, intent, "image/*", uri, true);
        intent.putExtra("crop", "true");
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1);
        intent.putExtra("outputX", 300);
        intent.putExtra("outputY", 300);
        //return-data為true時,直接返回bitmap舱禽,可能會很占內(nèi)存炒刁,不建議,小米等個別機(jī)型會出異常L苤伞O枋肌!
        //所以適配小米等個別機(jī)型里伯,裁切后的圖片城瞎,不能直接使用data返回,應(yīng)使用uri指向
        //裁切后保存的URI疾瓮,不屬于我們向外共享的脖镀,所以可以使用fill://類型的URI
        Uri outputUri = Uri.fromFile(outputFile);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, outputUri);
        intent.putExtra("return-data", false);
        intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
        intent.putExtra("noFaceDetection", true);
        activity.startActivityForResult(intent, REQUEST_CODE_CAIQIE);
    }

    /**
     * apk安裝
     */
    public static void InstallApk(Context context, File apkFile){
        try {
            //設(shè)置權(quán)限
            String command = "chmod 777 " + apkFile.getPath();
            Runtime runtime = Runtime.getRuntime();
            runtime.exec(command);

            //安裝apk
            Intent intent = new Intent();
            FileProviderUtils.setIntentDataAndType(context, intent, "application/vnd.android.package-archive", FileProviderUtils.uriFromFile(context, apkFile), true);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.setAction(android.content.Intent.ACTION_VIEW);
            intent.putExtra("return-data", false);
            context.startActivity(intent);
        }catch (Exception ex){
            ExceptionProxy.catchException(ex);
        }
    }
}

裁切方法注意點:
Uri outputUri = Uri.fromFile(outputFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputUri);
intent.putExtra("return-data", false);
這幾句代碼,就是告訴裁切程序狼电,當(dāng)裁切完成后蜒灰,不用直接返回數(shù)據(jù),而是把裁切的圖片輸出到outputUri上肩碟,我們自己會訪問該文件獲得裁切后的數(shù)據(jù)强窖。

安裝APK注意點:
1 安裝apk前,應(yīng)保證對該apk有操作的權(quán)限削祈,如不設(shè)置毕骡,個別機(jī)型手機(jī)可能報:無法解析安裝包
2 FileProviderUtils.setIntentDataAndType是我們封裝的7.0URI適配的方法
3 intent.putExtra("return-data", false);明確告訴系統(tǒng),我們不需要返回處理后的數(shù)據(jù)岩瘦;

代碼3:
調(diào)用

//獲得apk文件
File file = getApk();//注意:這是我們自己的方法未巫,不要理解成系統(tǒng)的方法
//安裝apk文件
SystemProgramUtils.InstallApk(context, file);

以上方法,我們進(jìn)行過測試启昧,使用時叙凡,請大家酌情優(yōu)化。
如果有問題密末,請留言或自行查詢資料N找!严里!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末新啼,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子刹碾,更是在濱河造成了極大的恐慌燥撞,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,204評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異物舒,居然都是意外死亡色洞,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評論 3 395
  • 文/潘曉璐 我一進(jìn)店門冠胯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來火诸,“玉大人,你說我怎么就攤上這事荠察≈檬瘢” “怎么了?”我有些...
    開封第一講書人閱讀 164,548評論 0 354
  • 文/不壞的土叔 我叫張陵悉盆,是天一觀的道長盾碗。 經(jīng)常有香客問我,道長舀瓢,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,657評論 1 293
  • 正文 為了忘掉前任耗美,我火速辦了婚禮京髓,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘商架。我一直安慰自己堰怨,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,689評論 6 392
  • 文/花漫 我一把揭開白布蛇摸。 她就那樣靜靜地躺著备图,像睡著了一般。 火紅的嫁衣襯著肌膚如雪赶袄。 梳的紋絲不亂的頭發(fā)上揽涮,一...
    開封第一講書人閱讀 51,554評論 1 305
  • 那天,我揣著相機(jī)與錄音饿肺,去河邊找鬼蒋困。 笑死,一個胖子當(dāng)著我的面吹牛敬辣,可吹牛的內(nèi)容都是我干的雪标。 我是一名探鬼主播,決...
    沈念sama閱讀 40,302評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼溉跃,長吁一口氣:“原來是場噩夢啊……” “哼村刨!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起撰茎,我...
    開封第一講書人閱讀 39,216評論 0 276
  • 序言:老撾萬榮一對情侶失蹤嵌牺,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體髓梅,經(jīng)...
    沈念sama閱讀 45,661評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡拟蜻,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,851評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了枯饿。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片酝锅。...
    茶點故事閱讀 39,977評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖奢方,靈堂內(nèi)的尸體忽然破棺而出搔扁,到底是詐尸還是另有隱情,我是刑警寧澤蟋字,帶...
    沈念sama閱讀 35,697評論 5 347
  • 正文 年R本政府宣布稿蹲,位于F島的核電站,受9級特大地震影響鹊奖,放射性物質(zhì)發(fā)生泄漏苛聘。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,306評論 3 330
  • 文/蒙蒙 一忠聚、第九天 我趴在偏房一處隱蔽的房頂上張望设哗。 院中可真熱鬧,春花似錦两蟀、人聲如沸网梢。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽战虏。三九已至,卻和暖如春党涕,著一層夾襖步出監(jiān)牢的瞬間烦感,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評論 1 270
  • 我被黑心中介騙來泰國打工膛堤, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留啸盏,地道東北人。 一個月前我還...
    沈念sama閱讀 48,138評論 3 370
  • 正文 我出身青樓骑祟,卻偏偏與公主長得像回懦,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子次企,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,927評論 2 355

推薦閱讀更多精彩內(nèi)容

  • ¥開啟¥ 【iAPP實現(xiàn)進(jìn)入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個線程怯晕,因...
    小菜c閱讀 6,419評論 0 17
  • Android7.0發(fā)布已經(jīng)有一個多月了,Android7.0在給用戶帶來一些新的特性的同時缸棵,也給開發(fā)者帶來了新的...
    善良的老農(nóng)閱讀 767評論 0 5
  • Android7.0發(fā)布已經(jīng)有一個多月了舟茶,Android7.0在給用戶帶來一些新的特性的同時,也給開發(fā)者帶來了新的...
    東經(jīng)315度閱讀 1,364評論 0 14
  • 小時候經(jīng)常做夢,記憶中夢很甜美吧凉。常常是一夢醒來隧出。呲呲的笑,覺得有趣的很阀捅。成長以后夢的構(gòu)造也非常有趣胀瞪,覺得可以寫來給...
    c1dd5a05d5c8閱讀 245評論 0 1
  • 天空嘆息 下起了驟雨, 是誰在為我哭泣饲鄙,澆滅了人間煙火凄诞。 我忙跑到屋檐下, 雨聲卻敲醒回憶忍级,帶我回到過去-----...
    遇見麥小麥閱讀 548評論 2 2