41.弹出悬浮窗体
弹出窗体一般是点击ListView的某个条目时弹出的,PopupWindow是弹出窗体,位于当前Activity上面。弹出窗体的定义和显示:
PopupWindow pw = new PopupWindow(View contentView,int width,int height);
其中,contentView是弹出窗体包含的内容;
width和height是弹出窗体的宽高,一般都指定为-2(ViewGroup.LayoutParams.WRAP_CONTENT),表示包括内容。-1是填充父窗体。
int[] location = new int[2];
view.getLocationInWindow(location);
该方法接收的是一个长度为2的int类型的数组,该方法没有返回值,但是当该方法执行完后,这个数组里面包含的是当前view对象距离屏幕左边和上边的距离。
pw.showAtLocation(View parent,int gravity,int x, int y);
其中,parent是当前ListView;
gravity是对齐方式,一般为Gravity.LEFT | Gravity.TOP,|相当于+,用|效率更高;
x,y为距离屏幕左边和上边的距离,即location[0]和location[1]。这里的距离单位是像素pix,如果想让弹出窗体都距离左边一个图标的位置,不同分辨率的手机的显示效果会不同,这时可以先将要设置的dp转换成pix后再设置x的值。
像素转换的工具类:
<span style="font-size:18px;">public class DensityUtil {
/**
* 根据手机的分辨率从 dip 的单位 转成为 px(像素)
*/
public static int dip2px(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
/**
* 根据手机的分辨率从 px(像素) 的单位 转成为 dp
*/
public static int px2dip(Context context, float pxValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (pxValue / scale + 0.5f);
}
}</span>
若要求不同分辨率的手机的显示效果不一样,这时可以定义不同的布局文件,这些不同的布局文件要放到不同的文件夹中,如layout-320x240,layout-480x320,layout-hdpi,layout-mdpi,layout-ldpi等。不同分辨率的手机会非常智能的加载对应的布局文件夹。
有些特殊窗体如popupWindow不提供任何的背景资源,而动画效果的播放要求窗体必须有背景颜色,所以这里我们可以设置窗体的背景资源为透明色:
popupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
关闭悬浮窗体:
if (popupWindow != null && popupWindow.isShowing()) {
// 关闭旧的弹出窗体
popupWindow.dismiss();
popupWindow = null;
}
弹出悬浮窗体返回键时会报错,原因是悬浮窗体是挂载在Activity上的,Activity消失时会发生
窗体泄露,采取措施是在Activity退出时重新onDestory方法,dismiss悬浮窗体。
42.开启软件
每个应用程序都有一个入口Activity,开启软件时,只需要查询要开启应用程序的入口Activity,把它启动起来即可。
启动应用程序的步骤:
用包管理器根据包名获得要启动应用程序的intent:
intent = pm.getLaunchIntentForPackage(要启动应用程序的包名);
启动意图时要判断该意图是否为空,因为有可能该应用程序是一个服务或广播接收者,没有启动界面。
手机桌面程序代码书写步骤:
开启应用程序的intent所关心的动作必须是:
intent.setAction("android.intent.action.MAIN");
要想开启应用程序,其要增加的category必须是:
intent.addCategory("android.intent.category.LAUNCHER");
用包管理器查询符合指定intent的所有Activity:
List<ResolveInfo> activities = pm.queryIntentActivities(intent, PackageManager.GET_INTENT_FILTERS);
得到的是手机上所有能够启动的Activity。
for(ResolveInfo activity : activies){
获得每个可启动的Activity的包名
String packname = activity.activityInfo.packageName;
可添加到一个List<String>集合中
}
然后再在一个Gridview中列出各个可启动应用程序的图标及程序名,再添加点击事件,根据包名启动。
按Home键回到自己写的桌面,只需要在桌面程序的清单文件中的启动Activity的节点中再添加一个意图过滤器即可:
<span style="font-size:18px;"><intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.MONKEY"/>
</intent-filter></span>
返回键也需要做处理:在启动Activity中重写onBackPressed()方法,为空函数即可。
43.软件分享
软件分享的步骤:
设置软件分享意图所关心的动作:
intent.setAction("android.intent.action.SEND");
添加默认的category:
intent.addCategory(Intent.CATEGORY_DEFAULT);
所关心数据的类型:
intent.setType("text/plain");
额外的数据,额外数据是键值对的形式,其key的名称都是固定的模式:
intent.putExtra(Intent.EXTRA_TEXT, "推荐你使用一款软件,软件名:直播吧");
再startActivity(intent)即可。
44.第一次打开应用程序时,在桌面创建快捷图标
快捷方式是创建在桌面上的,必须有桌面才有快捷方式。
桌面里面有一个特殊的广播接收者,专门用来监听其他应用程序的安装,只要新安装的应用程序发送了产生快捷方式的广播,桌面就会创建一个该应用程序的快捷图标。
生成快捷图标时需要添加权限:com.android.launcher.permission.INSTALL_SHORTCUT
这个权限只能复制粘贴上去,系统提供的可供选择的权限没有该权限。
<span style="font-size:18px;">boolean shortcut = sp.getBoolean("shortcut", false);
if(shortcut){
return;
}else{
//发送广播的意图,大吼一声告诉桌面,快捷图标要创建了
Intent intent = new Intent();
intent.setAction("com.android.launcher.action.INSTALL_SHORTCUT");
//快捷方式要包含3个重要的信息:1.图标 2.程序名 3.点击事件
intent.putExtra(Intent.EXTRA_SHORTCUT_ICON, BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher));
intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, "手机安全卫士");
PackageManager pm = getPackageManager();
//点击桌面快捷图标对应的意图
Intent shortcutIntent = pm.getLaunchIntentForPackage(getPackageName());
intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
sendBroadcast(intent);
Editor editor = sp.edit();
editor.putBoolean("shortcut", true);
editor.commit();
}</span>