GetTY allState始终返回空闲状态

时间:2013-10-29 06:42:24

标签: android reflection call telephonymanager

以下是我的代码,其中我使用反射来访问com.android.internal.telephony.CallManager。我正在使用其函数GetActiveFGCallState()来获取不同的状态,如警报传出呼叫,但它一直让我空闲状态即使状态为OFF_HOOK或RINGING.So我从中理解的是我的呼叫不在前台,因为如果没有活动的前台呼叫,活动前台呼叫的状态返回IDLE。那么我的理解是正确的吗?如果是,那么如何将呼叫活动带到前台,如果没有那么可能是什么问题?

主要活动代码:

package com.example.misscall;


import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.view.Menu;

public class MainActivity extends Activity {
     final Context context = this;



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Intent callIntent = new Intent(Intent.ACTION_CALL,
                Uri.parse("tel:" + "03365188508"));
        callIntent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
        startActivity(callIntent);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

}

最热门的文件:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.misscall"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="18" />
    <uses-feature android:name="android.hardware.telephony">
    </uses-feature>
    <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.CALL_PHONE" />
    <uses-permission android:name="android.permission.MODIFY_PHONE_STATE"/>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >

            <receiver android:name="com.example.misscall.DataConnection">
        <intent-filter>
                <action android:name="android.intent.action.PHONE_STATE"/>     
        </intent-filter>
</receiver>
        <activity
            android:name="com.example.misscall.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

</manifest>

数据连接类

    import android.os.RemoteException;
    import android.telephony.PhoneStateListener;
    import android.telephony.TelephonyManager;
    import android.util.Log;
    import android.widget.Toast;

    public class DataConnection extends BroadcastReceiver {
        TelephonyManager Tm;
         ITelephony telephonyService;
         Class c = null;
         Method methodGetInstance = null;
         Method methodGetActiveFgCallState=null;
         String TAG="Tag";
         Object objectCallManager=null;
        @Override
        public void onReceive(final Context context, Intent intent) {

            Tm=(TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
            final ClassLoader classLoader = this.getClass().getClassLoader();
            try {
                final Class<?> classCallManager = classLoader.loadClass("com.android.internal.telephony.CallManager");
                Log.e(TAG, "CallManager: Class loaded " + classCallManager.toString());

                 methodGetInstance = classCallManager.getDeclaredMethod("getInstance");
                methodGetInstance.setAccessible(true);
                Log.e(TAG, "CallManager: Method loaded " + methodGetInstance.getName());

                 objectCallManager = methodGetInstance.invoke(null);
                Log.e(TAG, "CallManager: Object loaded " + objectCallManager.getClass().getName());

                Method[] aClassMethods = classCallManager.getDeclaredMethods();  
                for(Method m : aClassMethods)  
                {  
                    Log.e("MEthods",m.getName());  
                }
                 methodGetActiveFgCallState = classCallManager.getDeclaredMethod("getActiveFgCallState");
                Log.e(TAG, "CallManager: Method loaded " + methodGetActiveFgCallState.getName());

                Log.e(TAG, "CallManager: What is the Call state = " + methodGetActiveFgCallState.invoke(objectCallManager));
            }
            catch (ClassNotFoundException e) {
                Log.e(TAG, e.getClass().getName() + e.toString());
            }
            catch (NoSuchMethodException e) {
                Log.e(TAG, e.getClass().getName() + e.toString());
            }
            catch (InvocationTargetException e) {
                Log.e(TAG, e.getClass().getName() + e.toString());
            }
            catch (IllegalAccessException e) {
                Log.e(TAG, e.getClass().getName() + e.toString());
            }
            Tm.listen(new PhoneStateListener(){
                public void  onCallStateChanged(int state,String number) {
                    super.onCallStateChanged(state, number);

                     try {
                        if (methodGetActiveFgCallState.invoke(objectCallManager).toString().toLowerCase() .equals("idle"))
                         {
                             Toast.makeText(context, "I am in idle state", Toast.LENGTH_LONG).show();
                         }
                    } catch (IllegalArgumentException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    } catch (IllegalAccessException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    } catch (InvocationTargetException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }

                }

            },PhoneStateListener.LISTEN_CALL_STATE);


        }

    }

2 个答案:

答案 0 :(得分:2)

请尝试以下:

    PhoneStateListener callStateListener = new PhoneStateListener() {
            public void onCallStateChanged(int state, String incomingNumber) 
            {
                  if(state==TelephonyManager.CALL_STATE_RINGING)
                    {
                            Toast.makeText(getApplicationContext(),"Phone Is Riging", Toast.LENGTH_LONG).show();

                    }
                    if(state==TelephonyManager.CALL_STATE_OFFHOOK)
                    {
                        Toast.makeText(getApplicationContext(),"Phone is Currently in A call", Toast.LENGTH_LONG).show();
                    }

                    if(state==TelephonyManager.CALL_STATE_IDLE)
                    {
                        Toast.makeText(getApplicationContext(),"phone is neither ringing nor in a call", Toast.LENGTH_LONG).show();
                    }
            }
            };


telephonyManager.listen(callStateListener,PhoneStateListener.LISTEN_CALL_STATE);

Reference

答案 1 :(得分:1)

<receiver android:name=".OutgoingCallReceiver">
        <intent-filter>
                <action android:name="android.intent.action.PHONE_STATE"/>     
        </intent-filter>
</receiver>



    public class OutgoingCallReceiver extends BroadcastReceiver {
        private static long timeStarted = -1L; // IMPORTANT!

        private static String number;
        private static boolean noCallListenerYet = true;

        @Override
        public void onReceive(final Context context, Intent intent) {
            PhoneCallListener phoneListener = new PhoneCallListener(context);
            TelephonyManager telephonyManager = (TelephonyManager) context
                    .getSystemService(Context.TELEPHONY_SERVICE);
            telephonyManager.listen(phoneListener,
                    PhoneStateListener.LISTEN_CALL_STATE);
        }

        private class PhoneCallListener extends PhoneStateListener {
            Context context;
            private boolean isPhoneCalling = false;

            public PhoneCallListener(Context context2) {
                // TODO Auto-generated constructor stub
                context=context2;
            }

            @Override
            public void onCallStateChanged(int state, String incomingNumber) {
                if (state == TelephonyManager.CALL_STATE_OFFHOOK) {
                //do something here
                }

                if (state == TelephonyManager.CALL_STATE_IDLE && timeStarted != -1L) {}
            }
        }
    }