[問題] 關於Uri

作者: gn00618777 (非常念舊)   2017-06-19 23:30:57
我是抓取 nordic nrftoolbox 的 source code。
https://goo.gl/5WxUPB
任務是利用這 code 抓取 bin file 來做 firmware 更新,客戶嫌麻煩說還要loader
去選擇檔案,想要寫死路徑。
dfuActivity 主要是在 663 行
final Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
最後在 433 行回傳,可以看到裡面大部分就只是利用 loader 選取的 data來獲取 uri
分析uri對以下填值
mFileType = mFileTypeTmp;
mFilePath = null;
mFileStreamUri = null;
接著我會經過 452 行的 else if,最後準備要更新時要執行的地方是 743行
裡面的參數就是這些變數。
我用官方沒改的 code ,在449行用
Log.d("",""+uri.toString);印出已經load下的檔案uri
content://com.android.externalstorage.documents/document/primary%3ANordic%20Semiconductor%2Fnrf52832_xxaa_s132.bin
接著我開始改 code
我就直接用上面這串
利用 Uri.parser("xxxxx") 來丟到 743行的 mFileStreamUri
最後APK卻說找不到檔案,我懷疑是 URI的轉換問題讓APK無法找到bin file,另
一個可能就是464行的restartLoader的問題,我把455~464 663~665 mark掉了。
也就是不透過其他APP例如檔案管理APK來載入檔案,直接寫死要上傳的檔案的uri
既然客戶希望按個 button,就可以不用開啟 loader 選取檔案,那麼有沒有辦法是
下了
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
startActivity(intent, SELECT_FILE_REQ));
可以不用由客戶去選檔,就指定給他路徑了呢?
還有我的URI可以這樣 assign嗎...?
作者: ssccg (23)   2017-06-20 12:57:00
就沒權限存取那個位置的檔案啊這個URI是個content uri,是跟系統的DocumentProvider取
作者: gn00618777 (非常念舊)   2017-06-20 15:12:00
或是我可以設定 ACTION_GET_CONTENT後可以直接存取某個特定的檔案嗎,不用經由客戶來選?setDataAndType好像也不能直接選取到我要的檔案..
作者: ssccg (23)   2017-06-20 15:14:00
MANAGE_DOCUMENTS不是第三方App可以要的權限問題不是在用ACTION_GET_CONTENT要,而是你要到的這個URI是content uri。你現在要存取的這個檔案是你可以控制的? 直接看它放在哪然後用file://的URI就可以了吧
作者: gn00618777 (非常念舊)   2017-06-20 15:33:00
s大感謝你的回覆。 你說可以控制的是指檔案格式還是存放位址還是 URI 的 scheme?從S大的回覆是指這個 bin 我可以用 file://的URI去設?經你一說我有看DfuActivity 有關於判斷得到的uri是屬於 sheme 是 file 或是 content的設置
作者: ssccg (23)   2017-06-20 15:48:00
content是找某個ContentProvider要,必須符合該Provider的限制,例如現在這個com.android.externalstorage.documents要求app必須就是當初用ACTION_GET_CONTENT跟它要的那個appfile是看如果是app自己的目錄就沒任何限制,如果是共用的目錄要READ_EXTERNAL_STORAGE權限,如果是系統目錄就不能存取用content的可能還是對應到某個檔案,但是用content去存取跟直接用file存取,遇到的限制就會不同如果你能控制那檔案放哪,就放在能取的地方然後用file
作者: gn00618777 (非常念舊)   2017-06-20 16:18:00
s大,我有更新4,請您看一下我的理解對不對?
作者: ssccg (23)   2017-06-20 16:32:00
不知道你說的loader是指哪個...ACTION_GET_CONTENT回來的uri的權限是檔案管理app給的,但是檔案管理app裡面實作當然有可能是再跟別人取的重點是你到底能不能直接存取那個檔案? 還是除了那個contentURI以外你現在根本不知道那個檔案在哪?
作者: gn00618777 (非常念舊)   2017-06-20 16:59:00
那個檔案存放的地方我可以決定,事實上我剛剛在搜尋怎樣將我要load的檔案轉成用file://表示的URI目前我用 File file = new File(Runtime.getExternal)StorageDirectory().toString() + "/Download/", name再用file.exists()先確認有沒有存在再用 Uri uri = Uri.fromFile(tmpFile);還不確定能不能用此Uri來更新 firmware,稍後測試
作者: paulku (蒼木浩介.改)   2017-06-20 17:45:00
我工作上是惡搞啦 ASSETS複製出去後在指定那位置更新更新成功後在onTransferCompleted階段刪檔這樣就不太用大改程式了....只是要多要讀寫權限就是了反正跟客戶說 因為更新設備 所以要讀寫檔案就呼嚨過去了..這是不好的示範就是了.....
作者: gn00618777 (非常念舊)   2017-06-20 18:05:00
天啊 我成功了>"<<>"< 太感謝了.....真的是很感謝..不太懂P大說的內容..那這樣content的使用時機是啥,file://比較好用阿..
作者: ssccg (23)   2017-06-20 18:32:00
asset如果在同個app不用複製,用file:///android_assets/可以直接存取content是跟ContentProvider要,ContentProvider的實作不一定是取檔案,可能從任何地方來,跟file是不同的概念
作者: bukiya (武器店)   2017-06-20 18:47:00
Android N上uri有限制file://的使用,要注意一下
作者: gn00618777 (非常念舊)   2017-06-20 18:53:00
p大以啥限制?我目前就是在N上開發
作者: ssccg (23)   2017-06-20 18:57:00
N之後不能share file uri給別的app,在同一個app裡沒關係
作者: gn00618777 (非常念舊)   2017-06-21 16:00:00
了解,謝謝分享

Links booklink

Contact Us: admin [ a t ] ucptt.com