如何根据包名packageName获取程序启动的主Activity名称

如何根据包名packageName获取程序启动的主Activity名称,第1张

方法一:使用aapt //aapt是sdk自带的一个工具,在sdk\builds-tools\目录下

1以ES文件浏览器为例,命令行中切换到aaptexe目录执行:aapt dump badging E:\apk\es3apk

2运行后的结果中以下两行分别是应用包名package和入口activity名称

package: name=’comestrongsandroidpop’

launchable-activity: name=’comestrongsandroidpopviewFileExplorerActivity’

注:在android sdk目录搜索可以找到aaptexe,如果没有可以下载apktool。

方法二:查看AndroidManifestxml

1使用apktool反编译app:apktoolbat d es3apk E:\apk\es

2打开AndroidManifestxml

manifest节点的package属性值是应用的包名:

查找androidintentactionMAIN和androidintentcategoryLAUNCHER对应的activity,该activity对应的android:name属性既是入口activity名称,如下:

ThemeNoTitleBar” android:label=”@string/app_name” android:name=”comestrongsandroidpopviewFileExplorerActivity”>

androidintentactionMAIN决定应用程序最先启动的Activity

androidintentcategoryLAUNCHER决定应用程序是否显示在程序列表里

在Android中取得当前进程

说明:上面代码关键的两个地方解释,也就是取得当前进程名

androidosProcessmyPid()) //获取PID,目前获取自己的也只有该API

ActivityManagerRunningAppProcessInfo类

说明: 封装了正在运行的进程信息

常用字段

int pid 进程ID

int uid 进程所在的用户ID

String processName 进程名,默认是包名或者由Android:process=””属性指定

String [ ] pkgList 运行在该进程下的所有应用程序包名

耳机控制需要使用Intent的,在intentjava(以下代码均来源于android44源码)中可以找到如下字段:

public static final String ACTION_MEDIA_BUTTON ="androidintentactionMEDIA_BUTTON";

这就是android自己用于耳机控制播放器的intent action字段了,我们可以利用它来找到相关代码,很容易我们找到了这个类MediaFocusControl类,其中包含方法dispatchMediaKeyEvent():

private void dispatchMediaKeyEvent(KeyEvent keyEvent, boolean needWakeLock) {

Intent keyIntent = new Intent(IntentACTION_MEDIA_BUTTON, null);

mRCStackpeek()mMediaIntentsend(mContext,

needWakeLock WAKELOCK_RELEASE_ON_FINISHED : 0 ,

keyIntent, this, mEventHandler);

}

这里讲intent发送了出去,具体去了哪里我们不用 *** 心,我们只要知道谁用了这个intent。这里的mRCStack是一个Stack类,其中包含着我们需要的RemoteControlStackEntry类对象。我们继续查看,这个对象是在哪被放入Stack中的,最后找到pushMediaButtonReceiver_syncAfRcs()方法,其中关键部分如下:

private boolean pushMediaButtonReceiver_syncAfRcs(PendingIntent mediaIntent,

ComponentName target, IBinder token) {

if (!wasInsideStack) {

rcse = new RemoteControlStackEntry(this, mediaIntent, target, token);

}

mRCStackpush(rcse); //rcse被push进mRCStack

}

由此,可以知道这个rcse就是我们需要的对象,而他是被直接new出来的,则这个构造函数的参数就变的很重要了。查看构造函数如下:

public RemoteControlStackEntry(MediaFocusControl controller, PendingIntent mediaIntent,

ComponentName eventReceiver, IBinder token)

可以发现,里面包含了一个重要的ComponentName对象,这个对象在android中就带表着一个应用程序,看来这就是我们要找的音乐播放软件了。那么他是如何被系统拿出来的呢?我们继续找。在刚刚的构造方法创建对象过程中,这个参数是使用target变量直接放入的。而这个target是pushMediaButtonReceiver_syncAfRcs方法的一个参数,那么继续根据这个线索向上找。发现这个参量是经过registerMediaButtonIntent()传入,但是仍然是方法的一个参数,那么继续找,发现找到了源头:

protected void restoreMediaButtonReceiver() {

String receiverName = SettingsSystemgetStringForUser(mContentResolver,

SettingsSystemMEDIA_BUTTON_RECEIVER, UserHandleUSER_CURRENT);

ComponentName eventReceiver = ComponentNameunflattenFromString(receiverName);

registerMediaButtonIntent(pi, eventReceiver, null);

}

由此我们发现了ComponentName对象的创建过程,它使用了一个receiverName对象,这个是个String,他就是我们的目标了。这是用了system的一个方法来创建,进入发现他竟然是个hide的方法,无法作为api使用。后来分析了方法名才释然,这个适用于多用户的,android43以后准备加入用户系统,可惜还不完善所以不给我们用,这肯定是有一般方法的,很快找到了getString方法,其实他就是调用了getStringForUser而已,只是屏蔽了id的参数。但是还有一个小问题,其实SettingsSystemMEDIA_BUTTON_RECEIVER字段也是个hide字段,是不可以当做api来用的,我想这就系统根本就是不想提供获取正在播放音乐的软件的方法,不过既然是个字段就没问题了,我们查看一下源码就能看到MEDIA_BUTTON_RECEIVER字段其实就代表着"media_button_receiver"而已。到这里我们已经可以实现功能了。方法如下,其实就简单的三句即可:

================================功能实现===========================================

String receiverName = SettingsSystemgetString(thisgetContentResolver(),

"media_button_receiver");

ComponentName eventReceiver = ComponentNameunflattenFromString(receiverName);

String musicPlayerPkgName = eventReceivergetPackageName();

我们即可得到我们所需要的包名。

以上就是关于如何根据包名packageName获取程序启动的主Activity名称全部的内容,包括:如何根据包名packageName获取程序启动的主Activity名称、如何获取当前应用app所在的进程id和进程名称、如何获取当前正在播放音乐的音乐软件的包名等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zz/9449976.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-28
下一篇 2023-04-28

发表评论

登录后才能评论

评论列表(0条)

保存