2015-01-01 2 views
-2

다음 코드를 실행하려고합니다. T 그는 코드의 목적은 호출을 감지하고 즉시 종료하는 것입니다. 다음과 같이 구성됩니다.실행 파일에 리스너 등록

1) 사용하는 새 스레드와의 통신을위한 핸들러가 포함 된 주 서비스 클래스와 실행할 코드가있는 실행 가능 파일. 또한 다른 기능을 기본적으로 구현합니다.

2) 다른 클래스는 수신기에 필요한 PhoneStateListener를 확장합니다.

개인 구성 요소를 사용해 보았습니다.하지만 활동의 일부로 사용했습니다. 그들은 모두 잘 작동하지만 지금은 백그라운드에서 별도의 스레드를 실행하는 서비스의 사용을 통해 모든 노력을 다하고 있습니다. 서비스가 시작되면 응용 프로그램이 중단됩니다.

public class Call_Message_Service extends Service { 

Thread serviceThread; 
CallStateListener callStateListener; 
//Handler to allow communication with main thread to display some toasts. 
public Handler serviceHandler = new Handler() { 
    @Override 
    public void handleMessage(Message msg) { 
     Bundle bundle = msg.getData(); 
     String string = bundle.getString("KEY"); 
     Toast.makeText(Call_Message_Service.this, string, Toast.LENGTH_SHORT).show(); 
    } 
}; 
//Main runnable 
Runnable serviceRunnable = new Runnable() { 
    @Override 
    public void run() { 
     TelephonyManager telephonyManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE); 
     Log.d(Constants.LOGTAG, "HERE_1"); 
     callStateListener = new CallStateListener(serviceHandler); 
     //Register PhoneStateListener 
     telephonyManager.listen(callStateListener, PhoneStateListener.LISTEN_CALL_STATE); 
    } 
}; 

@Override 
public void onCreate() { 
    Toast.makeText(this,"Service Created", Toast.LENGTH_SHORT).show(); 
} 

@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 
    serviceThread = new Thread (serviceRunnable); 
    serviceThread.start(); 
    return START_STICKY; 
} 

@Override 
public void onDestroy() { 
    Toast.makeText(this,"Service Destroyed", Toast.LENGTH_SHORT).show(); 
} 

@Override 
public IBinder onBind(Intent intent) { 
    return null; 
} 
} 
class CallStateListener extends PhoneStateListener{ 

String number; 
Handler extraHandler; 

public CallStateListener(Handler handler) { 
    Log.d(Constants.LOGTAG, "HERE_2"); 
    extraHandler = handler; 
} 

@Override 
public void onCallStateChanged(int state, String incomingNumber) { 
    //Store is number of the incoming call 
    number = incomingNumber; 

    //If phone is ringing 
    if (state == TelephonyManager.CALL_STATE_RINGING) { 
     Message msg = extraHandler.obtainMessage(); 
     Bundle bundle = new Bundle(); 
     String string = "Phone is Ringing"; 
     bundle.putString("KEY",string); 
     disconnectCallAndroid(); 
    } 
    //If incoming call received 
    if (state == TelephonyManager.CALL_STATE_OFFHOOK) { 
     Message msg = extraHandler.obtainMessage(); 
     Bundle bundle = new Bundle(); 
     String string = "Phone is Currently in a call"; 
     bundle.putString("KEY",string); 
    } 
    //If not ringing or idle 
    if (state == TelephonyManager.CALL_STATE_IDLE) { 
     Message msg = extraHandler.obtainMessage(); 
     Bundle bundle = new Bundle(); 
     String string = "Phone is neither Ringing nor in a call"; 
     bundle.putString("KEY",string); 
    } 
} 

//Function to disconnect call 
public int disconnectCallAndroid() 
{ 
    Runtime runtime = Runtime.getRuntime(); 
    int nResp = 0; 
    try 
    { 
     Log.d(Constants.LOGTAG, "service call phone 5 \n"); 
     runtime.exec("service call phone 5 \n"); 
    }catch(Exception exc) 
    { 
     Log.e(Constants.LOGTAG, exc.getMessage()); 
     exc.printStackTrace(); 
    } 
    return nResp; 
} 
} 

최소한 코드가 수행해야하는 작업입니다. 문제는 runnable에서 리스너를 등록하려고 시도하는 것이지만 훨씬 많은 문제가 있다는 것을 확신합니다. 누군가 코드를 잘못 이해할 수 있으면 좋을 것입니다.

주요 활동은 매우 간단합니다. 버튼을 누르면 서비스가 시작됩니다. 서비스가 시작되고 실행이 첫 번째 로그까지 가면 "java.lang.RuntimeException : Looper.prepare()"를 호출하지 않은 스레드에서 처리기를 만들 수 없습니다.

답변

1

여기에서 오류가 발생하여 중단됩니다.

CallStateListener으로 전달하는 Runnable은 별도의 Thread에서 실행됩니다.

Handler을 신품 Thread에 사용하는 경우 ThreadLooper에 부착해야합니다. Looper은 해당 ThreadMessageQueue을 관리합니다. Handler이 첨부 된 Looper이 없으면 Messages (또는 Runnables)을 처리 할 수 ​​없습니다.

메인 ThreadLooper에 부착해야하는 이유는 무엇입니까?

Application이 시작될 때 Android는 ThreadLooper에 연결합니다. 이 상호 작용은 ActivityThread에 의해 관리됩니다. ActivityThread의 출처를 보면 Looper.prepareMainLooper();으로 전화하는 것을 볼 수 있습니다.

+0

설명해 주셔서 감사합니다. 나는이 모든 것을 이해하지 못하지만 루퍼와 핸들러를 더 잘 이해하기 위해 튜토리얼을 살펴 보겠습니다. 그래서 나는 그것을 변화 시키려면 어떻게해야합니까? –

관련 문제