AppWidget开发实例讲解(二)

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 mounted
	private static final String state_unmount = "0";// state unmounted
	private 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管理器,用来更新RemoteView
	private 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启动等操作
	 */
	@Override
	public void onStart(Intent intent, int startId) {
		// TODO Auto-generated method stub
		super.onStart(intent, startId);
		refreshButtonState();
		dealButtonMsg(intent);
	}
	/**
	 * onCreate函数在service第一次创建时调用,这里将需要初始化的操作在这里完成
	 */
	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		super.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() {
		@Override
		public 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));
				// udisk
				break;
			} 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);
	}
	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		return 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函数来刷新文件中设备状态和桌面组件图标状态。

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值