方法一:使用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和进程名称、如何获取当前正在播放音乐的音乐软件的包名等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)