相信大家最近都看到了這條新聞《網(wǎng)友稱被拼多多APP遠程刪除照片》。
簡單描述一下事件的過程,一位網(wǎng)友從拼多多的 App 里,得知邀請一名新用戶,可以直接提現(xiàn)100元,當成功邀請后,發(fā)現(xiàn)給予的是隨機金額,并沒有100元提現(xiàn)這件事情,之后與客服聊天,發(fā)送了邀請一名新用戶,可以直接提現(xiàn)100元的截圖,然后在發(fā)送之后,收到了 vivo 手機系統(tǒng)通知,提示相機內(nèi)的照片被刪除,所以他懷疑拼多多遠程操控手機,刪除了那張圖片。
作為一名 Android 工程師,看到這個問題的時候,發(fā)現(xiàn)挺有意思的,所以決定去測試一下,到底拼多多是否真的存在刪除用戶照片的這個行為。
首先我們都知道,Android 的 App 幾乎所有的都會向用戶獲取了存儲空間的讀寫權限,用于保存和讀取相關的數(shù)據(jù),所以從技術的角度來說,只要獲取了這個權限,位于公共存儲空間的任何文件,都是可以被刪除的。
作為開發(fā)人員,我們都知道,隨意刪除用戶公共存儲空間的任意數(shù)據(jù),這絕對是不合理的行為,但有一個需要注意的點是,我們開發(fā) App 的時候,也會在某些時候把用戶在本 App 中產(chǎn)生的數(shù)據(jù)保存到公共存儲空間,例如圖片、文檔,或者其他的媒體資源文件。
在通過觀察拼多多的聊天頁面,我們可以知道,是存在兩種發(fā)送圖片的方式
1. 點擊照片發(fā)送(也就是說點擊照片按鈕,選擇手機本地的圖片發(fā)送)
2. 點擊拍攝發(fā)送(通過拼多多自己的拍照功能,拍攝一張照片發(fā)送)
所以這個事件中,有一個問題我們要搞清楚
被刪除的截圖是原本就存在于這部手機上,還是那名網(wǎng)友在和客服聊天的時候,通過拍攝這個功能,拍了存在于另一部手機上的截圖?
如果是按照第一種方式發(fā)送的圖片,那么這張圖片被刪除了,拼多多這么做顯然是有問題的。
又去翻了視頻,我發(fā)現(xiàn)發(fā)送的圖片并不是原本的截圖,而是拍攝的照片,當然這也不能絕對說就是用戶使用的拼多多聊天內(nèi)的拍照功能拍的,也可能是用手機拍了另一部手機的截圖,然后發(fā)送的圖片,當然這就和第一種發(fā)送方式一樣了。
不過這個問題,也就只要當事人知道是怎么回事了。
我們在這里討論一下第二種方式,如果用戶使用的是聊天頁面的拍攝按鈕,拍了一張截圖,發(fā)送過去,那么這張圖片會不會被刪除呢?
我用拼多多聊天頁面自帶的拍照功能,拍了一張照片,但這時還沒有點完成按鈕發(fā)送,去檢查手機存儲空間的時候,發(fā)現(xiàn)這張照片已經(jīng)被保存到了 DCIM/Pindd/image/16 這個文件目錄下面。
當點擊發(fā)送后,這照片還是存在的,沒有被刪除。
那么根據(jù) vivo 手機的系統(tǒng)通知,確實有張圖片被刪除了,這到底是怎么回事呢?
然后再次去看了遍視頻,我發(fā)現(xiàn)發(fā)送的這張圖上面??有一個很明顯的紅色標記,再結(jié)合上面我拍完的張照片的頁面,我們可以發(fā)現(xiàn),拼多多在拍完照片之后是提供圖片編輯功能的。
所以我猜測,應該是在應用的聊天頁面拍攝的截圖,然后通過拍攝后的編輯操作劃了紅線,然后發(fā)送的。
按照正常的邏輯,從拍攝到發(fā)送,應該只保留一張圖片,這是沒問題的。
根據(jù)我上面猜測的操作邏輯,其實是拍攝原圖并保存,編輯原圖生成新的編輯后的圖片,然后發(fā)送的是編輯后的圖片,那么這里的原圖其實屬于一張臨時圖片,所以刪掉原圖保留編輯后的圖片,這也是沒問題的。
看到這里,做開發(fā)的同學應該對這個操作非常熟悉,在大多數(shù)有拍照編輯的業(yè)務場景中,我們都是這樣處理的,因為拍攝的原圖相當于一個臨時文件,最終編輯后的文件才是最終的文件,這個臨時文件對用戶來說是無感知且無意義的,所以刪掉是正常的行為。
那么哪里有問題?
問題出現(xiàn)在,拼多多刪除原圖的時候,vivo 手機檢測到了圖片被刪除。為什么 vivo 手機會檢測到了圖片被刪除?
還記得拼多多保存圖片的地址嗎?DCIM/Pindd/image/16 是在 DCIM 下,DCIM 相當于系統(tǒng)公共的相冊目錄,在這個目錄下做任何圖片的保存,刪除操作,系統(tǒng)都會得到相冊被改動的通知,所以當拼多多刪除那張臨時文件時,vivo 出現(xiàn)了圖片被刪除的通知。
真正有問題的地方是,拼多多不應該在 DCIM 保存臨時的圖片文件,我相信這個問題不止拼多多一個 App 有,很多 App 都可能存在這個問題,歸根結(jié)底,是對 Android 文件目錄使用不規(guī)范的問題,應用內(nèi)的臨時文件,應該保存在 App 的私有緩存目錄下,Android 的開發(fā)文檔有明確說明。??
根據(jù)拼多多官方微博最新的聲明,也驗證了我的猜想是正確的。
正確的做法其實也很簡單,這種臨時文件放在內(nèi)部存儲 getCacheDir() 或外部存儲 getExternalCacheDir() 這兩個緩存文件目錄里面就可以了,當真正完成所有的邏輯之后,再將圖片同步到公共的相冊文件夾中。
相比拼多多,微信的聊天頁面也有拍照編輯發(fā)送這一場景,反觀微信,只有在最后一步發(fā)送點擊之后,該圖片才會被保存到手機里用戶可見的圖片文件夾中,至于中間的臨時文件,用戶是無法感知的。
當我寫這篇文章的時候,發(fā)現(xiàn)拼多多的 App 里在編輯圖片之后,已經(jīng)不會刪掉原圖了,大概是通過熱修復的方法,把這里的邏輯做了暫時性的處理。
看似解決了問題,不過根本上,還是對 Android 文件目錄使用不規(guī)范的問題,熱修復也是治標不治本的解決方案,希望拼多多之后可以徹底的解決這個問題吧。
況且 Android 10 Google 已經(jīng)推出了新的 Scoped Storage 規(guī)范,雖然在 Android 10 上沒有嚴格執(zhí)行,但在 Android 11 上是必須適配的,所以看到這篇文章的同學,也希望大家可以檢查一下這部分的代碼,盡早做適配。
現(xiàn)在再回看這個問題,你說這個問題嚴重嗎?
從技術的角度來說,確實是一個小問題,但從事件發(fā)酵的角度來說,它是一個大問題,任何一個小問題都有可能帶來嚴重的后果,所以說寫代碼是需要時刻保持嚴謹?shù)?,不只是簡單的完成需求,更要仔細想想,它真的沒問題了嗎?
再次推薦大家,無論你的技術如何,時不時的去翻閱一下 Android 的官方文檔,總會找到一些你過去忽略或理解有錯的知識。
作者:wanbo
鏈接:https://juejin.cn/post/6917417541195268104