Preface
這篇文件會描述如何撰寫 Home 切換器,並解剖相關 API 的用法。
程式碼懶得重構了 orz,我直接放到github,有興趣的人可以去看看,網址如下:
https://github.com/WTCho/HomeSelector
Home App and Switcher thereof
有玩Android系統手機的人應該都有使用過
Android Launcher 之類的應用程式,它是用於變換桌面環境或操作的應用程式,或可以說是變更使用者經驗 (UX)
的程式。在命名上我個人是比較偏好稱作 Home App,因為它是按下 Home 鍵切換或執行的程式,而且它也是跑在 home screen 的桌面程式;而 Launcher 的狹定義是來自 Android 官方預設的 Home app,即 Launcher.apk。我自己下載 Android source Froyo,裡面預設是 Launcher2.apk (com.android.launcher2),位於 {SourceDir}/packages/apps 下。
Activity 可以在 AndroidManifest.xml 中註冊啟動器,啟動器也就是 launcher,它不代表是 Launcher.apk 或任何一種 Home App,而是指應用程式進入口會顯示在 Home App (或 Launcher)上。而 Home App 一般來說都沒有註冊啟動器,因此有人就寫了偵測系統中所有 Home App 的程式,也就是 Home App Switcher。比較好的
Swicher 還會提供清除和設定 default Home App。我在 HTC Incredible S 中安裝了數種 Home App,即Launcher7、ADW、Zeam、Regina、LauncherPro、Home
Sample、Home++,當然預設的
HTC Sense 也有。其中只有 Zeam 是有註冊 launcher 分類,所以在應用程式選單上就能找得到。
Intent and Intent Filters
在 Android 系統中,Intent是極為重要,也是最基本要知道的東西。對於系統而言,Intent
就像是應用程式的描述,也類似標籤的概念。根據 Intent 內容,系統或應用程式能夠去使用與搜尋其他應用程式與其提供的服務。Intent 資訊是註冊在程式的 AndroidManifest.xml,並包含在 Intent Filters 標籤的內容中。當搜尋系統中的應用程式時,會去比對應用程式的 Intent Filters,而搜尋條件是包裝在 Intent 物件中以找到符合某種條件程式。Intent Filters 的內容就像是應用程式的索引,內容比對成功就會回傳相對應的ResolveInfo。有關
Intent 的詳細內容可以參考底下提供的官方網頁連結[1]。
一個 Activity 基本上要在 AndroidManifest.xml 的 intent-filter 中註冊一個 action 和 category; action預設是 intent.ACTION_MAIN,而 category 預設是 intent.CATEGORY_LAUNCHER。根據官方網站說明,ACTION_MAIN 指該 Activity 是個可開始啟動的進入點;CATEGORY_LAUNCHER 指該 Activity 在 Home App 上有啟動器,也就是在應用程式選單上會出現該 Activity
的 icon,以方便執行。註冊內容如下:
<activityandroid:name=".HomeSelector"android:label="@string/app_name">
<intent-filter>
<actionandroid:name="android.intent.action.MAIN"/>
<categoryandroid:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
一個應用程式中,可以有多個 Activity 都註冊 CATEGORY_LAUNCHER,那在安裝完後就會有多個 icon 出現在程式選單上,分別能執行各個 Activity。如果 Activity 沒有註冊 CATEGORY_LAUNCHER,那至少要註冊 CATEGORY_DEFAULT,因為它是系統使用 Intent 搜尋的預設條件之一。註冊 CATEGORY_DEFAULT 後該 Activity
不會有 icon 在應用程式選單上出現,所以一般都是給非 ACTION_MAIN 的 Activity 註冊,如 intent.ACTION_VIEW 之類的。如果 Activity 只註冊 action,一般預設 Intent 的搜尋可能會失效,那就需要使用顯形式啟動,以上面的例子來看,就是指定啟動 HomeSelector,例子如下:
1
|
Intent
i = new Intent( this ,
HomeSelector. class );
|
如果是指定啟動外部程式,那可以按照下面的做法:
1
|
Intent
myIntent = new Intent();
|
2
|
myIntent.setClassName( "com.KaDaNet" , "com.KaDaNet.KaDaNet_MainController" );
|
3
|
startActivity(myIntent);
|
那隱含式搜尋呢?如果你有 Android SDK 有研究,那你應該看過 SDK 中的 sample code,其中的API
Demo展示了許多使用 API 功能的 Activity,而 API Demo 是由階層式列表對這些 Activity 分類。這個階層式列表的內容是動態生成出來的,由 loadLabel 和 activityInfo.name 去分類。因為是動態生成,所以就不會把列表寫死,那所有列表上要顯示的 Activity 資訊,就是利用隱含式搜尋獲得,程式碼如下:
1
|
Intent
mainIntent = new Intent(Intent.ACTION_MAIN, null );
|
2
|
mainIntent.addCategory(Intent.CATEGORY_SAMPLE_CODE);
|
3
|
PackageManager
pm = getPackageManager();
|
4
|
List<resolveinfo>
list = pm.queryIntentActivities(mainIntent, 0 );
|
API Demo 只顯示 category 註冊為 CATEGORY_SAMPLE_CODE 的 Activity 的資訊。把條件塞進 Intent 後利用 queryIntentActivities 搜尋,其中的一個 Activity 註冊內容如下:
<activityandroid:name=".app.CustomDialogActivity"
android:label="@string/activity_custom_dialog"
android:theme="@style/Theme.CustomDialog">
<intent-filter>
<actionandroid:name="android.intent.action.MAIN"/>
<categoryandroid:name="android.intent.category.SAMPLE_CODE"/>
</intent-filter>
</activity>
Home App and Intent Filters
在 Android 中,Home App 需要告訴系統自己是一個 Home App,那它才會以 Home 的方式去執行,也就是跑在 home screen 上。同樣的,Home App 透過在 AndroidManifest.xml 上註冊 category 為 intent.CATEGORY_HOME 就可以了。以 SDK sample 中的Home為例,其註冊內容如下:
<activityandroid:name="Home"android:theme="@style/Theme"
android:launchMode="singleInstance"
android:stateNotNeeded="true">
<intent-filter>
<actionandroid:name="android.intent.action.MAIN"/>
<categoryandroid:name="android.intent.category.HOME"/>
<categoryandroid:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
搜尋 Home App 的做法與 API Demo 相同,使用PackageManager中的
queryIntentActivities 即可。在下面範例中,對搜尋到的結果取出我們想要的資訊包裝成 HomeInfo,並回傳 List。
01
|
private List<homeinfo>
queryHomeApp() {
|
02
|
Intent
mainIntent = new Intent(Intent.ACTION_MAIN, null );
|
03
|
mainIntent.addCategory(Intent.CATEGORY_HOME);
|
04
|
PackageManager
pm = getPackageManager();
|
05
|
List<resolveinfo>
rList = pm.queryIntentActivities(mainIntent, 0 );
|
06
|
List<homeinfo>
homeList = new ArrayList<homeinfo>();
|
08
|
for (ResolveInfo
r : rList) {
|
09
|
homeList.add( new HomeInfo(r,
pm));
|
這裡使用 HomeInfo 類別包裝四種資訊,即類別名稱、封包名稱、Activity 標籤和 Activity icon。
03
|
public String
packageName;
|
07
|
public HomeInfo(ResolveInfo
rInfo, PackageManager pm) {
|
08
|
name
= rInfo.activityInfo.name;
|
09
|
packageName
= rInfo.activityInfo.packageName;
|
10
|
label
= rInfo.loadLabel(pm).toString();
|
11
|
icon
= rInfo.loadIcon(pm);
|
很簡單吧!這樣就能取得系統中所有的 Home App 資訊,接下來根據這些資訊來切換 Home App。切換的方式,先前也提到過了,那就是顯形式啟動!
1
|
public void switchHome(String
packageName) {
|
2
|
Intent
homeIntent = new Intent( "android.intent.action.MAIN" );
|
3
|
homeIntent.addCategory( "android.intent.category.HOME" );
|
4
|
homeIntent.addCategory( "android.intent.category.DEFAULT" );
|
5
|
homeIntent.setPackage(packageName);
|
6
|
this .startActivity(homeIntent);
|
在程式界面上顯示所有已安裝的 Home App 資訊,最簡單的方式是利用 ListView,再新建一個 list adapter 進行配接並設定 list item 按下後要處理的事,以上面的程式碼來看就是我們要處理的事,即切換到另一個 Home App。界面設定的程式碼如下,顯示畫面如Fig.
1。
01
|
ListView
lvHome = (ListView) findViewById(R.id.lvHome);
|
02
|
final HomeListAdapter
hAdapter = new HomeListAdapter( this );
|
03
|
hAdapter.addItemList(queryHomeApp());
|
04
|
lvHome.setAdapter(hAdapter);
|
05
|
lvHome.setOnItemClickListener( new AdapterView.OnItemClickListener()
{
|
07
|
public void onItemClick(AdapterView
parent, View view, int position, long id)
{
|
08
|
HomeListItem
item = (HomeListItem) hAdapter.getItem(position);
|
09
|
switchTo(item.getHomeInfo().packageName);
|
Fig.1. Home App list
Home App Management
一個較好的 Home App 切換器都會提供相關管理的功能。一般來說,基本的管理功能就是顯示資訊。除了找出系統中的所有 Home App 之外,也要能夠顯示這些 Home App 相關的資訊,當然資訊的種類要依需求而定。以 Home App 來說,可以分成未執行和執行時的資訊,也就是說使用者或許希望能看到哪些 Home App 是正在執行;如果正在執行,還有額外的資訊可以看到,像是程序相關的資料。根據這些資訊可以讓使用者決定是否要切換或是關掉
Home App。在這節中,我將介紹如何獲知該 Home App 是否正在執行,與執行時所佔用記憶體的多寡,當然也包括移除 Home App 安裝和顯示應用程式細節。
Android 中的 ActivityManager 類別[2]是用來與系統裡正在執行的程序進行互動的 API;使用這個類別,我們能拿到所有正在執行的 App,並能以特定的 package 名稱去過濾某個 App 是否正在執行,範例如下:
1
|
public boolean isAppRunning()
{
|
2
|
for (RunningAppProcessInfo
info : mAM.getRunningAppProcesses()) {
|
3
|
if (info.processName.equals(packageName)) return true ;
|
4
|
for (String
pn : info.pkgList) {
|
5
|
if (pn.equals(packageName)) return true ;
|
函式中的 mAM 即 ActivityManager,利用 getRunningAppProcesses 方法取得所有的存活 App,因為 Android 並沒有提供過濾的功能,需要自行處理;其中先比對程序名稱是因為在一般的情況下,很多 App 的程序名稱會與 package 名稱相同,所以用這種方式加速比對。如果該 Home App 的 package 名稱與程序名稱不相同,只好比對這程序中所有被載進的
package 其名稱。
接下來是取得程序所佔用的記憶體,利用 ActivityManager 中的 getProcessMemoryInfo 並餵入程序 ID 即可得到 Debug.MemoryInfo。RunningAppProcessInfo 的欄位包含程序 ID,可以透過剛剛取得的執行中 App 資料獲得。不過實際上,程序所佔用的記憶體情況挺複雜的,可以參考[3-6]。RSS 指包含整個分享函式庫。PSS
是以等比例去切割分享函式庫大小,比例分母為所有使用到該函式庫的程序數。這邊我僅以程序全部的 PSS 來估計記憶體佔用,程式碼如下:
1
|
public int getMemoryUsed(ActivityManager
am) {
|
2
|
Debug.MemoryInfo
mInfo = am.getProcessMemoryInfo( new int []{PID})[ 0 ];
|
3
|
return mInfo.getTotalPss();
|
使用者可能會根據 Home App 佔用記憶體的多寡來決定是否要停止該程序,以移出更多的空間給其他比較需要資源的軟體使用。移除程序的 API 為用 ActivityManager 類別中的killBackgroundProcesses方法,使用它需要跟系統註冊KILL_BACKGROUND_PROCESSES權限,使用方法如下,只消
package 名稱:
1
|
mAM.killBackgroundProcesses(pkgName);
|
停止某 Home App 之後,Home Selector 需要更新畫面上的 ListView,這只要通知 ListView 的資料源更新即可,Android 有提供了notifyDataSetChanged這個方便的函式。不過要注意的是這個函式只是去通知更新,也就是說
Adapter 的 getView 會重新執行一遍,如果資料綁定處理不是寫在 getView 中就不會發生資料更新,而需要在更新通知前先處理資料綁定。
2
|
hAdapter.notifyDataSetChanged();
|
剩下的移除安裝和檢視應用程式細節功能也很簡單,都是透過 Intent 去啟動系統的 Activity,特別要注意的是設定 Intent 的 flag 和目標 URI,程式碼如下:
01
|
public void startHomeInfo(Context
cont, String pkgName) {
|
02
|
Uri
homeURI = getHomeUri(pkgName);
|
03
|
Intent
i = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
homeURI);
|
04
|
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
05
|
cont.startActivity(i);
|
08
|
public void unInstallHome(Context
cont, String pkgName) {
|
09
|
Uri
homeURI = getHomeUri(pkgName);
|
10
|
Intent
i = new Intent(Intent.ACTION_DELETE,
homeURI);
|
11
|
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
12
|
cont.startActivity(i);
|
增加這節所描述到的功能,程式畫面設計修改如Fig.2和Fig.3。
Fig.2. Home App list with memory Info
Fig.3. the functionality of Home management
Default Home
當 Android 手機開機後會啟動開機預設的 Home App,想要自行修改原始碼固定住 home 可參考[11]。如果手機沒有預設 Home,則會在啟動時跳出選單給使用者選擇,而這個部份的執行流程其實就跟按下 home 鍵的效果一樣,home 鍵就是啟動預設 Home
App,在程式上只是利用 Intent 去來完成,範例如下:
1
|
Intent
homeIntent = new Intent(Intent.ACTION_MAIN);
|
2
|
homeIntent.addCategory(Intent.CATEGORY_HOME);
|
3
|
homeIntent.addCategory(Intent.CATEGORY_DEFAULT);
|
4
|
context.startActivity(homeIntent);
|
Fig.4. default home list
跳出的 Home 選單如Fig.4。除了直接啟動預設 Home 之外,還能直接跳出 Home 選單來執行,這是因為如果手機有 Home 的預設值,直接啟動預設 Home 就不會出現選單,方法如下:
1
|
Intent
homeIntent = new Intent(Intent.ACTION_MAIN);
|
2
|
homeIntent.addCategory(Intent.CATEGORY_HOME);
|
3
|
homeIntent.addCategory(Intent.CATEGORY_DEFAULT);
|
4
|
Intent
chooser = Intent.createChooser(homeIntent, "Home" );
|
5
|
context.startActivity(chooser);
|
createChooser 是種簡便的用法,事實上一般的寫法是:
1
|
Intent
chooserIntent = new Intent(Intent.ACTION_CHOOSER);
|
2
|
chooserIntent.putExtra(Intent.EXTRA_INTENT,
homeIntent);
|
3
|
context.startActivity(chooser);
|
Home App 的選單如Fig.5,與Fig.4的差別在於最下方沒有預設值項可以勾選。
Fig.5. home chooser
default home 可以用來幫助使用者來管理預設啟動的 Home App,這節會講解 default home 的搜尋、清除和設定;這邊也是比較進階的部份。
在搜尋預設的 Home App 的部份,直接使用 PackageManager 中的getPreferredActivities方法;這個
API 會丟出之前使用 addPreferredActivity 加進的 Activity,使用方式是餵入 IntentFilter和ComponentName list 即可,也能指定 package 名稱。傳回的 IntentFilter 可用於之後的過濾動作,而傳回的 ComponentName 可拿到該預設 Component 的詳細資料,看看下面是怎麼寫的就能了解:
01
|
public ComponentName
queryDefaultHome() {
|
02
|
List<intentfilter>
intentList = new ArrayList<intentfilter>();
|
03
|
List<componentname>
cnList = new ArrayList<componentname>();
|
04
|
mPM.getPreferredActivities(intentList,
cnList, null );
|
06
|
for ( int i
= 0 ;
i < cnList.size(); i++) {
|
07
|
dhIF
= intentList.get(i);
|
08
|
if (dhIF.hasAction(Intent.ACTION_MAIN)
&&
|
09
|
dhIF.hasCategory(Intent.CATEGORY_HOME)
&&
|
10
|
dhIF.hasCategory(Intent.CATEGORY_DEFAULT))
{
|
因為要檢查是否有預設 Home,所以需要做過濾的處理,也就是檢查 IntentFilter 內容。再來是設定預設 Home,這個有新舊版之分。在舊版可以直接使用addPreferredActivity完成,不過這個方法已經更改成
deprecated,在新版本的手機使用的話,會完全沒有效果。這個部份我有在 2.3.3 版測試過,真的是沒效果,一些網路上的文章是說從 Froyo 開始失效,但這個我就不確定了,可參考[8-9]的內容。依官方網頁說明[7]:
This is a protected API that should not have been available to third party applications. It is the platform's
responsibility for assigning preferred activities and this can not be directly modified. Add a new preferred activity mapping to the system. This will be used to automatically select the given activity component when Context.startActivity() finds multiple
matching activities and also matches the given filter.
在新版中想要處理預設值,需要直接啟動該Activity,這就是說直接啟動預設 Home App,這和執行按下 Home 鍵會做的事相同。直接執行 Default Home 的方式之前就提到過,可參考上文。我在 market 下載了一些的 Home App 管理程式,的確都是以這種方式進行設定;不過像是Launcher選擇器採用舊的作法,它在新版本手機中的預設
Home 功能就會失效。
依前文所描述,要設定 Default Home App,需要在原本就沒有預設值的情況下啟動預設 Home App 才會出現選單!所以清除 Default Home 就相對的重要許多。一般清除預設 Home 的方式是開啟 Home App 的應用程式細節設定,去裡面手動清除預設值,如Fig.6中最下方按鈕。
Fig.6. dropping default home
如果使用程式化的方法,直覺就是用clearPackagePreferredActivities方法;一樣是清除之前使用
addPreferredActivity 設定過的 Activity。但實際執行過發現根本不可行[10],回到官方網頁的說明,才知道僅能清除自己擁有的 package!
Remove all preferred activity mappings, previously added with addPreferredActivity(IntentFilter, int, ComponentName[],
ComponentName), from the system whose activities are implemented in the given package name.An
application can only clear its own package(s).
那其他的管理程式到底怎麼做到清除預設 Home 的功能?其實我也不知道,只好去反編譯別人的 apk,我整理後的程式碼如下:
01
|
private void removeDefaultHome(Context
cont) {
|
02
|
String
pn = HomeSelectorAct. class .getPackage().getName();
|
03
|
String
hn = MockHome. class .getName();
|
04
|
ComponentName
mhCN = new ComponentName(pn,
hn);
|
06
|
PackageManager
pm = getPackageManager();
|
07
|
pm.setComponentEnabledSetting(mhCN, 1 , 1 );
|
08
|
mHManager.switchHome(cont);
|
09
|
pm.setComponentEnabledSetting(mhCN, 0 , 1 );
|
10
|
cont.startActivity( new Intent(cont,
HomeSelectorAct. class ));
|
這段程式碼的重點在於setComponentEnabledSetting這個方法,但我敢肯定你就算看完官方網頁解釋也不得其解。後來經過我自己的操作經驗,才發現當手機安裝新的
Home App 或移除某個 Home App 後再啟動預設 Home App,系統就會自動把 Home 的預設值清除,跳出 Home App 選單,而上面這段程式就是在做相同的事。
setComponentEnabledSetting 能以程式化的方式去設定 Component 的enable,根據官方網頁說明,這個東西是用來指定該
Component 是否能讓系統初始化,它的第一個參數要餵進 ComponentName,第二個是 enable 的設定值,數值 1 代表COMPONENT_ENABLED_STATE_ENABLED。事實上,如果在
AndroidManifest.xml 設定某個元件的 enable 為 false 時,就等於它根本不能被使用。
為了完成清除預設值功能,必須在 Home App 中新增一個假的 Home App,並且讓他的 enable 值為 false。當要進行清除預設值功能時,把假 Home 的 enable 值設為 true,這就像模擬安裝了一個新的 Home App,再啟動預設 Home,此時系統就幫我們移除Home 的預設值,而在 removeDefaultHome 函式中就是做這件事。因為假 Home 並沒有實際的功能,也不希望它真的出現在
Home 選單上,所以再把它的 enable 值設為 false。最後,因為在沒有預設值的情況下啟動預設 Home,那就會跑出 Home 選單,所以必須再重新開啟 Home App Selector;要注意切換器要設定 singleTask,才不會啟動多個切換器覆蓋。設定 enable 為 false 和重新啟動選擇器的步驟可以互換也沒關係,因為都不影響清除預設值。
那你可能會覺得還要自己做一個假 Home Activity 也太麻煩,為什麼不把系統中某個 Home App 的 enable 先設定為 false,清除預設值後再恢復為 true。其實這個方法我也有試過,但後來才發現 setComponentEnabledSetting 僅能用於同一個應用程式之內,即使增加了相關的權限也沒有效果 (CHANGE_COMPONENT_ENABLED_STATE)。這個問題也挺多人遇到過,因為這個函式他不僅會去檢查權限,還會檢查
User ID,這可以參考[12-13]。在[13]中有提到取得 PackageManager 等於是獲得 PackageManagerService 的服務,在進行設定 enable 時會同時檢查權限與 uid,這在 setEnabledSetting
中完成,原始碼如下:
01
|
final int permission
= mContext.checkCallingPermission(android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
|
03
|
final boolean allowedByPermission
= (permission == PackageManager.PERMISSION_GRANTED);
|
05
|
if (!allowedByPermission&&
(uid != pkgSetting.userId)) {
|
06
|
throw new SecurityException(
|
07
|
"Permission
Denial: attempt to change component state from pid="
|
08
|
+
Binder.getCallingPid() + ",
uid="
|
09
|
+
uid + ",
package uid="
|
完整的Android原始碼可參考PackageManagerService。另外,根據官方網頁對User
ID的說明,Android 系統視每個 package 為不同的 Linux User ID:
At install time, Android gives each package a distinct Linux user ID. The identity remains constant for
the duration of the package's life on that device. On a different device, the same package may have a different UID; what matters is that each package has a distinct UID on a given device.
Because security enforcement happens at the process level, the code of any two packages can not normally run in the same process, since they need to run as different Linux users. You can use thesharedUserIdattribute
in theAndroidManifest.xml'smanifesttag
of each package to have them assigned the same user ID. By doing this, for purposes of security the two packages are then treated as being the same application, with the same user ID and file permissions. Note that in order to retain security, only two applications
signed with the same signature (and requesting the same sharedUserId) will be given the same user ID.
如果想要多個 package 之間互相操作,就需要使用 shared user id,這可參考[14-15]。完成了清除的功能後,程式還可以在預設值設定方面加強操作。當想要進行預設值設定時,要先確定目前有沒有預設值,如果有就要清除,再去執行啟動預設 Home 以打開 Home
選單,流程如下:
1
|
if (mHManager.queryDefaultHome()
!= null )
{
|
2
|
mHManager.removeDefaultHome(thisCont);
|
4
|
mHManager.switchHome(thisCont);
|
Conclusion
在這篇文章中描述了一個 Home App 整體上該有的功能,像是顯示執行訊息和預設的管理,相信內容應該能讓你容易地建立起自己的 Home 切換器。當然 market 上很多 Home 切換器還有提供 Preference Setting 和 Notification 的功能,或是在應用程式界面上有下功夫,但這些都不是與 Home 本身有關的處理,所以也不多加描述。你可以試試 market 上的各種切換器,我自己是比較偏好
Home Manager 和 HomeSmack,Home Control 也不錯。如果你都覺得不好,那你看完這篇後,可以好好考慮寫一個自己專屬的切換器!最後,來看看Fig.7,這是程式加入預設功能的樣子。
Fig.7. the complete HomeSelector
分享到:
相关推荐
里面有2个源码包,分别用两种方式获得系统所安装的应用程序,并用listview和gridview两种布局方式分别显示出来。 通过遍历List,里面的每一个ResolveInfo就是一个应用的 信息,将应用显示出来。
Windows 命令行脚本的四种获取已安装程序列表方法有: wmic命令 、powershell直接获取 、powershell读注册表、reg 命令读注册表。 本质上说、前两种方法是一样的,第三种方法不能被cmd/bat批处理调用。所以、用reg...
获取安卓安装APP列表的ANE演示demo,利用该ANE可以读取安卓手机中的所有APP名称,包名等信息。可用于flash as3.0开发的安卓APP中。演示版可显示前10个应用程序。
★从导出的应用列表中安装应用 ★快速卸载或通过拖放移动应用程序 ★按名称,大小或安装时间对应用程序进行排序 ★与朋友分享定制的应用列表 ★支持主屏幕小部件 ★支持 Android 2/3/4/5/6 植根设备的更多功能 ★根...
3.10 列表框和弹出式列表 60 第4章 用activex automation处理autocad 图形 64 4.1 只有当你的工具是一把榔头的时 候,任何事情才会像一颗钉子 64 4.2 autocad的dxf文件格式 64 4.3 文件头段 64 4.4 表段 64 ...
离线图书阅读收藏列表页面简历书签...您将获得此文档和代码。 管理应用程序功能(移动的应用程序) 您可以从管理员应用程序添加类别和书籍 您可以从管理应用程序中删除类别和书籍 您可以从管理员应用程序更新类别和书籍
有经验的开发人员则可以通过本书获得丰富的、有价值的参考资料。... 本书内容包括: ·Series 60开发工具、IDE和C++ SDK。 ·Symbian OS的基础知识。 ·运用Series 60框架架构进行程序设计。 ·用户界面控件、...
5.2.12 获得屏幕属性 5.3 动画实现 5.3.1 Tween动画 5.3.2 Frame动画 5.3.3 GIF动画播放 5.4 小结 第6章 Android数据存储 6.1 Android数据存储初探 6.2 数据存储之Shared Preferences 6.3 数据...
完整的约会应用程序(Android...从应用程序提交工单以获得支持 对照片和用户的滥用报告 Facebook登录|报名|连接|断开 在照片评论,礼物评论和消息中支持Jiangji。 个人资料照片和封面 推送有关个人资料喜欢,礼物,消息
强大的控件支持,让你可以不用编写一句代码并在短短几分钟内完成数据库的读写 应用开发,开发效率得到充分提升,让编程不再是枯燥无味的工作。全书400多页,从开发环境的安装配置到使用基本界面控件、使用移动设备...
杨丰盛,Android应用开发先驱,对Android有深入研究,实战经验极其丰富。精通Java、C、C++等语言,专注于移动通信软件开发,在机顶盒软件开发和MTK平台软件开发方面有非常深厚的积累。2007年获得中国软件行业协会...
次底端 反馈 正确答案是:最顶端 题目7 正确 获得1.00分中的1.00分 标记题目 题干 从文件列表中同时选择多个不相邻文件的正确操作是______。 选择一项: a. 按住Shift键,用鼠标单击每一个文件名 b. 按住Ctrl+Shift...
作为PWA开发的应用程序的第一版可在额外的git分支中获得。 特征: m3u和m3u8播放列表支持 从文件系统上传播放列表 通过URL上传远程播放列表 搜索频道 基于组的频道列表 从文件系统打开播放列表 将频道另存为收藏 ...
我们试图涵盖几乎所有的新闻应用程序所需的功能,这里是包括到应用程序的功能的基本列表 安卓端 添加新闻图片以及YouTube视频链接 为新闻添加图片库 电视频道新闻(m3u8链接recommeded)或Youtube视频 选择您选择的...
Restorder是一个Android应用程序,餐厅老板向用户显示菜单,用户可以使用用户友好的应用程序订购食物。 安卓端 有吸引力的UI与材料设计 ... 你得到的 Android源代码 服务器端完整的Php代码 带屏幕截图的完整文档
他还是一位资深的Java软件开发工程师和Android/iOS移动应用开发工程师,活跃于CocoaChina、开源中国、CSDN等社区,CSDN博客专家,在CSDN博客撰写了系列微信公众平台二次开发的教程,深受欢迎并被广泛传播,也因此...
APP个人信息保护关乎人民群众获得感、幸福感和安全感,广大用户高度关注。推动标准化是加强个人信息保护工作的关键环节,对规范企业经营行为,提升监管检测的自动化、智能化水平具有重要意义。 2020年7月,工业和...
wince/mobile下的蓝牙应用层DLL,该DLL封装了采用微软蓝牙协议栈的蓝牙驱动调用流程。只需调用一个函数即可完成蓝牙设备的搜索、选择和连接过程。...该DLL已经在我的很多程序中得到应用,稳定可靠。
使用了许多方便用户的设计,如:快速最大化,窗口半屏显示,跳转列表(Jump List)等。 进一步提高了计算机系统的运行安全可靠性和易维护性。 增强了网络功能和多媒体功能。 在节能降耗、提高执行效率上,Windows也...
2.2.3. 获得Android SDK12 2.2.4(1). 在Eclipse 3.4(Ganymede)中安装ADT14 2.2.4(2). 在Eclipse 3.5(Galileo)中安装ADT17 2.2.5. 在Eclipse中配置Android SDK20 2.3 Android中运行仿真器环境21 2.3.1. 建立...