2012-06-24 5 views
1

들어오고 나가는 전화를 가로 챌 수 있습니다. 내 문제는 버전 인 2.3.x에서 작동하지 않는다는 것입니다들어오는 호출을 차단하는 방법 android 2.3.x

여기

내 코드 :

public class PhoneCallReceiver extends BroadcastReceiver { 

/** 
* Call back which fires off when the phone changes state. 
*/ 
@Override 
public void onReceive(Context context, Intent intent) { 


    //TODO 
    //=========== 
    //here i need to chack the number 

    //  Bundle b = intent.getExtras(); 
    //  String incommingNumber = b.getString(TelephonyManager.EXTRA_INCOMING_NUMBER); 
    // Additional Step 
    // Check whether this number matches with your defined Block List 
    // If yes, Reject the Call 
    //=========== 


    /* examine the state of the phone that caused this receiver to fire off */ 
    String phone_state = intent.getStringExtra(TelephonyManager.EXTRA_STATE); 
    if (phone_state.equals(TelephonyManager.EXTRA_STATE_RINGING)) 
    { 
     //     if (context.getSharedPreferences(Hc.PREFSNAME,0).getBoolean(Hc.PREF_CALL_ANSWER_TOOLS_KEY, true)) 
     //     { 
     logMe("Phone Ringing: the phone is ringing, scheduling creation call answer screen activity"); 
     Intent i = new Intent(context, CallAnswerIntentService.class); 
     i.putExtra("delay", 100L); 
     context.startService(i); 
     logMe("Phone Ringing: started, time to go back to listening"); 
     //     } else { 
     //       logMe("Phone Ringing: Call Answer tools disabled by user"); 
     //     } 
    } 
    if (phone_state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) 
    { 
     //     if (context.getSharedPreferences(Hc.PREFSNAME,0).getBoolean(Hc.PREF_SCREEN_GUARD_TOOLS_KEY, true)) 
     //     { 

     //TODO 
     Intent i = new Intent(context,InCallScreenGuardService.class); 
     i.putExtra("delay", 100L); 
     logMe("Phone Offhook: starting screen guard service"); 
     context.startService(i); 
     //     } else { 
     //       logMe("Phone Offhook: In-Call Screen Guard disabled by user"); 
     //     } 
    } 
    if (phone_state.equals(TelephonyManager.EXTRA_STATE_IDLE)) 
    { 
     //     if (context.getSharedPreferences(Hc.PREFSNAME,0).getBoolean(Hc.PREF_SCREEN_GUARD_TOOLS_KEY, true)) 
     //     { 
     //TODO 
     Intent i = new Intent(context,InCallScreenGuardService.class); 
     logMe("Phone Idle: stopping screen guard service"); 
     context.stopService(i); 
     //     } else { 
     //       logMe("Phone Idle: In-Call Screen Guard disabled by user"); 
     //     } 
    } 

    return; 
} 

이 서비스와 아가에게 의도를 보내 다음과 같은 활동에 의도를 보내

public class CallAnswerActivity extends Activity { 
/** 
* whether or not to use the AIDL technique or 
* the HEADSET_HOOK/package restart techniques 
*/ 
private static final boolean USE_ITELEPHONY = true; 

/** 
* internal phone state broadcast receiver 
*/ 
protected BroadcastReceiver r; 

/** 
* TelephonyManager instance used by this activity 
*/ 
private TelephonyManager tm; 

/** 
* AIDL access to the telephony service process 
*/ 
private com.android.internal.telephony.ITelephony telephonyService; 

// ------------------------------------------------------------------------ 
// primary life cycle call backs 
// ------------------------------------------------------------------------ 

/** 
* main() :) 
*/ 
@Override protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    debugLog("onCreate called"); 
    setContentView(R.layout.callanswerscreen); 

    // grab an instance of telephony manager 
    tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE); 

    // connect to the underlying Android telephony system 
    if (USE_ITELEPHONY) 
     connectToTelephonyService(); 

    // turn our idle phone state receiver on 
    registerReciever(); 



    // touch screen return button 
    Button returnToCallScreen = (Button) findViewById(R.id.returnToCallScreen); 
    returnToCallScreen.setOnClickListener(new ReturnButtonOnClickListener()); 

    // touch screen reject/ignore call button 
    Button rejectCall = (Button) findViewById(R.id.rejectCallButton); 
    //   if (getSharedPreferences(Hc.PREFSNAME,0).getBoolean(Hc.PREF_ALLOW_REJECT_KEY, true)) 
    rejectCall.setOnLongClickListener(new RejectCallOnLongClickListener()); 
    //   else 
    //     rejectCall.setVisibility(View.GONE);      

    // touch screen answer button 
    Button answerButton = (Button) findViewById(R.id.answerCallButton); 
    //   if (getSharedPreferences(Hc.PREFSNAME,0).getBoolean(Hc.PREF_ANSWER_WITH_BUTTON_KEY, true)) 
    answerButton.setOnLongClickListener(new AnswerCallOnLongClickListener()); 
    //   else 
    //     answerButton.setVisibility(View.GONE);     
} 

/** 
* (re)register phone state receiver on resume, exit if the phone is idle 
*/ 
@Override protected void onResume() { 
    super.onResume(); 

    registerReciever(); 

    if (tm.getCallState() == TelephonyManager.CALL_STATE_IDLE) { 
     debugLog("phone is idle, stopping."); 
     exitCleanly(); 
    } 
} 

/** 
* unregister phone state receiver, schedule restart if not exiting at the users request 
*/ 
@Override protected void onPause() { 
    super.onPause(); 

    unHookReceiver(); 

    if (!isFinishing()) 
    { 
     debugLog("system forced pause occured, scheduling delayed restart"); 
     Intent i = new Intent(getApplicationContext(), CallAnswerIntentService.class); 
     i.putExtra("delay", Hc.RESTART_DELAY); 
     startService(i); 
    } 
} 

// ------------------------------------------------------------------------ 
// Input event handler call backs 
// ------------------------------------------------------------------------ 

/** 
* Track ball press event handler that will answer a call 
*/ 
@Override public boolean onTrackballEvent(MotionEvent event) { 

    switch(event.getAction()) 
    { 
    case MotionEvent.ACTION_MOVE: return true; 
    case MotionEvent.ACTION_DOWN: answerCall(); return true; 
    default: debugLog("trackball event: "+event); 
    } 
    return super.dispatchTrackballEvent(event); 
} 

/** 
* Camera button press event handler that will answer a call 
*/ 
@Override public boolean dispatchKeyEvent(KeyEvent event) { 

    switch (event.getKeyCode()) 
    { 
    case KeyEvent.KEYCODE_FOCUS: return true; 
    case KeyEvent.KEYCODE_CAMERA: answerCall(); return true; 
    default: debugLog("Unknown key event: "+event); 
    } 
    return super.dispatchKeyEvent(event); 
} 

/** 
* Return button click listener will exit back to the 
* phones stock answer call application. 
*/ 
private class ReturnButtonOnClickListener implements OnClickListener { 
    public void onClick(View v) { 
     debugLog("returnToCallScreen onClick event"); 
     exitCleanly(); 
    } 
} 

/** 
* Reject button long click listener will reject the 
* incoming call. 
*/ 
private class RejectCallOnLongClickListener implements OnLongClickListener { 
    public boolean onLongClick(View v){ 
     debugLog("touch screen ignore call button onClick event"); 
     ignoreCall(); 
     exitCleanly(); 
     return true; 
    }    
} 

/** 
* Answer button long click listener will answer the 
* incoming call. 
*/ 
private class AnswerCallOnLongClickListener implements OnLongClickListener { 
    public boolean onLongClick(View v){ 
     debugLog("touch screen answer button onClick event"); 
     answerCall(); 
     return true; 
    }    
} 

// ------------------------------------------------------------------------ 
// broadcast receivers 
// ------------------------------------------------------------------------ 

/** 
* register phone state receiver 
*/ 
private void registerReciever() { 
    if (r != null) return; 

    r = new BroadcastReceiver() { 
     @Override 
     public void onReceive(Context c, Intent i)  { 
      String phone_state = i.getStringExtra(TelephonyManager.EXTRA_STATE); 
      if (!phone_state.equals(TelephonyManager.EXTRA_STATE_RINGING)) 
      { 
       debugLog("received "+phone_state+", time to go bye bye, thanks for playing!"); 
         exitCleanly(); 
      } 
     } 
    }; 

    registerReceiver(r, new IntentFilter("android.intent.action.PHONE_STATE")); 
} 

/** 
* unregister phone state receiver 
*/ 
private void unHookReceiver() { 
    if (r != null) 
    { 
     unregisterReceiver(r); 
     r = null; 
    } 
} 

// ------------------------------------------------------------------------ 
// application methods 
// ------------------------------------------------------------------------ 

/** 
* get an instance of ITelephony to talk handle calls with 
*/ 
@SuppressWarnings("unchecked") private void connectToTelephonyService() { 
    try 
    { 
     // "cheat" with Java reflection to gain access to TelephonyManager's ITelephony getter 
     Class c = Class.forName(tm.getClass().getName()); 
     Method m = c.getDeclaredMethod("getITelephony"); 
     m.setAccessible(true); 
      telephonyService = (com.android.internal.telephony.ITelephony) m.invoke(tm); 
    } catch (Exception e) { 
     e.printStackTrace(); 
     debugLog("FATAL ERROR: could not connect to telephony subsystem"); 
     debugLog("Exception object: "+e); 
     finish(); 
    }    
} 

// 
// answer call 
// 

/** 
* answer incoming calls 
*/ 
private void answerCall() { 
    if (USE_ITELEPHONY) 
     try { 
      answerCallAidl(); 
     } catch (RemoteException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    else 
     answerCallHeadsetHook(); 

    exitCleanly(); 
} 

/** 
* ACTION_MEDIA_BUTTON broadcast technique for answering the phone 
*/ 
private void answerCallHeadsetHook() { 
    KeyEvent headsetHook = new KeyEvent(KeyEvent.ACTION_DOWN,KeyEvent.KEYCODE_HEADSETHOOK); 
    Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON); 
    mediaButtonIntent.putExtra(Intent.EXTRA_KEY_EVENT, headsetHook); 
    sendOrderedBroadcast(mediaButtonIntent, null); 
} 

/** 
* AIDL/ITelephony technique for answering the phone 
*/ 
private void answerCallAidl() throws RemoteException { 
    telephonyService.silenceRinger(); 
    telephonyService.answerRingingCall();    
} 

// 
// ignore call 
// 

/** 
* ignore incoming calls 
*/ 
private void ignoreCall() { 
    if (USE_ITELEPHONY) 
     try { 
      ignoreCallAidl(); 
     } catch (RemoteException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    else 
     ignoreCallPackageRestart(); 
} 

/** 
* package restart technique for ignoring calls 
*/ 
private void ignoreCallPackageRestart() { 
    ActivityManager am = (ActivityManager)getSystemService(ACTIVITY_SERVICE); 
    am.restartPackage("com.android.providers.telephony"); 
    am.restartPackage("com.android.phone"); 
} 

/** 
* AIDL/ITelephony technique for ignoring calls 
*/ 
private void ignoreCallAidl() throws RemoteException { 
    telephonyService.silenceRinger(); 
    telephonyService.endCall(); 
}  

/** 
* cleanup and exit routine 
*/ 
private void exitCleanly() { 
    unHookReceiver(); 
    moveTaskToBack(true);   
    finish(); 
} 

I

: 그것은 2.3
감사

이 예외 사항에 작동하도록 도움을 필요로 0

java.lang.SecurityException: Neither user 10156 nor current process has android.permission.MODIFY_PHONE_STATE. 
at android.os.Parcel.readException(Parcel.java:1322) 
at android.os.Parcel.readException(Parcel.java:1276) 
at com.android.internal.telephony.ITelephony$Stub$Proxy.silenceRinger(ITelephony.java:1231) 
at com.y_y_full.photo_dailer.CallAnswerActivity.answerCallAidl(CallAnswerActivity.java:281) 
at com.y_y_full.photo_dailer.CallAnswerActivity.answerCall(CallAnswerActivity.java:256) 
at com.y_y_full.photo_dailer.CallAnswerActivity.access$3(CallAnswerActivity.java:253) 
at com.y_y_full.photo_dailer.CallAnswerActivity$AnswerCallOnLongClickListener.onLongClick(CallAnswerActivity.java:181) 
at android.view.View.performLongClick(View.java:2556) 
at android.widget.TextView.performLongClick(TextView.java:8358) 
at android.view.View$CheckForLongPress.run(View.java:9128) 
at android.os.Handler.handleCallback(Handler.java:587) 
at android.os.Handler.dispatchMessage(Handler.java:92) 
at android.os.Looper.loop(Looper.java:130) 
at android.app.ActivityThread.main(ActivityThread.java:3691) 
at java.lang.reflect.Method.invokeNative(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:507) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:907) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:665) 
at dalvik.system.NativeStart.main(Native Method) 
+0

정확히 * 작동하지 않는 것은 무엇입니까? : 예외가 발생하거나 무엇이 발생합니까? –

+0

한 가지 명확하고 확인하기 위해 - 매니페스트에 MODIFY_PHONE_STATE 권한이 지정되어 있습니까? – t0mm13b

+0

예, MODIFY_PHONE_STATE 권한이 있습니다. – user1458530

답변

3

는 진저 인 2.3.x에서 작동하지 않는 이유는 this 15031 issue이며, 15872 issue 구글은 많은 개발자의 성가심, 텔레포니에 대한 권한을 둘러싸고있는 프레임 워크를 변경. 그것이 보장되지는 않지만, 일부 휴대 전화 제조업체는 허가를 둡니다 (소니는 마음에 떠오 릅니다!), 다른 사람들은 Google의 AOSP에서 코드를 추출하고 변경된 프레임 워크 권한을 사용하여 제조 프로세스에 따라 변형을 구축했습니다. 그 자리에.

간단히 말하면 핸드셋을 뿌리 내리고 전화 소켓 레이어에 MITM을 작성한 다음 Android 스택이 이벤트를보기 전에 인터 셉션을 수행하는 것입니다.하지만 얼굴이 너무 복잡하고 할 가치가 없습니다.

이제 ICS가 해제되었으며 사용 권한이 변경되지 않았으므로이를 염두에 두어야합니다. 한편 GB 소스 구글이 "이 문제를 해결하십시오"전진과 거의가에도 불구하고 할 수있는 먼지를 수집하기 위해 남아있는 15,031 문제 페이지에 ...

0

MODIFY_PHONE_STATE 권한은 시스템 사용을 위해 예약, 그리고 ITelephony.silenceRinger() 필요 MODIFY_PHONE_STATE 권한입니다 . 전화를 걸 때 휴대 전화를 조용히해야하는 경우 AudioManager를 사용하십시오. 그러나 EndCall() 잘 작동합니다.

관련 문제