覆盖掉手机通话界面

    要实现一个打电话却不能显示号码的功能。本来想写一个拨号器,可以完全替代系统phone的软件。不过研究了系统的phone代码之后就放弃了这个想法。不是一件容易的事。所以只好另想他法。使用系统拨号软件,但是在其上覆盖一层自己的界面。开始查资料。
    首先要实现①拨号功能。使用反射和aidl。调用IPhoneInterface接口,获取对象并调用call方法来拨打电话。同时②在系统层添加一层覆盖。管段电话后③删除此次通话记录。


    1、利用反射原理打电话和挂断电话:
    a. 在src下新建一个包:com.android.internal.telephony(和ITelephony.aidl 中 package 声明的包名一样);

    b. 然后从系统源码中把ITelephony.aidl文件拷贝到 com.android.internal.telephony包下。(也可以先新建一个ITelephony.aidl, 然后再把内容拷贝进去(ITelephony.aidl文件内容可以                         http://www.netmite.com/android/mydroid/1.5/frameworks/base/telephony/java/com/android/internal/telephony/ITelephony.aidl找到,这个方法适合没有SDK源码文件的开发者));

    c. 在src下新建一个包:android.telephony, 然后新建一个NeighboringCellInfo.aidl,其内容为:
    package android.telephony;

    parcelable NeighboringCellInfo;

    下面是调用的代码:

        private static TelephonyManager manager;

        manager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);

         ITelephony phone = PhoneUtils.getITelephony(manager);

   //下面是拨打电话和挂断电话的操作   
       phone.call(number);
         phone.endCall();  

    PhoneUtils中代码:

package com.linwoain.dial;

import java.lang.reflect.Method;
import com.android.internal.telephony.ITelephony;
import android.content.Context;
import android.os.RemoteException;
import android.telephony.TelephonyManager;
public class PhoneUtils {
    /**
     * return the ITelephony instance
     * 
     * @param telMgr  Provides access to information about the telephony services on the device
     * @return ITelephony instance
     * @throws Exception
     */
    static ITelephony getITelephony(TelephonyManager manager) throws Exception {
    Method getITelephonyMethod = manager.getClass().getDeclaredMethod("getITelephony");
    getITelephonyMethod.setAccessible(true);
    return (ITelephony) getITelephonyMethod.invoke(manager);
    }
    public static void Call(Context context, String number) {
    try {
        TelephonyManager mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        getITelephony(mTelephonyManager).call(number);
    } catch (RemoteException e) {
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    }
    }
    /**
     * end the ringing call
     * 
     * @param context
     *            Interface to global information about an application
     *            environment
     */
    public static void endRingingCall(Context context) {
    try {
        TelephonyManager mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        getITelephony(mTelephonyManager).endCall();
    } catch (RemoteException e) {
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    }
    }
    /**
     * answer the ringing call
     * 
     * @param context
     *            Interface to global information about an application
     *            environment
     */
    public static void answerRingingCall(Context context) {
    try {
        TelephonyManager mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        getITelephony(mTelephonyManager).answerRingingCall();
    } catch (RemoteException e) {
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    }
    }
}


2 、覆盖图层,设计一层覆盖图层,在需要是调用。
package com.linwoain.dial;
import android.app.Activity;
import android.view.Gravity;
import android.view.View;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;

public class Layer
{
        private Activity mActivty;
        private WindowManager mWindowManager;
        private View mLockView;
        private LayoutParams mLockViewLayoutParams;
        private static Layer mLockLayer;
        private boolean isLocked;
        public static synchronized Layer getInstance(Activity act)
        {
                
                if (mLockLayer == null)
                {
                        mLockLayer = new Layer(act);
                }
                return mLockLayer;
        }
        private Layer(Activity act)
        {
                mActivty = act;
                init();
        }
        private void init()
        {
                isLocked = false;
                mWindowManager = (WindowManager) mActivty.getApplication().getSystemService("window");
                mLockViewLayoutParams = new LayoutParams();
                mLockViewLayoutParams.gravity = Gravity.LEFT | Gravity.TOP;
                mLockViewLayoutParams.x = 0;
                mLockViewLayoutParams.y = 0;
                mLockViewLayoutParams.width = 480;
                mLockViewLayoutParams.height = 800;
                mLockViewLayoutParams.type = LayoutParams.TYPE_SYSTEM_ALERT;
        }
        public synchronized void lock()
        {
                if (mLockView != null && !isLocked)
                {
                        mWindowManager.addView(mLockViewmLockViewLayoutParams);
                }
                isLocked = true;
        }
        public synchronized void unlock()
        {
                if (mWindowManager != null && isLocked)
                {
                        mWindowManager.removeView(mLockView);
                }
                isLocked = false;
        }
        public synchronized void setView(View v)
        {
                mLockView = v;
        }
        public synchronized void setLayer(int type)
        {
                mLockViewLayoutParams.type = type;
        }
}

需要调用时,获取实例。

            layer = Layer.getInstance(getActivity());
            layer.setView(view);
            layer.lock();
当挂断电话时执行
                layer.unlock();

3 、删除通话记录
        getContentResolver().delete(CallLog.Calls.CONTENT_URI"number=?"new String[]{number});
        因为使用了对通话记录的修改,需要添加权限。
    


小结:找了一天的资料,终于搞清楚了如何从覆盖一个图层上显示出来。有很多的代码参考了其他作者。将其列出:
关于对打电话部分的DIY-Android源码下载-eoe 移动开发者论坛 - Powered by Discuz! http://www.eoeandroid.com/thread-203681-1-1.html
android 悬浮窗口 - winson_jason的专栏 - 博客频道 - CSDN.NET http://blog.csdn.net/winson_jason/article/details/8160718
android 通话记录的查询与删除 - flying_vip_521的专栏 - 博客频道 - CSDN.NET http://blog.csdn.net/flying_vip_521/article/details/7258805






posted @ 2014-05-07 09:51  linwoain  阅读(727)  评论(0编辑  收藏  举报