標籤:
今天在編輯一個簡單的aidl的例子的時候遇到的一個小問題。本來編輯完後準備運行,無意中看到AndroidManifest.xml有個警告,內容為“Exported service does not require permission”.設定檔代碼如下:
1 <service android:name=".AidlService">2 <intent-filter >3 <action android:name="com.example.myaidldemo.action.AIDL_SERVICE"/>4 </intent-filter>5 </service>
警告“Exported service does not require permission”的意思是“外部的service不需要許可權”。既然不需要許可權那麼為什麼還會有警告呢???在網上搜了一些此類問題,也沒說為什麼。不過倒是按照他們的方法解決了問題。那就是直接在service中設定exported屬性為“false”,限制外界訪問。問題就解決了。如下:
1 <service android:name=".AidlService"2 android:exported="false">3 <intent-filter >4 <action android:name="com.example.myaidldemo.action.AIDL_SERVICE"/>5 </intent-filter>6 </service>
其實回過頭來想想,其實只是自己犯了個很弱智的問題,因為自己和很多遇到這種問題的人一樣,那就是:理解錯誤!因為以前學習大家遇到的通常都是沒有加許可權而導致的問題,所以自然而然的想到沒加許可權會報錯,無法訪問之類的。但是這次遇到的是“外部的service不需要許可權”,其意思是:外部的其他service根本不需要添加許可權就能夠輕易地訪問我們編寫的這個aidl,或者說這個service。這是出於安全性的考慮而給我們的警告。而不是告訴我們缺少相應的許可權。自己傻傻的還想require這個單詞是不是還有其他意思,會不會有“需要”的意思,查有道,沒有。翻牛津。還是沒有。最後甚至想是不是編輯文檔的人寫錯了,把acquire錯寫成了require?最後才發現只是理解錯了,習慣性思維犯的錯。
那麼,問題又來了,android:exported="false" 這句不是系統預設的嗎?怎麼還要自己手動加上?難道系統的預設值是“true”?api文檔中這麼說的:
android:exported Whether or not components of other applications can invoke the service or interact with it — " true" if they can, and " false" if not. When the value is " false", only components of the same application or applications with the same user ID can start the service or bind to it. The default value depends on whether the service contains intent filters. The absence of any filters means that it can be invoked only by specifying its exact class name. This implies that the service is intended only for application-internal use (since others would not know the class name). So in this case, the default value is "false". On the other hand, the presence of at least one filter implies that the service is intended for external use, so the default value is "true". This attribute is not the only way to limit the exposure of a service to other applications. You can also use a permission to limit the external entities that can interact with the service (see the permission attribute).
關鍵的一句是:
The default value depends on whether the service contains intent filters.
就是說預設值取決於該service是否包含intent過濾器filter。如果沒有<intent-filter>,那隻能通過指定其準確的類名訪問。這意味著該service打算只在該應用內部使用(因為其他應用可能根本不知道這個類的名字)。在這種情況下,預設值是“false”,另一方面,當存在至少一個filter時,就表明該service打算供外部來使用,因此預設值是“true”。寫到這裡相信大家知道問什麼了吧。原來api裡面寫的清清楚楚,看來api文檔才是最好的資料這句話一點沒錯。是真正的宗。
其實還有一種解決的辦法。那就是我們在這裡自己定義一個許可權。既然外部的其他service不需許可權就能訪問我們的service,那麼我們自己定義許可權,然後在需要調用該service的應用的設定檔裡面聲明調用該service的所需要的許可權不就可以了嗎?代碼更改為:
1 <service android:name=".AidlService"2 android:permission="com.exmaple.myaidldemo.myaidlservice">3 <intent-filter >4 <action android:name="com.example.myaidldemo.action.AIDL_SERVICE"/>5 </intent-filter>6 </service>
然後在我們需要調用該service的其他應用的設定檔中加入下面這行代碼:
<uses-permission android:name="com.exmaple.myaidldemo.myaidlservice"/>
現在為止我們就算是完整的就絕了遇到的問題了。最後感歎下,文檔時個好東西啊。畢竟書裡面不可能介紹的非常詳細。只有多讀文檔才是正道。
Exported service does not require permission問題。