- 浏览: 512982 次
- 性别:
- 来自: 惠州
文章分类
- 全部博客 (255)
- ant (1)
- springMVC (2)
- ajax (4)
- oracle (12)
- SSH (13)
- struts1 (2)
- Hibernate (14)
- spring (5)
- jstl (1)
- 连接池 (1)
- acegi (4)
- java (17)
- jquery (11)
- div+css (4)
- drupal (1)
- php (8)
- freemaker调模板生成静态页面 (1)
- xml (1)
- json (2)
- javascript (9)
- 正则表达式 (4)
- Ext (8)
- jdbc (1)
- sql server (2)
- perl (5)
- db4o (1)
- webservice (4)
- flex (13)
- it资讯 (1)
- joomla (0)
- 设计模式 (1)
- struts2 (4)
- s2sh (8)
- linux (3)
- ejb (2)
- android旅途 (24)
- android (36)
- C/C++ (16)
- mysql (1)
最新评论
-
fengyuxing168:
IBelyService bs = IBelyService. ...
为 Android 添加 Java 层服务也就是添加自定义的aidl服务到serviceManager 通过ServiceManager.getService取 -
dengzhangtao:
"由于ActivityManagerService是 ...
binder理解 -
yzyspy:
ActivityManagerService:startHom ...
Android的Launcher成为系统中第一个启动的,也是唯一的 -
Matchstick:
使用SELECT DISTINCT alias FROM Po ...
hibernate 一对多表查询时fetchMode.join 生成left outer join 出来数据重复问题 -
dlheart:
没看懂你什么意思啊,我遇到的问题是一对多,设了fetch = ...
hibernate 一对多表查询时fetchMode.join 生成left outer join 出来数据重复问题
Android的Launcher成为系统中第一个启动的,也是唯一的
如果你要定制一个Android系统,你想用你自己的Launcher(Home)作主界面来替换Android自己的Home,而且不希望用户安装的Launcher来替换掉你的Launcher.
我们可以通过修改Framework来实现这样的功能。
这里以Android2.1的源代码为例来实际说明。
1)首先了解一下Android的启动过程。
Android系统的启动先从Zygote开始启动,然后......(中间的过程就不说了).....一直到了SystemServer(framework)这个地方,看到这段代码:
/**
* This method is called from Zygote to initialize the system. This will cause the native
* services (SurfaceFlinger, AudioFlinger, etc..) to be started. After that it will call back
* up into init2() to start the Android services.
*/
native public static void init1(String[] args);
public static void main(String[] args) {
if (SamplingProfilerIntegration.isEnabled()) {
SamplingProfilerIntegration.start();
timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
SamplingProfilerIntegration.writeSnapshot("system_server");
}
}, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL);
}
// The system server has to run all of the time, so it needs to be
// as efficient as possible with its memory usage.
VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
System.loadLibrary("android_servers");
init1(args);
}
public static final void init2() {
Log.i(TAG, "Entered the Android system server!");
Thread thr = new ServerThread();
thr.setName("android.server.ServerThread");
thr.start();
}
}
从SystemServer的main函数开始启动各种服务。
首先启动init1,然后启动init2.
从上面的注释可以看到:init1这个方法时被Zygote调用来初始化系统的,init1会启动native的服务如SurfaceFlinger,AudioFlinger等等,这些工作做完以后会回调init2来启动Android的service。
这里我们主要来关注init2的过程。
init2中启动ServerThread线程,
ServerThread中启动了一系列的服务,比如这些:
ActivityManagerService
EntropyService
PowerManagerService
TelephonyRegistry
PackageManagerService
AccountManagerService
BatteryService
HardwareService
Watchdog
SensorService
BluetoothService
StatusBarService
ClipboardService
InputMethodManagerService
NetStatService
ConnectivityService
AccessibilityManagerService
NotificationManagerService
MountService
DeviceStorageMonitorService
LocationManagerService
SearchManagerService
FallbackCheckinService
WallpaperManagerService
AudioService
BackupManagerService
AppWidgetService
这些大大小小的服务起来以后,开始
((ActivityManagerService)ActivityManagerNative.getDefault()).systemReady()
在systemReady后开始开始启动Launcher。
在寻找Launcher的时候是根据HOME的filter(在Manifest中定义的<category android:name="android.intent.category.HOME" />)来过滤。
然后根据filter出来的HOME来启动,如果只有一个HOME,则启动这个HOME,如果用户自己装了HOME,那就会弹出来一个列表供用户选择。
我们现在希望从这里弹出我们自己定制的Launcher,同时也不希望弹出选择HOME的界面,我们不希望用户修改我们的home,比如我们的home上放了好多广告,以及强制安装的程序,不希望用户把它干掉。
我们可以通过这样来实现:
2) 定义一个私有的filter选项,然后用这个选项来过滤HOME.
一般情况下我们使用Manifest中定义的<category android:name="android.intent.category.HOME"来过滤的,我们现在增加一个私有的HOME_FIRST过滤。
在Intent.java(frameworks/base/core/java/android/content/Intent.java)中添加两行代码
//lixinso:添加CATEGORY_HOME_FIRST
@SdkConstant(SdkConstantType.INTENT_CATEGORY)
public static final String CATEGORY_HOME_FIRST = "android.intent.category.HOME_FIRST";
3)修改和CATEGORY_HOME相关的所有的地方,都改成HOME_FIRST,主要是framework中的这几个地方:
frameworks/base/services/java/com/android/server/am/ActivityManagerService.java中
//intent.addCategory(Intent.CATEGORY_HOME);
改成intent.addCategory(Intent.CATEGORY_HOME_FIRST); //lixinso:
//if (r.intent.hasCategory(Intent.CATEGORY_HOME)) {
改成if (r.intent.hasCategory(Intent.CATEGORY_HOME_FIRST)) { //lixinso: Intent.CATEGORY_HOME -> Intent.CATEGORY_HOME_FIRST
frameworks/base/services/java/com/android/server/am/HistoryRecorder.java中
// _intent.hasCategory(Intent.CATEGORY_HOME) &&
改成 _intent.hasCategory(Intent.CATEGORY_HOME_FIRST) && //lixinso: Intent.CATEGORY_HOME->Intent.CATEGORY_HOME_FIRST
frameworks/policies/base/mid/com/android/internal/policy/impl/MidWindowManager.java中
//mHomeIntent.addCategory(Intent.CATEGORY_HOME);
改成 mHomeIntent.addCategory(Intent.CATEGORY_HOME_FIRST); //lixinso
frameworks/policies/base/mid/com/android/internal/policy/impl/RecentApplicationsDialog.java中
//new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME),0);
改成 new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME_FIRST),0); //lixinso
frameworks/policies/base/phone/com/android/internal/policy/impl/PhoneWindowManager.java中
//mHomeIntent.addCategory(Intent.CATEGORY_HOME);
改成 mHomeIntent.addCategory(Intent.CATEGORY_HOME_FIRST); //lixinso
frameworks/policies/base/phone/com/android/internal/policy/impl/RecentApplicationsDialog.java中
//ResolveInfo homeInfo = pm.resolveActivity(new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME),0);
改成 ResolveInfo homeInfo = pm.resolveActivity(new
Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME_FIRST),0);
//lixinso
4) 写一个自己的Launcher.
可以参考android sample中的Launcher,或者android源代码中的 /packages/apps/Launcher 来写。
在Launcher中标记其是不是Launcher的最关键的代码时Manifest中的filter:android:name="android.intent.category.HOME"
现在我们定义了自己的filter,那么,我们在我们自己写的Launcher中将Manifest改为:
<application android:process="android.process.acore3" android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".FirstAppActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME_FIRST" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.MONKEY" />
</intent-filter>
</activity>
</application>
然后将编译好的apk放到/out/target/product/generic/system/app目录下。
5)将Android自带的Launcher删除掉,包括源代码(packages/apps/Launcher)和apk(/out/target/product/generic/system/app/Launcher.apk)。
6)
做完这些工作,就可以重新编译Android了,我们可以编译修改过的几个相关的包。
如果之前编译过了Android源码,可以用mmm命令来编译部分的改动。
这里需要这样编译:
$ . build/envsetup.sh
$ mmm frameworks/base
$ mmm frameworks/base/services/java
$ mmm frameworks/policies/base/mid
$ mmm frameworks/policies/base/phone
7)
编译完成后重新生成img文件。
$ make snod
8) 现在可以启动Android模拟器来看效果了。
首先设置环境变量:
$ export ANDROID_PRODUCT_OUT= ./out/target/product/generic
然后切换到
$ cd ./out/host/linux-x86/bin
运行
$ ./emulator
这样我们启动的模拟器里面用的image就是我们刚才编译好的自己定制的东西了。
从模拟器上可以看到启动的Launcher是我们自己的Launcher,不会出现默认的Launcher了,也不会出现选择界面。
9)我们再验证一下,如果用户装上了一个其他的Launcher(Home)会怎么样。
从网上找一个一般的Launcher或者自己写一个一般的Launcher装上去,重新启动,不会出现选择界面。
按HOME键也不会出来两个HOME来选择。
这样我们就牢牢控制了用户的桌面。
只有我们自己定制的HOME才能装上。 这对于定制Android设备的厂商很有用处。
发表评论
-
onInterceptTouchEvent和onTouchEvent调用时序
2012-02-08 08:44 1046onInterceptTouchEvent和onTouchEv ... -
Android2.2.1广播大全
2012-01-11 17:29 914Android2.2.1广播大全 博 ... -
Android Gesture Detector
2012-01-06 16:09 1208Android Gesture Detector * ... -
在程序中设置android:gravity 和 android:layout_Gravity属性
2012-01-06 10:04 1571【Android布局】在程序中 ... -
Android应用程序基础 >> 任务栈和亲属关系(Activities and Tasks)
2012-01-05 10:26 1147Android应用程序基础 >& ... -
android 中使用socket使native和framework通信
2011-09-01 10:14 1202android 中使用socket使native和frame ... -
android aidl iBinder理解
2011-06-01 11:51 2063在android中有一个程序员大量使用的操作,就是bindse ... -
Android开发者指南(6) —— AIDL
2011-05-31 10:59 1293Android开发者指南(6) —— AIDL ... -
android 线程间的通信
2011-05-20 13:22 895近来找了一些关 ... -
Android Service学习之AIDL, Parcelable和远程服务
2011-05-20 11:51 1072AIDL的作用 由于每个应用程序都 ... -
有关Android线程的学习
2011-05-20 11:20 10361. Android进程 在了解Android ... -
(转载)Android下Affinities和Task
2011-05-19 16:30 858(转载)Android下Affinities和Tas ... -
Launcher的启动过程
2011-05-12 19:36 22401. Launcher的启动过程 从网络上 ... -
android中使用jni,ndk的C语言回调方法
2011-05-12 19:19 6559android中使用jni,ndk的C ... -
典型应用之——将库打进apk
2011-05-12 19:19 2883典型应用之——将库打进apk (2010-12-17 1 ... -
一个打通jni,java framework,application三层的练习
2011-05-10 10:58 1165转自:http://blogold.chinaunix ... -
android eclipse 和 源码 情况下 引用第三方jar
2011-05-10 10:55 2480android eclipse 和 源码 情况 ... -
1.系统属性获取及设置中的设置值
2011-04-21 15:04 35161.系统属性获取及设置 android.os.SystemP ... -
给应用签名 uid.system platform 权限
2011-04-21 14:58 1480在生成的apk目录下放 signapk.jar platfo ... -
binder理解
2011-03-30 10:37 2226Binder理解 例子代码: /** {@hide} ...
相关推荐
描述中提到的"AnderWeb-android_packages_apps_Launcher-4458ee4.zip"与标题相同,暗示这可能是一个从AnderWeb(一个可能的第三方Android开发或资源分享平台)下载的定制版Android启动器应用的源代码或者二进制文件...
APK文件在系统中被安装后,会有一个对应的包名(Package Name),它是区分不同应用的唯一标识。因此,要打开一个系统APK,我们首先需要知道该APK的包名。 以下是一个简单的示例代码,展示如何通过Intent启动一个...
Intent是Android中的一个核心概念,它用于启动活动(Activity)、服务(Service)或广播接收器(BroadcastReceiver)。当我们要打开一个第三方应用时,只需要知道该应用的包名,就可以创建一个Intent并启动它。以下...
在Android系统中,通过应用包名启动第三方应用是一项常见的操作,尤其在开发过程中。这个小demo展示的就是如何利用已知的第三方应用包名来启动该应用。应用包名是每个Android应用的唯一标识,它在应用程序的...
在Android上,快捷方式是一种指向应用程序特定功能的接口,用户可以通过长按应用图标或通过启动器(Launcher)创建。在API 25及更高版本中,Android引入了动态快捷方式(Dynamic Shortcuts),允许开发者创建和管理...
在IT行业中,一键启动第三方应用是一项常见的需求,尤其是在自动化测试、设备管理或者用户便捷操作的场景下。"一键启动第三方app.rar"这个压缩包文件很可能包含了一个实现此功能的程序或者代码示例,用于帮助开发者...
- 启动另一个活动:通过Intent对象来启动新的活动,Intent是Android中用于组件间通信的重要工具。 - 结束活动:调用finish()方法可结束当前活动,将其从任务栈中移除。 2.3 在活动中使用Intent Intent是一种消息...
第一种方式是通过拨号界面输入命令来查询IMEI号;第二种方式除了查询IMEI号外还可以进行网络切换以及快速查询其他硬件信息。 - **快速查询硬件信息** `*#*#4636#*#*` 输入这个代码可以打开一个内置的菜单,用于...
1. **第一个Android应用**:开发Android应用的起点通常是从创建并运行你的第一个应用开始。这涉及到安装Android Studio,配置开发环境,并通过它来构建和运行应用。在命令行中,你可以使用`adb install`命令来安装...
在Android开发中,获取第三方APK的包名、启动类名以及图标是常见的需求,尤其在应用管理和自动化测试等领域。这个名为"获取第三方apk的包名启动类名icon.rar"的压缩包文件提供了相关的代码资源,尽管可能并非所有...
1. **Intent Intents**: 创建快捷图标的第一步是定义一个`Intent`,这个`Intent`用于启动快捷方式。通常,我们需要创建一个`Intent`来指定要启动的Activity和一些额外的数据。 ```java Intent shortcutIntent = new...
受第一个也是唯一一个图标包的深色版本,其灵感来自于新的Pixel设备样式,旨在转变设备的图形。 重要说明 •这是一个图标包,需要自定义启动器才能工作。Google Now Launcher,Pixel Launcher或工厂安装的任何...
受新Pixel启发而开发的第一个也是唯一的图标包的深色版本,用于变换设备的图形设备的样式。 重要说明 •这是一个图标包,需要自定义启动器才能工作。Google Now Launcher,Pixel Launcher或工厂安装的任何其他启动器...
- 创建Intent:首先,你需要创建一个Intent对象,设置其ACTION_MAIN和CATEGORY_LAUNCHER属性,这通常代表启动一个应用的主界面。 - 添加ComponentName:接着,使用ComponentName类来指定你想打开的应用的包名和...
在Android开发中,Java语言是主要的编程工具,而 APK 是 Android 应用程序的打包格式。本主题将深入探讨如何使用Java来获取APK文件的相关信息,包括包名、版本、权限、图标以及启动图等关键元数据。这些信息对于理解...
- **Android层的配置修改**: 对Android系统中的触控事件处理逻辑进行调整。 #### 3.5 G-Sensor配置 - **打包配置文件修改**: 修改与加速度传感器相关的配置文件。 - **Android层配置修改**: 在系统层面对加速度...
#### 一、创建第一个Android应用程序:Hello World ##### 1. 创建项目的步骤 在本教程中,我们将通过Eclipse IDE创建一个简单的Android应用程序,并实现显示“Hello World”的功能。 **步骤1:** 打开Eclipse,...
在AndroidManifest.xml中,这个类被指定在 `<activity>` 标签内,特别是带有 `android.intent.category.LAUNCHER` 和 `android.intent.action.MAIN` 属性的 `<intent-filter>` 下。 获取APK包名和主类名有多种方法...
下面我们将深入探讨如何在Android应用中创建并发送一个基本的通知。 首先,创建通知涉及以下步骤: 1. **获取`NotificationManager`实例**: 通过调用`getSystemService()`方法,并传入`Context.NOTIFICATION_...
在这个例子中,`.MainActivity` 是 Activity 的全限定类名,`android.intent.action.MAIN` 表示这是应用的主入口,而 `android.intent.category.LAUNCHER` 表示它会在应用程序列表中显示。 **Activity 中控件的添加...