안 드 로 이 드 는 전화 차단 및 차단 알림 기능 개발 을 실현 한다.
1.전화 차단
이 기능 은 반사 원 리 를 이용 해 아 이 템 포 니 의 숨겨 진 방법 으로 이 루어 진 다 는 것 을 잘 알 고 있 을 것 이다.
2.차단 후 알림 바 쁜 소리/빈 번호/꺼 져 있 음/꺼 져 있 음
이 기능 은 사실 MMI 명령 을 사용 해 야 합 니 다.호출 이전 지정 을 어떻게 설정 하 는 지 참고 할 수 있 습 니 다.http://baike.baidu.com/view/206402.html?fromTaglist。
본 논문 에서 우 리 는'바 쁜 일이 있 으 면 이동'하 는 기능 을 사용 할 것 이다.중국 이동 의 설정 방식 은**67\#전화번호\#이 고 취소 방식 은\##67\#입 니 다."무조건 이동"67 대신 21 로 대체 하면 된다.이 두 명령 은 휴대 전화의 다이얼 인터페이스 에 직접 입력 하고 다이얼 테스트 를 할 수 있다.아 이 템 포 니 의 엔 드 콜 방법 은 전 화 를 끊 으 면 전화 가 바쁘다 는 것 을 알려 준다.바 쁠 때 빈 번호/꺼 져 있 는 전화/꺼 져 있 는 전화 번 호 를 미리 설정 하면 전화 번 호 는 빈 번호/꺼 져 있 음/꺼 져 있 음 을 알려 줍 니 다.
사실 xxx 위 사 를 다운로드 하여 볼 수 있 습 니 다.이 는 전화 거부 모드 를 설정 한 후에 모두 MMI 명령 을 설정 하 는 화면 을 시작 합 니 다.그리고'설정->통화 설정->전화 연결'에 가서'통화 중 연결'에 설 치 된 전화 번 호 를 보면 빈 번호/꺼 져 있 음/정지 되 어 있 는 전화번호 가 무엇 인지 알 수 있 습 니 다.
1.BLOCKED 수정NUMBER 라 는 변 수 는 차단 을 테스트 할 전화번호 로 설정 합 니 다.
2.모든 기능 은 하나의 Activity 에서 이 루어 지기 때문에 여러분 들 은 먼저 이 Activity 를 실행 한 다음 에'호출 이동 설정'을 클릭 하고 호출 이동 설정 을 한 후에 이 Activity 를 끄 지 마 세 요.끄 면 전 화 를 차단 할 수 없습니다.마음 이 있 는 친 구 는 스스로 Service 를 써 서 배경 에서 차단 기능 을 실행 할 수 있다.
구현 방식 1:
코드 는 다음 과 같 습 니 다:
package net.toeach.android.callforwarding;
import java.lang.reflect.Method;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.RemoteException;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import com.android.internal.telephony.ITelephony;
/**
* , ( )
* @author Tony from ToEach.
* @email [email protected]
*/
public class MainActivity extends Activity {
private static final String TAG = MainActivity.class.getSimpleName();
private final static int OP_REGISTER = 100;
private final static int OP_CANCEL = 200;
private final static String BLOCKED_NUMBER = "1892501xxxx";//
// , 13800000000 ,
private final String ENABLE_SERVICE = "tel:**67*13800000000%23";
//
private final String DISABLE_SERVICE = "tel:%23%2367%23";
private IncomingCallReceiver mReceiver;
private ITelephony iTelephony;
private AudioManager mAudioManager;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
findViewById(R.id.btnEnable).setOnClickListener(new OnClickListener(){
public void onClick(View v) {
//
Message message = mHandler.obtainMessage();
message.what = OP_REGISTER;
mHandler.dispatchMessage(message);
}
});
findViewById(R.id.btnDisable).setOnClickListener(new OnClickListener(){
public void onClick(View v) {
//
Message message = mHandler.obtainMessage();
message.what = OP_CANCEL;
mHandler.dispatchMessage(message);
}
});
mReceiver = new IncomingCallReceiver();
IntentFilter filter = new IntentFilter("android.intent.action.PHONE_STATE");
registerReceiver(mReceiver, filter);// BroadcastReceiver
mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
// endcall
TelephonyManager telephonyMgr = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
try {
Method getITelephonyMethod = TelephonyManager.class.getDeclaredMethod("getITelephony", (Class[]) null);
getITelephonyMethod.setAccessible(true);
iTelephony = (ITelephony) getITelephonyMethod.invoke(telephonyMgr, (Object[]) null);
} catch (Exception e) {
e.printStackTrace();
}
}
private Handler mHandler = new Handler() {
public void handleMessage(Message response) {
int what = response.what;
switch(what) {
case OP_REGISTER:{
Intent i = new Intent(Intent.ACTION_CALL);
i.setData(Uri.parse(ENABLE_SERVICE));
startActivity(i);
break;
}
case OP_CANCEL:{
Intent i = new Intent(Intent.ACTION_CALL);
i.setData(Uri.parse(DISABLE_SERVICE));
startActivity(i);
break;
}
}
}
};
private class IncomingCallReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
Log.i(TAG, "State: "+ state);
String number = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
Log.d(TAG, "Incomng Number: " + number);
if(state.equalsIgnoreCase(TelephonyManager.EXTRA_STATE_RINGING)){//
if(number.equals(BLOCKED_NUMBER)){//
//
mAudioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
Log.d(TAG, "Turn ringtone silent");
try {
//
iTelephony.endCall();
} catch (RemoteException e) {
e.printStackTrace();
}
//
mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
}
}
}
}
}
AndroidManifest.xml 는 다음 과 같 습 니 다.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android "
package="net.toeach.android.callforwarding"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".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>
<uses-sdk android:minSdkVersion="8" />
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.CALL_PHONE"/>
</manifest>
구현 방식 2:1.패키지 android.refuseCalling 을 만 듭 니 다.
refuseCalling.java 코드 는 다음 과 같 습 니 다.
package android.refuseCalling;
import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import android.content.Context;
import android.content.Intent;
import android.os.RemoteException;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.widget.TextView;
import com.android.internal.telephony.ITelephony;
public class refuseCalling extends Activity {
private static final String TAG = "Telephony";
private TextView view = null;
private TelephonyManager tManager = null;
private ITelephony iTelephony = null;
// ,
private final String ENABLE_SERVICE = "tel:**67*13800000000%23";
// ,
private final String ENABLE_POWEROFF_SERVICE = "tel:**67*13810538911%23";
// ,
private final String ENABLE_STOP_SERVICE = "tel:**21*13701110216%23";
//
private final String DISABLE_SERVICE = "tel:%23%2321%23";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//
TelephonyManager mTelephonyMgr = (TelephonyManager) this
.getSystemService(Context.TELEPHONY_SERVICE);
mTelephonyMgr.listen(new TeleListener(),
PhoneStateListener.LISTEN_CALL_STATE);
//gui
view = new TextView(this);
view.setText("listen the state of phone
");
setContentView(view);
tManager = (TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE);
// iTelephony
Class <TelephonyManager> c = TelephonyManager.class;
Method getITelephonyMethod = null;
try {
getITelephonyMethod = c.getDeclaredMethod("getITelephony", (Class[])null);
getITelephonyMethod.setAccessible(true);
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
iTelephony = (ITelephony) getITelephonyMethod.invoke(tManager, (Object[])null);
} 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();
}
//
Intent i = new Intent(Intent.ACTION_CALL);
i.setData(Uri.parse(ENABLE_STOP_SERVICE));
startActivity(i);
Log.v(TAG, " ");
}
class TeleListener extends PhoneStateListener {
@Override
public void onCallStateChanged(int state, String incomingNumber) {
super.onCallStateChanged(state, incomingNumber);
switch (state) {
case TelephonyManager.CALL_STATE_IDLE: {
Log.e(TAG, "CALL_STATE_IDLE");
view.append("CALL_STATE_IDLE " + "
");
break;
}
case TelephonyManager.CALL_STATE_OFFHOOK: {
Log.e(TAG, "CALL_STATE_OFFHOOK");
view.append("CALL_STATE_OFFHOOK" + "
");
break;
}
case TelephonyManager.CALL_STATE_RINGING: {
Log.e(TAG, "CALL_STATE_RINGING");
view.append("CALL_STATE_RINGING" + "
");
try {
iTelephony.endCall();
} catch (RemoteException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
break;
}
default:
break;
}
}
}
protected void onStop() {
super.onStop();
}
protected void onDestroy() {
super.onDestroy();
finish();
Intent i = new Intent(Intent.ACTION_CALL);
i.setData(Uri.parse(DISABLE_SERVICE));
startActivity(i);
}
}
2.가방 android.telephony 를 만 듭 니 다.NeighboringCellInfo.aidl 코드 는 다음 과 같 습 니 다.
package android.telephony;
3.가방 com.android.internal.telephony 를 만 듭 니 다.
ITelephony.aidl 코드 는 다음 과 같 습 니 다.
/*
*
* Licensed under the android License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.internal.telephony;
import android.os.Bundle;
import java.util.List;
import android.telephony.NeighboringCellInfo;
//import com.FrameSpeed.NeighboringCellInfo;
/**
* Interface used to interact with the phone. Mostly this is used by the
* TelephonyManager class. A few places are still using this directly.
* Please clean them up if possible and use TelephonyManager insteadl.
*
* {@hide}
*/
interface ITelephony {
/**
* Dial a number. This doesn't place the call. It displays
* the Dialer screen.
* @param number the number to be dialed. If null, this
* would display the Dialer screen with no number pre-filled.
*/
void dial(String number);
/**
* Place a call to the specified number.
* @param number the number to be called.
*/
void call(String number);
/**
* If there is currently a call in progress, show the call screen.
* The DTMF dialpad may or may not be visible initially, depending on
* whether it was up when the user last exited the InCallScreen.
*
* @return true if the call screen was shown.
*/
boolean showCallScreen();
/**
* Variation of showCallScreen() that also specifies whether the
* DTMF dialpad should be initially visible when the InCallScreen
* comes up.
*
* @param showDialpad if true, make the dialpad visible initially,
* otherwise hide the dialpad initially.
* @return true if the call screen was shown.
*
* @see showCallScreen
*/
boolean showCallScreenWithDialpad(boolean showDialpad);
/**
* End call if there is a call in progress, otherwise does nothing.
*
* @return whether it hung up
*/
boolean endCall();
/**
* Answer the currently-ringing call.
*
* If there's already a current active call, that call will be
* automatically put on hold. If both lines are currently in use, the
* current active call will be ended.
*
* TODO: provide a flag to let the caller specify what policy to use
* if both lines are in use. (The current behavior is hardwired to
* "answer incoming, end ongoing", which is how the CALL button
* is specced to behave.)
*
* TODO: this should be a oneway call (especially since it's called
* directly from the key queue thread).
*/
void answerRingingCall();
/**
* Silence the ringer if an incoming call is currently ringing.
* (If vibrating, stop the vibrator also.)
*
* It's safe to call this if the ringer has already been silenced, or
* even if there's no incoming call. (If so, this method will do nothing.)
*
* TODO: this should be a oneway call too (see above).
* (Actually *all* the methods here that return void can
* probably be oneway.)
*/
void silenceRinger();
/**
* Check if we are in either an active or holding call
* @return true if the phone state is OFFHOOK.
*/
boolean isOffhook();
/**
* Check if an incoming phone call is ringing or call waiting.
* @return true if the phone state is RINGING.
*/
boolean isRinging();
/**
* Check if the phone is idle.
* @return true if the phone state is IDLE.
*/
boolean isIdle();
/**
* Check to see if the radio is on or not.
* @return returns true if the radio is on.
*/
boolean isRadioOn();
/**
* Check if the SIM pin lock is enabled.
* @return true if the SIM pin lock is enabled.
*/
boolean isSimPinEnabled();
/**
* Cancels the missed calls notification.
*/
void cancelMissedCallsNotification();
/**
* Supply a pin to unlock the SIM. Blocks until a result is determined.
* @param pin The pin to check.
* @return whether the operation was a success.
*/
boolean supplyPin(String pin);
/**
* [ASD2-ES1|Connice|2011.04.14]
*/
boolean supplyPuk(String puk, String pin);
/**
* Handles PIN MMI commands (PIN/PIN2/PUK/PUK2), which are initiated
* without SEND (so <code>dial</code> is not appropriate).
*
* @param dialString the MMI command to be executed.
* @return true if MMI command is executed.
*/
boolean handlePinMmi(String dialString);
/**
* Toggles the radio on or off.
*/
void toggleRadioOnOff();
/**
* Set the radio to on or off
*/
boolean setRadio(boolean turnOn);
/**
* Request to update location information in service state
*/
void updateServiceLocation();
/**
* Enable location update notifications.
*/
void enableLocationUpdates();
/**
* Disable location update notifications.
*/
void disableLocationUpdates();
/**
* Enable a specific APN type.
*/
int enableApnType(String type);
/**
* Disable a specific APN type.
*/
int disableApnType(String type);
/**
* Allow mobile data connections.
*/
boolean enableDataConnectivity();
/**
* Disallow mobile data connections.
*/
boolean disableDataConnectivity();
/**
* Report whether data connectivity is possible.
*/
boolean isDataConnectivityPossible();
Bundle getCellLocation();
/**
* Returns the neighboring cell information of the device.
*/
List<NeighboringCellInfo> getNeighboringCellInfo();
int getCallState();
int getDataActivity();
int getDataState();
/**
* Returns the current active phone type as integer.
* Returns TelephonyManager.PHONE_TYPE_CDMA if RILConstants.CDMA_PHONE
* and TelephonyManager.PHONE_TYPE_GSM if RILConstants.GSM_PHONE
*/
int getActivePhoneType();
/**
* Returns the CDMA ERI icon index to display
*/
int getCdmaEriIconIndex();
/**
* Returns the CDMA ERI icon mode,
* 0 - ON
* 1 - FLASHING
*/
int getCdmaEriIconMode();
/**
* Returns the CDMA ERI text,
*/
String getCdmaEriText();
/**
* Returns true if OTA service provisioning needs to run.
* Only relevant on some technologies, others will always
* return false.
*/
boolean needsOtaServiceProvisioning();
/**
* Returns the unread count of voicemails
*/
int getVoiceMessageCount();
/**
* Returns the network type
*/
int getNetworkType();
/**
* Return true if an ICC card is present
*/
boolean hasIccCard();
}
parcelable NeighboringCellInfo;
4.AndroidManifest.xml 코드 는 다음 과 같 습 니 다.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.refuseCalling"
android:versionCode="1"
android:versionName="1.0">
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".refuseCalling"
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>
이 글 을 통 해 안 드 로 이 드 가 전화 애플 리 케 이 션 을 개발 하 는 친구 에 게 도움 을 줄 수 있 기 를 바 랍 니 다.본 사이트 에 대한 지원 에 감 사 드 립 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Bitrise에서 배포 어플리케이션 설정 테스트하기이 글은 Bitrise 광고 달력의 23일째 글입니다. 자체 또는 당사 등에서 Bitrise 구축 서비스를 사용합니다. 그나저나 며칠 전 Bitrise User Group Meetup #3에서 아래 슬라이드를 발표했...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.