編輯:關於Android編程
一般情況下,為了讓用戶更方便的打開應用,程序會在桌面上生成一些快捷方式。
本來呢,如果是原生的桌面,其實是十分簡單,直接調用系統相關的API就行了。但是眾多的系統廠商以及眾多第三方自己定制的桌面(Launcher),導致在適配、兼容方面存在很多問題。
比如,有些桌面無法刪除快捷方式(比如小米),有些桌面無法生成快捷方式(比如錘子),有些系統無法更新桌面圖標(比如華為榮耀6)。
在升級、降級的時候快捷方式發生變化;比如,全部變成應用的主圖標,升級、降級後點擊快捷方式沒有反應,刪除應用後無法刪除快捷方式。
很多問題都是需要解決的,雖然有些由於系統限制,沒有辦法搞定所有的,但是仍然需要尋求一個最優的方案。這也就是本文需要討論的問題。
本文說指的快捷方式是指應用桌面快捷方式,不包含長按彈出的生成快捷方式。
快捷方式所有信息都是存在於launcher的favorite表。一般需要用到的字段為_id,title,intent,iconResource,icon,分別表示 快捷方式名稱,快捷方式intent,快捷方式圖標(本地),快捷方式圖標(data二進制壓縮數據)。
兩個intent數據如下
數據可以通過SQLite Editor查看,需要已經ROOT的手機
在AndroidManifest.xml增加權限
同時,根據Intent是隱式還是顯示在相關的Activity聲明相關的intent-filter。
相關代碼:
跟增加快捷方式一樣,也是需要增加權限的。加上
相關代碼:
需要增加權限
如果適配所有桌面,請添加附錄中第二條所列出的權限。/** *更新桌面快捷方式圖標,不一定所有圖標都有效 *如果快捷方式不存在,則不更新 . */ publicstaticvoidupdateShortcutIcon(Contextcontext,Stringtitle,Intentintent,Bitmapbitmap){ if(bitmap==null){ XLog.i(TAG,"updateshortcuticon,bitmapempty"); return; } try{ finalContentResolvercr=context.getContentResolver(); StringBuilderuriStr=newStringBuilder(); StringurlTemp=""; Stringauthority=LauncherUtil.getAuthorityFromPermissionDefault(context); if(authority==null||authority.trim().equals("")){ authority=LauncherUtil.getAuthorityFromPermission(context,LauncherUtil.getCurrentLauncherPackageName(context)+".permission.READ_SETTINGS"); } uriStr.append("content://"); if(TextUtils.isEmpty(authority)){ intsdkInt=android.os.Build.VERSION.SDK_INT; if(sdkInt<8){//Android2.1.x(API7)以及以下的 uriStr.append("com.android.launcher.settings"); }elseif(sdkInt<19){//Android4.4以下 uriStr.append("com.android.launcher2.settings"); }else{//4.4以及以上 uriStr.append("com.android.launcher3.settings"); } }else{ uriStr.append(authority); } urlTemp=uriStr.toString(); uriStr.append("/favorites?notify=true"); Uriuri=Uri.parse(uriStr.toString()); Cursorc=cr.query(uri,newString[]{"_id","title","intent"}, "title=?andintent=?", newString[]{title,intent.toUri(0)},null); intindex=-1; if(c!=null&&c.getCount()>0){ c.moveToFirst(); index=c.getInt(0);//獲得圖標索引 ContentValuescv=newContentValues(); cv.put("icon",flattenBitmap(bitmap)); Uriuri2=Uri.parse(urlTemp+"/favorites/"+index+"?notify=true"); inti=context.getContentResolver().update(uri2,cv,null,null); context.getContentResolver().notifyChange(uri,null);//此處不能用uri2,是個坑 XLog.i(TAG,"updateok:affected"+i+"rows,indexis"+index); }else{ XLog.i(TAG,"updateresultfailed"); } if(c!=null&&!c.isClosed()){ c.close(); } }catch(Exceptionex){ ex.printStackTrace(); XLog.i(TAG,"updateshortcuticon,geterrors:"+ex.getMessage()); } } privatestaticbyte[]flattenBitmap(Bitmapbitmap){ //Trygoguesstimatehowmuchspacetheiconwilltakewhenserialized //toavoidunnecessaryallocations/copiesduringthewrite. intsize=bitmap.getWidth()*bitmap.getHeight()*4; ByteArrayOutputStreamout=newByteArrayOutputStream(size); try{ bitmap.compress(Bitmap.CompressFormat.PNG,100,out); out.flush(); out.close(); returnout.toByteArray(); }catch(IOExceptione){ XLog.w(TAG,"Couldnotwriteicon"); returnnull; } }
需要增加的權限同修改快捷方式
雖然說通過SharePreference來保證快捷方式不會重復創建,以及通過shortcutIntent.putExtra(“duplicate”, false)也可以確保,但是為了萬無一失,還是可以通過去查詢數據判斷快捷方式是否存在,來避免重復創建。 代碼如下:
/** *檢查快捷方式是否存在 *注意:有些手機無法判斷是否已經創建過快捷方式 *因此,在創建快捷方式時,請添加 *shortcutIntent.putExtra("duplicate",false);//不允許重復創建 *最好使用{@link#isShortCutExist(Context,String,Intent)} *進行判斷,因為可能有些應用生成的快捷方式名稱是一樣的的 *此處需要在AndroidManifest.xml中配置相關的桌面權限信息 *錯誤信息已捕獲 */ publicstaticbooleanisShortCutExist(Contextcontext,Stringtitle){ booleanresult=false; try{ finalContentResolvercr=context.getContentResolver(); StringBuilderuriStr=newStringBuilder(); Stringauthority=LauncherUtil.getAuthorityFromPermissionDefault(context); if(authority==null||authority.trim().equals("")){ authority=LauncherUtil.getAuthorityFromPermission(context,LauncherUtil.getCurrentLauncherPackageName(context)+".permission.READ_SETTINGS"); } uriStr.append("content://"); if(TextUtils.isEmpty(authority)){ intsdkInt=android.os.Build.VERSION.SDK_INT; if(sdkInt<8){//Android2.1.x(API7)以及以下的 uriStr.append("com.android.launcher.settings"); }elseif(sdkInt<19){//Android4.4以下 uriStr.append("com.android.launcher2.settings"); }else{//4.4以及以上 uriStr.append("com.android.launcher3.settings"); } }else{ uriStr.append(authority); } uriStr.append("/favorites?notify=true"); Uriuri=Uri.parse(uriStr.toString()); Cursorc=cr.query(uri,newString[]{"title"}, "title=?", newString[]{title},null); if(c!=null&&c.getCount()>0){ result=true; } if(c!=null&&!c.isClosed()){ c.close(); } }catch(Exceptione){ e.printStackTrace(); result=false; } returnresult; } /** *不一定所有的手機都有效,因為國內大部分手機的桌面不是系統原生的 *更多請參考{@link#isShortCutExist(Context,String)} *桌面有兩種,系統桌面(ROM自帶)與第三方桌面,一般只考慮系統自帶 *第三方桌面如果沒有實現系統響應的方法是無法判斷的,比如GO桌面 *此處需要在AndroidManifest.xml中配置相關的桌面權限信息 *錯誤信息已捕獲 */ publicstaticbooleanisShortCutExist(Contextcontext,Stringtitle,Intentintent){ booleanresult=false; try{ finalContentResolvercr=context.getContentResolver(); StringBuilderuriStr=newStringBuilder(); Stringauthority=LauncherUtil.getAuthorityFromPermissionDefault(context); if(authority==null||authority.trim().equals("")){ authority=LauncherUtil.getAuthorityFromPermission(context,LauncherUtil.getCurrentLauncherPackageName(context)+".permission.READ_SETTINGS"); } uriStr.append("content://"); if(TextUtils.isEmpty(authority)){ intsdkInt=android.os.Build.VERSION.SDK_INT; if(sdkInt<8){//Android2.1.x(API7)以及以下的 uriStr.append("com.android.launcher.settings"); }elseif(sdkInt<19){//Android4.4以下 uriStr.append("com.android.launcher2.settings"); }else{//4.4以及以上 uriStr.append("com.android.launcher3.settings"); } }else{ uriStr.append(authority); } uriStr.append("/favorites?notify=true"); Uriuri=Uri.parse(uriStr.toString()); Cursorc=cr.query(uri,newString[]{"title","intent"}, "title=?andintent=?", newString[]{title,intent.toUri(0)},null); if(c!=null&&c.getCount()>0){ result=true; } if(c!=null&&!c.isClosed()){ c.close(); } }catch(Exceptionex){ result=false; ex.printStackTrace(); } returnresult; }
所有的快捷方式Intent如果不是之前版本的存在很大問題,絕對不要改變參數,否則升級或者降級時快捷方式會出現問題;
同時,盡可能的采用隱式調用,自定義CATEGORY,而不是自定義ACTION,ACTION參數一定要為ACTION_MAIN,否則有些手機在卸載時無法刪除快捷方式(WTF)。
一、概述現在app中,圖片預覽功能肯定是少不了的,用戶基本已經形成條件反射,看到小圖,點擊看大圖,看到大圖兩個手指開始進行放大,放大後,開始移動到指定部位~~~我相信看圖
創建服務器端的步驟:1,指定端口實例化一個ServerSocket2,調用ServerSocket的accept方法等待連接期間阻塞3,獲取位於底層的Socket流進行讀
這個問題本身不難,但是由於項目中的需求太過於復雜,結果導致這個問題變得不是那麼容易實現。在網上一搜,結果如下:int scrollPos = refreshListVie
好了,跟隨潮流,還是先看下效果,不然可能都沒人想看下去了(不會看到效果後不想看了吧O(∩_∩)O~)嗯,就是讓左面板在主面板的下面,所以我們自定義的控件S