刚学做了哥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. 通过本地Git部署网站到WebSite

    玩过Azure WebSite(WebApp)的同学应该知道部署网站的方式非常多,今天我要讲的是如果通过本地Git部署网站到WebSite. 1.新建WebSite 创建WebSite非常简单,我这里 ...

  2. Android应用程序模型:应用程序,任务,进程,线程

    大多数操作系统,在应用程序所寄存的可执行程序映像(如Windows系统里的.exe).它所运行的进程以及和用户交互的图标和应用之间有一种严格的1对1关系.在Android系统里,这些关联要松散得多.并 ...

  3. RSS介绍、RSS 2.0规范说明和示例代码

    RSS是一种消息来源格式规范,用以发布经常更新资料的网站,例如博客.新闻的网摘.RSS文件,又称做摘要.网摘.更新.频道等,包含了全文或节选文字,再加上一定的属性数据.RSS让发布者自动发布信息,也使 ...

  4. LDO current regulator for power LED

    LDO current regulator for power LED Challenge You've got a power LED? Great! Build a flash light! Wh ...

  5. Keil debugging techniques and alternative printf (SWO function)

    One of the basic needs of the embedded software development through the terminal to output debugging ...

  6. Jquery DataTable基本使用

    1,首先需要引用下面两个文件 <link rel="stylesheet" href="https://cdn.datatables.net/1.10.16/css ...

  7. Javascript Array和String的互转换。

    Array类可以如下定义: var aValues = new Array(); 如果预先知道数组的长度,可以用参数传递长度 var aValues = new Array(20); -------- ...

  8. 突破 BTrace 安全限制

    http://blog.csdn.net/alivetime/article/details/6548615

  9. maria-developers 开发者邮件

    https://lists.launchpad.net/maria-developers/

  10. Modbus读写模拟量寄存器具体解释

    读可读写模拟量寄存器: 发送命令(主机向从机)格式: [设备地址] [命令号03] [起始寄存器地址高8位] [低8位] [读取的寄存器数高8位] [低8位] [CRC校验的低8位] [CRC校验的高 ...