안드로이드는 휴대전화 연결 후 진동 알림 기능을 실현한다
Android SDK에서 제공하는 통화 상태
전화가 연결될 때 진동 알림이 생기려면 먼저 전화가 언제 연결되는지 알아야 한다.안드로이드 SDK는 이런 상태를 직접 읽는 방법을 제시하지 않았다.다음은 Android SDK의 전화 서비스 클래스인 Telephony Manager에서 제공하는 3가지 전화 상태입니다.
CALL_STATE_IDLE 유휴 상태
CALL_STATE_OFFHOOK 오프셋 상태
CALL_STATE_링링 상태
이 몇 가지 상태는 쉽게 이해할 수 있다. 오프라인 상태는 바로 마이크를 잡는 것이다. 그러나 이 상태는 전화가 연결될 때 발생할 수도 있고, 전화가 연결될 때 발생할 수도 있지만, 전화가 연결될 때 발생할 수도 있다.상기 세 가지 상태를 통해 우리는 자동사냥과 전보 연결 두 가지 상태만 조합할 수 있다.오늘날 우리가 실현하고자 하는 기능은 실현할 수 없다.
다른 방법을 찾아야 할 것 같은데, SDK는 믿을 수가 없네...
Android 실행 log 분석
다행히 안드로이드가 운행할 때 대량의 로그가 생길 수 있으니 이 위에서 돌파구를 찾을 수 있는지 확인해 볼까요?Android 라디오 모듈의 로그를 선택하여 분석합니다.우선 우리는 라디오와 관련된 로그를 읽기 위해 코드를 써야 한다. 로그를 읽으면 로그캣을 사용할 수밖에 없다.
Process process;
InputStream inputstream;
BufferedReader bufferedreader;
try {
process = Runtime.getRuntime().exec("logcat -v time -b radio");
inputstream = process.getInputStream();
InputStreamReader inputstreamreader = new InputStreamReader(
inputstream);
bufferedreader = new BufferedReader(inputstreamreader);
String str = "";
while ((str = bufferedreader.readLine()) != null) {
log.i("mLogcat",str);
}
} catch (Exception e) {
}
또한 프로그램이 시스템 로그를 읽을 수 있도록 권한을 지정해야 합니다. 안드로이드 매니페스트에서.xml 파일에 내용을 넣으세요.
XML/HTML 코드
위의 코드를 통해 우리는 라디오의 로그를 출력할 수 있다. 그러면 우리는 DDMS에서 이 로그를 보고 그 중의 통화 과정을 분석할 수 있다.구체적으로 잡은 로그는 붙이지 않고 여러분이 직접 프로그램을 작성하여 위의 코드를 통해 캡처하고 분석할 수 있습니다.제 분석 결과만 말씀드리겠습니다.
분석log를 통해 약간의 거미줄과 말 흔적을 발견하였다.다음과 같은 유용한 로그가 있습니다.
GET_CURRENT_CALLS id=1,DIALING
GET_CURRENT_CALLS id=1,ALERTING
GET_CURRENT_CALLS id=1,ACTIVE
로그가 비교적 길기 때문에 나는 모든 로그의 시작 부분만 가져왔기 때문에 진실한 것은 많은 내용이 있을 것이다.우리가 전화를 걸 때, 이렇게 몇 개의 로그를 입력할 것이다.
전화 접속 -> 알림-> 이벤트
대체로 이런 과정이다.몇 차례의 테스트를 통해 전화가 연결되면 활성 상태가 되고 출력: GETCURRENT_CALLS id=1, ACTIVE 이 log, 이로써 우리는 성공에 가까워졌다.
그러나 이후에 나는 전화를 걸기 시작하면서 전화가 연결되는 동안 여러 차례의'전화를 걸기->알람->활동'과 같은 상태 변화를 거치는 것을 발견했다. 마이크에서 삐걱거리는 소리만 나면 GETCURRENT_CALLS 로그는 ALERTING에 잠깁니다.전화가 연결되기 전에 GET 가 나타나지 않습니다CURRENT_CALLS 로그입니다.
위에서 설명한 바와 같이 여러분은 잘 모르실 수도 있습니다. 다시 말하면 통화가 연결되기 전에 여러 차례의 GET 가 나타날 것입니다.CURRENT_CALLS ACTIVE와 같은 로그는 한 번만 전화 연결이 이루어집니다.이것은 우리에게 폐를 끼쳤다.그냥 GET만 잡으면 안 되는데...CURRENT_CALLS ACTIVE라는 메시지로 판단했습니다.
우리는 단지 논리적인 판단을 통해 실현할 수 있을 뿐이다.
실례 코드 설명
다음은 내 코드를 살펴보겠습니다.
class TestThread implements Runnable {
//
Vibrator mVibrator;
//
TelephonyManager telManager;
public TestThread(Vibrator mVibrator, TelephonyManager telManager) {
this.mVibrator = mVibrator;
this.telManager = telManager;
}
@Override
public void run() {
//
int callState = telManager.getCallState();
Log.i("TestService", " .........." + Thread.currentThread().getName());
//
long threadStart = System.currentTimeMillis();
Process process;
InputStream inputstream;
BufferedReader bufferedreader;
try {
process = Runtime.getRuntime().exec("logcat -v time -b radio");
inputstream = process.getInputStream();
InputStreamReader inputstreamreader = new InputStreamReader(
inputstream);
bufferedreader = new BufferedReader(inputstreamreader);
String str = "";
long dialingStart = 0;
boolean enableVibrator = false;
boolean isAlert = false;
while ((str = bufferedreader.readLine()) != null) {
// ,
if (callState == TelephonyManager.CALL_STATE_OFFHOOK
&& telManager.getCallState() == TelephonyManager.CALL_STATE_IDLE) {
break;
}
// 5
if (System.currentTimeMillis() - threadStart > 300000) {
break;
}
Log.i("TestService", Thread.currentThread().getName() + ":"
+ str);
// GSM DIALING
if (str.contains("GET_CURRENT_CALLS")
&& str.contains("DIALING")) {
// DIALING ALERTING DIALING
if (!isAlert || dialingStart == 0) {
// DIALING
dialingStart = System.currentTimeMillis();
isAlert = false;
}
continue;
}
if (str.contains("GET_CURRENT_CALLS")
&& str.contains("ALERTING")&&!enableVibrator) {
long temp = System.currentTimeMillis() - dialingStart;
isAlert = true;
// , DIALING , ALERTING 1.5 20
// ACTIVE .
if (temp > 1500 && temp < 20000) {
enableVibrator = true;
Log.i("TestService", " ....." + temp + "....."
+ Thread.currentThread().getName());
}
continue;
}
if (str.contains("GET_CURRENT_CALLS") && str.contains("ACTIVE")
&& enableVibrator) {
mVibrator.vibrate(100);
enableVibrator = false;
break;
}
}
Log.i("TestService", " .........."
+ Thread.currentThread().getName());
} catch (Exception e) {
// TODO: handle exception
}
}
}
나의 이 방법은 비교적 억지스럽다. 첫 번째 DIALING과 매번의 ALERTING 사이의 간격을 판단함으로써 1.5초 이상 간격을 두면'뚜'소리의 힌트에 들어갔다고 생각하면 다음 ACTIVE는 전화가 연결될 것이다.이 1.5초는 일지 분석을 통해 나온 것이다.그러나 이런 방법은 시종 믿기지 않는다.여러분에게 좋은 방법이 있다면 교류할 수 있습니다.
나머지는 이 라인을 전화가 걸릴 때 터치하고 전화에 상주할 때 준비하면 된다.Receiver와 함께 Service를 사용할 수 있습니다.Service는 상주를 실현하고, Receiver는 전화를 감청하는 것을 실현한다.기본적으로 우리가 원하는 기능을 완성할 수 있다.
이상의 코드는 내가 모두 테스트해 봤는데 99퍼센트가 유효하다. 하하.여기에는 logcat, 서비스, Receiver 등 안드로이드의 기초 내용들이 언급되어 있는데 여러분이 잘 모르시면 관련 문장 자료를 찾아서 배울 수 있습니다.
이 글을 통해 안드로이드 개발을 도와주신 분들, 본 사이트에 대한 지지에 감사드립니다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.