androidappwidget
① 【Android】如何在自己的程序中添加appWidget
其實在android中提供了三個非常簡單的類,應用這三個類我們可以將一個appWidget「表面上」,注意是「表面上」添加到你的應用中。代碼如下: AppWidgetHost host = new AppWidgetHost(this, 1024);
int appWidgetId = host.allocateAppWidgetId();
AppWidgetManager mAppWidgetManager = AppWidgetManager.getInstance(this);
mAppwidgetProviderInfos = (ArrayList
) mAppWidgetManager.getInstalledProviders();
for (int i = 0; i < mAppwidgetProviderInfos.size(); i++){AppWidgetProviderInfo widgetInfo = mAppwidgetProviderInfos.get(i);
AbsoluteLayout.LayoutParams allp = new AbsoluteLayout.LayoutParams(100, 100, 0, 0);
abl.addView(hostView, allp);
稍微解釋下,新建個AppWidgetHost,分配個appWidgetId,用AppWidgetManager得到一個AppWidgetProviderInfo,再用host建立AppWidgetHostView,最後設置下在layout中的位置,把它添加到layout上。
這樣,一個表面上的就好了。不過問題也隨之而來,這是個又困擾了我幾天的問題,就是這個appWidget根本就是處於個disable的狀態,即不更新,也無法響應broadcast。經過對於launcher,framework和網上的一些理解和查閱,終於找到了問題所在,而且是個相對來說比較惡心的問題。launcher中是這么做的,就是通過起一個
Intent pickIntent = new Intent(AppWidgetManager.ACTION_APPWIDGET_PICK);
將appWidgetId 傳入這個
pickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);再調用startActivityForResult(pickIntent, REQUEST_PICK_APPWIDGET);
來實現的,當然這個intent還要些必要的參數。這里就不說了,代碼里自己看。
在onActivityResult里進行得到appWidgetId,AppWidgetProviderInfo,並建立個AppWidgetHostView,添加到layout上。
② Android開發如何獲得第三方應用Widget的包名和類名
最近在做Android的平板的開發,想在桌面上預置一些第三方應用的Widget,在桌面預置Widget的方法就是要獲得應用的包名和類名。 桌面預置widget的方法 在Launcher的配置文件 res/xml/default_workspace.xml中添加如下的代碼:<appwidget launcher:packageName="com.google.android.apps.genie.geniewidget" //預置應用的包名 launcher:className="com.google.android.apps.genie.geniewidget.miniwidget.MiniWidgetProvider" //預置應用的Provider的類名,不是Activity的類名 launcher:screen="1"//在第幾屏0為第一屏,launcher:x="0"//x坐標launcher:y="0"//y坐標 launcher:spanX="4"//x方向占幾個單元格 launcher:spanY="1"///y方向占幾個單元格 通過logcat有時可以找到應用的包名和Provider類名,此方法不可取,容易出錯。系統的widget可以通過查找相關的源碼找到對應的包名和Provider的類名,但是第三方應用看不到源碼,但是也可以通過反編譯第三方應用,獲得相應的Maifest.xml文件,找到對應的包名和Provider類名,但是此方法比較繁瑣。 可以通過在Launcher中添加如下代碼,可以將系統中所安裝的所有 的widget的信息列印出來: 在Launcher.java中的onCreate方法中添加下面的代碼: List<=mAppWidgetManager.getInstalledProviders();finalintproviderCount=providers.size();for(inti=0;i<providerCount;i++){ ComponentNameprovider=providers.get(i).provider;Log.i("xxx", "packagename:" +provider.getPackageName()+ "classname:" +provider.getClassName());}新編譯Launcher,把Launcher push進去之後,執行 adb logcat -s xxx,就可以看到列印出來的Log信息,包名和Provider了類名。 桌面預置shortcut的方法: 在Launcher的配置文件 res/xml/default_workspace.xml中添加如下的代碼:<favorites
③ 如何在Android實現桌面清理內存簡單Widget小控制項
一、UI部分的編寫:
參照Google的文檔,首先在建立一個類繼承AppWidgetProvider
import android.appwidget.AppWidgetProvider;
public class MyWidget extends AppWidgetProvider {
}
然後在清單文件中申明它,我們必須注意到,AppWidgetProvider實際上是BroadcastReceiver,所以要注冊成一個receiver,然後還有一些其他的東西需要注意:
<receiver android:name="com.alexchen.widget.MyWidget" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/example_appwidget_info" />
</receiver>
android.appwidget.action.APPWIDGET_UPDATE 表明這個receiver能夠接受一個APPWIDGET_UPDATE的廣播,而且在這里,只能加入這一個action。
android.appwidget.provider 表明數據類型時widget提供者提供的數據,example_appwidget_info表明這個widget的參數配置文件名和位置
那麼接下來就需要在res目錄下建立一個xml文件夾,並且在其中建立一個example_appwidget_info.xml的配置文件,Google的文檔中給出了示例有很多參數,實際上關鍵的參數只有下面的4個:
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="94dp"
android:minHeight="72dp"
android:updatePeriodMillis="86400000"
android:initialLayout="@layout/example_appwidget">
</appwidget-provider>
其中,minWidth和minHeight代表這個widget控制項所佔據的最小空間,這個空間一般來講不需要太大,因為太大的話,一個屏幕可能都沒辦法放下,Google的官方文檔的說法是大於4x4的就可能無法顯示。
updatePeriodMillis代表數據更新的時間,這里86400000毫秒實際上是24小時,可能最開始看到這個參數會想我能否將其設的很小,每一秒刷新很多次?,實際上對於updatePeriodMillis這個參數而言,即算你設的再小也沒用,Google設定widget控制項這個參數控制的最短update時間為30分鍾,就算將其設置在30分鍾以內也會以30分鍾的頻率來更新數據。
initialLayout參數代表的是本widget空間的布局文件。
那麼下一步就是定義出一個對應的布局文件。我們可以簡單的在layout目錄下建立一個布局文件example_appwidget.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="200dp"
android:layout_height="80dp"
android:background="@android:color/white"
android:gravity="center_vertical"
android:orientation="vertical" >
<TextView
android:id="@+id/tv_widget"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="widget控制項測試"
android:textColor="@android:color/black"
android:textSize="15sp" />
<Button
android:id="@+id/btn_clear"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="清理內存"
android:textColor="#ff000000" />
</LinearLayout>
二、功能邏輯部分的實現
大部分的Widget小控制項都會需要在特定情況下更新上面顯示的數據,那麼這個是如何實現的呢,我們經過上面的代碼不難發現實際上這個widget控制項並沒有一個Activity,所以說這個控制項的顯示實際上不是本應用來實現的,它實際上是桌面這個應用來顯示的,所以我們也不可能直接去更新它上面的數據。
回過頭去看看上面我們寫的那個receiver,實際上沒有實現任何方法。實際上AppWidgetProvider裡面有幾個比較重要的方法:onReceive、onUpdate、onDisabled、onEnabled
其中onReceive方法跟大多數廣播接收者的onReceive方法一樣,但是在這里,onReceive方法的調用並不是我們可以決定的,它依賴於顯示該widget控制項的Host組件,在這里也就是Android桌面應用,所以我們會發現在不同的手機上,將widget控制項拖到桌面上顯示的時候onReceive可能調用的次數和先後順序可能完全不一樣,這依賴於Host組件是如何實現的。
所以在這里onReceive方法對於我們刷新widget數據基本沒有什麼幫助。
而onUpdate方法則是由上面所說的updatePeriodMillis參數來控制的,經過上面的分析,我們都知道了,它的最小周期為30分鍾。所以我們一般將這個參數設為0即可。那麼在這個方法里,我們往往會在其中放置一些啟動更新數據服務的功能,因為如果後台的更新數據的Service被意外停止了,那麼每30分鍾還會被重新啟用,不至於一直啟動不了了:
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
// System.out.println("onUpdate");
//每隔一段時間重新啟動服務,防止服務中間被終止了之後沒法重啟
Intent intent = new Intent(context, UpdateWidgetService.class);
context.startService(intent);
}
下面是比較重要的兩個方法了:onDisabled和onEnabled
我們知道,widget小控制項是可以拖動多個到桌面上的,而onEnabled方法會在第一個widget控制項拖到桌面上的時候調用一次,onDisabled會在最後一個widget控制項從桌面被刪除時調用一次,那麼我們需要做的就是在onEnabled這個方法中啟用一個刷新widget數據的服務,在onDisabled方法中使用stopService方法來停止這個服務。
@Override
public void onDisabled(Context context) {
super.onDisabled(context);
System.out.println("onDisabled");
//停止數據刷新服務
Intent intent = new Intent(context, UpdateWidgetService.class);
context.stopService(intent);
}
@Override
public void onEnabled(Context context) {
super.onEnabled(context);
System.out.println("onEnabled");
//開啟數據刷新服務
Intent intent = new Intent(context, UpdateWidgetService.class);
context.startService(intent);
}
三、刷新數據的服務
那麼下面的任務就只剩下UpdateWidgetService這個刷新數據的服務(Service)如何實現的問題了。
我們在這里的想法很簡單,比如說每隔三秒鍾來刷新一下widget中的數據。Android中定時執行任務的方法有很多,我們這里使用Timer和TimerTask來實現,之後我們需要關心的就是具體如何實現刷新widget中的數據,畢竟這些數據是在桌面應用中顯示的。
並且我們需要用到一個API--AppWidgetManager,它有一個實例方法AppWidgetManager.updateAppWidget(ComponentName provider, RemoteViews views)來實現更新widget數據,我們都知道,如果需要調用另外應用的方法,需要使用遠程調用的方法來實現,在這里起到在我們的應用和桌面應用之間的橋梁作用的就是這第二個參數:RemoteViews views,它會將我們設置的數據傳送到桌面應用來刷新widget上的數據,我們需要經過下面幾步:
1、定義一個RemoteViews的實例:
RemoteViews views = new RemoteViews(getPackageName(),R.layout.process_widget);
2、設置views的內容,也就是刷新其中的數據,這里的方法名會比較奇怪,RemoteViews.setTextViewText(int
viewId, CharSequence text)
其中viewId是在我們前面定義的widget布局文件中的子組件的id,也就是我們要刷新內容的對象,這里就是R.id.tv_test,第二個參數是我們要更新的內容
3、定義好第一個參數ComponentName provider之後,就可以調用AppWidgetManager.updateAppWidget(ComponentName provider, RemoteViews views)來實現更新數據
if (timer == null && task == null) {
//AppWidgetManager對象,用於更新widget的數據
awm = AppWidgetManager.getInstance(this);
timer = new Timer();
task = new TimerTask() {
@Override
public void run() {
ComponentName provider = new ComponentName(UpdateWidgetService.this, MyWidget.class);
//遠程view對象,用於在本應用和桌面應用中起傳遞數據的橋梁作用
RemoteViews views = new RemoteViews(getPackageName(),R.layout.example_appwidget);
views.setTextViewText(R.id.tv_widget, "想刷新的數據的內容");
awm.updateAppWidget(provider, views);
System.out.println("====刷新了widget====");
}
//設置循環時間
timer.schele(task, 0, 3000);
}
四、定時刷新可用內存和一鍵清理內存功能實現
要實現這個功能,我們需要再上面定時刷新數據服務中將定時刷新的內容改為當前內存所剩餘的量,我們這里寫一個工具類方法來實現返回內存剩餘量;
另外我們還需要在widget控制項的布局文件中添加一個button,並在更新widget數據的服務中,設置這個button的點擊事件,但是這里也不像以前的點擊事件,同樣要應用到RemoteView對象,在這個點擊事件中需要發送一個廣播,Action為自定義的,我們這里設為:"com.alexchen.mobilesafeexercise.killall",之後,我們需要再寫一個廣播接收者,來接收這個廣播,在onReceive方法中執行殺死後台進程的操作。這里也不能直接使用Intent,由於我們這個意圖的Action不是由我們自己執行而是由其他應用程序(桌面應用)執行的,所以需要用到PendingIntent。
④ androidwidget有用嗎
1.身材微:它們一般都很小,在終端上嵌入非常方便,運行快速。
2.形式多:Widget可以以多種形式呈現出來,幻燈秀、視頻、地圖、新聞、小游戲……
3.功能巨:別看它們小,卻服務周到,它可以為你報告新聞、幫你買東西、列出你最喜歡的樂隊,還有你最近看的視頻。另外,它還是一個殷勤的管家,你不必親自去Flickr或者天氣預報網站,Widget會將信息主動帶給你。
4.姿容麗:它們可以稱得上玉面飛龍、以色服人。只要你願意,你可以把它變成任何你想要得樣子。它的出現,無異於一枚「桌面炸彈」,狹窄而單調的IE窗口將被更為廣闊和絢麗的桌面空間所取代。
5.個性化:Widget更像一個屬於我們每個人的魔方,任由用戶聚合。你可以根據自己喜好,將多個Widget,隨心所欲的去精心組裝你的網路世界。通過Widget,可以用戶把一切在「網」中的內容打亂重來,並按照用戶希望看到的樣子重新排列組合一個屬於自己的互聯網。比如說一個由微件搭建個人空間,可以包括來自新浪的體育新聞,來自論壇的一個板塊,來自權威財經網站的一則隨時更新的股票信息 ——這些以往需要用戶同時分別進入幾個網站才能看到的信息,現在由一個個微件將其轉變為用戶個人空間的一部分,從而可以直接在同一個頁面中並存。傳統互聯網訪問方式處於分裂狀態的後Web2.0時期,多樣性、炫酷且更具個性化的Widget流行,或許能引領一個新的潮流。
6.易製作:製作 Widget 部件並不復雜,只需要熟悉三方面的知識:圖像處理、HTML/XML、java,就可以按照開發站點里的教程做出漂亮的部件來。Widget能夠流行的一個要點在於開放製作,UGC應用帶來爆炸式地增長。
那麼,什麼是android widget呢?
在Android 1.5 SDK preview中,我們看到了一系列功能和API上的變化變化,包括軟鍵盤、桌面Widget和Live Folder API、視頻錄制API,藍牙功能升級等,Google近來對於這些全新功能的解析使得Android開發者blog變得異常活躍。上周,Jeff Sharkey就有一篇對於Android桌面widget和AppWidget框架的簡介,以「Word of the day」的一個例子講述了桌面Widget的運作機制。昨天他又在個人blog上放出了一個天氣預報Widget的例子,事實上這已經是一個真正實用的程序了。它每天更新4次天氣預報,我們可以添加多個Widget來關注多個城市的天氣情況,另外,點擊Widget後我們還可以看到今後幾天的詳細預報。
這讓我想起了HTC Source的Nick Gray上周的一篇文章Android Widgets, Unlimited Potential中提到的幾類可能會大受歡迎的Android桌面Widget。
Android本身已經自帶了時鍾、音樂播放器、相框和Google搜索4個Widget程序,不過這並不能阻止大家開發自己更加美觀,功能更豐富的版本。另外,微博客、RSS訂閱、股市信息、天氣預報這些Widget也都有流行的可能。
微博客Widget:Twidroid是Android上迄今為止最棒的Twitter客戶端,大家顯然都期待著它會推出支持桌面Widget的版本,另外像國內比較受歡迎的飯否、嘀咕、嘰歪等應該也會有類似的Widget推出。對於一個微博客類的Widget來說,有兩個方面是必不可少的,一是用來發布消息,另一個則是用來瀏覽。
RSS訂閱Widget: 盡管微博客(尤其是Twitter)已經完全蓋過來RSS訂閱的風頭,越來越多的人用Twitter來跟蹤站點的更新,不過RSS訂閱也並非完全沒有了市場,像分類訂閱這樣的功能還是需要RSS來幫忙,另外站點管理員也未必會在Twitter上發布所有的更新。
股市信息Widget:對於炒股的人來說,大概沒有什麼能比在手機桌面上放上幾個所關注股票的實時股價更有運籌帷幄的感覺了吧。
天氣預報Widget:對於我這樣成天窩在辦公室或者家裡的人來說,有一個Widget能夠讓我了解當前的天氣和近1、2天的天氣是非常有用的,這大概會大大減少我下了樓又跑回去拿雨傘的幾率。如果能加上像TouchFLO 3D中那樣的UI效果,當然就更酷了。
這只是我現在想到的一些Widget,得益於Android 1.5為我們提供的Widget API為我們的手機桌面帶來的無限的可能,我們的手機桌面無疑將會更有趣。
對國內G1的用戶,如果想體驗Android 1.5的桌面Widget,可以看看Haykuro的blog,他正在為製作G1可用的Android 1.5 ROM而努力。另外,T-Mobile已經計劃在五月向德國的T-Mobile G1用戶推送1.5的更新了,所以即使到時候沒有官方的G1簡體中文1.5 ROM,相信Haykuro的 1.5 ROM for G1也能非常接近官方的成熟度。
Widget應用目前在Android手機上得到了廣泛的應用。由於其方便小巧,所以得到了很多的應用,像天氣,微博,信息,歌曲,時間等等。
關於android Wpp widget:
應用程序窗口小部件(Widget)是微小的應用程序視圖,可以被嵌入到其它應用程序中(比如桌面)並接收周期性的更新。你可以通過一個App Widget provider來發布一個Widget。可以容納其它App Widget的應用程序組件被稱為App Widget宿主。下面的截屏顯示了一個音樂App Widget。
⑤ android 開發桌面小插件的大小問題
appWidget是可以放在一個view裡面的,你只要給這個view設置大小就可以了