手机卫士-08

手机卫士-08

课1

上一节课:软件管家改善 activityappmanager.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/textview_title_style"
        android:gravity="center"
        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="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="剩余手机内部" />

        <TextView
            android:id="@+id/tv_sd"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="sd卡:" />
    </LinearLayout>

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

        <LinearLayout
            android:id="@+id/ll_loading"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center"
            android:orientation="vertical"
            android:visibility="invisible" >

            <ProgressBar
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="玩命加载中...." />
        </LinearLayout>

        <include layout="@layout/list_view" />

        <TextView
            android:id="@+id/tv_appsize_lable"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:background="#ff888888"
            android:text="用户程序:5个"
            android:textColor="@android:color/white" />
    </FrameLayout>

</LinearLayout>

给显示应用程序和系统程序列表加上可以移动的小条目,我们之前的是固定在第一行,不美观 AppManagerActivity.java 继续完善应用程序条目和系统程序条目的显示 在handler里的listview.setAdapter下方进行控件赋值 但是在老师的软件管家里下滑时第一栏显示的应用程序size还是固定在那里,因此在 AppManagerActivity.java里给listview增加滚动监听事件,当listview滚动到某个位置的时候修改textView

AppManagerActivity.java

/**
 * 显示应用程序列表的状态
 */
private TextView tv_appsize_lable;

tv_appsize_lable = (TextView) findViewById(R.id.tv_appsize_lable);

    ViewUtils.inject(this);

    /**
     * 设置listview的一个滚动监听事件
     */
    list_view.setOnScrollListener(new OnScrollListener() {
        @Override
        public void onScrollStateChanged(AbsListView view, int scrollState) {
            // 滚动--》静止 --》滚动
        }

        /**
         * 当界面滚动的时候调用的方法
         * 
         * @param firstVisibleItem
         *            第一个可见条目的位置
         */
        @Override
        public void onScroll(AbsListView view, int firstVisibleItem,
                int visibleItemCount, int totalItemCount) {
            if (userAppInfos != null && systemAppInfos != null) {
                //在滑动listView的时候,第一位的位置已经大于等于应用程序的长度+1时,就把在第一个位置的textView改成系统程序的样式和其长度
                if (firstVisibleItem >= (userAppInfos.size() + 1)) {
                    // 用户把界面拖动到下方
                    tv_appsize_lable.setText("系统程序:"
                            + systemAppInfos.size() + "个");
                } else {
                    // 用户把界面拖动到上方
                    tv_appsize_lable.setText("用户程序:" + userAppInfos.size()
                            + "个");
                }
            }
            //当滑动时就关闭弹框窗口
            dismissPopupWindow();
        }
    });


private Handler handler = new Handler() {
    public void handleMessage(android.os.Message msg) {
        // 加载完成之后。隐藏进度条
        ll_loading.setVisibility(View.INVISIBLE);
        adapter = new AppManagerAdapter(
                AppManagerActivity.this, infos);

        list_view.setAdapter(adapter);
        tv_appsize_lable.setText("用户程序:" + userAppInfos.size() + "个");
    };
};

如何实现像微信用户列表的分类显示名字头字母的分类显示。 在activityappmanager.xml里进行调整marginTop

继续实现点击app的条目是实现一些功能,例如卸载等操作

以前是弹出一些dialog,现在使用一些新显示示例。 

技术分享

显示老师在低版本的这种气泡式的显示画面提供功能。 这种小气泡别名叫popup window 弹出窗体 轻量级比dialog,dialog重量级,一般显示在窗体的居中位置。 所以老师的需求就是在每个小条目点击的时候就弹出气泡式窗体。 AppManagerActivity.java 给listview的item条目注册一个点击事件 list_view.setOnItemClickListener

AppManagerActivity.java

// 给listview 的item条目注册一个点击事件
        list_view.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id) {

根据position可以把小条目的对象取出来,通过MyAdapter里的getItem去获取对象,所以在listener里配合Adapter的getItem使用获取条目对象。 测试点击listview的时候对象信息拿取完成后,就在listener里使用popupWindow,气泡窗体:PopupWindow popupWindow = new PopupWindow(contentView, 宽,高) 在contentView里放入一个new出来的文本控件对象 然后显示

AppManagerActivity.java

// 准备弹出窗体,指定view和宽高信息
popupWindow = new PopupWindow(contentView, -2, -2);
popupWindow.setBackgroundDrawable(new ColorDrawable(
        Color.TRANSPARENT));
// 显示到指定的位置
int[] location = new int[2];
view.getLocationInWindow(location);// 获取了view对象在窗体上的位置
popupWindow.showAtLocation(parent, Gravity.LEFT
        + Gravity.TOP, 50, location[1] - 15);

测试时非常丑,因此修改popupWindow的属性。 PopupWindow.setBackGroundDrawable 效果坑爹,把PopupWindow修改成单例,把其改为类成员变量,一次区分新旧窗体 并做判断:显示悬浮窗体之前,应该判断是否有旧的窗体存在。 isShowing() 继续测试,发现打开了窗体,不点击关闭就一直处在窗体中; 因此我们把窗体关闭封装成方法,然后在listview的滚动监听事件里监听并关闭窗体。

AppManagerActivity.java

private void dismissPopupWindow() {
    // 显示悬浮窗体之前,应该判断是否有旧的窗体存在
    if (popupWindow != null && popupWindow.isShowing()) {
        popupWindow.dismiss();
        popupWindow = null;
    }
}

课2

继续气泡窗体 新建一个popupappitem.xml,替代之前的textView去填充气泡窗体:PopupWindow popupWindow = new PopupWindow(contentView, 宽,高)

popupappitem.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:gravity="center_horizontal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical" >

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/img1" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="卸载" />
    </LinearLayout>

     <LinearLayout
           android:id="@+id/ll_start"
         android:gravity="center_horizontal"
         android:layout_marginLeft="5dip"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical" >

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/img2" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="启动" />
    </LinearLayout>

      <LinearLayout
            android:id="@+id/ll_share"
              android:gravity="center_horizontal"
         android:layout_marginLeft="5dip"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical" >

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/img3" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="分享" />
    </LinearLayout>

       <LinearLayout
             android:id="@+id/ll_detail"
               android:gravity="center_horizontal"
         android:layout_marginLeft="5dip"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical" >

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/img4" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="信息" />
    </LinearLayout>

</LinearLayout> 

技术分享

样式

然后进行资源填充。

// 准备一个要显示到界面的view对象

View contentView = View.inflate(AppManagerActivity.this,R.layout.popup_app_item, null); 

技术分享

(暂时效果) 然后注释掉setBackground

老师介绍sdk画图片方法。tools目录-->draw 9-patch--->画图

技术分享

技术分享

 这样点击后编辑出来的png在android里如果强迫拉伸后也不会变型了。 继续调整窗体的位置、showAtLocation方法里修改

// 显示到指定的位置
int[] location = new int[2];
view.getLocationInWindow(location);// 获取了view对象在窗体上的位置
popupWindow.showAtLocation(parent, Gravity.LEFT
        + Gravity.TOP, 50, location[1] - 15);
        + 

继续给气泡弹出加上动画效果

加上缩放的动画ScaleAnimation

// 注意:重要细节,动画的播放要求窗体一定有背景颜色。

ScaleAnimation sa = new ScaleAnimation(0.2f, 1.0f, 0.2f,
        1.0f, Animation.RELATIVE_TO_SELF, 0,
        Animation.RELATIVE_TO_SELF, 0.5f);
sa.setDuration(300);
contentView.startAnimation(sa);

但是测试时发现动画效果没出来,

原因:没考虑窗体的背景颜色。如果窗体没有背景颜色,那么动画效果显示不出来。 然后尝试取消掉之前注销的背景,然后发现气泡窗体有动画效果了,但是还是很难看。

// 准备弹出窗体,指定view和宽高信息
popupWindow = new PopupWindow(contentView, -2, -2);
popupWindow.setBackgroundDrawable(new ColorDrawable(
        Color.TRANSPARENT));

所以把之前的绿色背景改成透明的就ok

继续实现popup里的功能点击事件。(卸载、启动、分享、信息) 在AppManagerActivity里拿到控件的变量。 在点击事件里那到xml里的控件变量。 在每个控件设置点击监听事件。 但是这些监听事件在监听事件里嵌套太深,那么就让本类实现接口。 然后实现点击事件

public class AppManagerActivity extends Activity implements OnClickListener {

    ll_start = (LinearLayout) contentView
            .findViewById(R.id.ll_start);
    ll_detail = (LinearLayout) contentView
            .findViewById(R.id.ll_detail);
    ll_uninstall = (LinearLayout) contentView
            .findViewById(R.id.ll_uninstall);
    ll_share = (LinearLayout) contentView
            .findViewById(R.id.ll_share);
    ll_start.setOnClickListener(AppManagerActivity.this);
    ll_detail.setOnClickListener(AppManagerActivity.this);
    ll_uninstall.setOnClickListener(AppManagerActivity.this);
    ll_share.setOnClickListener(AppManagerActivity.this);


/**
 * 界面里面控件的点击事件
 */
@Override
public void onClick(View v) {
    switch (v.getId()) {
    case R.id.ll_share:
        Log.i(TAG, "分享:" + clickedAppInfo.getAppName());
        shareApplication();
        break;
    case R.id.ll_start:
        Log.i(TAG, "启动:" + clickedAppInfo.getAppName());
        startApplication();
        break;
    case R.id.ll_uninstall:
        Log.i(TAG, "卸载:" + clickedAppInfo.getAppName());
        uninstallApplication();
        break;
    case R.id.ll_detail:
        Log.i(TAG, "详细信息:" + clickedAppInfo.getAppName());
        showApplicationDetail();
        break;
    }
    dismissPopupWindow();
}

先实现分享:模板代码(以后使用。),在公司里直接复制粘贴:老师带我们看源码:--->编写短信发给指定人。shareApplication.java在AppManagerActivity.jvava

看系统上层所有应用的源代码包--->mms--->AndroidManifest.xml 把清单文件的部分代码复制到了shareApplication里,对照用意图来编写。

/**
 * 分享应用程序
 */
private void shareApplication() {
    // <action android:name="android.intent.action.SEND" />
    // <category android:name="android.intent.category.DEFAULT" />
    // <data android:mimeType="text/plain" />
    Intent intent = new Intent();
    intent.setAction("android.intent.action.SEND");
    intent.addCategory("android.intent.category.DEFAULT");
    intent.setType("text/plain");
    intent.putExtra(Intent.EXTRA_TEXT,
            "推荐您使用一款软件,名称叫:" + clickedAppInfo.getAppName());
    startActivity(intent);
}

使用源代码加意图开启分享功能。(容易)

技术分享

课3

开发卸载功能:总结成技巧!!! 回顾之前的下载安装APK。 观看源码-->上层源码--->packageInstall-->清单文件--->发现有几个Activity里的intent节点--->我们可以通过这些intent节点去通过意图调用他们 在AppManagerActivity.java里实现卸载应用程序方法uninstallAppliacation() 使用意图调用源代码中的卸载activity,这里注意技巧!! 这种方法以后再编程时想调用系统的应用,就观察系统的源码-->清单文件里观察intent-filter节点,然后使用在代码里用意图调用。 但是发现一个bug,点击卸载后但是listview里还是没有刷新软件被卸载,虽然已经被现在了 所以我们需要使用广播接收者来监听应用的卸载情况,以此来实时更新listview 内部的卸载应用程序的广播接收者 InnerUnInstallReceiver 然后在oncreate里进行注册该内部广播接收者。(注意一定要记得设置广播关心的数据类型:是包被卸载的类型)

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_app_manager);
    //初始化注册内部的广播接受者
    receiver = new InnerUninstallAppReceiver();
    IntentFilter filter = new IntentFilter();
    //指定关心 应用程序卸载的广播事件
    filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
    //注意:一定要记得设置 广播关心的数据类型 是包被卸载的类型
    filter.addDataScheme("package");
    //注册广播接受者
    registerReceiver(receiver, filter);

然后在activity里的ondestroy里注销掉内部广播接收者。

@Override
protected void onDestroy() {
    //取消内部的广播接受者
    unregisterReceiver(receiver);
    receiver = null;
    super.onDestroy();
}

首先搭建框架--->并测试框架是否成功--->在内部广播框架里输出一些广播接收到的应用卸载的信息:包名

广播框架搭建好了,然后在广播里实现逻辑。(更新listview) 使用for循环去匹配,匹配对了就删去listview里的条目-->并更新 检查是否有报错:报了,数据冲突异常:所以新定义一个对象集合:unInstalledInfo 然后在for里进行迭代,避免了数据冲突异常。 测试成功!程序卸载了动态刷新界面

/**
 * 内部的卸载应用程序的广播接受者
 */
private class InnerUninstallAppReceiver extends BroadcastReceiver{
    @Override
    public void onReceive(Context context, Intent intent) {
        System.out.println("----------------内部广播接受者,发现卸载了应用"+intent.getData().toString());
        //package:com.example.gagaga
        AppInfo uninstalledInfo = null;
        for(AppInfo info: userAppInfos){
            if(("package:"+info.getPackageName()).equals(intent.getData().toString())){
                uninstalledInfo = info;
                break;
            }
        }
        userAppInfos.remove(uninstalledInfo);
        adapter.notifyDataSetChanged();
    }
}

开发启动功能:startApplication

每个app里的清单文件的逻辑 发现入口activity必须满足两个条件:1、action为main2、Launcher 如何获取app里的这两个条件?

PackageManager类

/**
 * 启动应用程序
 */
private void startApplication() {
    PackageManager pm = getPackageManager();
    Intent intent = pm.getLaunchIntentForPackage(clickedAppInfo.getPackageName());
    if(intent!=null){
        startActivity(intent);
    }else{
        Toast.makeText(this, "无法启动该应用程序", 0).show();
    }
}

展示应用信息:调用源码的应用信息界面

从低版本的android系统去打开应用信息界面。 寻找——>点击一个应用的详细信息,发现控制台有打印信息

技术分享

在上层源码的setting里找到清单文件--->InstallAppDetail--->这就是关键信息 实现展示应用信息的方法:showApplicationDetail() 使用意图去打开! 测试

    /**
     * 显示应用程序的详细信息
     */
    private void showApplicationDetail() {
//      <action android:name="android.settings.APPLICATION_DETAILS_SETTINGS" />
//        <category android:name="android.intent.category.DEFAULT" />
//        <data android:scheme="package" />
        Intent intent = new Intent();
        intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
        intent.addCategory("android.intent.category.DEFAULT");
        intent.setData(Uri.parse("package:"+clickedAppInfo.getPackageName()));
        startActivity(intent);
    }

软件管家的全部功能都实现完了


资料下载

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。