泡泡窗有卸载,打开,分享以及显示详细信息等功能,显示详细信息需要读取配置的权限。
<uses-permission android:name="android.permission.WIFI_STATE_CHANGED"></uses-permission>
<uses-permission android:name="android.launcher2.permission.READ_SETTINGS"></uses-permission>
泡泡窗的布局文件item_popup.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/local_popup_bg"
android:orientation="horizontal" >
<LinearLayout
android:id="@+id/ll_uninstall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:orientation="vertical"
>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/img1"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="卸载"
/>
</LinearLayout>
<LinearLayout
android:id="@+id/ll_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:orientation="vertical"
>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/img2"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="运行"
/>
</LinearLayout>
<LinearLayout
android:id="@+id/ll_share"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:orientation="vertical"
>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/img3"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="分享"
/>
</LinearLayout>
<LinearLayout
android:id="@+id/ll_detail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:orientation="vertical"
>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/img3"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="详情"
/>
</LinearLayout>
</LinearLayout>
所有软件显示的主布局文件
activity_app_manager.xml
<?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_rom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="内存可用"
android:textSize="20sp"
android:textColor="@color/black"
android:layout_weight="1"
/>
<TextView
android:id="@+id/tv_sd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="内存可用"
android:textSize="20sp"
android:textColor="@color/black"
android:layout_weight="1"
/>
</LinearLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<include
android:id="@+id/list_view_callsafe"
layout="@layout/list_view_callsafe"
/>
<TextView
android:id="@+id/tv_app"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/black"
android:background="#ff888888"
android:text="第三方软件"
/>
</FrameLayout>
</LinearLayout>
泡泡窗功能实现的逻辑代码AppManagerActivity.java
package com.ldw.safe.Activity;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.text.format.Formatter;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.ScaleAnimation;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.TextView;
import com.ldw.safe.R;
import com.ldw.safe.bean.AppInfo;
import com.ldw.safe.engine.AppInfos;
import com.lidroid.xutils.ViewUtils;
import com.lidroid.xutils.view.annotation.ViewInject;
/*
* 软件管理
*/
public class AppManagerActivity extends Activity implements View.OnClickListener {
//不用findViewById的方法填充
@ViewInject(R.id.list_view_callsafe)
private ListView list_view_callsafe;
@ViewInject(R.id.tv_rom)
private TextView tv_rom;
@ViewInject(R.id.tv_sd)
private TextView tv_sd;
private List<AppInfo> appInfos;//所有应用的集合
private AppManagerAdapter adapter;
private ArrayList<AppInfo> userAppInfos;//第三方应用的集合
private ArrayList<AppInfo> systemAppInfos;//系统应用的集合
private AppInfo clickAppInfo;
private PopupWindow popupWindow;
@ViewInject(R.id.tv_app)
private TextView tv_app;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initUi();
initData();
}
@Override
public void onClick(View v) {
switch (v.getId()) {
//分享
case R.id.ll_share:
//跳转到信息界面,分享相关的内容,和下载地址
Intent share_localIntent = new Intent("android.intent.action.SEND");
share_localIntent.setType("text/plain");
share_localIntent.putExtra("android.intent.extra.SUBJECT", "f分享");
share_localIntent.putExtra("android.intent.extra.TEXT",
"Hi!推荐您使用软件:" + clickAppInfo.getApkName()+"下载地址:"+"https://play.google.com/store/apps/details?id="+clickAppInfo.getApkPackageName());
this.startActivity(Intent.createChooser(share_localIntent, "分享"));
popupWindowDismiss();
break;
//运行
case R.id.ll_start:
Intent start_localIntent = this.getPackageManager().getLaunchIntentForPackage(clickAppInfo.getApkPackageName());
this.startActivity(start_localIntent);
popupWindowDismiss();
break;
//卸载
case R.id.ll_uninstall:
//发送意图
Intent uninstall_localIntent = new Intent("android.intent.action.DELETE", Uri.parse("package:" + clickAppInfo.getApkPackageName()));
//跳转到卸载软件的界面
startActivity(uninstall_localIntent);
popupWindowDismiss();
break;
//详细信息
case R.id.ll_detail:
Intent detail_intent = new Intent();
detail_intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
detail_intent.addCategory(Intent.CATEGORY_DEFAULT);
detail_intent.setData(Uri.parse("package:" + clickAppInfo.getApkPackageName()));
startActivity(detail_intent);
break;
}
}
private class AppManagerAdapter extends BaseAdapter{
@Override
public int getCount() {
//多出2个特殊的条目
return userAppInfos.size() + systemAppInfos.size() + 2; }
@Override
public Object getItem(int position) {
//获取到ListView中应该显示的正常的对象
if(position == 0){
return null;
}else if(position == userAppInfos.size() + 1){
return null;
}
AppInfo appInfo;
if(position < userAppInfos.size() + 1){
//中间添加了一个条目,需要减掉
appInfo = userAppInfos.get(position - 1);
}else{
//多出了2个特殊条目
int location = 1 + userAppInfos.size() + 1;
appInfo = systemAppInfos.get(position - location);
}
return appInfo;
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if(position == 0){
//第三方应用程序的展示
TextView textView = new TextView(AppManagerActivity.this);
textView.setTextColor(Color.WHITE);
textView.setBackgroundColor(Color.GRAY);
textView.setText("第三方应用(" + userAppInfos.size() + ")");
return textView;
}else if(position == userAppInfos.size() + 1){
//系统程序的展示
TextView textView = new TextView(AppManagerActivity.this);
textView.setTextColor(Color.WHITE);
textView.setBackgroundColor(Color.GRAY);
textView.setText("系统应用(" + systemAppInfos.size() + ")");
return textView;
}
AppInfo appInfo;
if (position < userAppInfos.size() + 1) {
//把多出来的特殊的条目减掉
appInfo = userAppInfos.get(position - 1);
} else {
int location = userAppInfos.size() + 2;
appInfo = systemAppInfos.get(position - location);
}
View view = null;
ViewHoler holder;
//防止特殊条目的影响,特殊条目的LinearLayout是空的
if(convertView != null && convertView instanceof LinearLayout){
view = convertView;
holder = (ViewHoler) convertView.getTag();
}else{
view = View.inflate(AppManagerActivity.this, R.layout.item_app_manager, null);
holder = new ViewHoler();
holder.iv_icon = (ImageView) view.findViewById(R.id.iv_icon);
holder.tv_apksize = (TextView) view.findViewById(R.id.tv_apksize);
holder.tv_location = (TextView) view.findViewById(R.id.tv_location);
holder.tv_name = (TextView) view.findViewById(R.id.tv_name);
view.setTag(holder);
}
//AppInfo appInfo = appInfos.get(position);
holder.iv_icon.setBackground(appInfo.getIcon());
holder.tv_apksize.setText(Formatter.formatShortFileSize(AppManagerActivity.this, appInfo.getApkSize()));
holder.tv_name.setText(appInfo.getApkName());
if(appInfo.isRom()){
//手机内存
holder.tv_location.setText("手机内存");
}else{
//sd卡
holder.tv_location.setText("sd卡内存");
}
return view;
}
}
static class ViewHoler{
ImageView iv_icon;
TextView tv_apksize;
TextView tv_location;
TextView tv_name;
}
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg){
adapter = new AppManagerAdapter();
list_view_callsafe.setAdapter(adapter);
}
};
/*
* 初始化apk的数据
*/
private void initData() {
//子线程中初始化,防止anr
new Thread(){
@Override
public void 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();
}
//初始化界面
private void initUi() {
setContentView(R.layout.activity_app_manager);
//View viewById = findViewById(R.id.list_view_callsafe);
//不用findViewById的方法填充
ViewUtils.inject(this);
//获取到rom内存的剩余空间
long rom_freeSpace = Environment.getDataDirectory().getFreeSpace();
//获取到sd卡的剩余空间
long sd_freeSpace = Environment.getExternalStorageDirectory().getFreeSpace();
System.out.println("内存可用" + rom_freeSpace + "sd卡可用" + sd_freeSpace);
//格式化存储卡的大小
tv_rom.setText("内存可用" + Formatter.formatFileSize(this, rom_freeSpace));
tv_sd.setText("sd卡可用" + Formatter.formatFileSize(this, sd_freeSpace));
//list_view_callsafe的滚动事件监听
list_view_callsafe.setOnScrollListener(new OnScrollListener(){
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
//firstVisibleItem 第一个可见的条的位置
//visibleItemCount 一页可以展示多少个条目
//totalItemCount 总共的item的个数
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
System.out.println("firstVisibleItem==" + firstVisibleItem + "visibleItemCount==" + visibleItemCount + " totalItemCount==" + totalItemCount);
//清空现有的泡泡窗
popupWindowDismiss();
//滚动的时候根据应用的不同展示不同的特殊条目
if (userAppInfos != null && systemAppInfos != null) {
if (firstVisibleItem > (userAppInfos.size() + 1)) {
//系统应用程序
tv_app.setText("系统程序(" + systemAppInfos.size() + ")个");
} else {
//第三方应用程序
tv_app.setText("第三方程序(" + userAppInfos.size() + ")个");
}
}
}
});
//list_view_callsafe添加点击事件,弹出泡泡窗
list_view_callsafe.setOnItemClickListener(new OnItemClickListener(){
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
//获取当前点击的对象
Object obj = list_view_callsafe.getItemAtPosition(position);
if(obj != null && obj instanceof AppInfo){
//获取到被点击的应用对象
clickAppInfo = (AppInfo) obj;
View contentView = View.inflate(AppManagerActivity.this, R.layout.item_popup, null);
LinearLayout ll_uninstall = (LinearLayout) contentView.findViewById(R.id.ll_uninstall);
LinearLayout ll_share = (LinearLayout) contentView.findViewById(R.id.ll_share);
LinearLayout ll_start = (LinearLayout) contentView.findViewById(R.id.ll_start);
LinearLayout ll_detail = (LinearLayout) contentView.findViewById(R.id.ll_detail);
//添加点击事件
//需要继承implements View.OnClickListener,在onClic中实现了相应的点击方法
ll_uninstall.setOnClickListener(AppManagerActivity.this);
ll_share.setOnClickListener(AppManagerActivity.this);
ll_start.setOnClickListener(AppManagerActivity.this);
ll_detail.setOnClickListener(AppManagerActivity.this);
//清空现有的泡泡窗
popupWindowDismiss();
//ViewGroup.LayoutParams.WRAP_CONTENT表示包裹内容,也可以直接写-2
popupWindow = new PopupWindow(contentView, ViewGroup.LayoutParams.WRAP_CONTENT, -2);
//需要注意:使用PopupWindow 必须设置背景。不然没有动画
popupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
//location第一个值表示x,第二个值表示y
int[] location = new int[2];
//获取view展示到窗体上面的位置,后面两个参数表示在整个屏幕中坐标的相对位置
view.getLocationInWindow(location);
popupWindow.showAtLocation(parent, Gravity.LEFT + Gravity.TOP, 70, location[1]);
//动画效果
ScaleAnimation sa = new ScaleAnimation(0.5f, 1.0f, 0.5f, 1.0f,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
sa.setDuration(3000);
contentView.startAnimation(sa);
}
}
});
}
private class UninstallReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
System.out.println("接收到卸载的广播");
}
}
private void popupWindowDismiss() {
//泡泡窗格式化
if(popupWindow != null && popupWindow.isShowing()){
popupWindow.dismiss();
popupWindow = null;
}
}
//activity销毁的时候关闭泡泡窗,不然会打印错误信息
@Override
protected void onDestroy() {
popupWindowDismiss();
super.onDestroy();
}
}