MobileSafeNotes Day08

##Day08##

#8.1删除通话记录# (知道内容观察者怎么去用)

内容观察者
	final ContentResolver contentResolver = getContentResolver();
	//获取内容提供者的地址call_log   calls表示地址:calls
	//生成uri地址
	final Uri uri = Uri.parse("content://call_log/calls");
	//删除通话记录,因为电话来了之后,因为系统是要将电话添加到数据库中的,所以需要耗费一定的时间,也就是说系统不是来电一瞬间就添加到数据库中的,而是过了一段时间才添加
	//内容观察者,notifyForDescendents:是否精确匹配 true:精确匹配 	false:模糊匹配
	contentResolver.registerContentObserver(uri, true, new ContentObserver(new Handler()) {
			//当内容提供者内容变化的时候会调用的操作
			@Override
			public void onChange(boolean selfChange) {
				super.onChange(selfChange);
				//where : 查询条件
				//selectionArgs :查询条件的参数
				contentResolver.delete(uri, "number=?", new String[]{incomingNumber});
				//注销内容观察者
				contentResolver.unregisterContentObserver(this);
			}
	});

#8.2获取应用程序信息# (重点)

/**
 * 获取系统中安装所有应用程序
 * @return
 */
public static List<AppInfo> getAppInfos(Context context){
	List<AppInfo> list  = new ArrayList<AppInfo>();
	//1.获取出包的管理者
	PackageManager pm = context.getPackageManager();
	//2.获取系统中安装的所有应用信息
	List<PackageInfo> installedPackages = pm.getInstalledPackages(0);
	//3.遍历集合
	for (PackageInfo packageInfo : installedPackages) {
		//4.获取应用程序的包名
		String packageName = packageInfo.packageName;
		//5.获取应用程序的版本号
		String versionName = packageInfo.versionName;
		//6.获取应用程序中applicaiton的信息
		ApplicationInfo applicationInfo = packageInfo.applicationInfo;
		//6.1获取应用程序的图标
		Drawable icon = applicationInfo.loadIcon(pm);
		//6.2获取应用程序的名称
		String name = applicationInfo.loadLabel(pm).toString();
		//6.3判断应用程序是否是系统应用
		//获取应用系统中的所有标签
		boolean isUser;
		int flags = applicationInfo.flags;
		if((flags & applicationInfo.FLAG_SYSTEM) == applicationInfo.FLAG_SYSTEM){
			//系统应用
			isUser = false;
		}else{
			//用户应用
			isUser = true;
		}
		//6.4是否安装到sd卡
		boolean isSD;
		if((flags & applicationInfo.FLAG_EXTERNAL_STORAGE) == applicationInfo.FLAG_EXTERNAL_STORAGE){
			//安装到了SD卡
			isSD = true;
		}else{
			//安装到手机内存
			isSD = false;
		}
		//7.将获取的信息通过bean对象进行保存
		AppInfo appInfo = new AppInfo(name, icon, packageName, versionName, isSD, isUser);
		//8.添加到list集合中
		list.add(appInfo);
	}
	return list;
}

#8.3软件管理的界面展示# (重点,listview复用缓存,添加textview条目)

1.创建activity,清单文件配置,复制选择联系人界面,修改控件的id
2.在activity中使用异步加载框架去加载数据
	private void filldata() {
	//获取应用程序信息
	new MyAsyncTask() {
		
		@Override
		public void preTask() {
			loading.setVisibility(View.VISIBLE);
		}
		
		@Override
		public void postTask() {
			lv_softmanager_applications.setAdapter(new MyAdapter());
			loading.setVisibility(View.INVISIBLE);//数据显示完成,隐藏进度条
		}
		
		@Override
		public void doinBack() {
			//获取应用程序信息
			list = AppEngine.getAppInfos(getApplicationContext());
		}
	}.execute();
}
3.在adapter使用listview缓存复用操作,并填充数据
	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		View view;
		ViewHolder viewHolder;
		if (convertView == null) {
			view = View.inflate(getApplicationContext(), R.layout.item_softmanager, null);
			//new ViewHolder
			viewHolder = new ViewHolder();
			//将初始化的控件保存到viewholder中
			viewHolder.iv_itemsoftmanager_icon = (ImageView) view.findViewById(R.id.iv_itemsoftmanager_icon);
			viewHolder.tv_itemsoftmanager_name = (TextView) view.findViewById(R.id.tv_itemsoftmanager_name);
			viewHolder.tv_itemsoftmanager_issd = (TextView) view.findViewById(R.id.tv_itemsoftmanager_issd);
			viewHolder.tv_itemsoftmanager_versionname = (TextView) view.findViewById(R.id.tv_itemsoftmanager_versionname);
			//将viewholder绑定到view上
			view.setTag(viewHolder);
		}else{
			//获取view
			view = convertView;
			//获取viewholder
			viewHolder = (ViewHolder) view.getTag();
		}
		//获取条目对应的信息
		AppInfo appInfo = list.get(position);
		//数据填充操作
		//设置图片
		viewHolder.iv_itemsoftmanager_icon.setImageDrawable(appInfo.getIcon());
		//设置名称
		viewHolder.tv_itemsoftmanager_name.setText(appInfo.getName());
		//设置安装位置
		if (appInfo.isSD()) {
			viewHolder.tv_itemsoftmanager_issd.setText("SD卡");
		}else{
			viewHolder.tv_itemsoftmanager_issd.setText("手机内存");
		}
		//设置版本号
		viewHolder.tv_itemsoftmanager_versionname.setText(appInfo.getVersion());
		return view;
	}
	
}
static class ViewHolder{
	ImageView iv_itemsoftmanager_icon;
	TextView tv_itemsoftmanager_name,tv_itemsoftmanager_issd,tv_itemsoftmanager_versionname;
}

#8.4用户程序和系统程序拆分#(重点)

1.在异步加载框架中,将list分拆成userappinfos和systemappinfos,分别存放用户程序和系统程序
		@Override
		public void doinBack() {
			//获取应用程序信息
			list = AppEngine.getAppInfos(getApplicationContext());
			//根据应用是否是用户程序将应用程序分别放到用户应用程序的集合和系统应用程序的集合
			userAppInfos = new ArrayList<AppInfo>();
			systemAppInfos = new ArrayList<AppInfo>();
			//遍历list集合,分拣用户程序和系统程序
			for (AppInfo appinfo : list) {
				if (appinfo.isUser()) {
					//用户程序
					userAppInfos.add(appinfo);
				}else{
					//系统程序
					systemAppInfos.add(appinfo);
				}
			}
		}
2.在adapter的getcount中将原来的list.size()改成userappinfos.size+systemappinfos.size
	@Override
	public int getCount() {
		//方便我们从不同的集合中拿出数据
		return userAppInfos.size()+systemAppInfos.size()
	}
3.因为用户程序和系统程序,我们要从不同的集合中去拿,所以在getview中要根据显示的条目数据去判断是从userAppInfos去拿数据还是从systemAppInfos中去拿数据
		//获取条目对应的信息
		AppInfo appInfo;
		//判断用户程序是否展示完
		if (position <= userAppInfos.size()-1) {
			//获取用户程序
			appInfo = userAppInfos.get(position);
		}else{
			//系统程序
			appInfo = systemAppInfos.get(position - userAppInfos.size());
		}
4.将数据分别显示了,但是还要添加textiview显示
	a.在getcount中添加两个条目的长度
		@Override
		public int getCount() {
			//方便我们从不同的集合中拿出数据
			return userAppInfos.size()+systemAppInfos.size()+2;
		}
	b.在getview中添加textview条目
		if (position == 0) {
			//添加用户程序多少个
			TextView textView = new TextView(getApplicationContext());
			textView.setText("用户程序("+userAppInfos.size()+")");
			textView.setTextColor(Color.WHITE);
			textView.setBackgroundColor(Color.GRAY);
			return textView;
		}else if(position == userAppInfos.size()+1){
			//添加系统程序多少个
			TextView textView = new TextView(getApplicationContext());
			textView.setText("系统程序("+systemAppInfos.size()+")");
			textView.setTextColor(Color.WHITE);
			textView.setBackgroundColor(Color.GRAY);
			return textView;
		}
	c.因为添加了两个条目,所以要改变获取数据的方式
		//获取条目对应的信息
		AppInfo appInfo;
		//判断用户程序是否展示完
		if (position <= userAppInfos.size()) {
			//获取用户程序
			appInfo = userAppInfos.get(position-1);
		}else{
			//系统程序
			appInfo = systemAppInfos.get(position - userAppInfos.size()-2);
		}

#8.5浮动显示程序多少个操作# (重点)

给listview添加滑动监听
	lv_softmanager_applications.setOnScrollListener(new OnScrollListener() {
		//滑动状态改变的时候调用
		@Override
		public void onScrollStateChanged(AbsListView view, int scrollState) {
			// TODO Auto-generated method stub
			
		}
		//滑动的时候调用
		//view : listview
		//firstVisibleItem : 界面可见的第一个条目的位置
		//visibleItemCount : 界面可见条目的个数,多少可见
		//totalItemCount : 总条目数   包含可见和不可见所有条目,listview的所有条目个数
		@Override
		public void onScroll(AbsListView view, int firstVisibleItem,
				int visibleItemCount, int totalItemCount) {
			//为null的原因:因为listview在初始化的时候就会调用onScroll
			if (userAppInfos != null && systemAppInfos !=null) {
				//根据可见条目来判断是否是显示的系统程序的个数,是显示系统程序多少个,不是显示用户程序多少个
				if (firstVisibleItem >= userAppInfos.size()+1) {
					tv_softmanager_count.setText("系统程序("+systemAppInfos.size()+")");
				}else{
					tv_softmanager_count.setText("用户程序("+userAppInfos.size()+")");
				}
			}
		}
	});
}

#8.6显示气泡# (重点)

/**
 * listview的条目的点击事件
 */
private void listviewitemClick() {
	lv_softmanager_applications.setOnItemClickListener(new OnItemClickListener() {

		@Override
		public void onItemClick(AdapterView<?> parent, View view,
				int position, long id) {
			//1.屏蔽用户程序多少个和系统程序多少个弹出气泡
			if (position == 0 || position == userAppInfos.size()+1) {
				return;
			}
			//2.获取软件信息
			//获取条目对应的信息
			AppInfo appInfo;
			//判断用户程序是否展示完
			if (position <= userAppInfos.size()) {
				//获取用户程序
				appInfo = userAppInfos.get(position-1);
			}else{
				//系统程序
				appInfo = systemAppInfos.get(position - userAppInfos.size()-2);
			}
			//4.判断有没有显示气泡 有的话关闭气泡
			hidePopuWindow();
			//3.弹出气泡

// TextView contentView = new TextView(getApplicationContext());
// contentView.setText(“我是popupwindow的布局控件”);
// contentView.setBackgroundColor(Color.RED);
View contentView = View.inflate(getApplicationContext(), R.layout.popu_window, null);
//3.1.创建气泡
//contentView : 要填充到气泡中的view对象
//width : 宽度
//height : 高度 100px像素
popupWindow = new PopupWindow(contentView, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
//3.3.获取条目位置,同时将气泡显示在条目位置上
int[] location = new int[2];//保存x和y的坐标
//location : int[] 包含有x和y的坐标
view.getLocationInWindow(location);//获取x和y的坐标,将x和y的坐标保存到int数组中
//获取坐标
int x = location[0];
int y = location[1];
//3.2.显示气泡
//parent : 表示popupwindow要挂载到那个控件中
//gravity、x、y就是控制popupwindow显示位置
popupWindow.showAtLocation(parent, Gravity.LEFT|Gravity.TOP, x+50, y);
}
});
}
/**
* 关闭popupwindow
*/
private void hidePopuWindow() {
if (popupWindow != null) {
popupWindow.dismiss();
popupWindow = null;
}
}

#8.7动画效果# (重点)

动画没有执行的原因:android中动画要想执行,必须让执行动画控件有背景才能执行,动画经过一些算法执行,但是popupwindow默认是没有背景的,所以控件执行才没有效果,疑问:布局文件中控件已经设置了背景没什么也不能执行动画,通过popupwindow进行展示的时候,其实就相当于在控件的外面有包裹了一层效果

			//5.添加动画效果
			//缩放动画
			//前四个:控制控件从0开始变化到控件的大小,动画中0:没有;1:整个控件的大小
			//后面四个:表示按照自身变化还是按照父控件变化
			//pivotXType : 类型     pivotXValue : 值
			//RELATIVE_TO_SELF : 按照自身变化
			//RELATIVE_TO_PARENT : 按照父控件变化
			ScaleAnimation scaleAnimation = new ScaleAnimation(0, 1, 0, 1, Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0.5f);
			scaleAnimation.setDuration(200);//动画的持续时间
			//渐变动画
			//从透明到不透明的效果
			AlphaAnimation alphaAnimation = new AlphaAnimation(0.4f, 1f);
			alphaAnimation.setDuration(200);
			
			//组合动画
			//shareInterpolator : 是否使用相同的动画插入器,true:使用相同的   false:各自使用各自
			AnimationSet animationSet = new AnimationSet(true);
			//添加动画
			animationSet.addAnimation(scaleAnimation);
			animationSet.addAnimation(alphaAnimation);
			//执行动画
			//动画没有执行原因
			contentView.startAnimation(animationSet);

	popupwindow设置背景
			//设置背景,TRANSPARENT : 透明
			popupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));

#8.8点击事件#

第三种点击方式,多个控件点击事件中
	1.让activity实现onclicklistener,实现其onclick方法
	2.给控件设置点击事件
		ll_popu_window_uninstall.setOnClickListener(SoftManagerActivity.this);
	3.在实现的onclick方法中进行相应的操作

#8.9卸载#

/**
 * 卸载
 */
private void uninstall() {
	/*
	 * <intent-filter>
            <action android:name="android.intent.action.VIEW" />
            <action android:name="android.intent.action.DELETE" />
            <category android:name="android.intent.category.DEFAULT" />
            <data android:scheme="package" /> package 表示格式是  package:应用程序的包名
        </intent-filter>
	 * 
	 */
	//判断是否是用户应用
	if (appInfo.isUser()) {
		//判断卸载的是否是自己
		if (!appInfo.getPackageName().equals(getPackageName())) {
			Intent intent = new Intent();
			intent.setAction("android.intent.action.DELETE");
			intent.addCategory("android.intent.category.DEFAULT");
			intent.setData(Uri.parse("package:"+appInfo.getPackageName()));
			startActivityForResult(intent, 0);
		}else{
			Toast.makeText(getApplicationContext(), "文明社会,杜绝自杀", 0).show();
		}
	}else{
		Toast.makeText(getApplicationContext(), "系统软件无法卸载,想卸载,请root先!!", 0).show();
	}

#8.10启动# (重点)

/**
 * 启动
 */
private void start() {
	//获取包的管理者
	PackageManager packageManager = getPackageManager();
	//根据包名获取启动应用程序的意图
	//packageName : 包名
	Intent intent = packageManager.getLaunchIntentForPackage(appInfo.getPackageName());
	if (intent != null) {
		startActivity(intent);
	}else{
		Toast.makeText(getApplicationContext(), "系统核心程序,无法打开", 0).show();
	}
}

#8.11详情#

打印的log

/**
 * 详情
 */
private void detail() {
	/**
	 *  act=android.settings.APPLICATION_DETAILS_SETTINGS   action
		dat=package:com.example.android.softkeyboard     data
		cmp=com.android.settings/.applications.InstalledAppDetails   要打开的界面
	 */
	Intent intent = new Intent();
	intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
	intent.setData(Uri.parse("package:"+appInfo.getPackageName()));
	startActivity(intent);
}

#8.12分享# (比较重要)

packages\apps\Mms\AndroidManifest.xml\.ui.ComposeMessageActivity
如何让一个应用具有分享功能
	要想让应用接受分享信息的功能,必须让activity在清单文件中配置
		<intent-filter>
           <action android:name="android.intent.action.SEND" />
           <category android:name="android.intent.category.DEFAULT" />
           <data android:mimeType="text/plain" />
    	</intent-filter>
分享的操作
	/**
	 * 分享
	 */
	private void share() {
		/**
		 * act=android.intent.action.SEND    action
		   typ=text/plain flg=0x3000000     type
           cmp=com.android.mms/.ui.ComposeMessageActivity (has extras)    要打开的界面   (has extras):表示传递内容过去
		 */
		Intent intent = new Intent();
		intent.setAction("android.intent.action.SEND");
		intent.setType("text/plain");
		intent.putExtra(Intent.EXTRA_TEXT, "发现一个很牛的杀毒软件"+appInfo.getName()+",下载地址,www.baidu.com,自己去搜。");
		startActivity(intent);
	}

shareSDK,第三方的分享sdk,微信,微博,qq

#8.13获取可用空间# (重点)

1.创建工具类
	/**
	 * 获取SD卡可用空间
	 * @return
	 */
	public static long  getSDAvailable(){
		//获取SD卡路径
		 File path = Environment.getExternalStorageDirectory();
		 //硬盘的操作
         StatFs stat = new StatFs(path.getPath());
         //获取每块的大小
         long blockSize = stat.getBlockSize();
         //获取总块数
         long totalBlocks = stat.getBlockCount();
         //获取可用的块数
         long availableBlocks = stat.getAvailableBlocks();
         
        return availableBlocks*blockSize;
	}
	/**
	 * 获取手机内存可用空间
	 * @return
	 */
	public static long  getROMAvailable(){
		//获取SD卡路径
		 File path = Environment.getDataDirectory();
		 //硬盘的操作
         StatFs stat = new StatFs(path.getPath());
         //获取每块的大小
         long blockSize = stat.getBlockSize();
         //获取总块数
         long totalBlocks = stat.getBlockCount();
         //获取可用的块数
         long availableBlocks = stat.getAvailableBlocks();
         
        return availableBlocks*blockSize;
	}
2.调用
	//获取可用内存信息,设置给相应控件
	//SD卡
	long sdAvailable = AppUtils.getSDAvailable();
	//kb -> mb
	String sd_size = Formatter.formatFileSize(this, sdAvailable);
	tv_softmanager_sd.setText("SD卡可用:"+sd_size);
	//手机内存
	long romAvailable = AppUtils.getROMAvailable();
	String rom_size = Formatter.formatFileSize(this, romAvailable);
	tv_softmanager_rom.setText("内存可用:"+rom_size);
  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值