AppWidget开发实例讲解(二)

来源:互联网 发布:特效素材软件 编辑:程序博客网 时间:2024/05/17 21:49

5、service的编写

import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.util.ArrayList;import java.util.Iterator;import java.util.List;import java.util.Properties;import android.app.Activity;import android.app.ActivityManager;import android.app.Service;import android.app.ActivityManager.RunningTaskInfo;import android.app.AlertDialog;import android.appwidget.AppWidgetManager;import android.content.BroadcastReceiver;import android.content.ComponentName;import android.content.Context;import android.content.DialogInterface;import android.content.Intent;import android.content.IntentFilter;import android.content.SharedPreferences;import android.content.SharedPreferences.Editor;import android.os.Bundle;import android.os.Environment;import android.os.IBinder;import android.os.RemoteException;import android.util.Log;import android.view.Window;import android.widget.RemoteViews;import android.widget.Toast;import android.os.storage.IMountService;import android.os.ServiceManager;import android.os.storage.StorageManager;import android.os.storage.StorageEventListener;public class EpOperaService extends Service {/** Called when the activity is first created. */private static final int DLG_ERROR_UNMOUNT = 2;private static final String state_mount = "1";// state mountedprivate static final String state_unmount = "0";// state unmountedprivate static final String SD_CLICK="com.roadrover.lyf.equipmentTask.widgetAppProvider.action.sd.click";private static final String USB_CLICK="com.roadrover.lyf.equipmentTask.widgetAppProvider.action.usb.click";private String SDflag, USBflag;//private static ArrayList<UsbModel> usbList = new ArrayList<UsbModel>();//保存设备相应信息private static AppWidgetManager appManager;// Appwidget管理器,用来更新RemoteViewprivate static RemoteViews views;// 更新单元private static ComponentName thisWidget;// 组件名private IMountService mMountService = null;private StorageManager mStorageManager = null;private static SharedPreferences sharedPreferences;private static Editor editor;private boolean flag, flag1;//这两个标记用于计算两次连续点击桌面组件按钮间隔时间,防止频繁点击private long sdlastTime;private long udisklaskTime;/** * onStart函数在每次启动时调用,包括通过intent对象启动或者系统对service启动等操作 */@Overridepublic void onStart(Intent intent, int startId) {// TODO Auto-generated method stubsuper.onStart(intent, startId);refreshButtonState();dealButtonMsg(intent);}/** * onCreate函数在service第一次创建时调用,这里将需要初始化的操作在这里完成 */@Overridepublic void onCreate() {// TODO Auto-generated method stubsuper.onCreate();sharedPreferences = getSharedPreferences("setting",Context.MODE_WORLD_WRITEABLE);editor = sharedPreferences.edit();// 获取编辑器flag = true;flag1 = true;sdlastTime = System.currentTimeMillis();udisklaskTime = System.currentTimeMillis();initRemoteViewComponents();initEquipmentListStatus();if (mStorageManager == null) {//设备状态侦听器创建mStorageManager = (StorageManager) getSystemService(Context.STORAGE_SERVICE);mStorageManager.registerListener(mStorageListener);}}/** * usb和sd按钮消息处理 *  * @param intent */private void dealButtonMsg(Intent intent) {if (intent != null && intent.getAction() != null) {//需要判空,因为系统启动onstart也许就intent对象就为空if (intent.getAction().equals(SD_CLICK)) {//sd卡按钮点击传递过来的消息long nowTime = System.currentTimeMillis();long timeDuring = nowTime - sdlastTime;if (timeDuring > 3000 || flag) {sdCarkClicked(sharedPreferences.getString("sdFlag", ""));sdlastTime = nowTime;} else {Toast.makeText(getApplicationContext(),getUserString(R.string.times_error), 1000).show();return;}} else if (intent.getAction().equals(USB_CLICK)) {//usb按钮点击传递过来的消息long nowTime = System.currentTimeMillis();long timeDuring = nowTime - udisklaskTime;if (timeDuring > 3000 || flag) {UDiskClicked(sharedPreferences.getString("usbFlag", ""));udisklaskTime = nowTime;} else {Toast.makeText(getApplicationContext(),getUserString(R.string.times_error),Toast.LENGTH_SHORT).show();return;}}flag = false;}}/** * 初始化RemoteView对象 */public void initRemoteViewComponents() {appManager = AppWidgetManager.getInstance(EpOperaService.this);views = new RemoteViews(EpOperaService.this.getPackageName(),R.layout.equipment_task_widget_layout);thisWidget = new ComponentName(EpOperaService.this,EquipmentTaskOperationProvider.class);}/** * 外设侦听器,因平台而异,不用平台可以相应修改后使用 */StorageEventListener mStorageListener = new StorageEventListener() {@Overridepublic void onStorageStateChanged(String path, String oldState,String newState) {updateUsbState(path, oldState, newState);}};//更新设备状态private void updateUsbState(String path, String oldState, String newState) {if (path.equals("/mnt/sdcard")) {if (newState.equalsIgnoreCase(Environment.MEDIA_MOUNTED)) {editor.putString("sdFlag", "1");} else {editor.putString("sdFlag", "0");}} else if (path.equals("/mnt/udisk")) {if (newState.equalsIgnoreCase(Environment.MEDIA_MOUNTED)) {editor.putString("usbFlag", "1");} else {editor.putString("usbFlag", "0");}}editor.commit();refreshButtonState();}/** * sd卡按钮消息处理 *  * @param sdflag */private void sdCarkClicked(String sdflag) {if (sdflag.equals("0"))mount(usbList.get(0).getFile().getPath(), "sdFlag");else {unmount(usbList.get(0).getFile().getPath(), true, "sdFlag");}}/** * USB按键消息处理 *  * @param usbflag *            标记是加载状态还是卸载状态 */private void UDiskClicked(String usbflag) {if (usbflag.equals("0"))mount(usbList.get(1).getFile().getPath(), "usbFlag");else {unmount(usbList.get(1).getFile().getPath(), true, "usbFlag");}}/** * 加载设备 * @param path * @param itemName * @return */private boolean mount(String path, String itemName) {IMountService mountService = getMountService();try {if (mountService != null) {Toast.makeText(getApplicationContext(),getUserString(R.string.mount_going), Toast.LENGTH_SHORT).show();mountService.mountVolume(path);} else {Toast.makeText(getApplicationContext(),getUserString(R.string.operation_null),Toast.LENGTH_SHORT).show();return false;}} catch (RemoteException ex) {showDialogInner(DLG_ERROR_UNMOUNT);return false;}return true;}/** * 卸载设备 * @param path * @param force * @param itemName * @return */private boolean unmount(String path, boolean force, String itemName) {IMountService mountService = getMountService();try {if (mountService != null) {Toast.makeText(getApplicationContext(),getUserString(R.string.unmount_going),Toast.LENGTH_SHORT).show();mountService.unmountVolume(path, force);} else {Toast.makeText(getApplicationContext(),getUserString(R.string.operation_null),Toast.LENGTH_SHORT).show();return false;}} catch (RemoteException e) {showDialogInner(DLG_ERROR_UNMOUNT);return false;}return true;}private void showDialogInner(int id) {Toast.makeText(getApplicationContext(),getUserString(R.string.mount_error), Toast.LENGTH_SHORT).show();}/** * @author  * @category 获取并设备列表的状态,如果设备存在且设置其状态为1,否则状态为0 * @param file */private void setUsbList(File file) {if (file.getName().equalsIgnoreCase(getUserString(R.string.sdcard))&& usbList.get(0).getExist() == 1) {String name = getUserString(R.string.sdcard).toUpperCase();String usbType = getUserString(R.string.sdcard);String state = Environment.getExternalSDStorageState().equalsIgnoreCase(Environment.MEDIA_MOUNTED) ? state_mount: state_unmount;usbList.get(0).setFile(file);editor.putString("sdFlag", state);}if (file.getName().equalsIgnoreCase(getUserString(R.string.udisk))&& usbList.get(1).getExist() == 1) {String name = getUserString(R.string.usb).toUpperCase();String usbType = getUserString(R.string.udisk);String state = Environment.getExternalUDiskStorageState().equalsIgnoreCase(Environment.MEDIA_MOUNTED) ? state_mount: state_unmount;usbList.get(1).setFile(file);editor.putString("usbFlag", state);}editor.commit();// 提交修改}/** *获取文件中保存的设备状态并刷新组件图标状态 */private void refreshButtonState() {if (sharedPreferences.getString("sdFlag", "").equals("1")) {views.setImageViewResource(R.id.SD_ImgView, R.drawable.sd);} else {views.setImageViewResource(R.id.SD_ImgView, R.drawable.sd1);}if (sharedPreferences.getString("usbFlag", "").equalsIgnoreCase("1")) {views.setImageViewResource(R.id.USB_ImgView, R.drawable.udisk);} else {views.setImageViewResource(R.id.USB_ImgView, R.drawable.udisk1);}appManager.updateAppWidget(thisWidget, views);}private String getUserString(int r) {return this.getResources().getString(r);}/** * 初始化设备列表信息,包括是否支持该设备和该设备是否可用等信息 */private void initEquipmentListStatus() {usbList.clear();File currentDirectoryFile = new File(getUserString(R.string.mnt));File[] fileList = currentDirectoryFile.listFiles();judgeEquipmentExist(fileList);if (fileList != null) {for (int i = 0; i < fileList.length; i++) {File file = fileList[i];setUsbList(file);}}refreshButtonState();}/** * @author  * @category 判断是否存在SD卡,TF卡和USB设备 * @param fileList */private void judgeEquipmentExist(File[] fileList) {UsbModel sdcardModel, udiskModel;sdcardModel = new UsbModel();udiskModel = new UsbModel();sdcardModel.setName(getUserString(R.string.sdcard));udiskModel.setName(getUserString(R.string.udisk));// 查找是否存在SD卡设备for (int i = 0; i < fileList.length; i++) {if (getUserString(R.string.sdcard).equalsIgnoreCase(fileList[i].getName())) {sdcardModel.setExist(1);// 设备存在// Log.d("myDebug", "sd exist!");sdcardModel.setUsbType(getUserString(R.string.sdcard));// sdcardModel.setFile(file);break;} else if (i == fileList.length - 1) {sdcardModel.setExist(0);// 设备不存在sdcardModel.setState("0");// 不存在肯定不可用break;}}// 查找是否存在USB设备for (int i = 0; i < fileList.length; i++) {if (getUserString(R.string.udisk).equalsIgnoreCase(fileList[i].getName())) {// Log.d("myDebug", "usb exist!");udiskModel.setExist(1);// 设备存在udiskModel.setUsbType(getUserString(R.string.udisk));// udiskbreak;} else if (i == fileList.length - 1) {udiskModel.setExist(0);// 设备不存在udiskModel.setState("0");udiskModel.setUsbType(getUserString(R.string.udisk));break;}}usbList.add(sdcardModel);usbList.add(udiskModel);}@Overridepublic IBinder onBind(Intent intent) {// TODO Auto-generated method stubreturn null;}/** *获取加载卸载服务,因平台而异,相应修改后使用 */private synchronized IMountService getMountService() {if (mMountService == null) {IBinder service = ServiceManager.getService("mount");if (service != null) {mMountService = IMountService.Stub.asInterface(service);} else {Toast.makeText(getApplicationContext(),getUserString(R.string.operation_null),Toast.LENGTH_SHORT).show();}}return mMountService;}}

        上面给的是service处理部分代码,这里由于IMountService和StorageManager和具体平台驱动相关,大家可根据不同平台修改后使用,这里主要讲下这个service的处理思路,首先上一篇的setOnClickPendingIntent函数绑定了组件按钮的点击事件,因为我们绑定的是servcie所以它会通过调用onstart启动service,并且将绑定时intent对象传递过来,此时我们可以通过判断intent的action对象来确定是sd卡或者是usb设备按钮点击了,这个在ontart中的dealbuttonmsg函数中处理了,这里改变按钮状态交由设备侦听器来处理,设备状态改变时,组件图标相应改变,刚刚开始设计时,由于mount和unmount后没有状态返回,所以我写的代码是每次改变按钮再去判断设备状态然后进行相应的改变,后面发现是多余的,其实每次点击按钮后,首先判断存储在文件中设备的状态,确定调用mount或者是unmount函数,设备只要改变了,侦听器就会调用UpdateusbState函数来刷新文件中设备状态和桌面组件图标状态。

    其余代码功能我就不一一介绍了,代码注释给的很清楚,下一篇给出如何过滤并停止相应进程任务管理器。