12.PackageManager&&Popwindow必须设置背景

本文介绍了一个App管理器的实现过程,包括如何获取已安装应用信息、区分用户与系统应用、创建自定义进度条视图、使用PopupWindow显示操作菜单等功能。通过具体的代码示例展示了从界面布局到业务逻辑的完整实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Popwindow

mLvApp.setOnItemClickListener(new OnItemClickListener() {
			@ViewInject(R.id.tv_uninstall)
			TextView tvUnInstall;
			@ViewInject(R.id.tv_open)
			TextView tvOpen;
			@ViewInject(R.id.tv_share)
			TextView tvShare;
			@ViewInject(R.id.tv_info)
			TextView tvInfo;

			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				// if (position == userAppInfos.size()) {
				// return;
				// }
				View contentView = View.inflate(getApplicationContext(),
						R.layout.view_app_popup, null);
				mPopupWindow = new PopupWindow(contentView,
						ViewGroup.LayoutParams.WRAP_CONTENT,
						ViewGroup.LayoutParams.WRAP_CONTENT, true);
				// popupWindow.setOutsideTouchable(true);
				// PopupWindow的小bug:假如不设置,外面都无法点击了
				mPopupWindow.setBackgroundDrawable(new ColorDrawable(
						Color.WHITE));
				// xutils
				ViewUtils.inject(this, contentView);
				// px -- dp
				mPopupWindow.showAsDropDown(view, px2dp(60), -view.getHeight());

				final AppInfo appInfo = position < userAppInfos.size() ? userAppInfos
						.get(position) : sysAppInfos.get(position
						- userAppInfos.size() - 1);

				// 设置点击事件
				// 卸载
				tvUnInstall.setOnClickListener(new OnClickListener() {

					@Override
					public void onClick(View v) {
						Intent intent = new Intent();
						intent.setAction("android.intent.action.DELETE");
						intent.addCategory("android.intent.category.DEFAULT");
						intent.setData(Uri.parse("package:"
								+ appInfo.packageName));
						startActivity(intent);

						if (mPopupWindow != null) {
							mPopupWindow.dismiss();
						}
					}
				});

				// 打开
				tvOpen.setOnClickListener(new OnClickListener() {

					@Override
					public void onClick(View v) {
						PackageManager pm = getPackageManager();
						Intent intent = pm
								.getLaunchIntentForPackage(appInfo.packageName);
						startActivity(intent);
						if (mPopupWindow != null) {
							mPopupWindow.dismiss();
						}
					}
				});

				tvShare.setOnClickListener(new OnClickListener() {

					@Override
					public void onClick(View v) {
						Intent intent = new Intent(Intent.ACTION_SENDTO, Uri
								.parse("smsto:"));
						intent.putExtra("sms_body", "分享某软件");
						startActivity(intent);
						if (mPopupWindow != null) {
							mPopupWindow.dismiss();
						}
					}
				});

				tvInfo.setOnClickListener(new OnClickListener() {

					@Override
					public void onClick(View v) {
						Intent intent = new Intent();
						intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
						intent.addCategory("android.intent.category.DEFAULT");
						intent.setData(Uri.parse("package:"
								+ appInfo.packageName));
						startActivity(intent);

						if (mPopupWindow != null) {
							mPopupWindow.dismiss();
						}
					}
				});
			}
		});





1 获取app信息的封装类

package org.heima.mobilesafe01.engine;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.heima.mobilesafe01.bean.AppInfo;
import org.heima.mobilesafe01.utils.L;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;

/**
 * @author U 软件管家数据提供者
 */
public class AppProvider {

	public static List<AppInfo> getAllAppInfos(Context context) {
		List<AppInfo> infos = new ArrayList<AppInfo>();
		PackageManager pm = context.getPackageManager();
		List<PackageInfo> installedPackages = pm.getInstalledPackages(0);
		for (PackageInfo packageInfo : installedPackages) {
			AppInfo info = new AppInfo();
			info.packageName = packageInfo.packageName;
			info.icon = packageInfo.applicationInfo.loadIcon(pm);
			info.name = packageInfo.applicationInfo.loadLabel(pm).toString();
			// packageInfo.applicationInfo.name;
			// 安装包的大小
			String sourceDir = packageInfo.applicationInfo.sourceDir;
//			L.d("sourcedir:" + sourceDir);
			File file = new File(sourceDir);
			info.size = file.length();
			//
			int flags = packageInfo.applicationInfo.flags;

			// packageInfo.applicationInfo.FLAG_SYSTEM
			// ApplicationInfo.FLAG_EXTERNAL_STORAGE:0000 0010
			// ApplicationInfo.FLAG_SYSTEM=0000 0001
			// flags=0000 0011
			if ((flags & ApplicationInfo.FLAG_SYSTEM) == ApplicationInfo.FLAG_SYSTEM) {// 0001
																						// 0011
																						// 0001
				info.isSystem = true; // 0001
				// 0000
				// 0001
			} else {
				info.isSystem = false;
			}
			if ((flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) == ApplicationInfo.FLAG_EXTERNAL_STORAGE) {
				// 0000 0011
				// 0000 0010
				// 0000 0010
				info.isInstallSD = true;
			} else {
				info.isInstallSD = false;
			}
//			L.d(String.valueOf(info.name+":"+Integer.toBinaryString(flags)));
			infos.add(info);
		}
		return infos;
	}
}


2 AppManagerActivity的布局文件

<?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/TvTitleStyle"
        android:text="软件管家" />

    <org.heima.mobilesafe01.view.DesProgressView
        android:id="@+id/dpv_ram"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <org.heima.mobilesafe01.view.DesProgressView
        android:id="@+id/dpv_sd"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="1dp" />

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

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

        <ListView
            android:id="@+id/lv_app"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:divider="#e7e7e7"
            android:dividerHeight="1dp"
            android:scrollbars="none" >
        </ListView>

        <ProgressBar
            android:id="@+id/pb_app_loading"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:indeterminateDrawable="@drawable/pd_loadind_rotate" />
    </RelativeLayout>

</LinearLayout>

3 DesProgressView

package org.heima.mobilesafe01.view;

import org.heima.mobilesafe01.R;

import android.content.Context;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.lidroid.xutils.ViewUtils;
import com.lidroid.xutils.view.annotation.ViewInject;

/**
 * @author U 自定义进度条的描述
 */
public class DesProgressView extends LinearLayout {
	@ViewInject(R.id.tv_title_type)
	private TextView tvTitleType;
	@ViewInject(R.id.pb_des)
	private ProgressBar pdDes;
	@ViewInject(R.id.tv_left)
	private TextView tvLeft;
	@ViewInject(R.id.tv_right)
	private TextView tvRight;

	public DesProgressView(Context context) {
		this(context, null);
	}

	public DesProgressView(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}

	public DesProgressView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		View.inflate(getContext(), R.layout.view_des_progerss, this);
		ViewUtils.inject(this);
	}

	public void setTitleType(String type) {
		if (TextUtils.isEmpty(type)) {
			throw new IllegalArgumentException("type can not be null");
		}
		tvTitleType.setText(type);
	}

	public void setLeftMsg(String left) {
		if (TextUtils.isEmpty(left)) {
			throw new IllegalArgumentException("left can not be null");
		}
		tvLeft.setText(left);
	}

	public void setRightMsg(String right) {
		if (TextUtils.isEmpty(right)) {
			throw new IllegalArgumentException("right can not be null");
		}
		tvRight.setText(right);
	}

	public void setProgerss(int progress) {
		pdDes.setProgress(progress);
	}

}

4 AppManagerActivity

package org.heima.mobilesafe01;

import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.heima.mobilesafe01.bean.AppInfo;
import org.heima.mobilesafe01.engine.AppProvider;
import org.heima.mobilesafe01.utils.L;
import org.heima.mobilesafe01.view.DesProgressView;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.SystemClock;
import android.text.format.Formatter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
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.ListView;
import android.widget.PopupWindow;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.lidroid.xutils.ViewUtils;
import com.lidroid.xutils.view.annotation.ContentView;
import com.lidroid.xutils.view.annotation.ViewInject;

/**
 * @author U 软件管家
 */
@ContentView(R.layout.activity_app_manager)
public class AppManagerActivity extends Activity {
	@ViewInject(R.id.dpv_ram)
	private DesProgressView dpvRam;
	@ViewInject(R.id.dpv_sd)
	private DesProgressView dpvSd;
	@ViewInject(R.id.lv_app)
	private ListView mLvApp;
	@ViewInject(R.id.pb_app_loading)
	private ProgressBar pbLoading;
	@ViewInject(R.id.tv_app)
	private TextView tvApp;

	private List<AppInfo> allAppInfos = new ArrayList<AppInfo>();
	private List<AppInfo> userAppInfos = new ArrayList<AppInfo>();
	private List<AppInfo> sysAppInfos = new ArrayList<AppInfo>();
	private PopupWindow mPopupWindow;
	private AppManagerAdapter mAppManagerAdapter;
	private UnInstallReceiver mReceiver;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		initView();
		initData();
		initEvent();
	}

	private void initView() {
		ViewUtils.inject(this);
	}

	private void initData() {
		initHeadData();
		pbLoading.setVisibility(View.VISIBLE);
		tvApp.setVisibility(View.GONE);
		new Thread(new Runnable() {

			@Override
			public void run() {
				allAppInfos = AppProvider
						.getAllAppInfos(getApplicationContext());
				// 区分集合
				for (AppInfo appInfo : allAppInfos) {
					if (appInfo.isSystem) {
						sysAppInfos.add(appInfo);
					} else {
						userAppInfos.add(appInfo);
					}
				}
				SystemClock.sleep(1000);
				runOnUiThread(new Runnable() {

					@Override
					public void run() {
						tvApp.setVisibility(View.VISIBLE);
						tvApp.setText("用户程序(" + userAppInfos.size() + ")个");
						mAppManagerAdapter = new AppManagerAdapter();
						mLvApp.setAdapter(mAppManagerAdapter);
						pbLoading.setVisibility(View.GONE);
					}
				});
			}
		}).start();

		// 注册卸载apk的广播
		mReceiver = new UnInstallReceiver();
		IntentFilter filter = new IntentFilter();
		filter.addAction(Intent.ACTION_PACKAGE_REMOVED);// 千万不要用这个Intent.ACTION_UNINSTALL_PACKAGE
		filter.addDataScheme("package");
		registerReceiver(mReceiver, filter);
	}

	private void initEvent() {
		mLvApp.setOnScrollListener(new OnScrollListener() {

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

			}

			@Override
			public void onScroll(AbsListView view, int firstVisibleItem,
					int visibleItemCount, int totalItemCount) {
				if (firstVisibleItem <= userAppInfos.size()) {
					tvApp.setText("用户程序(" + userAppInfos.size() + ")个");
				} else {
					tvApp.setText("系统程序(" + sysAppInfos.size() + ")个");
				}
			}
		});

		mLvApp.setOnItemClickListener(new OnItemClickListener() {
			@ViewInject(R.id.tv_uninstall)
			TextView tvUnInstall;
			@ViewInject(R.id.tv_open)
			TextView tvOpen;
			@ViewInject(R.id.tv_share)
			TextView tvShare;
			@ViewInject(R.id.tv_info)
			TextView tvInfo;

			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				// if (position == userAppInfos.size()) {
				// return;
				// }
				View contentView = View.inflate(getApplicationContext(),
						R.layout.view_app_popup, null);
				mPopupWindow = new PopupWindow(contentView,
						ViewGroup.LayoutParams.WRAP_CONTENT,
						ViewGroup.LayoutParams.WRAP_CONTENT, true);
				// popupWindow.setOutsideTouchable(true);
				// PopupWindow的小bug:假如不设置,外面都无法点击了
				mPopupWindow.setBackgroundDrawable(new ColorDrawable(
						Color.WHITE));
				// xutils
				ViewUtils.inject(this, contentView);
				// px -- dp
				mPopupWindow.showAsDropDown(view, px2dp(60), -view.getHeight());

				final AppInfo appInfo = position < userAppInfos.size() ? userAppInfos
						.get(position) : sysAppInfos.get(position
						- userAppInfos.size() - 1);

				// 设置点击事件
				// 卸载
				tvUnInstall.setOnClickListener(new OnClickListener() {

					@Override
					public void onClick(View v) {
						Intent intent = new Intent();
						intent.setAction("android.intent.action.DELETE");
						intent.addCategory("android.intent.category.DEFAULT");
						intent.setData(Uri.parse("package:"
								+ appInfo.packageName));
						startActivity(intent);

						if (mPopupWindow != null) {
							mPopupWindow.dismiss();
						}
					}
				});

				// 打开
				tvOpen.setOnClickListener(new OnClickListener() {

					@Override
					public void onClick(View v) {
						PackageManager pm = getPackageManager();
						Intent intent = pm
								.getLaunchIntentForPackage(appInfo.packageName);
						startActivity(intent);
						if (mPopupWindow != null) {
							mPopupWindow.dismiss();
						}
					}
				});

				tvShare.setOnClickListener(new OnClickListener() {

					@Override
					public void onClick(View v) {
						Intent intent = new Intent(Intent.ACTION_SENDTO, Uri
								.parse("smsto:"));
						intent.putExtra("sms_body", "分享某软件");
						startActivity(intent);
						if (mPopupWindow != null) {
							mPopupWindow.dismiss();
						}
					}
				});

				tvInfo.setOnClickListener(new OnClickListener() {

					@Override
					public void onClick(View v) {
						Intent intent = new Intent();
						intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
						intent.addCategory("android.intent.category.DEFAULT");
						intent.setData(Uri.parse("package:"
								+ appInfo.packageName));
						startActivity(intent);

						if (mPopupWindow != null) {
							mPopupWindow.dismiss();
						}
					}
				});
			}
		});
	}

	// px to dp
	public int px2dp(int px) {
		// dp: 10dp
		float mDensity = getResources().getDisplayMetrics().density;// 在不同手机里面:l:0.75,m:1,h:1.5,xh:2
		// L.d("mDensity:"+mDensity);
		// dp*mDensity=px;
		// dp=px/mDensity
		return (int) (px / mDensity + 0.5f);
	}

	private void initHeadData() {
		dpvRam.setTitleType("内存");
		File dataDir = Environment.getDataDirectory();
		// L.d(dataDir.getAbsolutePath());
		long ramFreeSpace = dataDir.getFreeSpace();
		long ramTalSpace = dataDir.getTotalSpace();
		long ramUsedSpace = ramTalSpace - ramFreeSpace;
		String ramFree = Formatter.formatFileSize(getApplicationContext(),
				ramFreeSpace);// bit byte kb MB GB TB
		String ramUsed = Formatter.formatFileSize(getApplicationContext(),
				ramUsedSpace);
		dpvRam.setLeftMsg(ramUsed);
		dpvRam.setRightMsg(ramFree);
		dpvRam.setProgerss((int) (ramUsedSpace * 100 / ramTalSpace));

		// sd
		dpvSd.setTitleType("SD");
		File exFile = Environment.getExternalStorageDirectory();
		long sdFreeSpace = exFile.getFreeSpace();
		long sdTotalSpace = exFile.getTotalSpace();
		long sdUsedSpace = sdTotalSpace - sdFreeSpace;

		String sdFree = Formatter.formatFileSize(getApplicationContext(),
				sdFreeSpace);// bit byte kb MB GB TB
		String sdUsed = Formatter.formatFileSize(getApplicationContext(),
				sdUsedSpace);
		dpvSd.setLeftMsg(sdUsed);
		dpvSd.setRightMsg(sdFree);
		dpvSd.setProgerss((int) (sdUsedSpace * 100 / sdTotalSpace));
	}

	class AppManagerAdapter extends BaseAdapter {
		LayoutInflater mInflater;

		public AppManagerAdapter() {
			mInflater = LayoutInflater.from(getApplicationContext());
		}

		@Override
		public int getCount() {
			return userAppInfos.size() + sysAppInfos.size() + 1;
		}

		@Override
		public Object getItem(int position) {
			return null;
		}

		@Override
		public long getItemId(int position) {
			return 0;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			/*
			 * <TextView android:id="@+id/tv_app"
			 * android:layout_width="match_parent" android:layout_height="35dp"
			 * android:background="#55ff0000" android:text="用户"
			 * android:textColor="#000000" android:textSize="17sp"
			 * android:gravity="center_vertical" android:paddingLeft="10dp" />
			 */
			// if (position == userAppInfos.size()) {
			// TextView tv = new TextView(getApplicationContext());
			// ListView.LayoutParams params = new ListView.LayoutParams(
			// ListView.LayoutParams.MATCH_PARENT, 35);
			// tv.setLayoutParams(params);
			// tv.setText("系统程序(" + sysAppInfos.size() + ")个");
			// tv.setBackgroundColor(Color.parseColor("#55ff0000"));
			// tv.setTextColor(Color.parseColor("#000000"));
			// tv.setTextSize(17);
			// tv.setGravity(Gravity.CENTER_VERTICAL);
			// tv.setPadding(10, 0, 0, 0);
			// return tv;
			// }

			if (position == userAppInfos.size()) {
				TextView tv = (TextView) mInflater.inflate(
						R.layout.view_lv_app_head, parent, false);
				tv.setText("系统程序(" + sysAppInfos.size() + ")个");
				return tv;
			}

			ViewHolder viewHolder;
			if (convertView == null || (convertView instanceof TextView)) {
				viewHolder = new ViewHolder();
				convertView = mInflater.inflate(R.layout.view_app_item_lv,
						parent, false);
				viewHolder.ivIcon = (ImageView) convertView
						.findViewById(R.id.iv_icon);
				viewHolder.tvAppName = (TextView) convertView
						.findViewById(R.id.tv_app_name);
				viewHolder.tvInstallSd = (TextView) convertView
						.findViewById(R.id.tv_install_sd);
				viewHolder.tvAppSize = (TextView) convertView
						.findViewById(R.id.tv_app_size);
				convertView.setTag(viewHolder);
			} else {
				viewHolder = (ViewHolder) convertView.getTag();
			}
			AppInfo appInfo = null;
			if (position < userAppInfos.size()) {// 7<8
				appInfo = userAppInfos.get(position);
			} else {
				appInfo = sysAppInfos.get(position - userAppInfos.size() - 1);// 8
																				// 8
			}
			viewHolder.ivIcon.setImageDrawable(appInfo.icon);
			viewHolder.tvAppName.setText(appInfo.name);
			viewHolder.tvInstallSd
					.setText(appInfo.isInstallSD ? "SD卡" : "手机内存");
			viewHolder.tvAppSize.setText(Formatter.formatFileSize(
					getApplicationContext(), appInfo.size));
			return convertView;
		}

		@Override
		public boolean isEnabled(int position) {
			if (position == userAppInfos.size()) {
				return false;
			}
			return super.isEnabled(position);
		}
	}

	class ViewHolder {
		ImageView ivIcon;
		TextView tvAppName;
		TextView tvInstallSd;
		TextView tvAppSize;
	}

	class UnInstallReceiver extends BroadcastReceiver {

		@Override
		public void onReceive(Context context, Intent intent) {
			String data = intent.getDataString();
			L.d(data);// package:org.heima.mobilesafe01
			String packageName = data.replace("package:", "");

			// 用户激活删除
			Iterator<AppInfo> iterator = userAppInfos.iterator();
			while (iterator.hasNext()) {
				AppInfo appInfo = iterator.next();
				if (appInfo.packageName.equals(packageName)) {
					iterator.remove();
				}
			}

			if (mAppManagerAdapter != null) {
				mAppManagerAdapter.notifyDataSetChanged();
			}

			// 消耗PopupWindow
			if (mPopupWindow != null) {
				mPopupWindow.dismiss();
			}
		}

	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		if (mReceiver != null) {
			unregisterReceiver(mReceiver);
		}
	}

}

之前写的跟PackageManager有关的

package org.heima.mobilesafe01.utils;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;

public class PackageUtils {

	// 获取版本名字
	public static String getVersionName(Context context) {
		PackageManager pm = context.getPackageManager();
		try {
			PackageInfo packageInfo = pm.getPackageInfo(
					context.getPackageName(), 0);
			return packageInfo.versionName;
		} catch (NameNotFoundException e) {
			e.printStackTrace();
		}
		return null;
	}

	// 获取版本号
	public static int getVersionCode(Context context) {
		PackageManager pm = context.getPackageManager();
		try {
			PackageInfo packageInfo = pm.getPackageInfo(
					context.getPackageName(), 0);
			return packageInfo.versionCode;
		} catch (NameNotFoundException e) {
			e.printStackTrace();
		}
		return -1;
	}
}





<think>我们正在讨论Android开发中Intent的使用,特别是关于如何安全地启动Activity。用户提供的引用中提到了几种检查Activity是否存在的方法,包括使用`Intent.resolveActivity()`、`Intent.resolveActivityInfo()`和`PackageManager.queryIntentActivities()`。用户特别询问了`intent.resolveActivity(context.packageManager)!=null`这行代码的含义和用法。首先,我们来解析这行代码:-`Intent.resolveActivity(PackageManagerpm)`:这个方法会根据Intent中的信息(如action、data、category等)查找最适合处理该Intent的Activity组件。如果找到,返回一个`ComponentName`对象(非null),否则返回null。-因此,`intent.resolveActivity(context.packageManager)!=null`用于判断是否存在能够处理该Intent的Activity。如果存在,我们可以安全地启动该Activity;如果不存在(即返回null),则我们可以采取其他措施,比如禁用功能、提示用户或者跳转到应用市场等。接下来,我们参考用户提供的引用:-引用[2]给出了一个示例:如果通过`resolveActivity`得到`ComponentName`为null,则尝试引导用户到应用市场下载相关应用;否则直接启动Activity。-引用[3]展示了在Kotlin和Java中如何安全地打开WIFI设置界面,使用`resolveActivity`进行检查。-引用[4]提到了在Android11(targetSdkVersion>=30)及以上版本,某些系统内置的Intent(如相机)可能返回null,需要特别注意。-引用[5]则是对这种做法的总结,强调在启动Activity前检查以避免应用崩溃。因此,我们可以这样组织回答:1.解释代码的含义:检查是否存在能处理该Intent的Activity。2.说明为什么需要这样检查:避免因没有合适的Activity导致应用崩溃。3.举例说明如何使用:用代码示例展示安全启动Activity的流程。4.注意事项:特别是在Android11及以上版本中,系统行为的变化可能导致之前可用的Intent返回null,需要额外处理。最后,按照用户要求,在回答中自然地添加引用标识,并生成相关问题。由于用户的问题集中在代码解析和用法上,我们可以直接给出解析和示例代码,并注意使用正确的LaTeX格式(虽然问题中数学表达式较少,但我们仍需注意规则,比如行内变量用$...$,如无必要可不使用)。另外,用户要求使用中文回答。以下是我将给出的回答:</think> ### Android `intent.resolveActivity(packageManager) != null` 代码解析 #### 1. **核心作用:安全启动检查** 此代码用于验证系统是否存在能处理指定`Intent`的 Activity,避免因目标组件不存在导致应用崩溃。当且仅当系统找到匹配的 Activity 时,返回非空 `ComponentName` 对象。 #### 2. **工作流程** ```java Intent intent = new Intent(Settings.ACTION_WIFI_SETTINGS); // 创建意图 PackageManager pm = getPackageManager(); // 获取包管理器 // 检查是否存在处理意图的 Activity if (intent.resolveActivity(pm) != null) { startActivity(intent); // 安全启动 } else { // 处理无可用组件的情况(示例参考引用[2][5]) Log.e(TAG, "无可用应用处理该操作"); } ``` **执行逻辑**: - `resolveActivity()` 根据 Intent 的 `Action`、`Data` 等属性查找匹配组件 - 返回 `ComponentName` 对象(非空=找到组件 | `null`=未找到) - 典型应用场景:启动系统功能(如 Wi-Fi 设置、相机等需兼容不同设备) #### 3. **关键要点** - **兼容性保障**:预防 `startActivity()` 因无匹配组件抛出 `ActivityNotFoundException`(引用[5]) - **系统级行为**:Android 11+ 需注意权限变化可能导致返回 `null`(引用[4]) - **替代方案**: - `Intent.resolveActivityInfo()` 获取更详细的 Activity 信息 - `PackageManager.queryIntentActivities()` 查询所有匹配组件列表(引用[1]) #### 4. **常见使用场景** ```kotlin // Kotlin 示例(引用[3]) fun openCamera() { val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE) if (intent.resolveActivity(packageManager) != null) { startActivityForResult(intent, REQUEST_CODE) } else { showDialog("请安装相机应用") } } ``` > **最佳实践**:涉及系统功能(如相机、NFC、应用商店跳转)时必须检查,避免用户设备不支持时崩溃(引用[2][4]) [^1]: 隐式启动检测方式(引用[1]) [^2]: 无组件时的市场跳转逻辑(引用[2]) [^3]: Kotlin/Java 标准用法(引用[3]) [^4]: Android 11+ 兼容性问题(引用[4]) [^5]: 安全启动的必要性说明(引用[5])
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值