android自定义桌面(launcher)

    有时候需要开发一个自己的桌面程序,特别是做产品开发的开发人员,android自定义桌面其实就是一个launcher,然后在相应的activity中把系统中的所有APK加载进来,显示相应的icon图标。
开发自定义桌面需要用到以下几个类
1,ComponentName:组件名称,通常用来打开其他应用程序中的Activity或服务。,
2,PackageInfo:包含了一些信息的基类,它的直接子类有:ApplicationInfo、ComponentInfo、InstrumentationInfo、PermissionGroupInfo、PermissionInfo。它的间接子类有:ActivityInfo、ProviderInfo、ServiceInfo。这个类包含的信息对于所有包中项目是平等的。这些Package items是被Package manager所持有的,这个类提供了属性的非常普通的基本设置。通过 PackageInfo 获取具体信息方法:
    包名获取方法:packageInfo.packageName
    icon获取获取方法:packageManager.getApplicationIcon(applicationInfo)
    应用名称获取方法:packageManager.getApplicationLabel(applicationInfo)
    使用权限获取方法:packageManager.getPackageInfo(packageName,PackageManager.GET_PERMISSIONS).requestedPermissions

3,ResolveInfo:这个类是通过解析一个与IntentFilter相对应的intent得到的信息。它部分地对应于从AndroidManifest.xml的标签收集到的信息。通过 ResolveInfo 获取具体信息方法:
    包名获取方法:resolve.activityInfo.packageName
    icon获取获取方法:resolve.loadIcon(packageManager)
    应用名称获取方法:resolve.loadLabel(packageManager).toString()

4,PackageManger : 获得已安装的应用程序信息,常用方法: 
    public abstract PackageManager getPackageManager()  //功能:获得一个PackageManger对象  
    public abstract Drawable getApplicationIcon(String packageName) //参数: packageName 包名,功能:返回给定包名的图标,否则返回null
    public abstract ApplicationInfo   getApplicationInfo(String packageName, int flags) //参数:packagename 包名 flags 该ApplicationInfo是此flags标记,通常可以直接赋予常数0即可,功能:返回该ApplicationInfo对象
    public abstract List  getInstalledApplications(int flags) //参数:flag为一般为GET_UNINSTALLED_PACKAGES,那么此时会返回所有ApplicationInfo。我们可以对ApplicationInfo的flags过滤,得到我们需要的。功能:返回给定条件的所有PackageInfo

    public abstract List  getInstalledPackages(int flags) //参数如上,功能:返回给定条件的所有PackageInfo

首先,需要在manifest中加入



系统启动后,ActivityManagerService会寻找系统中的"android.intent.category.HOME",然后进行加载,如果"android.intent.category.HOME"有多个,则会让其进行选择,完整的如下




    
    
    
        
            
                
  				
                
                
            
        

 />
    

需定义一个xml来定义桌面的布局:


然后,实现功能函数:

private ArrayList mApps;
private int mNumAppsPages;
private int mMaxAppCellCountX, mMaxAppCellCountY;
 
public void setApps(ArrayList list) {
    mApps = list;
    //Collections.sort(mApps, LauncherModel.APP_NAME_COMPARATOR);
    updatePageCounts();
        
    if (testDataReady())requestLayout();
}

public void addApps(ArrayList list) {
    addAppsWithoutInvalidate(list);
    updatePageCounts();
    invalidatePageData();
}

public void removeApps(ArrayList list) {
    removeAppsWithoutInvalidate(list);
    updatePageCounts();
    invalidatePageData();
}

public void updateApps(ArrayList list) {
    removeAppsWithoutInvalidate(list);
    addAppsWithoutInvalidate(list);
    updatePageCounts();
    invalidatePageData();
}
private void updatePageCounts() {
    mNumAppsPages = (int) Math.ceil((float) mApps.size() / (mCellCountX * mCellCountY));
}

private boolean testDataReady() {
    // We only do this test once, and we default to the Applications page, so we only really
    // have to wait for there to be apps.
    // TODO: What if one of them is validly empty   
	return !mApps.isEmpty();
}

private void addAppsWithoutInvalidate(ArrayList list) {
    // We add it in place, in alphabetical order
    int count = list.size();
    for (int i = 0; i < count; ++i) {
        ApplicationInfo info = list.get(i);
        int index = Collections.binarySearch(mApps, info, ApplicationInfoComparator());
        if (index < 0) {
            mApps.add(-(index + 1), info);
        }
    }
}

static class ApplicationInfoComparator implements Comparator {
	@Override
	public int compare(ApplicationInfo a, ApplicationInfo b) {
	    return a.arrID - b.arrID;
	}
}


private void removeAppsWithoutInvalidate(ArrayList list) {
    // loop through all the apps and remove apps that have the same component
    int length = list.size();
    for (int i = 0; i < length; ++i) {
        ApplicationInfo info = list.get(i);
        int removeIndex = findAppByComponent(mApps, info);
        if (removeIndex > -1) {
            mApps.remove(removeIndex);
        }
    }
}

private int findAppByComponent(List list, ApplicationInfo item) {
    ComponentName removeComponent = item.intent.getComponent();
    int length = list.size();
    for (int i = 0; i < length; ++i) {
        ApplicationInfo info = list.get(i);
        if (info.intent.getComponent().equals(removeComponent)) {
            return i;
        }
    }
    return -1;
}

自定义ApplicationInfo类:

public class ApplicationInfo extends ItemInfo{
    private static final String TAG = "ApplicationInfo";

    /**
     * The application name.
     */
    CharSequence title;

    /**
     * The intent used to start the application.
     */
    Intent intent;

    /**
     * A bitmap version of the application icon.
     */
    Bitmap iconBitmap;

    /**
     * The time at which the app was first installed.
     */
    long firstInstallTime;

    ComponentName componentName;

    static final int DOWNLOADED_FLAG = 1;
    static final int UPDATED_SYSTEM_APP_FLAG = 2;

    int flags = 0;

    public int arrID;
    
    ApplicationInfo() {
        itemType = LauncherSettings.BaseLauncherColumns.ITEM_TYPE_SHORTCUT;
    }

    /**
     * Must not hold the Context.
     */
    public ApplicationInfo(PackageManager pm, ResolveInfo info, IconCache iconCache,
            HashMap labelCache, int arrId) {
        final String packageName = info.activityInfo.applicationInfo.packageName;

        this.componentName = new ComponentName(packageName, info.activityInfo.name);
        this.container = ItemInfo.NO_ID;
        this.setActivity(componentName,
                Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);

        try {
            int appFlags = pm.getApplicationInfo(packageName, 0).flags;
            if ((appFlags & android.content.pm.ApplicationInfo.FLAG_SYSTEM) == 0) {
                flags |= DOWNLOADED_FLAG;

                if ((appFlags & android.content.pm.ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) {
                    flags |= UPDATED_SYSTEM_APP_FLAG;
                }
            }
            firstInstallTime = pm.getPackageInfo(packageName, 0).firstInstallTime;
            
            arrID = arrId;
        } catch (NameNotFoundException e) {
            Log.d(TAG, "PackageManager.getApplicationInfo failed for " + packageName);
        }

        iconCache.getTitleAndIcon(this, info, labelCache);
    }

    public ApplicationInfo(ApplicationInfo info) {
        super(info);
        componentName = info.componentName;
        title = info.title.toString();
        intent = new Intent(info.intent);
        flags = info.flags;
        firstInstallTime = info.firstInstallTime;
        arrID= info.arrID;

    }

    /**
     * Creates the application intent based on a component name and various launch flags.
     * Sets {@link #itemType} to {@link LauncherSettings.BaseLauncherColumns#ITEM_TYPE_APPLICATION}.
     *
     * @param className the class name of the component representing the intent
     * @param launchFlags the launch flags
     */
    final void setActivity(ComponentName className, int launchFlags) {
        intent = new Intent(Intent.ACTION_MAIN);
        intent.addCategory(Intent.CATEGORY_LAUNCHER);
        intent.setComponent(className);
        intent.setFlags(launchFlags);
        itemType = LauncherSettings.BaseLauncherColumns.ITEM_TYPE_APPLICATION;
    }

    @Override
    public String toString() {
        return "ApplicationInfo(title=" + title.toString() + ")";
    }

    public static void dumpApplicationInfoList(String tag, String label,
            ArrayList list) {
        Log.d(tag, label + " size=" + list.size());
        for (ApplicationInfo info: list) {
            Log.d(tag, "   title=\"" + info.title + "\" iconBitmap="
                    + info.iconBitmap + " firstInstallTime="
                    + info.firstInstallTime);
        }
    }

    public ShortcutInfo makeShortcut() {
        return new ShortcutInfo(this);
    }
}

由于水平较次,高手勿喷,仅供学习

你可能感兴趣的:(android)