『壹』 android實現分享功能時,分享的內容怎麼提取到,比如瀏覽一篇文章時,可以提取文章標題,鏈接等信息。
通常分享功能是調用者發起的,如果是文字分享調用都需要做
intent.putExtra(Intent.EXTRA_SUBJECT, "分享");
intent.putExtra(Intent.EXTRA_TEXT, "好東西,與您分享!");
傳遞這兩個參數,接收都就拿這兩個值就可以了。
各種接受分享的軟體都是這樣處理的,包括系統內置的簡訊功能,各種微博應用都是一樣的。
『貳』 利用 Android 系統原生 API 實現分享功能(2)
在之前的一篇文章 利用 Android 系統原生 API 實現分享功能 中主要說了下實現流程,但具體實施起來其實還是有許多坑要面對。那這篇文章就是提供一個封裝好的 Share2 庫供大家參考。
GitHub 項目地址:Share2
看過上一篇文章的同學應該知道,要調用 Android 系統內建的分享功能,主要有三步流程:
更多相關內容請參考上一篇,這里就不再重復贅述了。
知道大致的實現流程後,其實只要解決下面幾個問題後就可以具體實施了。
這其實是直接決定了最終的實現形態,我們知道常見的使用場景中,只是為了在應用間分享圖片和一些文件,那對於那些只是分享文本的產品而言,兩者實現起來要考慮的問題完全不同。
所以為了解決這個問題,我們可以預先定好支持的分享內容類型,針對不同類型可以進行不同的處理。
在 Share2 中,一共定義了5種類別的分享內容,基本能覆蓋常見的使用場景。在調用分享介面時可以直接指定內容類型,比如像文本、圖片、音視頻、已經其他各種類型文件。
對於不同類別的內容,可能會有不同的來源。比如文本可能就只是一個字元串對象,而對於分享圖片或其他文件,我們需要一個 Uri 來標識一個資源。這其實就引出來具體實施時的一個大問題,如何獲取要分享文件的 Uri,並且這個 Uri 要能被接收分享內容的應用處理才行 。
那麼,如何獲取要分享內容文件的 Uri?如果處理才能讓接收方也能夠根據 Uri 獲取到文件?
我們把文件 Uri 的來源劃分為下面三種類型:
常見場景 :通過文件選擇器獲取一個文件的 Uri
通過這種方式獲取到的 Uri 是由系統 ContentProvider 返回的,在 Android 4.4 之前的版本和之後的版本有較大的區別,我們後面再說怎麼處理。只要先記住這種系統返回給我們的 Uri 就行了。
比如調用系統相機進行拍照或錄制音視頻,要傳入一個生成目標文件的 Uri ,從 7.0 開始我們需要用到 FileProvider 來實現。
如果用到了 FileProvider 就要注意跟系統 ContentProvider 返回 Uri 的區別,比如我們在 Manifest 中對 FileProvider 配置 android:authorities="com.xx.xxx.fileProvider" 屬性,那這時系統返回的 Uri 格式就變成了 : content://com.xx.xxx.fileProvider... ,對於這種類型的 Uri 我們姑且叫 自定義 FileProvider 返回的 Uri ,後面一並說怎麼處理。
我們調用 new File 時需要傳入指定的文件路徑,這個絕對路徑通常是: /storage/emulated/0/... 這種樣式,我們要想調用分享時也要變成 Uri 的形式才可以,那麼如何把文件路徑變成一個文件 Uri ?這個問題下面也一並進行回答。
前面提到了文件 Uri 的三種分類,對應不同類型處理方式也不同,不然你最先遇到的問題就是:
這是由於對系統返回的 Uri 缺失訪問許可權導致,所以要對應用進行臨時訪問 Uri 的授權才行,不然會提示許可權缺失。
對於要分享系統返回的 Uri 我們可以這樣進行處理:
需要注意的是對於自定義 FileProvider 返回 Uri 的處理,即使是設置臨時訪問許可權,但是分享到第三方應用也會無法識別該 Uri
典型的場景就是,我們如果把自定義 FileProvider 的返回的 Uri 設置分享到微信或 QQ 之類的第三方應用,會提示文件不存在,這是因為他們無法識別該 Uri。
關於這個問題的處理其實跟下面要說的把文件路徑變成系統返回的 Uri 一樣,我們只需要把自定義 FileProvider 返回的 Uri 變成第三方應用可以識別系統返回的 Uri 就行了。
創建 FileProvider 時需要傳入一個 File 對象,所以直接可以知道文件路徑,那就把問題都轉換成了: 如何通過文件路徑獲取系統返回的 Uri
下面是根據傳入的 File 對象和類型來查詢系統 ContentProvider 來獲取相應的 Uri,已經按照不同文件類型在不同系統版本下的進行了適配。
其中 forceGetFileUri 方法是通過反射實現的,處理 7.0 以上系統的特殊情況下的兼容性,一般情況下不會調用到。Android 7.0 開始不允許 file:// Uri 的方式在不同的 App 間共享文件,但是如果換成 FileProvider 的方式依然是無效的,我們可以通過反射把該檢測幹掉。
通過 File Path 轉成 Uri 的方式,我們最終統一了調用系統分享時傳入內容 Uri 的三種不同場景,最終全部轉換為傳遞系統返回的 Uri,讓第三方應用能夠正常的獲取到分享內容。
Share2 按照上述方法進行了具體實施,可以通過下面的方式進行集成:
分享圖片到指定界面,比如分享到微信朋友圈
GitHub 項目地址:Share2
『叄』 android studio開發應用分享功能怎麼實現
1、項目組織結構區,用於瀏覽項目文件,默認Project以Android組織方式展示。
2、設計區,默認在打開布局文件時為設計模式,可直接拖動控制項到界面上實現所見即所得,下方的Design和Text就是代碼和設計模式的切換按鈕,切換至TEXT時,左側為代碼編輯區,右側為所見即所得的預覽。
下圖為切換至TEXT的界面
而我們常用的代碼編輯時的界面就很簡單,左邊項目樹,右側代碼編輯區,下圖為代碼編輯界面:
3、組件樹,用於展示整個頁面布局的層級關系。
4、屬性區,顯示選中控制項的可編輯屬性(僅在設計模式可見)。
5、工具欄,提供常用操作按鈕
二、左側Structure、Project、Captures面板
1、Structure面板
切換到Structure面板, Structure用於顯示當前活動文件的結構,不僅僅支持 java 文件,同時支持 Xml 文件、 .properties 配置文件等多種類型的文件。在圖中1位置可以設置過濾要顯示的內容,如是否顯示屬性、內部匿
『肆』 Android 系統原生 API 實現分享功能
GitHub 項目地址:LocalShare-master
直接上圖,這是一個典型的調用系統原生分享場景下的界面,相信大家應該都很熟悉。
那下面說一下遇到的一些問題,特別針對是 7.0 以後的系統,以及兼容一些主流 app 時遇到的坑。
前面說到分享文件時需要知道文件的類型,不然的指定類型為 / ,這樣分享到某些 App 會因為無法判斷文件類型而導致失敗,所以最好先根據文件路徑獲取其文件類型。
使用這種方法獲取文件類型,一定要注意 ContentResolver 獲取返回為 null 的情況,不然空指針異常的崩潰率可能會讓你笑不出來。實際測試中,發現在某些國產機型下,這個方法可以說直接是不可用,查詢返回一直都是空,所以單純依賴這一個方法會很不可靠。具體問題原因請看: What causes Android's ContentResolver.query() to return null?
下面按照第二條思路,按照文件頭信息簡單實現一個獲取文件類型的例子:
// 獲取文件Uri
要向在 MediaStore 中查詢到文件,要不就是通知媒體庫更新查詢或則往裡面插入一條新記錄(會比較耗時)
可以參考我的另外一篇文章: Android 系統原生 API 實現分享功能(2)
參考: https://www.jianshu.com/p/1d4bd2c5ef69
『伍』 基於android天氣預報開發中的分享功能是怎麼實現的
現在的分享基本上都是現成:
android 自帶分享功能:雖然比較low,而且不同廠家顯示的分享面板可能不一樣,但是功能是可以用的,如果要開發寫高級功能的那麼需要使用到第三方的分享啦
/**3. 第三方分享:使用較多的分享->Umeng(友盟),鏈接:http://www.umeng.com/
*分享功能
*
*@paramcontext上下文
*@paramactivityTitleActivity的名字
*@parammsgTitle消息標題
*@parammsgText消息內容
*@paramimgPath圖片路徑,不分享圖片則傳null
*/
publicvoidshareMsg(StringactivityTitle,StringmsgTitle,StringmsgText,
StringimgPath){
Intentintent=newIntent(Intent.ACTION_SEND);
if(imgPath==null||imgPath.equals("")){
intent.setType("text/plain");//純文本
}else{
Filef=newFile(imgPath);
if(f!=null&&f.exists()&&f.isFile()){
intent.setType("image/jpg");
Uriu=Uri.fromFile(f);
intent.putExtra(Intent.EXTRA_STREAM,u);
}
}
intent.putExtra(Intent.EXTRA_SUBJECT,msgTitle);
intent.putExtra(Intent.EXTRA_TEXT,msgText);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(Intent.createChooser(intent,activityTitle));
}
4. 第三方分享:使用較多的分享->ShareSDK ,鏈接:http://www.mob.com/