小作坊的安全管家之软件管理

软件管理

作为安全管家里最为基本的功能之一,软件管家的工作大致包括读取内部存储容量剩余,内存卡容量剩余,系统应用列表,用户应用列表,先来看看我low了一脸的界面:


首先把我们的布局搭起来,整体的布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        style="@style/TitleStyle"
        android:text="软件管理" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >

        <TextView
            android:id="@+id/tv_romfree"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="内存可用XXX" />

        <TextView
            android:id="@+id/tv_sdfree"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="SD卡可用XXX" />
    </LinearLayout>

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <ListView
            android:id="@+id/lv_app"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >
        </ListView>

        <TextView
            android:id="@+id/tv_app"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#ff888888"
            android:textColor="#fff" />
    </FrameLayout>

</LinearLayout>

整个布局使用了垂直方向的线性布局,在软件管理这一标题栏中设置了style,因为每个功能的Activity中都会用到这种Style,所以设置通用的Style可以增加工作效率,TitleStyle内容设置在style.xml文件中
<style name="TitleStyle">
        <item name="android:layout_width">match_parent</item>
        <item name="android:layout_height">50dp</item>
        <item name="android:background">#8866ff00</item>
        <item name="android:gravity">center</item>
        <item name="android:textColor">@android:color/black</item>
        <item name="android:textSize">22sp</item>
    </style>

下面的大部分显示空间使用了帧布局,主要是为了实现用户应用顶栏,系统应用顶栏的顶部停留,喜闻乐见的ListView就不用详细介绍了,下面上ListView的item布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" >

    <ImageView
        android:paddingTop="5dip"
        android:paddingBottom="5dip"
        android:id="@+id/iv_icon"
        android:layout_width="45dip"
        android:layout_height="45dip"
        android:src="@drawable/ic_launcher" />

    <LinearLayout
        android:paddingTop="5dip"
        android:paddingBottom="5dip"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" >

        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal" >

            <TextView
                android:singleLine="true"
                android:id="@+id/tv_name"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:layout_weight="1.0"
                android:ellipsize="end"
                android:textSize="20sp"
                android:textColor="#000000"
                android:gravity="center_vertical"
                android:paddingLeft="5.0dip"
                android:text="标题" />

            <TextView
                android:textSize="14sp"
                android:textColor="#99000000"
                android:id="@+id/tv_apk_size"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:gravity="center_vertical"
                android:paddingRight="5.0dip"
                android:text="应用程序大小" />
        </LinearLayout>

        <TextView
            android:textSize="14sp"
            android:textColor="#99000000"
            android:id="@+id/tv_location"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:gravity="center_vertical"
            android:paddingLeft="5.0dip" />
    </LinearLayout>

</LinearLayout>
大家对照图上的显示就能清楚理解item布局。
说完布局就说一下软件管理的业务逻辑:
看图片我们需要拿到手机的内部存储剩余,外部存储剩余,每个应用的详细信息,我们先写一个类,用来存取传递应用的详细信息
import android.graphics.drawable.Drawable;

public class AppInfo {

	/**
	 * 软件图标
	 */
	private Drawable icon;
	/**
	 * 软件名称
	 */
	private String apkName;
	/**
	 * 软件名字
	 */
	private long apkSize;
	/**
	 * 是否用户软件
	 * 是则为true
	 * 否则为false
	 */
	private boolean userApp;
	/**
	 * 软件的包名
	 */
	private String apkPackageName;
	/**
	 * 放置的位置
	 */
	private boolean isRom;
	public Drawable getIcon() {
		return icon;
	}
	public void setIcon(Drawable icon) {
		this.icon = icon;
	}
	public String getApkName() {
		return apkName;
	}
	public void setApkName(String apkName) {
		this.apkName = apkName;
	}
	public long getApkSize() {
		return apkSize;
	}
	public void setApkSize(long apkSize) {
		this.apkSize = apkSize;
	}
	public boolean isUserApp() {
		return userApp;
	}
	public void setUserApp(boolean userApp) {
		this.userApp = userApp;
	}
	public String getApkPackageName() {
		return apkPackageName;
	}
	public void setApkPackageName(String apkPackageName) {
		this.apkPackageName = apkPackageName;
	}
	public boolean isRom() {
		return isRom;
	}
	public void setRom(boolean isRom) {
		this.isRom = isRom;
	}
	@Override
	public String toString() {
		return "AppInfo [icon=" + icon + ", apkName=" + apkName + ", apkSize="
				+ apkSize + ", userApp=" + userApp + ", apkPackageName="
				+ apkPackageName + ", isRom=" + isRom + "]";
	}
	
}

有了应用信息存储传递的地方,我们就要想办法把手机里的所有应用详细信息给获取出来,下面再创建一个类:
import java.io.File;
import java.util.ArrayList;
import java.util.List;

import com.mobileSafe.bean.AppInfo;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;

public class AppInfos {

	public static List<AppInfo> getAppInfos(Context context) {
		/**
		 * 新建一个list用来存放应用信息
		 */
		ArrayList<AppInfo> list = new ArrayList<AppInfo>();
		/**
		 * 获取包管理器
		 * 利用包管理器获取所有安装过应用的包信息并存放在list中
		 */
		PackageManager pm = context.getPackageManager();
		List<PackageInfo> installPackages = pm.getInstalledPackages(0);

		/**
		 * 获取每个PackageInfo中我们需要的信息
		 */
		for (PackageInfo installPackage : installPackages) {
			AppInfo appInfo = new AppInfo();

			/**
			 * 获取app的图标并设置
			 */
			Drawable loadIcon = installPackage.applicationInfo.loadIcon(pm);
			appInfo.setIcon(loadIcon);

			/**
			 * 获取app的名字并设置
			 */
			String loadLabel = installPackage.applicationInfo.loadLabel(pm).toString();
			appInfo.setApkName(loadLabel);

			/**
			 * 获取app的包名并设置
			 */
			String packageName = installPackage.packageName.toString();
			appInfo.setApkPackageName(packageName);

			/**
			 * 获取apk的资源路径
			 */
			String apkDir = installPackage.applicationInfo.sourceDir.toString();
			File file = new File(apkDir);
			/**
			 * 获取app的大小并设置
			 */
			long length = file.length();
			appInfo.setApkSize(length);

			// 获取应用标记,标记中存储了大量信息
			int flags = installPackage.applicationInfo.flags;
			/**
			 * 利用标记判断应用存放位置
			 */
			if ((flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
				appInfo.setRom(false);
			} else {
				appInfo.setRom(true);
			}
			/**
			 * 利用标记判断用户应用还是系统应用
			 */
			if ((flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
				appInfo.setUserApp(false);
			} else {
				appInfo.setUserApp(true);
			}
			
			list.add(appInfo);
		}
		return list;
	}

}

利用这个类获取应用信息并返回给Activity。
package com.lyang.mobileSafe.Activity;

import java.util.ArrayList;
import java.util.Formatter;
import java.util.List;

import com.example.mobileSafe.R;
import com.lyang.mobileSafe.bean.AppInfo;
import com.lyang.mobileSafe.engine.AppInfos;

import android.app.Activity;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;

public class AppManagerActivity extends Activity {

	private TextView romFree;
	private TextView sdFree;
	private ListView lv;
	private TextView tv_app;
	private List<AppInfo> appInfos;
	private List<AppInfo> userAppInfos;
	private List<AppInfo> systemAppInfos;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		/**
		 * 初始化UI
		 */
		initUI();
		initData();
	}

	/**
	 * 接受子线程消息
	 */
	private Handler handler = new Handler() {

		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			AppManagerAdapter adapter = new AppManagerAdapter();
			lv.setAdapter(adapter);

		}

	};

	/**
	 * 获取应用信息为耗时操作,所以要在子线程执行
	 */
	private void initData() {
		new Thread() {

			@Override
			public void run() {
				super.run();
				/**
				 * 获取应用信息
				 */
				appInfos = AppInfos.getAppInfos(AppManagerActivity.this);

				/**
				 * 新建两个分别存储用户应用信息,系统应用信息
				 */
				userAppInfos = new ArrayList<AppInfo>();
				systemAppInfos = new ArrayList<AppInfo>();

				for (AppInfo appInfo : appInfos) {
					if (appInfo.isUserApp()) {
						userAppInfos.add(appInfo);

					} else {
						systemAppInfos.add(appInfo);
					}
				}
				/**
				 * 向主线程发送空消息
				 */
				handler.sendEmptyMessage(0);
			}
		}.start();
	}

	/**
	 * 
	 * @author 
	 *listview需要用到的adapter,继承自BaseAdapter,更加灵活
	 *
	 */
	private class AppManagerAdapter extends BaseAdapter {

		/**
		 * 返回item数量
		 */
		@Override
		public int getCount() {
			return appInfos.size() + 2;
		}

		@Override
		public Object getItem(int position) {
			if (position == 0) {
				return null;
			} else if (position == userAppInfos.size() + 1) {
				return null;
			} else if (position < userAppInfos.size() + 1) {
				return userAppInfos.get(position - 1);
			} else if (position > userAppInfos.size() + 1) {
				return systemAppInfos.get(position - userAppInfos.size() - 2);
			}
			return null;
		}

		@Override
		public long getItemId(int position) {
			// TODO Auto-generated method stub
			return position;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {

			
			/**
			 * 这两种情况是显示用户应用,系统应用及其个数的TextView
			 */
			if (position == 0) {
				TextView textView = new TextView(AppManagerActivity.this);
				textView.setText("用户应用:" + userAppInfos.size());
				textView.setTextColor(Color.WHITE);
				textView.setBackgroundColor(Color.GRAY);
				return textView;
			} else if (position == userAppInfos.size() + 1) {
				TextView textView = new TextView(AppManagerActivity.this);
				textView.setText("系统应用:" + systemAppInfos.size());
				textView.setTextColor(Color.WHITE);
				textView.setBackgroundColor(Color.GRAY);
				return textView;
			}

			/**
			 * 在任一position时要取的appInfo的对应位置
			 */
			AppInfo appInfo = null;
			if (position < userAppInfos.size() + 1) {
				appInfo = userAppInfos.get(position - 1);
			} else if (position > userAppInfos.size() + 1) {
				appInfo = systemAppInfos
						.get(position - userAppInfos.size() - 2);
			}

			View view = null;
			ViewHolder holder;

			/**
			 * 优化item的显示,减少findViewById的次数
			 */
			if (convertView != null && convertView instanceof LinearLayout) {
				view = convertView;
				holder = (ViewHolder) view.getTag();
			} else {
				view = View.inflate(AppManagerActivity.this,
						R.layout.app_manager_item, null);
				holder = new ViewHolder();
				holder.icon = (ImageView) view.findViewById(R.id.iv_icon);
				holder.apkName = (TextView) view.findViewById(R.id.tv_name);
				holder.apkSize = (TextView) view.findViewById(R.id.tv_apk_size);
				holder.userApp = (TextView) view.findViewById(R.id.tv_location);
				view.setTag(holder);
			}

			holder.icon.setImageDrawable(appInfo.getIcon());
			holder.apkName.setText(appInfo.getApkName());
			holder.apkSize.setText(android.text.format.Formatter
					.formatFileSize(AppManagerActivity.this,
							appInfo.getApkSize()));
			if (!appInfo.isRom()) {
				holder.userApp.setText("外部存储");
			} else {
				holder.userApp.setText("手机内存");
			}
			
			return view;
		}

	}
	/**
	 * 
	 * @author 
	 * 设置内部类用于数据的存取
	 *
	 */

	static class ViewHolder {
		ImageView icon;
		TextView apkName;
		TextView apkSize;
		TextView userApp;
	}

	private void initUI() {
		setContentView(R.layout.activity_app_manager);

		lv = (ListView) findViewById(R.id.lv_app);
		romFree = (TextView) findViewById(R.id.tv_romfree);
		sdFree = (TextView) findViewById(R.id.tv_sdfree);
		tv_app = (TextView) findViewById(R.id.tv_app);
		/**
		 * 获取运行内存的剩余空间ROM
		 */
		long romFreeSpace = Environment.getDataDirectory().getFreeSpace();
		romFree.setText("内存可用:"
				+ android.text.format.Formatter.formatFileSize(
						AppManagerActivity.this, romFreeSpace));
		/**
		 * 获取内存卡剩余空间
		 */
		long sdcardFreeSpace = Environment.getExternalStorageDirectory()
				.getFreeSpace();
		sdFree.setText("sd卡可用:"
				+ android.text.format.Formatter.formatFileSize(
						AppManagerActivity.this, sdcardFreeSpace));

		lv.setOnScrollListener(new OnScrollListener() {

			@Override
			public void onScrollStateChanged(AbsListView view, int scrollState) {

			}

			/**
			 * 设置滚动时顶部TextView
			 */
			@Override
			public void onScroll(AbsListView view, int firstVisibleItem,
					int visibleItemCount, int totalItemCount) {
				if (userAppInfos != null && systemAppInfos != null) {
					if (firstVisibleItem > (userAppInfos.size())) {

						tv_app.setText("系统进程:" + systemAppInfos.size());
					} else {
						tv_app.setText("用户进程:" + userAppInfos.size());
					}
				}
			}
		});

	}

}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值