You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:使用Package Manager与Broadcast打开无Launcher图标应用时崩溃

问题分析与解决方案

崩溃直接原因

你的代码中错误地直接实例化了PackageManager:

private PackageManager pm = new PackageManager();

PackageManager是Android系统服务,不能通过new关键字创建实例,必须通过上下文的getPackageManager()方法获取,这是导致应用崩溃的核心原因。

修正与功能实现

1. 修正PackageManager获取方式

在onCreate方法中正确初始化PackageManager:

private PackageManager pm;

@Override
protected void onCreate(Bundle _savedInstanceState) {
    super.onCreate(_savedInstanceState);
    setContentView(R.layout.main);
    pm = getPackageManager(); // 正确获取系统PackageManager服务
    initialize(_savedInstanceState);
    initializeLogic();
}

2. 通过PackageManager启动无Launcher图标应用

无Launcher图标的应用通常没有配置LAUNCHER类别,需要通过包名查询其可启动的Activity组件:

// 根据包名启动无Launcher图标应用
private void launchHiddenApp(String targetPackage) {
    Intent launchIntent = pm.getLaunchIntentForPackage(targetPackage);
    // 如果没有默认启动Intent,遍历应用内所有可启动的Activity
    if (launchIntent == null) {
        List<ResolveInfo> resolveInfos = pm.queryIntentActivities(
                new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_DEFAULT),
                PackageManager.GET_RESOLVED_FILTER
        );
        for (ResolveInfo info : resolveInfos) {
            if (info.activityInfo.packageName.equals(targetPackage)) {
                launchIntent = new Intent();
                launchIntent.setComponent(new ComponentName(targetPackage, info.activityInfo.name));
                launchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                break;
            }
        }
    }
    // 启动应用
    if (launchIntent != null) {
        try {
            startActivity(launchIntent);
        } catch (ActivityNotFoundException e) {
            showMessage("应用未找到或无法启动");
            e.printStackTrace();
        }
    } else {
        showMessage("未找到该应用的可启动组件");
    }
}

3. 通过BroadcastReceiver启动应用

步骤1:创建自定义BroadcastReceiver

public class AppLaunchReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        String targetPackage = intent.getStringExtra("TARGET_PACKAGE");
        if (targetPackage == null) return;
        
        PackageManager pm = context.getPackageManager();
        Intent launchIntent = pm.getLaunchIntentForPackage(targetPackage);
        if (launchIntent == null) {
            List<ResolveInfo> resolveInfos = pm.queryIntentActivities(
                    new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_DEFAULT),
                    PackageManager.GET_RESOLVED_FILTER
            );
            for (ResolveInfo info : resolveInfos) {
                if (info.activityInfo.packageName.equals(targetPackage)) {
                    launchIntent = new Intent();
                    launchIntent.setComponent(new ComponentName(targetPackage, info.activityInfo.name));
                    launchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    break;
                }
            }
        }
        if (launchIntent != null) {
            context.startActivity(launchIntent);
        }
    }
}

步骤2:在AndroidManifest.xml中注册Receiver

<receiver
    android:name=".AppLaunchReceiver"
    android:exported="true">
    <intent-filter>
        <!-- 自定义广播Action,替换为你的包名前缀 -->
        <action android:name="com.your.package.action.LAUNCH_HIDDEN_APP" />
    </intent-filter>
</receiver>

步骤3:发送广播触发启动

// 发送广播启动目标应用
private void sendLaunchBroadcast(String targetPackage) {
    Intent broadcastIntent = new Intent("com.your.package.action.LAUNCH_HIDDEN_APP");
    broadcastIntent.putExtra("TARGET_PACKAGE", targetPackage);
    sendBroadcast(broadcastIntent);
}

4. 完整修正后的MainActivity代码

import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import java.util.List;

public class MainActivity extends Activity {
    private LinearLayout linear1;
    private LinearLayout linear2;
    private TextView textview2;
    private TextView textview3;
    private PackageManager pm;

    @Override
    protected void onCreate(Bundle _savedInstanceState) {
        super.onCreate(_savedInstanceState);
        setContentView(R.layout.main);
        pm = getPackageManager();
        initialize(_savedInstanceState);
        initializeLogic();
    }

    private void initialize(Bundle _savedInstanceState) {
        linear1 = findViewById(R.id.linear1);
        linear2 = findViewById(R.id.linear2);
        textview2 = findViewById(R.id.textview2);
        textview3 = findViewById(R.id.textview3);

        linear2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View _view) {
                // 替换为目标应用的实际包名
                String targetPackage = "com.example.hiddenapp";
                // 方式1:直接通过PackageManager启动
                launchHiddenApp(targetPackage);
                // 方式2:通过广播启动
                // sendLaunchBroadcast(targetPackage);
            }
        });
    }

    private void initializeLogic() {
    }

    private void launchHiddenApp(String targetPackage) {
        Intent launchIntent = pm.getLaunchIntentForPackage(targetPackage);
        if (launchIntent == null) {
            List<ResolveInfo> resolveInfos = pm.queryIntentActivities(
                    new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_DEFAULT),
                    PackageManager.GET_RESOLVED_FILTER
            );
            for (ResolveInfo info : resolveInfos) {
                if (info.activityInfo.packageName.equals(targetPackage)) {
                    launchIntent = new Intent();
                    launchIntent.setComponent(new ComponentName(targetPackage, info.activityInfo.name));
                    launchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    break;
                }
            }
        }
        if (launchIntent != null) {
            try {
                startActivity(launchIntent);
            } catch (ActivityNotFoundException e) {
                showMessage("应用未找到或无法启动");
                e.printStackTrace();
            }
        } else {
            showMessage("未找到该应用的可启动组件");
        }
    }

    private void sendLaunchBroadcast(String targetPackage) {
        Intent broadcastIntent = new Intent("com.your.package.action.LAUNCH_HIDDEN_APP");
        broadcastIntent.putExtra("TARGET_PACKAGE", targetPackage);
        sendBroadcast(broadcastIntent);
    }

    @Deprecated
    public void showMessage(String _s) {
        Toast.makeText(getApplicationContext(), _s, Toast.LENGTH_SHORT).show();
    }

    @Deprecated
    public int getLocationX(View _v) {
        int _location[] = new int[2];
        _v.getLocationInWindow(_location);
        return _location[0];
    }

    @Deprecated
    public int getLocationY(View _v) {
        int _location[] = new int[2];
        _v.getLocationInWindow(_location);
        return _location[1];
    }

    @Deprecated
    public int getRandom(int _min, int _max) {
        java.util.Random random = new java.util.Random();
        return random.nextInt(_max - _min + 1) + _min;
    }

    @Deprecated
    public List<Double> getCheckedItemPositionsToArray(android.widget.ListView _list) {
        List<Double> _result = new java.util.ArrayList<>();
        android.util.SparseBooleanArray _arr = _list.getCheckedItemPositions();
        for (int _iIdx = 0; _iIdx < _arr.size(); _iIdx++) {
            if (_arr.valueAt(_iIdx))
                _result.add((double)_arr.keyAt(_iIdx));
        }
        return _result;
    }

    @Deprecated
    public float getDip(int _input) {
        return android.util.TypedValue.applyDimension(android.util.TypedValue.COMPLEX_UNIT_DIP, _input, getResources().getDisplayMetrics());
    }

    @Deprecated
    public int getDisplayWidthPixels() {
        return getResources().getDisplayMetrics().widthPixels;
    }

    @Deprecated
    public int getDisplayHeightPixels() {
        return getResources().getDisplayMetrics().heightPixels;
    }
}

注意事项

  • 替换代码中的com.example.hiddenapp为目标应用的实际包名
  • 替换广播Actioncom.your.package.action.LAUNCH_HIDDEN_APP为你的应用包名前缀,避免冲突
  • Android 12及以上版本中,目标应用的Activity必须显式声明android:exported="true"才能被其他应用启动
  • 若目标应用为自研,可在其内部注册专属BroadcastReceiver,提升启动安全性

内容的提问来源于stack exchange,提问作者Pouya Mohamadi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 22:32:02