Android手机通话界面-更改
如何更改电话用户界面?就像我有自己的拨号器布局和联系人布局,但我如何更改呼叫用户界面。那么,当通话开始时,我可以移除扬声器按钮吗 以下是我创建的拨号器场景: 但我不知道如何编辑此屏幕: 编辑:我已经构建了UI,我只是无法在通话中显示它强> 以下是更简单版本的代码:Android手机通话界面-更改,android,user-interface,phone-call,Android,User Interface,Phone Call,如何更改电话用户界面?就像我有自己的拨号器布局和联系人布局,但我如何更改呼叫用户界面。那么,当通话开始时,我可以移除扬声器按钮吗 以下是我创建的拨号器场景: 但我不知道如何编辑此屏幕: 编辑:我已经构建了UI,我只是无法在通话中显示它 以下是更简单版本的代码: public class MainActivity extends Activity { private Button callBtn; private Button dialBtn; private EditText number;
public class MainActivity extends Activity {
private Button callBtn;
private Button dialBtn;
private EditText number;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
number = (EditText) findViewById(R.id.phoneNumber);
callBtn = (Button) findViewById(R.id.call);
dialBtn = (Button) findViewById(R.id.dial);
// add PhoneStateListener for monitoring
MyPhoneListener phoneListener = new MyPhoneListener();
TelephonyManager telephonyManager =
(TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
// receive notifications of telephony state changes
telephonyManager.listen(phoneListener,PhoneStateListener.LISTEN_CALL_STATE);
callBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
try {
// set the data
String uri = "tel:"+number.getText().toString();
Intent callIntent = new Intent(Intent.ACTION_CALL, Uri.parse(uri));
startActivity(callIntent);
}catch(Exception e) {
Toast.makeText(getApplicationContext(),"Your call has failed...",
Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
});
dialBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
try {
String uri = "tel:"+number.getText().toString();
Intent dialIntent = new Intent(Intent.ACTION_DIAL, Uri.parse(uri));
startActivity(dialIntent);
}catch(Exception e) {
Toast.makeText(getApplicationContext(),"Your call has failed...",
Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
});
}
private class MyPhoneListener extends PhoneStateListener {
private boolean onCall = false;
@Override
public void onCallStateChanged(int state, String incomingNumber) {
switch (state) {
case TelephonyManager.CALL_STATE_RINGING:
// phone ringing...
Toast.makeText(MainActivity.this, incomingNumber + " calls you",
Toast.LENGTH_LONG).show();
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
// one call exists that is dialing, active, or on hold
Toast.makeText(MainActivity.this, "on call...",
Toast.LENGTH_LONG).show();
//because user answers the incoming call
onCall = true;
break;
case TelephonyManager.CALL_STATE_IDLE:
// in initialization of the class and at the end of phone call
// detect flag from CALL_STATE_OFFHOOK
if (onCall == true) {
Toast.makeText(MainActivity.this, "restart app after call",
Toast.LENGTH_LONG).show();
// restart our application
Intent restart = getBaseContext().getPackageManager().
getLaunchIntentForPackage(getBaseContext().getPackageName());
restart.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(restart);
onCall = false;
}
break;
default:
break;
}
}
}
}
谢谢 构建您自己的拨号器用户界面。退房
您将需要一个活动来处理意图,然后显示自定义UI是您的业务。在清单中添加调用权限
<uses-permission android:name="android.permission.CALL_PHONE" />
然后需要检查呼叫按钮是否按下。用于以下目的过滤器
<intent-filter>
<action android:name="android.intent.action.CALL_BUTTON" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
当启动UI时
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.DIAL" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="tel" />
</intent-filter>
这意味着您在清单中的调用活动如下
<activity
android:name="com.example.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<!-- open activity when establishing a call -->
<intent-filter>
<action android:name="android.intent.action.CALL_PRIVILEGED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="tel" />
</intent-filter>
</activity>
编辑:
实际上api 23已经发布了,请检查。请记住,某些设备可能不支持此功能
预览:
无法更改实际通话视图(通话过程中看到的内容)
更具体地说,android的某些部分无法被覆盖,
安卓有他的核心,作为开发者,我们对此的访问是有限的
核心。在您的情况下,您可以覆盖拨号器,但您不能
覆盖实际电话通话视图
在android团队决定分享之前,你不能做任何事情
这是我们(开发人员)的核心功能
由于API 23,这是可能的,请参见arekolek Kotlin版本: Java版本: 编辑 根据推荐,下面是最简单的java版本 下面显示了清单,需要
意图过滤器
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.aliton.customphonecall">
<uses-permission android:name="android.permission.CALL_PHONE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".DialerActivity" >
<intent-filter>
<!-- Handle links from other applications -->
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.DIAL" />
<!-- Populate the system chooser -->
<category android:name="android.intent.category.DEFAULT" />
<!-- Handle links in browsers -->
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="tel" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.DIAL" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<service
android:name=".CallService"
android:permission="android.permission.BIND_INCALL_SERVICE">
<meta-data
android:name="android.telecom.IN_CALL_SERVICE_UI"
android:value="true" />
<intent-filter>
<action android:name="android.telecom.InCallService" />
</intent-filter>
</service>
<activity android:name=".CallActivity"></activity>
</application>
</manifest>
下面是如何实现InCallService
来管理呼叫
public class CallService extends InCallService {
OngoingCallObject ongoingCallObject;
@Override
public void onCallAdded(Call call) {
super.onCallAdded(call);
new OngoingCallObject().setCall(call);
//Intent CallAct = new Intent(this, CallActivity.class);
//startActivity(CallAct);
CallActivity.start(this, call);
}
@Override
public void onCallRemoved(Call call) {
super.onCallRemoved(call);
new OngoingCallObject().setCall(null);
}
}
下面是对象的实现方式
public class OngoingCallObject {
private static Call call;
private Object callback = new Callback() {
@Override
public void onStateChanged(Call call, int state) {
super.onStateChanged(call, state);
Log.i("debinf OngoingObj", "state is "+state);
}
};
public void setCall(Call call) {
if (this.call != null) {
this.call.unregisterCallback((Call.Callback)callback);
}
if (call != null) {
call.registerCallback((Call.Callback)callback);
Log.i("debinf OngoingObj", "call.getState() is "+call.getState());
}
this.call = call;
}
public void answer() {
//assert this.call != null;
if (this.call != null) {
this.call.answer(VideoProfile.STATE_AUDIO_ONLY);
}
}
public void hangup() {
//assert this.call != null;
if (this.call != null) {
this.call.disconnect();
}
}
}
最后是启动UI的CallActivity
public class DialerActivity extends AppCompatActivity {
private static final int REQUEST_CALL_PHONE = 10;
EditText phoneNumber;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dialer);
phoneNumber = (EditText) findViewById(R.id.etNumber);
Button bCall = (Button) findViewById(R.id.btnCall);
offerReplacingDefaultDialer();
bCall.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
makeCall();
}
});
}
private void makeCall() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) == PackageManager.PERMISSION_GRANTED) {
Uri uri = Uri.parse("tel:"+phoneNumber.getText().toString().trim());
Intent Call = new Intent(Intent.ACTION_CALL, uri);
//Toast.makeText(this, "Entered makeCall()", Toast.LENGTH_SHORT).show();
Log.i("debinf Dialer", "Entered makeCall()");
startActivity(Call);
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CALL_PHONE}, REQUEST_CALL_PHONE);
}
}
private void offerReplacingDefaultDialer() {
if (getSystemService(TelecomManager.class).getDefaultDialerPackage() != getPackageName()) {
Intent ChangeDialer = new Intent(TelecomManager.ACTION_CHANGE_DEFAULT_DIALER);
ChangeDialer.putExtra(TelecomManager.EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME, getPackageName());
startActivity(ChangeDialer);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_CALL_PHONE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
makeCall();
} else {
Toast.makeText(this, "calling permission denied", Toast.LENGTH_LONG).show();
}
//return;
}
}
}
public class CallActivity extends AppCompatActivity {
TextView callInfo;
Button answer, hangup;
private String number;
private OngoingCallObject ongoingCall;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_call);
ongoingCall = new OngoingCallObject();
answer = (Button) findViewById(R.id.answer);
hangup = (Button) findViewById(R.id.hangup);
callInfo = (TextView) findViewById(R.id.callInfo);
number = Objects.requireNonNull(getIntent().getData().getSchemeSpecificPart());
callInfo.setText("Calling number : "+number);
answer.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//Toast.makeText(CallActivity.this, "Answer button", Toast.LENGTH_SHORT).show();
ongoingCall.answer();
}
});
hangup.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ongoingCall.hangup();
}
});
}
public static void start(Context context, Call call) {
Intent intent = new Intent(context, CallActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setData(call.getDetails().getHandle());
context.startActivity(intent);
}
}
以下是DialerActivity
的xml:activity\u dialer.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".DialerActivity">
<EditText
android:id="@+id/etNumber"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Tel number"/>
<Button
android:id="@+id/btnCall"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="CallActivity"
android:layout_below="@+id/etNumber" />
</RelativeLayout>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".CallActivity">
<TextView
android:id="@+id/callInfo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.3"
tools:text="Hello World!" />
<Button
android:id="@+id/answer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Answer"
app:layout_constraintBaseline_toBaselineOf="@+id/hangup"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/hangup" />
<Button
android:id="@+id/hangup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hang up"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/answer"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/callInfo" />
</android.support.constraint.ConstraintLayout>
我希望有帮助 建立你自己的拨号接口我建立的用户界面,但我如何使它显示在通话中?你解决了吗?有一个代码,但它是用一种我不知道如何将其翻译成普通java(Android Studio)的语言编写的。如果你遵循这个链接,它会告诉你如何将意图重新定向到你的应用程序请更具描述性,也许会告诉他可以做什么,因为他想要的不起作用,谢谢。Ash Patel问“我就是不能让它在通话中显示出来!答案是:不,你不能,因为没有人能!是的,在投票之前,阅读我的答案,最后是“你不能做任何事情,直到android团队决定与我们(开发者)共享这个核心功能。”。“因此,基本上api是可以预测的,它在小米设备上不起作用。i、 e.呼叫服务在呼叫过程中不调用。我使用的是适当的级别,这就是为什么它除了小米设备外都能正常工作。对于某些设备+1不支持此功能,请务必检查如下品牌:排除Xiomi,这也需要在华为进行测试。