刚学做了哥Widget,感觉不错哦,先来秀下效果(用朋友手机截的图)

这个Widget会每隔5秒钟自动切换内容和图片,图片最好使用小图,大图会导致你手机桌面(UI)线程卡顿

教程开始:

1、首先创建一个布局(layout),用以显示Wdiget

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/ddz_gameend_frame"
>
<!--Relativelayout 的 android:background请自行更换你的图片-->
 <TextView
android:id="@+id/textview_1"
android:layout_width="60.0dp"
android:layout_height="90.0dp"
android:layout_marginLeft="35.0dp"
android:layout_marginTop="34.0dp"
android:textColor="#000000"
android:text=""
/>
<ImageView
android:id="@+id/imageview_1"
android:layout_width="136.0dp"
android:layout_height="92.0dp"
android:layout_toRightOf="@+id/textview_1"
android:layout_marginLeft="5.0dp"
android:layout_marginTop="42.0dp"
/>
<Button
android:id="@+id/button_1"
android:layout_width="50.0dp"
android:layout_height="20.0dp"
android:layout_below="@+id/textview_1"
android:layout_marginTop="10.0dp"
android:layout_marginLeft="35.0dp"
android:text="详情"
/>
<!--本人的程序用了android:background="@drawable/mybutton",为了简化示例在此不使用-->
 </RelativeLayout>

2、然后创建一个appwidget-provider 的XML文件,点击资源目录的Res文件夹,鼠标右键选择New- android xml file

mywidget_provider.xml

<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:resizeMode="horizontal"
android:minWidth="250.0dp"
android:minHeight="110.0dp"
android:updatePeriodMillis="86400000"
android:initialLayout="@layout/activity_main"
android:widgetCategory="home_screen|keyguard"
>
</appwidget-provider>

android:updatePeriodMillis指示了更新间隔,86400000为24小时,也就是一天一次,本程序自己采用后台服务更新,所以该设置其实对本程序来说关系不大。 android:initialLayout就是指向的Widget布局
android:widgetCategory指示该Widget可以用作桌面和锁屏

3、在src目录创建代码文件(本实例建了包  com.feature.test;)

Constant.class   (用来定义一些常量的类)

package com.feature.test;

public class Constant {

	//更新广播
public static final String ACTION_UPDATE_ALL="com.feature.test.update_all"; //intent integer data
public static final String INTEGER_DATA="integer_data";
}

MyAppWidgetProvider.class    (用来处理Widget更新的类)

package com.feature.test;

import java.util.HashSet;
import java.util.Iterator; import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.util.Log;
import android.widget.RemoteViews;
import android.widget.Toast; public class MyAppWidgetProvider extends AppWidgetProvider{ private static final Intent AppWidget_Service=new Intent("com.feature.test.MyAppWidgetService"); //保存WidgetId HashSet 可能有用户创建了多个Widget
private static HashSet<Integer> hashSet=new HashSet<Integer>();
//图片资源,作者请自行修改成自己的图片
private static final int[] ResId={R.drawable.a1,R.drawable.a2,R.drawable.a3,R.drawable.a4,R.drawable.a5};
//文本资源
private static final String[] intro={"神挡杀神,佛挡杀佛","仿佛兮若轻云之蔽月,飘飘兮若流风之回雪",
"此乃驱狼吐虎之计,敬你之手他一搏吧","汝等小儿,可敢杀我",
"汝等看好了"};
private static int iCur=-1; //周期更新时调用
@Override
public void onUpdate(Context context,AppWidgetManager appWidgetProvider,int[] appWidgetIds)
{
Log.v("创建Widget", "OK");
// 每次 widget 被创建时,对应的将widget的id添加到set中
for(int id:appWidgetIds)
hashSet.add(Integer.valueOf(id)); } //当桌面组件删除时调用
@Override
public void onDeleted(Context context,int[] appWidgetIds)
{
for(int id:appWidgetIds)
hashSet.remove(id); super.onDeleted(context, appWidgetIds);
} //当桌面提供的第一个组件创建时调用
@Override
public void onEnabled(Context context)
{
//启动服务
context.startService(AppWidget_Service); super.onEnabled(context);
} //当桌面提供的最后一个组件删除时调用
@Override
public void onDisabled(Context context)
{
//停止服务
context.stopService(AppWidget_Service); super.onDisabled(context);
} /*
* 重写广播接收方法
* 用于接收除系统默认的更新广播外的 自定义广播(本程序由服务发送过来的,一个是更新UI,一个是按钮事件消息)
*/
@Override
public void onReceive(Context context,Intent intent)
{
String getAction=intent.getAction();
if(getAction.equals(Constant.ACTION_UPDATE_ALL))
{
//更新广播 updateAllWidget(context,AppWidgetManager.getInstance(context), hashSet);
}
else if(intent.hasCategory(Intent.CATEGORY_ALTERNATIVE))
{
Uri data=intent.getData();
Log.v("button",data.toString()+" ");
int buttonid=Integer.parseInt(data.getSchemeSpecificPart());
Toast.makeText(context, intro[buttonid],Toast.LENGTH_SHORT).show();
} super.onReceive(context, intent);
} //更新UI
public void updateAllWidget(Context context,AppWidgetManager manager,HashSet<Integer> set)
{
int AppId;
Iterator iterator=set.iterator(); iCur=iCur+1>=intro.length? 0: iCur+1; while(iterator.hasNext())
{
AppId=((Integer)iterator.next()).intValue(); RemoteViews remoteViews=new RemoteViews(context.getPackageName(),R.layout.activity_main);
//设置显示的文字图片
remoteViews.setTextViewText(R.id.textview_1, intro[iCur]);
remoteViews.setImageViewResource(R.id.imageview_1, ResId[iCur]);
//添加按钮事件处理
remoteViews.setOnClickPendingIntent(R.id.button_1, getPendingIntent(context, iCur));
//更新
manager.updateAppWidget(AppId, remoteViews);
}
} //设置按钮事件处理
private PendingIntent getPendingIntent(Context context,int buttonid)
{
Intent intent=new Intent("test.test");
intent.setClass(context, MyAppWidgetProvider.class);
intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
intent.setData(Uri.parse("custom:"+buttonid));
//进行广播
PendingIntent pi=PendingIntent.getBroadcast(context, 0, intent, 0);
return pi;
}
}

4、创建后台服务,用来定时发送广播,通知Widget需要更新了

MyAppWidgetService。class

package com.feature.test;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder; public class MyAppWidgetService extends Service{ private Context context;
//更新周期
private static final int UPDATE_TIME=5000;
//周期性更新的Widget 线程
private WidgetThread widgetThread; @Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
} @Override
public void onCreate()
{
widgetThread=new WidgetThread();
widgetThread.start(); context=this.getApplicationContext();
super.onCreate();
} @Override
public void onDestroy()
{
if(widgetThread!=null&&widgetThread.isAlive())
widgetThread.interrupt(); super.onDestroy();
} private class WidgetThread extends Thread
{
@Override
public void run()
{
try
{
while(true)
{
Intent intent=new Intent(Constant.ACTION_UPDATE_ALL);
context.sendBroadcast(intent); sleep(UPDATE_TIME);
}
}catch(InterruptedException error)
{
// 将 InterruptedException 定义在while循环之外,意味着抛出 InterruptedException 异常时,终止线程。
}
}
}
}

5、在AndroidManifest.xml注册Widget和服务

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.feature.test"
android:versionCode="1"
android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="8"/>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@android:style/Theme.Black" >
<!-- 注册AppWidget Provider -->
<receiver
android:name="com.feature.test.MyAppWidgetProvider">
<meta-data android:name="android.appwidget.provider"
android:resource="@xml/mywidget_provider"
/>
<intent-filter >
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="com.feature.test.update_all" />
</intent-filter>
</receiver> <!-- 注册服务 -->
<service android:name=".MyAppWidgetService">
<intent-filter>
<action android:name="com.feature.test.MyAppWidgetService"/>
</intent-filter>
</service> </application> </manifest>

至此大功告成!有问题请、意见请回复,本人虚心求教

另外如果你手机安装了自己做的Widget,在添加-窗口小工具显示不出来,那是因为你把它装到SD卡导致的,请在应用程序里找到自己的Widget将其移至手机存储即可显示

android 桌面小工具(Widget)开发教程的更多相关文章

  1. Android桌面小插件——Widget

    Android桌面小插件--Widget 效果图 实现 1. 创建Widget类 创建一个Widget类,并实现页面创建的时候,就实现显示时间 package com.kongqw.kqwwidget ...

  2. Django微信小程序后台开发教程

    本文链接:https://blog.csdn.net/qq_43467898/article/details/83187698Django微信小程序后台开发教程1 申请小程序,创建hello worl ...

  3. iOS桌面小插件 Widget Extension

    iOS桌面小插件 Widget Extension 这个插件时iOS14以后才出现的,基于SwiftUI 旧项目新建时可能一堆错误,其中一个时要把插件target 开发sdk版本设置为14.0以上 新 ...

  4. android桌面小火箭升空动画

    public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceS ...

  5. Android 性能测试小工具 Emmagee

    Emmagee 是一个性能测试小工具 用来监控指定被测应用在使用过程中占用机器的CPU, 内存,流量资源的性能小工具 Emmagee 介绍 Emmagee是网易杭州研究院QA团队开发的一个简单易上手的 ...

  6. [Android Memory] Android性能测试小工具Emmagee

    转载:http://blog.csdn.net/anlegor/article/details/22895993 Emmagee是网易杭州QA团队开发的用于测试指定android应用性能的小工具.该工 ...

  7. Android 桌面小部件

    1. 添加AppWidgetProvider 实际上就是个带有界面的BroadcastReceiver public class SimpleWidgetProvider extends AppWid ...

  8. 介绍两个Ubuntu上的桌面小工具

    经常使用Windows10,Sticky Notes和壁纸自动切换功能挺好用的.我经常会使用Sticky Notes来记录一些信息,内容是实时保存的,而且启动的时候会自动显示在桌面上.其实Ubuntu ...

  9. 微信小程序插件 - 开发教程

    昨天(2018.3.13),微信小程序发布了重大功能更新,支持插件的使用和开发,个人预计,不超过2个月,优质服务的插件将会如雨后春笋般涌现. 这篇文章,我将会带大家,从0开始,学习如何开发和使用插件. ...

随机推荐

  1. 轻量级IOC框架:Ninject (上)

    前言 前段时间看Mvc最佳实践时,认识了一个轻量级的IOC框架:Ninject.通过google搜索发现它是一个开源项目,最新源代码地址是:http://github.com/enkari/ninje ...

  2. 使用WSL连接Docker Server(Windows/Linux)

    在Windows下安装Docker for Windows Cotana搜索功能,打开Windows的Hype-v功能(注:会影响Virtualbox和Vmware的使用)并重启电脑. 从Docker ...

  3. 新手学cocos2dx,centos7下的安装过程

    背景 打算学写游戏,新手向,当然从cocos2d-x开始. 看了cocos的文档,安装是针对ubuntu的,这里记录下centos7上安装.编译.运行测试的过程. 如果你已经有ubuntu,不推荐看此 ...

  4. Overclock STM32F4 device up to 250MHz

    http://stm32f4-discovery.com/2014/11/overclock-stm32f4-device-up-to-250mhz/ Let’s test what STM32F4x ...

  5. Either, neither, both

    http://speakspeak.com/resources/english-grammar-rules/various-grammar-rules/either-neither-both One ...

  6. 让AngularJS的controllers之间共享数据

    如何让controller之间共享数据呢?大致是让不同controller中的变量指向同一个实例. 通过service创建一个存放共享数据的对象. .service("greeting&qu ...

  7. CListCtrlEx:一个支持文件拖放和实时监视的列表控件——用未公开API函数实现Shell实时监视

    一.需求无论何时,当你在Explorer窗口中创建.删除或重命名一个文件夹/文件,或者插入拔除移动存储器时,Windows总是能非常快速地更新它所有的视图.有时候我们的程序中也需要这样的功能,以便当用 ...

  8. maven生命周期理解

    你可以仅仅调用clean来清理工作目录,仅仅调用site来生成站点.当然你也可以直接运行 mvn clean install site 运行所有这三套生命周期. 知道了每套生命周期的大概用途和相互关系 ...

  9. Java Calendar,Date,DateFormat,TimeZone,Locale等时间相关内容的认知和使用(1) Calendar

    Java 操作日期/时间,往往会涉及到Calendar,Date,DateFormat这些类. 最近决定把这些内容系统的整理一下,这样以后使用的时候,会更得心应手.本章的内容是主要讲解“Java时间框 ...

  10. xcode 不能选择模拟器

    重新安装了xcode后,程序无法运行,不能选择模拟器 或者 设备? 1.你之所以选择不了模拟器或者设备,是因为你工程中的iOS Deployment Target设置不对.比如你装的是xcode4.0 ...