Andorid桌面小部件AppWidgetProvider应用

/**
 * 桌面小部件 AppWidget配置
 * 
 * @description:
 * @author ldm
 * @date 2016-5-16 下午1:57:16
 */
public class ExampleAppWidgetConfigure extends Activity {
    static final String TAG = "ExampleAppWidgetConfigure";
    // 保存的文件名
    private static final String PREFS_NAME = "com.example.android.apis.appwidget.ExampleAppWidgetProvider";
    // 保存的字段KEY
    private static final String PREF_PREFIX_KEY = "prefix_";
    // 小部件 对应ID
    int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
    // 输入框
    EditText mAppWidgetPrefix;

    public ExampleAppWidgetConfigure() {
        super();
    }

    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        setResult(RESULT_CANCELED);
        // 设置布局
        setContentView(R.layout.appwidget_configure);
        mAppWidgetPrefix = (EditText) findViewById(R.id.appwidget_prefix);
        // 设置监听
        findViewById(R.id.save_button).setOnClickListener(mOnClickListener);
        // 获取intent传递过来的数据
        Intent intent = getIntent();
        Bundle extras = intent.getExtras();
        if (extras != null) {
            mAppWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID,
                    AppWidgetManager.INVALID_APPWIDGET_ID);
        }

        if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
            finish();
        }

        mAppWidgetPrefix.setText(loadTitlePref(ExampleAppWidgetConfigure.this,
                mAppWidgetId));
    }

    View.OnClickListener mOnClickListener = new View.OnClickListener() {
        public void onClick(View v) {
            final Context context = ExampleAppWidgetConfigure.this;
            String titlePrefix = mAppWidgetPrefix.getText().toString();
            //保存到SharedPreferences文件
            saveTitlePref(context, mAppWidgetId, titlePrefix);
            AppWidgetManager appWidgetManager = AppWidgetManager
                    .getInstance(context);
            //更新小部件 
            ExampleAppWidgetProvider.updateAppWidget(context, appWidgetManager,
                    mAppWidgetId, titlePrefix);

            Intent resultValue = new Intent();
            resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
                    mAppWidgetId);
            setResult(RESULT_OK, resultValue);
            finish();
        }
    };

    static void saveTitlePref(Context context, int appWidgetId, String text) {
        SharedPreferences.Editor prefs = context.getSharedPreferences(
                PREFS_NAME, 0).edit();
        prefs.putString(PREF_PREFIX_KEY + appWidgetId, text);
        prefs.commit();
    }

    static String loadTitlePref(Context context, int appWidgetId) {
        SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, 0);
        String prefix = prefs.getString(PREF_PREFIX_KEY + appWidgetId, null);
        if (prefix != null) {
            return prefix;
        } else {
            return context.getString(R.string.appwidget_prefix_default);
        }
    }

    static void deleteTitlePref(Context context, int appWidgetId) {
    }

    static void loadAllTitlePrefs(Context context,
            ArrayList<Integer> appWidgetIds, ArrayList<String> texts) {
    }
}

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="This text will be shown before the date in our example widget." />

    <EditText
        android:id="@+id/appwidget_prefix"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <Button
        android:id="@+id/save_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@android:string/ok" />

</LinearLayout>

/**
 * AppWidgetProvider小部件广播组件使用:
 * 1, 实现AppWidgetProvider的子类,并至少override onUpdate()方法
 * 2,在AndroidManifest.xml中,声明上述的AppWidgetProvider的子类是一个Receiver,并且:
 * 该Receiver的intent-filter的Action必须包含“android.appwidget.action.APPWIDGET_UPDATE”;
 * 该Receiver的meta-data为“android.appwidget.provider”,并用一个xml文件来描述布局属性。
 * 3, 在第2点中的xml文件中描述布局属性的节点名称必须为“appwidget-provider”。
 * 
 * @description:
 * @author ldm
 * @date 2016-5-16 下午1:43:31
 */
public class ExampleAppWidgetProvider extends AppWidgetProvider {
    // Log打印日志标签
    private static final String TAG = "ExampleAppWidgetProvider";

    /**
     * onUpdate() 处理AppWidgetManager.ACTION_APPWIDGET_UPDATE广播。
     * 该广播在需要AppWidgetProvider提供RemoteViews数据时
     * ,由AppWidgetService.sendUpdateIntentLocked()发出。
     */
    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager,
            int[] appWidgetIds) {
        Log.d(TAG, "onUpdate");

        final int N = appWidgetIds.length;
        for (int i = 0; i < N; i++) {
            //获取到id
            int appWidgetId = appWidgetIds[i];
            //设置标题
            String titlePrefix = ExampleAppWidgetConfigure.loadTitlePref(
                    context, appWidgetId);
            //更新AppWidget
            updateAppWidget(context, appWidgetManager, appWidgetId, titlePrefix);
        }
    }

    /**
     * onDeleted() 处理AppWidgetManager.ACTION_APPWIDGET_DELETED广播。
     * 该广播在有该AppWidgetProvider的实例被删除时
     * ,由AppWidgetService.deleteAppWidgetLocked()发出。
     */
    @Override
    public void onDeleted(Context context, int[] appWidgetIds) {
        Log.d(TAG, "onDeleted");
        final int N = appWidgetIds.length;
        for (int i = 0; i < N; i++) {
            ExampleAppWidgetConfigure.deleteTitlePref(context, appWidgetIds[i]);
        }
    }

    /**
     * onEnabled() 处理AppWidgetManager.ACTION_APPWIDGET_ENABLED广播。
     * 该广播在该AppWidgetProvider被实例化时,由AppWidgetService.sendEnableIntentLocked()发出。
     */
    @Override
    public void onEnabled(Context context) {
        Log.d(TAG, "onEnabled");
        PackageManager pm = context.getPackageManager();
        pm.setComponentEnabledSetting(new ComponentName(
                "com.example.android.apis",
                ".appwidget.ExampleBroadcastReceiver"),
                PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
                PackageManager.DONT_KILL_APP);
    }

    /**
     * onDisabled() 处理AppWidgetManager.ACTION_APPWIDGET_DISABLED广播。
     * 该广播在该AppWidgetProvider的所有实例中的最后一个实例被删除时
     * ,由AppWidgetService.deleteAppWidgetLocked()发出。
     */
    @Override
    public void onDisabled(Context context) {
        Log.d(TAG, "onDisabled");
        PackageManager pm = context.getPackageManager();
        //设置组件可用
        pm.setComponentEnabledSetting(new ComponentName(
                "com.example.android.apis",
                ".appwidget.ExampleBroadcastReceiver"),
                PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
                PackageManager.DONT_KILL_APP);
    }

    static void updateAppWidget(Context context,
            AppWidgetManager appWidgetManager, int appWidgetId,
            String titlePrefix) {
        Log.d(TAG, "updateAppWidget appWidgetId=" + appWidgetId
                + " titlePrefix=" + titlePrefix);
        CharSequence text = context.getString(R.string.appwidget_text_format,
                ExampleAppWidgetConfigure.loadTitlePref(context, appWidgetId),
                "0x" + Long.toHexString(SystemClock.elapsedRealtime()));
        // 创建RemoteViews 对象
        RemoteViews views = new RemoteViews(context.getPackageName(),
                R.layout.appwidget_provider);
        // 设置RemoteViews 对象的文本
        views.setTextViewText(R.id.appwidget_text, text);
        // 告诉AppWidgetManager 显示 views对象给widget.
        appWidgetManager.updateAppWidget(appWidgetId, views);
    }
}

小部件布局

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/appwidget_text"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="#ffff00ff"
    android:textColor="#ff000000"
/>

public class ExampleBroadcastReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d("ExmampleBroadcastReceiver", "intent=" + intent);
        //获取广播的ACTION
        String action = intent.getAction();
        //对ACTION进行判断
        if (action.equals(Intent.ACTION_TIMEZONE_CHANGED)
                || action.equals(Intent.ACTION_TIME_CHANGED)) {

            AppWidgetManager gm = AppWidgetManager.getInstance(context);
            ArrayList<Integer> appWidgetIds = new ArrayList<Integer>();
            ArrayList<String> texts = new ArrayList<String>();

            ExampleAppWidgetConfigure.loadAllTitlePrefs(context, appWidgetIds, texts);

            final int N = appWidgetIds.size();
            for (int i=0; i<N; i++) {
                ExampleAppWidgetProvider.updateAppWidget(context, gm, appWidgetIds.get(i), texts.get(i));
            }
        }
    }
}

在AndroidManifest.xml中添加相应组件:
ExampleAppWidgetConfigure

 <activity android:name=".appwidget.ExampleAppWidgetConfigure" >
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
            </intent-filter>
        </activity>

ExampleAppWidgetProvider

<receiver android:name=".appwidget.ExampleAppWidgetProvider" >
            <meta-data
                android:name="android.appwidget.provider"
                android:resource="@xml/appwidget_provider" />

            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
            </intent-filter>
        </receiver>

ExampleBroadcastReceiver

 <receiver
            android:name=".appwidget.ExampleBroadcastReceiver"
            android:enabled="false" >
            <intent-filter>
                <action android:name="android.intent.ACTION_TIMEZONE_CHANGED" />
                <action android:name="android.intent.ACTION_TIME" />
            </intent-filter>
        </receiver>

开源代码:https://github.com/ldm520/ANDROID_API_DEMOS

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值