androidlauncher源碼
Ⅰ 有沒有人分享一下修改launcher的歷程
我自己總結的,ubuntu和windows下幾種不同的修改Launcher的方法:
總共有三大類:
#################
第一類,改簽名:
#################
前面幾個步驟ubuntu和windows通用:
=====================================================================================================
1 eclipse中新建android project,選擇create project from existing source,去android源碼目錄下的packages/apps下找到相應的文件夾。(直接修改的是源碼,所以需要先打包備份一下)然後選擇build target之後finish,可能會等待一段時間。
2 導入完成後,src全是錯誤,由於在Android源碼中,很多方法、成員、類、包都被打上@hide標簽,這些成員在SDK中沒有公開,以至於在編譯Launcher源碼時最常遇到的類android.view.View的成員mScrollX無法訪問。
。以Launcher2為例,我們用到的有:(生成的包的路徑為out/target/common/obj/java_LIBRARIES)
1)framework_intermediates/classes.jar :這個主要是android的框架類
2)android-common_intermediates/classes.jar :這個包含com.android.common.Search這個類
3)core_intermediates/classes.jar :這個包包含dalvik.system.VMRuntime這個類
右鍵工程名稱然後選擇Build Path->Configure Build Path...->Libraries->Add Library->User Library->User Libraries...->New...
然後將上面3個依賴的包一個個的加入進來,分別命名為android_framework,android_common,android_core.
將3個包加入進來後,然後還需要將它們放到android2.3.3這個包的前面,可以在Build Path配置中選擇Order and Export
這時候就會發現Launcher2工程以及沒有錯誤了,也可以編譯了。(其他的模塊可能需要別的jar包,都在out/target/common/obj/JAVA_LIBRARIES下能找到).
=====================================================================================================
然後:
===================================================================================================
windows環境下:工程現在是不能直接運行的,因為eclipse默認的debug簽名跟模擬器中的系統簽名不相符合。因此,因此,需要手動簽名。
3 用eclipse導出沒有簽名的版本,右鍵工程,android tools->export unsigned application package,得到未簽名的apk包。
4 在build\target\proct\security下都是一些公鑰和密鑰,system版本的公鑰和密鑰是platform.pk8和platform.x509.pem兩個文件,shared版本的公鑰和密鑰是shared.pk8和shared.x509.pem兩個文件。模塊應用是什麼版本的可以查看AndroidManifest.xml文件,android:sharedUserId="android.uid.system" 表示是system版android:sharedUserId="android.uid.shared"是shared版。除了公鑰密鑰之外,還需要簽名的包即signapk.jar,它在out/host/linux-x86/framework下。
5 將這些工具准備好後,就能打出簽名包了。比如我的為簽名apk是Launcher.apk並且是shared版本。因此java -jar signapk.jar share.x509.pem shared.pk8 Launcher.apk Launcher-signed.apk(system版本就用platform.pk8和platform.x509.pem相應的替換一下)
6 得到了簽名包之後,adb install -r Lancher-signed.apk就行了,直接替換掉原來的Launcher。
=====================================================================================================
ubuntu環境下:利用android源碼提供的工具自動簽名
3 編譯源碼
4 gedit .bashrc 最後面添加
export PATH=$PATH:/home/xxx/android/out/host/linux-x86/bin
export ANDROID_PRODUCT_OUT=/home/xxx/android/out/target/proct/generic
其中的/home/xxx/android是源碼目錄
5 然後啟動模擬器,命令為emulator
6 在eclipse中修改好源碼模塊比如Launcher2之後,將工程放到android源碼目錄下的packages/apps下,刪除掉自動生成的一些文件,比如bin,assets,gen等等。跟其他模塊文件保持一致。
7 android源碼目錄下執行 . build/envsetup.sh 這個時候多出mm,mmm等命令,進入修改過後的那個模塊目錄下,比如packages/apps/Launcher2/下,執行mm,會自動生成已經簽名過的apk文件,放在out/target/proct/generic/system/app下。
8直接adb install -r out/target/proct/generic/system/app/Launcher2.apk即可。
=====================================================================================================
注意:以上的簽名跟源碼相關,如果源碼只是generic的也就是模擬器版,那麼編譯出來的也只能在模擬器上跑,若要在真機上跑,則需要真機的簽名庫,可惜沒有- -,所以需要:
##################
第二類,改包名。
##################
照常理說,應該很簡單,直接在src下的包上F2,然後修改。但是我的機器這個eclipse很奇怪,總有各種問題,現在總結下:
1.導入工程,備份一下AndroidManifest.xml,原因下面有。F2修改包名,修改的時候下面四個選項都選上。
2.修改AndroidManifest.xml
將備份的AndroidManifest.xml換回來,然後ctrl+f,替換全部的原來包名為你現在的,比如之前是com.android.launcher2,現在換成com.pqrs.launcherEx。然後將android:sharedUserId="XXX"這句話刪掉。(這么做的原因是,在第一步中可能已經自動的替換了一些這個xml文件的東西,但是我這eclipse亂七八糟的,缺字或者其他什麼的,此時文件已經損壞了。所以第一步之前,需要備份一下AndroidManifest.xml,在這個步驟中替換回來,然後ctrl+f進行替換。)
3.保存後會有提示,說這個文件變化了,是否作出其他變更,點擊yes。然後res下可能會有一些錯誤,打開那些xml文件,一般都是有些資源引用還是之前的com.android.launcher2,相應的都該成com.pqrs.launcherEx.
比如<favorites xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher2">改為<favorites xmlns:launcher="http://schemas.android.com/apk/res/com.pqrs.launcherEx">
4.由於AndroidManifest.xml中的包名改了,gen目錄下的自動生成文件也會跟著變化,但是src下的java文件引用的R文件路徑還沒便過來,還需要更正過來。方法:包名上ctrl+h,選擇file search,在Containing text下輸入之前的import語句,比如是import com.android.launcher2.R;在File name patterns:中填入*.java(表示搜索java文件)scope下選擇Selected resources,然後點擊Replace進行全局替換。
5.如果都順利的話,現在這就是一個新的工程了,直接在eclipse中修改運行即可,而且不限操作系統。
====================================================================================================
#############################################
第三類,網上流傳的,最傳統的方法,只限於ubuntu下。
##############################################
1、建立基本的Android開發環境
請參考官方文檔或<<Android模擬器在Ubuntu8.10的安裝>>
2、編譯Android源碼
Android源碼根目錄下通過make進行編譯,請注意一些配置,具體可參考<<android源碼的編譯>>
3、把eclipse工程配置文件復制到Android源碼根目錄下
cp development/ide/eclipse/.classpath ./
chmod u+w .classpath # Make the writable
4、修改eclipse程序的配置
1)、增大eclipse內存設置
把eclipse.ini(在eclipse軟體的安裝目錄下)的3個值改為下面的值:
-Xms128m
-Xmx512m
-XX:MaxPermSize=256m
2)、把Android-formatting.xml和android.importorder導入eclipse(可選)
Android-formatting.xml、.classpath和android.importorder都放在development/ide/eclipse/下
Android-formatting.xml用來配置eclipse編輯器的代碼風格;android.importorder用來配置eclipse的import的順序和結構。
在window->preferences->java->Code style->Formatter中導入Android-formatting.xml
在window->preferences->java->Code style->Organize Imports中導入Android.importorder
3)、安裝anyedit插件(可選)
在http://andrei.gmxhome.de/anyedit/下載並導入eclipse中
5、把Android源碼作為一個工程導入eclipse
導入前先檢查.classpath里的文件在Android源碼中是否有相應的文件(文件夾),否則也會破壞android源碼(一般是多添加文件/文件夾),.classpath里多餘的路徑可刪除
新建Java Project(不是Android project,否則會破壞android源碼),www.linuxidc.com選擇從已存在的工程導入,工程名任意,完成。
導入時,eclipse要build工程,比較慢。導完後,一般都沒有錯誤。
這里也就回答了第4個問題
6、eclipse上調試Android里的程序。
為了不讓其它版本的Android工具和android文件系統影響下面的編譯和調試,需要從環境變數中去除android工具和android文件系統的路徑:
vim ~/.bashrc
看看有沒有在PATH變數中加入Android工具和android文件系統的路徑,如果加有,則注釋它。通過下面的方法,我們是不需要在.bashrc中添加android工具和android文件系統的路徑的
執行:
cd Android源碼目錄
. build/envsetup.sh #設了環境變數之後,會多出mmm等命令,可以通過輸入help來查看
lunch 1 # 把emulator等工具和ramdisk.img等文件的路徑對應起來,就可以直接調用emulator等工具,也解決了第3個問題
emulator &
ddms &
注意,先啟動ddms,再啟動eclipse,這樣eclipse中就不會說埠沖突
然後在eclipse中配置調試類型和埠:
在Run->Debug Configurations->Remote java application上雙擊,然後,」Host:」設為localhost,」Port:」設為8800,」Connection Type」為Standard(Socket Attach)
然後「Apply」
注意,上面設置的埠要與DDMS中設置的埠一致,ADT插件使用了8700埠,因此上面設置的埠是8800。如果出現連不到VM的錯誤時,請注意,要先在DDMS中選中某一進程(對應某一應用程序),才能在eclipse執行 Debug。
在eclipse調試時,可以設斷點、單步調試。估計google團隊也是這樣開發、調試Android應用程序的
7、編譯Android源碼
執行:
cd Android源碼目錄
. build/envsetup.sh
那 么就會多出mm/mmm等命令,mm/mmm用來編譯模塊(包括C、C++、JAVA程序)。我們也可以直接在 Android源碼根目錄下執行「make 模塊名」來編譯模塊(模塊名可以在.mk文件中找到)。模塊編譯後會在out/target/proct/generic/system/app下生 成對應的.apk包。但是,用mm/mmm來編譯生成的.apk並不會打包到system.img中,需要我們手動通過make snod把 system文件夾打包為system.img,不過這就得重新運行模擬器了,這也是很麻煩了。對於我們開發者來說,我們可以這樣做:
1)把需要修改、調試的模塊(比如AlarmClock.apk)從/system/app下移除,然後make snod,這樣system.img就沒有AlarmClock.apk了。
2)運行模擬器,就看不到AlarmClock了
3)修改AlarmClock源碼並用mm/mmm來編譯,在/system/app下生成AlarmClock.apk
4)通過adb把AlarmClock.apk安裝到Android文件系統中,安裝方法有兩個:
A、通過adb install xxx/AlarmClock.apk
B、通過adb push xxx/AlarmClock.apk /data/app
兩 種方法都可以把 AlarmClock安裝到/data/app下,Android會自動把它顯示在主菜單中(只要AlarmClock.apk中有一Activity包 含android.intent.category.LAUNCHER屬性),不過A方法在/data/app生成 com.android.alarmclock.apk,B方法則是 AlarmClock.apk。用A方法時,如果原來已經安裝了 AlarmClock,你還得先adb uninstall 它,而B方法則不用。推薦使用B方法。同樣,卸載可以通過adb uninstall或adb shell rm xxx/xxx.apk來,也推薦用刪除的方法來卸載
Ⅱ android launcher源碼怎麼用
在前面一篇文章中,我們分析了Android系統在啟動時安裝應用程序的過程,這些應用程序安裝好之後,還需要有一個Home應用程序來負責把它們在桌面上展示出來,在Android系統中,這個默認的Home應用程序就是Launcher了,本文將詳細分析Launcher應用程序的啟動過程。
Android系統的Home應用程序Launcher是由ActivityManagerService啟動的,而ActivityManagerService和PackageManagerService一樣,都是在開機時由SystemServer組件啟動的,SystemServer組件首先是啟動ePackageManagerServic,由它來負責安裝系統的應用程序,具體可以參考前面一篇文章Android應用程序安裝過程源代碼分析,系統中的應用程序安裝好了以後,SystemServer組件接下來就要通過ActivityManagerService來啟動Home應用程序Launcher了,Launcher在啟動的時候便會通過PackageManagerServic把系統中已經安裝好的應用程序以快捷圖標的形式展示在桌面上,這樣用戶就可以使用這些應用程序
Ⅲ Android源碼環境編譯出來的apk 怎麼安裝到手機上去
如果手機上已經有包名一樣的apk是安裝不上去的吧,如果可以用adb remount 再push到system/app替換原來的launcher試試
Ⅳ Android的Launcher3源碼中,FocusIndicatorView有什麼作用
1、Launcher進程啟動過程可以由下面圖看到Launcher進程是如何被創建啟動:ActivityManager通過發送Intend來啟動Launcher。Intentintent=newIntent(mTopAction,mTopData!=null?Uri.parse(mTopData):null);intent.setComponent(mTopComponent);if(mFactoryTest!=SystemServer.FACTORY_TEST_LOW_LEVEL){intent.addCategory(Intent.CATEGORY_HOME);}startActivityLocked(null,intent,null,null,0,aInfo,null,null,0,0,0,false,false);復制代碼因此,如果你要開機啟動一個替換Launcher的程序,只要在程序裡面加入action.MAIN、category.HOME、category.DEFAULT就可以。如果出現多個程序都加入這種intent,系統會彈出讓你選擇哪個作為啟動器。2、Launcher初始化——LauncherApplication。Application類,我想大部分做Android應用的朋友都用過,每個Android應用默認都有一個Application類,你也可以繼承Application類,然後加入自己代碼。Application是一個全局的應用類,在AndroidManifest.xml我們也可以找到Application標簽。復制代碼Android四大組件的聲明都需要放到application標簽裡面,默認使用的是系統的Application類,如果你在項目裡面重載了它。就需要在標簽,name屬性下寫上你的新的Application類名。Launcher裡面就是繼承了Application為LauncherApplication。應用啟動的時候首先會載入Application。我們可以看到Launcher主類Launcher.java的onCreate函數裡面,第一個就是獲取Application的實例。LauncherApplicationapp=((LauncherApplication)getApplication());復制代碼接下來我們看看LauncherApplication裡面初始化,LauncherApplication大部分工作就是在初始化完成,剩下都是一些返回介面。@OverridepublicvoidonCreate(){super.onCreate();//獲取屏幕大小,主要用來區分手機還是平板finalintscreenSize=getResources().getConfiguration().screenLayout&Configuration.SCREENLAYOUT_SIZE_MASK;sIsScreenLarge=screenSize==Configuration.SCREENLAYOUT_SIZE_LARGE||screenSize==Configuration.SCREENLAYOUT_SIZE_XLARGE;//屏幕密度sScreenDensity=getResources().getDisplayMetrics().density;//IconCahe裡面保存了界面所有應用圖標的繪畫需要的數據,這個到時候具體分析再說。//加入這東西的主要原因是為了提高繪畫界面的效率mIconCache=newIconCache(this);//資料庫載入類,LauncherModel是Launcher裡面非常重要的一個類,相當於MVC模式裡面的//Model功能,管理數據和初始化數據mModel=newLauncherModel(this,mIconCache);//下面注冊了一些監聽器,主要包含APK文件更新刪除等數據變化的時候接收的通知//接收通知後,主要是用來更新Launcher裡面的資料庫。因為桌面應用圖標數據,只會載入一次IntentFilterfilter=newIntentFilter(Intent.ACTION_PACKAGE_ADDED);filter.addAction(Intent.ACTION_PACKAGE_REMOVED);filter.addAction(Intent.ACTION_PACKAGE_CHANGED);filter.addDataScheme("package");registerReceiver(mModel,filter);filter=newIntentFilter();filter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);filter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);filter.addAction(Intent.ACTION_LOCALE_CHANGED);filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);registerReceiver(mModel,filter);filter=newIntentFilter();filter.addAction(SearchManager.INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED);registerReceiver(mModel,filter);filter=newIntentFilter();filter.addAction(SearchManager.INTENT_ACTION_SEARCHABLES_CHANGED);registerReceiver(mModel,filter);//contentresolver則是用於管理所有程序的contentprovider實例ContentResolverresolver=getContentResolver();//注冊內容觀察者,監聽application資料庫變化,回調resolver.registerContentObserver(LauncherSettings.Favorites.CONTENT_URI,true,mFavoritesObserver);}復制代碼上面是LauncherApplication最主要的工作,初始化整個Launcher的一些關鍵類,和注冊一些監聽器。主要都是用來監聽應用的安裝更新刪除等導致Launcher資料庫變化的操作。Launcher數據都是使用contentprovider來提供數據。其中注冊的監聽介面是=newContentObserver(newHandler()){@OverridepublicvoidonChange(booleanselfChange){//重新載入界面數據mModel.startLoader(LauncherApplication.this,false);}};復制代碼LauncherSettings.Favorites.CONTENT_URI裡面數據發生變化的時候,都會調用mModel.startLoader()介面,重新載入Launcher的數據。startLoader的具體操作,我後面分析LauncherModel類的時候會分析。這一塊涉及Launcher所有數據載入。剩下的接都是返回初始化時候創建的對象或者獲取屏幕密度、獲取是否大屏幕。後面很多處理都需要判斷是否是大屏幕,4.0以後手機平板都共用一套系統,導致多了很多處理。3、Launcher.java初始化Launcher.java是Launcher裡面最主要的類,是一個Activity。啟動的第一個組件。既然是Activity,我們要分析它初始化,毫無疑問,需要找到onCreate()裡面分析。把主要一些分析用注釋方式寫在代碼裡面,這樣比較方便閱讀。
Ⅳ android Launcher的滑動效果怎麼實現
滑動功能主要分兩步:
1、在onInterceptTouchEvent中進行攔截。
2、在onTouchEvent中進行滑動。
1,onInterceptTouchEvent(MotionEvent en)
在這個方法中,決定了什麼時候截獲MotionEvent來實現滑動,避免了子View的其他事件的影響(如點擊事件)。
[java] view plain
public boolean onInterceptTouchEvent(MotionEvent ev) {
/**
* This method JUST determines whether we want to intercept the motion.
* If we return true, onTouchEvent will be called and we do the actual
* scrolling there.
**/
//獲取速度跟蹤器,記錄各個時刻的速度。並且添加當前的MotionEvent以記錄更行速度值。
(ev);
......
/**
* Shortcut the most recurring case: the user is in the dragging
* state and he is moving his finger. We want to intercept this
* motion.
* 最常見的需要攔截的情況:用戶已經進入滑動狀態,並且正在滑動手指。
* 對這種情況直接進行攔截,執行onTouchEvent()繼續執行滑動操作。
**/
final int action = ev.getAction();
if ((action == MotionEvent.ACTION_MOVE) &&
(mTouchState == TOUCH_STATE_SCROLLING)) {
return true;
}
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_MOVE: {
/**
* mIsBeingDragged == false, otherwise the shortcut would have caught it. Check
* whether the user has moved far enough from his original down touch.
*/
/**
* 當在這里接受到ACTION_MOVE時,說明mTouchState!=TOUCH_STATE_SCROLLING並且mIsBeingDragged的值應該為false,
* 否則DragLayer就應該截獲了MotionEvent用於實現拖拽。
* 此時還沒有進入滑動狀態,當mActivePointerId == INVALID_POINTER時,也就是在此之前沒有接收到任何touch事件。
* 這種情況發生在Workspace變小時,也就是之前Workspace處於SPRING_LOADED狀態。當出現這種情況時直接把當前的事件當作ACTION_DOWN進行處理。
* 反之,則通過determineScrollingStart()嘗試能夠進入滑動狀態。
*/
if (mActivePointerId != INVALID_POINTER) {
determineScrollingStart(ev);
break;
}
// if mActivePointerId is INVALID_POINTER, then we must have missed an ACTION_DOWN
// event. in that case, treat the first occurence of a move event as a ACTION_DOWN
// i.e. fall through to the next case (don't break)
// (We sometimes miss ACTION_DOWN events in Workspace because it ignores all events
// while it's small- this was causing a crash before we checked for INVALID_POINTER)
}
case MotionEvent.ACTION_DOWN: {
final float x = ev.getX();
final float y = ev.getY();
// Remember location of down touch
//記錄按下的x的坐標值
mDownMotionX = x;
//記錄前次發生touch時的坐標
mLastMotionX = x;
mLastMotionY = y;
//因為在ScrollBy時只能使用int,而記錄的x和y都是float,會產生誤差,故這里用mLastMotionXRemainder記錄余數
//用於消除誤差
mLastMotionXRemainder = 0;
//x方向上的總位移
mTotalMotionX = 0;
mActivePointerId = ev.getPointerId(0);
//設置mAllowLongPress=true,允許LongClick事件發生。LongClick事件定義在Launcher中
//處理的內容包括啟動對shortcut的拖拽或彈出壁紙選擇的對話框,若mAllowLongPress=false,
//則不會響應以上事件。
mAllowLongPress = true;
/**
* If being flinged and user touches the screen, initiate drag;
* otherwise don't. mScroller.isFinished should be false when
* being flinged.
* 當屏幕處於flinged狀態(快速滑動)時,若此時用戶觸摸了屏幕,需要使滑動停止。
* 並且初始化拖拽的條件
**/
final int xDist = Math.abs(mScroller.getFinalX() - mScroller.getCurrX());
final boolean finishedScrolling = (mScroller.isFinished() || xDist < mTouchSlop);
if (finishedScrolling) {
mTouchState = TOUCH_STATE_REST;
mScroller.abortAnimation();
} else {
mTouchState = TOUCH_STATE_SCROLLING;
}
// check if this can be the beginning of a tap on the side of the pages
// to scroll the current page
if (mTouchState != TOUCH_STATE_PREV_PAGE && mTouchState != TOUCH_STATE_NEXT_PAGE) {
if (getChildCount() > 0) {
if (hitsPreviousPage(x, y)) {
mTouchState = TOUCH_STATE_PREV_PAGE;
} else if (hitsNextPage(x, y)) {
mTouchState = TOUCH_STATE_NEXT_PAGE;
}
}
}
break;
}
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
mTouchState = TOUCH_STATE_REST;
mAllowLongPress = false;
mActivePointerId = INVALID_POINTER;
releaseVelocityTracker();
break;
case MotionEvent.ACTION_POINTER_UP:
onSecondaryPointerUp(ev);
releaseVelocityTracker();
break;
}
/**
* The only time we want to intercept motion events is if we are in the
* drag mode.
* 只有進入了滑動狀態,才進行攔截,進入onTouchEvent執行滑動操作。當mTouchState != TOUCH_STATE_REST
* 時,就說明沒有進入滑動狀態。
**/
return mTouchState != TOUCH_STATE_REST;
}
2,onTouchEvent(MotionEvent en)
在這個方法中,執行各種關於滑動的工作的計算,界面的刷新等工作。
[java] view plain
public boolean onTouchEvent(MotionEvent ev) {
......
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
/*
* If being flinged and user touches, stop the fling. isFinished
* will be false if being flinged.
*/
/**
* 如果Workspace此時已經被「擲出去」(靠慣性滑動)。
* 此時發生ACTION_DOWN則需要停止滑動。
*/
if (!mScroller.isFinished()) {
mScroller.abortAnimation();
}
// Remember where the motion event started
mDownMotionX = mLastMotionX = ev.getX();
mLastMotionXRemainder = 0;
mTotalMotionX = 0;
mActivePointerId = ev.getPointerId(0);
if (mTouchState == TOUCH_STATE_SCROLLING) {
pageBeginMoving();
}
break;
case MotionEvent.ACTION_MOVE:
if (mTouchState == TOUCH_STATE_SCROLLING) {
......
if (Math.abs(deltaX) >= 1.0f) {
......
if (!mDeferScrollUpdate) {
//調用scrollBy滑動桌面
scrollBy((int) deltaX, 0);
......
} else {
......
}
mLastMotionX = x;
mLastMotionXRemainder = deltaX - (int) deltaX;
} else {
awakenScrollBars();
}
} else {
/**
* 如果條件滿足,則進入滑動狀態,開始滑動。
*/
determineScrollingStart(ev);
}
break;
case MotionEvent.ACTION_UP:
if (mTouchState == TOUCH_STATE_SCROLLING) {
......
boolean isSignificantMove = Math.abs(deltaX) > MIN_LENGTH_FOR_MOVE;
boolean returnToOriginalPage = false;
final int pageWidth = getScaledMeasuredWidth(getPageAt(mCurrentPage));
if (Math.abs(deltaX) > pageWidth * RETURN_TO_ORIGINAL_PAGE_THRESHOLD &&
Math.signum(velocityX) != Math.signum(deltaX)) {
returnToOriginalPage = true;
}
boolean isFling = mTotalMotionX > MIN_LENGTH_FOR_FLING &&
Math.abs(velocityX) > snapVelocity;
int finalPage;
//判斷拿起手指之後應該進入哪個分屏
if (((isSignificantMove && deltaX > 0 && !isFling) ||
(isFling && velocityX > 0)) && mCurrentPage > 0) {
finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage - 1;
snapToPageWithVelocity(finalPage, velocityX);
} else if (((isSignificantMove && deltaX < 0 && !isFling) ||
(isFling && velocityX < 0)) &&
mCurrentPage < getChildCount() - 1) {
finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage + 1;
snapToPageWithVelocity(finalPage, velocityX);
} else {
snapToDestination();
}
} else if (mTouchState == TOUCH_STATE_PREV_PAGE) {
//直接進入前一屏
int nextPage = Math.max(0, mCurrentPage - 1);
if (nextPage != mCurrentPage) {
snapToPage(nextPage);
} else {
snapToDestination();
}
} else if (mTouchState == TOUCH_STATE_NEXT_PAGE) {
//直接進入後一屏
int nextPage = Math.min(getChildCount() - 1, mCurrentPage + 1);
if (nextPage != mCurrentPage) {
snapToPage(nextPage);
} else {
snapToDestination();
}
} else {
onUnhandledTap(ev);
}
mTouchState = TOUCH_STATE_REST;
mActivePointerId = INVALID_POINTER;
releaseVelocityTracker();
break;
case MotionEvent.ACTION_CANCEL:
if (mTouchState == TOUCH_STATE_SCROLLING) {
snapToDestination();
}
mTouchState = TOUCH_STATE_REST;
mActivePointerId = INVALID_POINTER;
releaseVelocityTracker();
break;
case MotionEvent.ACTION_POINTER_UP:
onSecondaryPointerUp(ev);
break;
}
return true;
}
Ⅵ 怎樣查看 Android APP 源代碼
用壓縮軟體打開apk文件,解壓出根目錄中的classes.dex文件
使用cmd ,dex2jar.bat classes.dex命令將classes.dex轉換為jar
再用jd-gui打開該jar就可以查看源碼了,如果apk安全性好的話,有些代碼是看不到的
Ⅶ Android4.0 怎麼在launcher2 源碼中添加快捷鍵
薩斯
Ⅷ 如何編譯android launcher
注意前提條件是具備下面事項,需要系統級別的許可權
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.rtkj.switchlauncher"
android:sharedUserId="android.uid.systemui"
<uses-permission android:name="android.permission.SET_PREFERRED_APPLICATIONS" />
可以導出Apk文件放到系統的system/app目錄下面去編譯
第一種方式 : 清理Launcher的默認設置的 默認值相當於在設置->應用程序->管理應用程序->所有應用程序列表,找到之前設置的
默認Launcher,並取消了默認值,系統會重新彈出launcher選擇框。
private void clearDefaultValues(String packageName) {
getPackageManager().(packageName);
}
第二種方式: 通過pm進行 清理 後添加 或者是替換當前的 ,這里顯示的是兩個Launcher的替換
view plain
private void setDefaultHome(String packeageName ,String className,String oldPackage,String oldName) {
PackageManager pm = getPackageManager();
IntentFilter f = new IntentFilter();
f.addAction(Intent.ACTION_MAIN);
f.addCategory(Intent.CATEGORY_HOME);
f.addCategory(Intent.CATEGORY_DEFAULT);
ComponentName component = new ComponentName(packeageName,className );
ComponentName[] components = new ComponentName[] {new ComponentName(oldPackage,oldName),component};
<span style="color:#FF0000;">pm.(oldPackage);</span>// 清理配置的默認信息
pm.addPreferredActivity(f, IntentFilter.MATCH_CATEGORY_EMPTY, components, component);//添加
<span style="color:#FF0000;">//pm.replacePreferredActivity(f, IntentFilter.MATCH_CATEGORY_EMPTY, components, component);</span> //替換
}
view plain
//存在多個以上的Launcher的時候
private void setDefaultLauncher() {
// remove this activity from the package manager.
PackageManager pm = getPackageManager();
String examplePackageName = "com.jeejen.family"; //請修改為需要設置的 package name
String exampleActivityName = "com.jeejen.home.launcher.Launcher"; //請修改為需要設置的 launcher activity name
ComponentName defaultLauncher = null;
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
List<ResolveInfo> resolveInfoList =
pm.queryIntentActivities(intent, 0);
if (resolveInfoList != null) {
int size = resolveInfoList.size();
for (int j = 0; j < size; ) {
final ResolveInfo r = resolveInfoList.get(j);
if (!r.activityInfo.packageName.equals(examplePackageName)) {
resolveInfoList.remove(j);
size -= 1;
} else {
j++;
}
}
ComponentName[] set = new ComponentName[size];
defaultLauncher = new ComponentName(examplePackageName, exampleActivityName);
int defaultMatch = 0;
for (int i = 0; i < size; i++) {
final ResolveInfo resolveInfo =
resolveInfoList.get(i);
set[i] = new ComponentName(resolveInfo.activityInfo.packageName, resolveInfo.activityInfo.name);
if (defaultLauncher.getClassName().equals(resolveInfo.activityInfo.name)) {
defaultMatch = resolveInfo.match;
}
}
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_MAIN);
filter.addCategory(Intent.CATEGORY_HOME);
filter.addCategory(Intent.CATEGORY_DEFAULT);
pm.(defaultLauncher.getPackageName());
pm.addPreferredActivity(filter, defaultMatch, set, defaultLauncher);
}
}
切換後啟動當前的Launcher,
view plain
public void startMainLauncher(){
Intent startMain = new Intent(Intent.ACTION_MAIN);
startMain.addCategory(Intent.CATEGORY_HOME);
startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(startMain);
}
Ⅸ 請教關於make/編譯android源碼中的Launcher2出現錯誤/error41
其實這個問題我也遇到了,不過樓上的方法雖然能解決問題,但是各位有木有相關想過一個問題:每次都要刪除不閑麻煩嗎?為什麼packages/apps/下面的應用我們導入到Eclipse里,一樣的生成了R.java文件,為什麼能夠順利的編譯通過?我覺得:弄清楚了這個問題才算是徹底的解決了樓主提出的問題。