Android 中拦截 Activity 的启动(拦截系统的 Intent)

目的

最近因为项目需要,我们自己定制的只能硬件里面没有系统的电话、相机、短信、浏览器等组件,如果其他 App 来发 Intent 调用的话,程序就会崩溃。要求我们做一个系统拦截,拦截这些意图。

有几种方法:
1.写一个 App 专门来拦截这些 Intent。(通用性比较高)
2.在源码层做拦截。(比较简单)

给程序加锁

360等相关程序可以给我们装上的应用程序加锁,也就是我们在点开某个应用程序的时候,会弹出一个提示框,比如输入密码或者相关操作才可以进入这个程序。其实原理也就是拦截 Intent,分析 Intent 中携带的内容,然后进行相关操作。

GitHub 上有人写了相关的文章,可以看一下:https://github.com/chuwuwang/AppBlock

分析原理:

我们调用 Context.startActivity() 方法。

这里写图片描述

调用本类的 startActivity()方法。

这里写图片描述

调用 startActivityForResult()方法。

这里写图片描述

查看执行步骤,定位到 3810行,调用 Instarumentation.execStartActivity()方法。进入 Instarumentation 类,查看execStartActivity()方法。

这里写图片描述

查看执行步骤,定位到 1507行,调用 ActivityManagerNative.getDefault().startActivity()方法。进入到 ActivityManagerNative 类,定位到 onTransact() 方法。在 START_ACTIVITY_TRANSACT 的分支,这里面就是捕获 Intent 的相关信息。我们可以在这里面拦截我们想要拦截的 Intent。

这里写图片描述

单独写一个 App 来拦截 Activity的启动

其实我们只要在 AndroidManifest.xml 中注册 Activity 的标签中,添加相关的 Intent-filter 就可以了。匹配相应的 Action。

给 intent-filter 的 android:priority=”-1” :如果没有和他一样的 Action,就启动它。 有相同的 Action,就启动另一个 Action 的 Activity。

        <!-- 浏览器 -->
        <activity
            android:name="woyou.system.intercepet.activity.BrowserActivity"
            android:theme="@style/dialogActivityStyle" >
            <intent-filter android:priority="-1" >
                <action android:name="android.speech.action.VOICE_SEARCH_RESULTS" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
            <!-- For these schemes were not particular MIME type has been
                 supplied, we are a good candidate. -->
            <intent-filter android:priority="-1" >
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data android:scheme="http" />
                <data android:scheme="https" />
                <data android:scheme="about" />
                <data android:scheme="javascript" />
                <data android:scheme="content" />
            </intent-filter>
            <!-- For these schemes where any of these particular MIME types
                 have been supplied, we are a good candidate. -->
            <intent-filter android:priority="-1" >
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.BROWSABLE" />
                <category android:name="android.intent.category.DEFAULT" />

                <data android:scheme="http" />
                <data android:scheme="https" />
                <data android:scheme="inline" />
                <data android:mimeType="text/html" />
                <data android:mimeType="text/plain" />
                <data android:mimeType="application/xhtml+xml" />
                <data android:mimeType="application/vnd.wap.xhtml+xml" />
            </intent-filter>
            <!-- For viewing saved web archives. -->
            <intent-filter android:priority="-1" >
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.BROWSABLE" />
                <category android:name="android.intent.category.DEFAULT" />

                <data android:scheme="http" />
                <data android:scheme="https" />
                <data android:scheme="file" />
                <data android:mimeType="application/x-webarchive-xml" />
            </intent-filter>
            <!-- Accept inbound NFC URLs at a low priority -->
            <intent-filter android:priority="-101" >
                <action android:name="android.nfc.action.NDEF_DISCOVERED" />

                <category android:name="android.intent.category.DEFAULT" />

                <data android:scheme="http" />
                <data android:scheme="https" />
            </intent-filter>
            <!-- The maps app is a much better experience, so it's not
                 worth having this at all... especially for a demo!
            <intent-filter android:label="Map In Browser">
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="vnd.android.cursor.item/postal-address" />
            </intent-filter> -->
            <intent-filter android:priority="-1" >
                <action android:name="android.intent.action.WEB_SEARCH" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data android:scheme="" />
                <data android:scheme="http" />
                <data android:scheme="https" />
            </intent-filter>
            <intent-filter android:priority="-1" >
                <action android:name="android.intent.action.MEDIA_SEARCH" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
            <intent-filter android:priority="-1" >
                <action android:name="android.intent.action.SEARCH" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>

        <!-- 音乐播放器 -->
        <activity
            android:name="woyou.system.intercepet.activity.MusicActivity"
            android:theme="@style/dialogActivityStyle" >
            <intent-filter android:priority="-1" >
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.DEFAULT" />

                <data android:scheme="file" />
                <data android:mimeType="audio/*" />
                <data android:mimeType="application/ogg" />
                <data android:mimeType="application/x-ogg" />
                <data android:mimeType="application/itunes" />
                <data android:mimeType="application/aac" />
                <data android:mimeType="application/imy" />
                <data android:mimeType="application/x-flac" />
            </intent-filter>
            <intent-filter android:priority="-1" >
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data android:scheme="http" />
                <data android:mimeType="audio/*" />
                <data android:mimeType="application/ogg" />
                <data android:mimeType="application/x-ogg" />
                <data android:mimeType="application/itunes" />
                <data android:mimeType="application/aac" />
                <data android:mimeType="application/imy" />
                <data android:mimeType="application/x-flac" />
            </intent-filter>
            <intent-filter android:priority="-1" >
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data android:scheme="content" />
                <data android:mimeType="audio/*" />
                <data android:mimeType="application/ogg" />
                <data android:mimeType="application/x-ogg" />
                <data android:mimeType="application/itunes" />
                <data android:mimeType="application/aac" />
                <data android:mimeType="application/imy" />
                <data android:mimeType="application/amr" />
                <data android:mimeType="application/awb" />
                <data android:mimeType="application/x-flac" />
            </intent-filter>
            <intent-filter android:priority="-1" >
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.DEFAULT" />

                <data android:scheme="content" />
                <data android:host="media" />
                <data android:mimeType="audio/*" />
                <data android:mimeType="application/ogg" />
                <data android:mimeType="application/x-ogg" />
                <data android:mimeType="application/itunes" />
                <data android:mimeType="application/aac" />
                <data android:mimeType="application/imy" />
            </intent-filter>
            <intent-filter android:priority="-1" >
                <action android:name="com.android.music.PLAYBACK_VIEWER" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>

        <!-- 短信 -->
        <activity 
            android:name="woyou.system.intercepet.activity.SMSActivity"
            android:theme="@style/dialogActivityStyle" >
            <intent-filter android:priority="1000" >
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.DEFAULT" />

                <data android:mimeType="vnd.android-dir/mms-sms" />
            </intent-filter>
            <intent-filter android:priority="1000" >
                <action android:name="android.intent.action.VIEW" />
                <action android:name="android.intent.action.SENDTO" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data android:scheme="sms" />
                <data android:scheme="smsto" />
            </intent-filter>
            <intent-filter android:priority="1000" >
                <action android:name="android.intent.action.VIEW" />
                <action android:name="android.intent.action.SENDTO" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data android:scheme="mms" />
                <data android:scheme="mmsto" />
            </intent-filter>
            <intent-filter android:priority="1000" >
                <action android:name="android.intent.action.SEND" />

                <category android:name="android.intent.category.DEFAULT" />

                <data android:mimeType="image/*" />
            </intent-filter>
            <intent-filter android:priority="1000" >
                <action android:name="android.intent.action.SEND" />

                <category android:name="android.intent.category.DEFAULT" />

                <data android:mimeType="video/*" />
            </intent-filter>
            <intent-filter android:priority="1000" >
                <action android:name="android.intent.action.SEND" />

                <category android:name="android.intent.category.DEFAULT" />

                <data android:mimeType="audio/*" />
            </intent-filter>
            <intent-filter android:priority="1000" >
                <action android:name="android.intent.action.SEND" />

                <category android:name="android.intent.category.DEFAULT" />

                <data android:mimeType="text/plain" />
            </intent-filter>
            <intent-filter android:priority="1000" >
                <action android:name="android.intent.action.SEND" />

                <category android:name="android.intent.category.DEFAULT" />

                <data android:mimeType="text/x-vcalendar" />
            </intent-filter>
            <intent-filter android:priority="1000" >
                <action android:name="android.intent.action.SEND_MULTIPLE" />

                <category android:name="android.intent.category.DEFAULT" />

                <data android:mimeType="image/*" />
            </intent-filter>
            <intent-filter android:priority="1000" >
                <action android:name="android.intent.action.SEND_MULTIPLE" />

                <category android:name="android.intent.category.DEFAULT" />

                <data android:mimeType="video/*" />
            </intent-filter>
            <intent-filter android:priority="1000" >
                <action android:name="android.intent.action.SEND_MULTIPLE" />

                <category android:name="android.intent.category.DEFAULT" />

                <data android:mimeType="audio/*" />
            </intent-filter>
            <intent-filter android:priority="1000" >
                <action android:name="android.intent.action.SEND_MULTIPLE" />
                <action android:name="android.intent.action.SEND" />

                <category android:name="android.intent.category.DEFAULT" />

                <data android:mimeType="application/ogg" />
            </intent-filter>
            <intent-filter android:priority="1000" >
                <action android:name="com.android.mms.ui.ComposeMessageActivity" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>

        <!-- 打电话 -->
        <activity
            android:name="woyou.system.intercepet.activity.CallPhoneActivity"
            android:theme="@style/dialogActivityStyle" >
            <intent-filter android:priority="1000" >
                <action android:name="android.intent.action.DIAL" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data android:mimeType="vnd.android.cursor.item/phone" />
                <data android:mimeType="vnd.android.cursor.item/person" />
            </intent-filter>
            <intent-filter android:priority="1000" >
                <action android:name="android.intent.action.DIAL" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data android:scheme="voicemail" />
            </intent-filter>
            <intent-filter android:priority="1000" >
                <action android:name="android.intent.action.DIAL" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
            <intent-filter android:priority="1000" >
                <action android:name="android.intent.action.VIEW" />
                <action android:name="android.intent.action.DIAL" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data android:scheme="tel" />
            </intent-filter>
            <intent-filter android:priority="1000" >
                <action android:name="android.intent.action.CALL_BUTTON" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
            </intent-filter>
            <intent-filter android:priority="1000" >
                <action android:name="com.android.phone.action.TOUCH_DIALER" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.TAB" />
            </intent-filter>
            <intent-filter android:priority="1000" >
                <action android:name="com.android.phone.action.RECENT_CALLS" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.TAB" />
            </intent-filter>
            <intent-filter android:priority="1000" >
                <action android:name="android.intent.action.CALL" />

                <category android:name="android.intent.category.DEFAULT" />

                <data android:scheme="tel" />
            </intent-filter>
            <intent-filter android:priority="1000" >
                <action android:name="android.intent.action.CALL" />

                <category android:name="android.intent.category.DEFAULT" />

                <data android:scheme="sip" />
            </intent-filter>
            <intent-filter android:priority="1000" >
                <action android:name="android.intent.action.CALL" />

                <category android:name="android.intent.category.DEFAULT" />

                <data android:scheme="voicemail" />
            </intent-filter>
            <intent-filter android:priority="1000" >
                <action android:name="android.intent.action.CALL" />

                <category android:name="android.intent.category.DEFAULT" />

                <data android:mimeType="vnd.android.cursor.item/phone" />
                <data android:mimeType="vnd.android.cursor.item/phone_v2" />
                <data android:mimeType="vnd.android.cursor.item/person" />
            </intent-filter>
        </activity>

运行以后你会发现,我们在调用 打电话的时候(android.intent.action.CALL) 会弹出 一个让你选择执行的界面。仔细查看 你会发现,在源码里原来是这样的。

这里写图片描述

哔了狗。这个类在源码的 com.android.service.telecom 包下。想要怎样改,能达到需求就好。可能你还需要屏蔽相机、相册… 可能需要你去看看源码,那些 action 是怎样写的,我也在5.0的源码中抠出了一些。

下载地址:http://download.csdn.net/detail/u012301841/9466031

借鉴的相关文章:http://blog.csdn.net/jiangwei0910410003/article/details/48787777

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Android ,可以使用 ActivityManager 监听 Activity启动情况,并在需要的时候拦截某个 Activity启动。具体步骤如下: 1. 在 AndroidManifest.xml 注册一个监听器服务。 ```xml <service android:name=".MyService"> <intent-filter> <action android:name="android.intent.action.MAIN" /> </intent-filter> </service> ``` 2. 创建一个 Service 类,并在其实现一个继承自 Binder 的内部类 MyBinder。 ```java public class MyService extends Service { private MyBinder binder = new MyBinder(); public class MyBinder extends Binder { public void intercept(String packageName, String activityName) { // 在这里实现拦截逻辑 } } @Nullable @Override public IBinder onBind(Intent intent) { return binder; } } ``` 3. 在 MyBinder 的 intercept 方法,通过 ActivityManager 监听 Activity启动情况,并在需要的时候拦截某个 Activity启动。 ```java public void intercept(String packageName, String activityName) { final ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); activityManager.addOnBackStackChangedListener(new ActivityManager.OnBackStackChangedListener() { @Override public void onBackStackChanged() { String currentPackageName = ""; String currentActivityName = ""; if (activityManager.getRunningTasks(1).size() > 0) { ComponentName componentName = activityManager.getRunningTasks(1).get(0).topActivity; currentPackageName = componentName.getPackageName(); currentActivityName = componentName.getClassName(); } if (currentPackageName.equals(packageName) && currentActivityName.equals(activityName)) { // 拦截逻辑 } } }); } ``` 注意,为了保证拦截的准确性,需要在拦截逻辑判断当前启动Activity 是否是需要拦截Activity。在上面的代码,通过比较包名和类名的方式来判断。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值