gpt4 book ai didi

android - 如何像truecaller一样实现dialog

转载 作者:可可西里 更新时间:2023-11-01 18:48:23 26 4
gpt4 key购买 nike

我正在尝试实现类似于真实调用者的应用程序,当电话响起时,我可以使用广播接收器并打开 MyCustomDialog Activity 来获取电话号码

这是我的接收器类,我通过它获得调用开始或结束的调用状态。在此,我制作了一些我在 CallReceiver.java

中使用的方法

PhonecallReceiver.java

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.TelephonyManager;
import java.util.Date;

public abstract class PhonecallReceiver extends BroadcastReceiver
{
private static int lastState = TelephonyManager.CALL_STATE_IDLE;
private static Date callStartTime;
private static boolean isIncoming;
private static String savedNumber;

@Override
public void onReceive(Context context, Intent intent)
{
try
{
if (intent.getAction().equals("android.intent.action.NEW_OUTGOING_CALL"))
{
savedNumber = intent.getExtras().getString("android.intent.extra.PHONE_NUMBER");
}
else
{
String stateStr = intent.getExtras().getString(TelephonyManager.EXTRA_STATE);
String number = intent.getExtras().getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
int state = 0;
if(stateStr.equals(TelephonyManager.EXTRA_STATE_IDLE))
{
state = TelephonyManager.CALL_STATE_IDLE;
}
else if(stateStr.equals(TelephonyManager.EXTRA_STATE_OFFHOOK))
{
state = TelephonyManager.CALL_STATE_OFFHOOK;
}
else if(stateStr.equals(TelephonyManager.EXTRA_STATE_RINGING))
{
state = TelephonyManager.CALL_STATE_RINGING;
}

onCallStateChanged(context, state, number);
}
}
catch (Exception e)
{
e.printStackTrace();
}
}

//Derived classes should override these to respond to specific events of interest
protected void onIncomingCallStarted(Context ctx, String number, Date start){}
protected void onIncomingCallEnded(Context ctx, String number, Date start, Date end){}

public void onCallStateChanged(Context context, int state, String number)
{
if(lastState == state)
{
//No change, debounce extras
return;
}
switch (state)
{
case TelephonyManager.CALL_STATE_RINGING:
isIncoming = true;
callStartTime = new Date();
savedNumber = number;
onIncomingCallStarted(context, number, callStartTime);
break;

case TelephonyManager.CALL_STATE_OFFHOOK:
if (isIncoming)
{
onIncomingCallEnded(context,savedNumber,callStartTime,new Date());
}

case TelephonyManager.CALL_STATE_IDLE:
if(isIncoming)
{
onIncomingCallEnded(context, savedNumber, callStartTime, new Date());
}
}
lastState = state;
}
}

CallReceiver.java

import android.app.Activity;
import android.app.Dialog;
import android.app.Notification;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.ColorDrawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import android.widget.Toast;
import android.os.Handler;
import java.util.Date;

import dootam.dspl.com.lawyercasecall.R;

public class CallReceiver extends PhonecallReceiver
{
Context context;

@Override
protected void onIncomingCallStarted(final Context ctx, String number, Date start)
{
Toast.makeText(ctx,"Kushal Incoming Call"+ number,Toast.LENGTH_LONG).show();

context = ctx;

final Intent intent = new Intent(context, MyCustomDialog.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.putExtra("phone_no",number);

new Handler().postDelayed(new Runnable()
{
@Override
public void run()
{
context.startActivity(intent);
}
},2000);

// MyCus/*tomDialog dialog = new MyCustomDialog(context);
// dialog.*/show();
}

@Override
protected void onIncomingCallEnded(Context ctx, String number, Date start, Date end)
{
Toast.makeText(ctx,"Bye Bye"+ number,Toast.LENGTH_LONG).show();
}
}

MyCustomDialog.java

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import android.widget.TextView;
import dootam.dspl.com.lawyercasecall.R;

public class MyCustomDialog extends Activity
{
TextView tv_client;
String phone_no;
Button dialog_ok;

@Override
protected void onCreate(Bundle savedInstanceState)
{
try
{
requestWindowFeature(Window.FEATURE_NO_TITLE);
this.setFinishOnTouchOutside(false);
super.onCreate(savedInstanceState);
setContentView(R.layout.dialog);
initializeContent();

/*WindowManager.LayoutParams params = getWindow().getAttributes();
params.x = -100;
params.height = 70;
params.width = 1000;
params.y = -50;

this.getWindow().setAttributes(params);*/

phone_no = getIntent().getExtras().getString("phone_no");
tv_client.setText(""+phone_no +" is calling you");

dialog_ok.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
MyCustomDialog.this.finish();
// this.setFinishOnTouchOutside(false);
System.exit(0);
}
});
}
catch (Exception e)
{
Log.d("Exception", e.toString());
e.printStackTrace();
}
}

private void initializeContent()
{
tv_client = (TextView) findViewById(R.id.tv_client);
dialog_ok = (Button) findViewById(R.id.dialog_ok);
}
}

我的 AndroidManifest.xml

 <application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".AddCasesActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".receiver.MyCustomDialog"
android:theme="@android:style/Theme.Dialog"
android:noHistory="true"
/>


<receiver android:name=".receiver.CallReceiver" >
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
</receiver>

</application>

<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
<uses-permission android:name="android.permission.MODIFY_PHONE_STATE" tools:ignore="ProtectedPermissions"/>
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

通过实现所有这些东西,我得到了想要的输出

my receiver output on incoming call

请指导我如何使此 Activity 对话框像 truecaller 应用程序的弹出窗口一样可拖动。

我正在搜索类似于此图像的对话框,

truecaller incoming screen

最佳答案

It is possible through OnTouchListener, Try this https://github.com/andreilisun/Swipe-To-Dismiss-Dialog The Dialog is draggable, I have changed the SwipeDimissDialog to remove dismissal of Dialog in the following class -

public class SwipeDismissDialog extends FrameLayout {

private final Params params;
private View dialog;

protected SwipeDismissDialog(@NonNull Context context, Params params) {
super(context);
this.params = params;
init();
}

private void init() {
setOnClickListener(overlayClickListener);
setBackgroundColor(params.overlayColor);
dialog = params.view;
if (dialog == null) {
dialog = LayoutInflater.from(getContext()).inflate(params.layoutRes, this, false);
}
LayoutParams layoutParams = (LayoutParams) dialog.getLayoutParams();
if (layoutParams == null) {
layoutParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.CENTER);
} else {
layoutParams.gravity = Gravity.CENTER;
}
dialog.setOnTouchListener(touchListener);
addView(dialog, layoutParams);
}

@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN
&& event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
cancel();
return true;
}
return false;
}

public SwipeDismissDialog show() {
WindowManager windowManager = (WindowManager)
getContext().getSystemService(Context.WINDOW_SERVICE);
WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();
layoutParams.height = WindowManager.LayoutParams.MATCH_PARENT;
layoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
layoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION;
layoutParams.format = PixelFormat.TRANSLUCENT;
windowManager.addView(this, layoutParams);
return this;
}

public void cancel() {
if (params.cancelListener != null) {
params.cancelListener.onCancel(dialog);
}
if (params.dismissOnCancel) {
dismiss();
}
}

public void dismiss() {
dialog.setOnTouchListener(null);
removeView(dialog);
WindowManager windowManager = (WindowManager)
getContext().getSystemService(Context.WINDOW_SERVICE);
windowManager.removeViewImmediate(this);
}

private void dismiss(SwipeDismissDirection direction) {
if (params.swipeDismissListener != null) {
params.swipeDismissListener.onSwipeDismiss(this, direction);
}
dismiss();
}

private final OnTouchListener touchListener = new OnTouchListener() {

private float initCenterX;
private float lastEventY;
private float lastEventX;
private float initY;
private float initX;

public boolean onTouch(View view, MotionEvent motionEvent) {
/*Fling detected*/

int action = motionEvent.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN: {
initX = view.getX();
initY = view.getY();
lastEventX = motionEvent.getRawX();
lastEventY = motionEvent.getRawY();
initCenterX = initX + view.getWidth() / 2;
break;
}

case MotionEvent.ACTION_MOVE: {
float eventX = motionEvent.getRawX();
float eventY = motionEvent.getRawY();
float eventDx = eventX - lastEventX;
float eventDy = eventY - lastEventY;
float centerX = view.getX() + eventDx + view.getWidth() / 2;
float centerDx = centerX - initCenterX;
view.setX(view.getX() + eventDx);
view.setY(view.getY() + eventDy);
//view.invalidate();
lastEventX = eventX;
lastEventY = eventY;
break;
}

}
return true;
}
};

private final OnClickListener overlayClickListener = new OnClickListener() {
@Override
public void onClick(View v) {
cancel();
}
};


public static class Builder {

private final Params params;
private final Context context;

public Builder(Context context) {
this.context = context;
this.params = new Params();
}

public Builder setView(@NonNull View view) {
params.view = view;
params.layoutRes = 0;
return this;
}

public Builder setLayoutResId(@LayoutRes int layoutResId) {
params.layoutRes = layoutResId;
params.view = null;
return this;
}

public SwipeDismissDialog build() {
if (params.view == null && params.layoutRes == 0) {
throw new IllegalStateException("view should be set with setView(View view) " +
"or with setLayoutResId(int layoutResId)");
}
return new SwipeDismissDialog(context, params);
}
}
}

关于android - 如何像truecaller一样实现dialog,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32134649/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com