- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
检测到来电后,我在来电上打开聊天图标之类的 Messenger。但我面临两个问题:
1.当我的应用程序关闭时(即使在后台也不运行),未检测到来电。
2.当我的手机被锁定时,聊天图标没有出现。聊天图标隐藏在来电时的拨号器应用程序后面。
我正在使用 Broadcast Receiver
使用 PhoneCallReceiver
类接收来电,该类调用 CallReceiver
类下的方法 defined
等检测来电 我正在启动服务 ChatHeadService
,它会打开一个聊天图标。我附上了聊天图标显示方式的屏幕截图。自过去 6 个月以来,我一直面临这个问题,但无法解决。如有任何帮助,我们将不胜感激。
编译SDK版本23
buildToolsVersion '27.0.3'
targetSdk版本 23
我在 API 级别 18 和 API 级别 26 的两台设备上测试了该应用程序。在 API 级别 18 中,我的应用程序运行良好,并且上述两个问题都已修复。但在 API 级别 26 中,我的应用程序无法运行,聊天图标隐藏在拨号器应用程序的后面。
我在 Oreo API 26 的传入调用中遇到以下错误。06-13 16:22:23.969 1238-4375/? W/BroadcastQueue:权限拒绝:接收 Intent { act=android.intent.action.PHONE_STATE flg=0x1000010(有额外的)} 到 com.skype.m2/com.skype.nativephone.connector.NativePhoneCallReceiver 需要 android.permission.READ_PHONE_STATE 由于发件人 android (uid 1000)
API 级别 26
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.tarun.notifyme2">
<uses-sdk
android:minSdkVersion="16"
android:targetSdkVersion="23" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.Settings.ACTION_MANAGE_OVERLAY_PERMISSION" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission
android:name="android.permission.MODIFY_PHONE_STATE"
tools:ignore="ProtectedPermissions" />
<application
android:allowBackup="true"
android:enabled="true"
android:icon="@drawable/app_icon"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".SignUp">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".SendNoti" />
<receiver android:name=".CallReceiver"
android:enabled="true">
<intent-filter android:priority="1000">
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
</receiver>
<service
android:name=".ChatHeadService"
android:exported="true"
android:enabled="true"/>
<service android:name=".FirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<service android:name=".FirebaseInstanceIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
<activity
android:name=".MainActivity"
android:label="@string/title_activity_main"
android:theme="@style/AppTheme.NoActionBar" />
<activity android:name=".MainChat" />
<activity android:name=".ChatRoom" />
<activity android:name=".Feedback" />
</application>
</manifest>
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.content.SharedPreferences;
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;
public class CallReceiver extends PhonecallReceiver
{
Context context;
@Override
protected void onIncomingCallStarted(final Context ctx, String number, Date start)
{
Toast.makeText(ctx,"New Incoming Call"+ number,Toast.LENGTH_LONG).show();
context = ctx;
final Intent intent = new Intent(context, ChatHeadService.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.putExtra("phone_no",number);
SharedPreferences.Editor editor = ctx.getSharedPreferences("Notify", Context.MODE_PRIVATE).edit();
editor.putString("incomingNo",number);
editor.commit();
new Handler().postDelayed(new Runnable()
{
@Override
public void run()
{
//start service which opens a chat icon after 2 seconds wait
context.startService(intent);
}
},2000);
}
@Override
protected void onIncomingCallEnded(Context ctx, String number, Date start, Date end)
{
final Intent intent = new Intent(context, ChatHeadService.class);
ctx.stopService(intent);
Toast.makeText(ctx,"Bye Bye"+ number,Toast.LENGTH_LONG).show();
}
}
ChatHeadService.java
import android.app.Service;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.os.IBinder;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.Toast;
public class ChatHeadService extends Service {
private WindowManager windowManager;
private ImageView chatHead;
WindowManager.LayoutParams params;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
int res = super.onStartCommand(intent, flags, startId);
return res;
}
@Override
public void onCreate() {
super.onCreate();
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
chatHead = new ImageView(this);
chatHead.setImageResource(R.drawable.bell2);
chatHead.setClickable(true);
params= new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.TOP | Gravity.LEFT;
params.x = 0;
params.y = 400;
windowManager.addView(chatHead, params);
chatHead.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(new Intent(ChatHeadService.this, SendNoti.class)
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
stopSelf();
}
});
//this code is for dragging the chat head
chatHead.setOnTouchListener(new View.OnTouchListener() {
private int initialX;
private int initialY;
private float initialTouchX;
private float initialTouchY;
int flag=0;
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
initialX = params.x;
initialY = params.y;
initialTouchX = event.getRawX();
initialTouchY = event.getRawY();
if(flag==3){
flag=1;
return true;
}else{
flag=1;
return false;
}
case MotionEvent.ACTION_UP:
if(flag==3){
flag=2;
return true;
}else{
flag=2;
return false;
}
case MotionEvent.ACTION_MOVE:
flag=3;
params.x = initialX
+ (int) (event.getRawX() - initialTouchX);
params.y = initialY
+ (int) (event.getRawY() - initialTouchY);
windowManager.updateViewLayout(chatHead, params);
return true;
default:
Toast.makeText(getApplicationContext(),"You ckiced the imageview",Toast.LENGTH_LONG).show();
Log.i("tag","You clicked the imageview");
/*
Intent i = new Intent(view.getContext(),SendNoti.class);
startActivity(i);
stopSelf();*/
return true;
}
}
});
/*
Snackbar.make(chatHead, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();*/
}
@Override
public void onDestroy() {
super.onDestroy();
if (chatHead != null)
windowManager.removeView(chatHead);
stopSelf();
}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
最佳答案
前段时间我发现了这个例子。我只添加了,调用是传入或传出。按 Intent 将您的数据传递给服务,并使用它来执行服务。应该在 api 23 中工作。在最新版本中我不能确保这一点。
public class CallReceiver extends BroadcastReceiver {
private final static String TAG = "CallReceiver";
private static PhoneCallStartEndDetector listener;
private String outgoingSavedNumber;
protected Context savedContext;
@Override
public void onReceive(Context context, Intent intent) {
this.savedContext = context;
if (listener == null) {
listener = new PhoneCallStartEndDetector();
}
String phoneState = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
if (phoneState == null) {
listener.setOutgoingNumber(intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER));
} else if (phoneState.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
listener.setOutgoingNumber(intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER));
}
TelephonyManager telephony = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
telephony.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);
}
//Deals with actual events
private class PhoneCallStartEndDetector extends PhoneStateListener {
int lastState = TelephonyManager.CALL_STATE_IDLE;
boolean isIncoming;
boolean isOutgoing;
String savedNumber; //because the passed incoming is only valid in ringing
private PhoneCallStartEndDetector() {
}
//The outgoing number is only sent via a separate intent, so we need to store it out of band
private void setOutgoingNumber(String number) {
savedNumber = number;
}
Intent serviceIntent = new Intent(savedContext, YourService.class);
//Incoming call- goes from IDLE to RINGING when it rings, to OFFHOOK when it's answered, to IDLE when its hung up
//Outgoing call- goes from IDLE to OFFHOOK when it dials out, to IDLE when hung up
@Override
public void onCallStateChanged(int state, String incomingNumber) {
super.onCallStateChanged(state, incomingNumber);
if (lastState == state) {
//No change, debounce extras
return;
}
switch (state) {
case TelephonyManager.CALL_STATE_RINGING:
isIncoming = true;
savedNumber = incomingNumber;
serviceIntent.putExtra("label", value);
savedContext.startService(serviceIntent);
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
//Transition of ringing->offhook are pickups of incoming calls. Nothing donw on them
if (lastState != TelephonyManager.CALL_STATE_RINGING) {
if (!isOutgoing) {
isOutgoing = true;
}
if (!savedNumber.equals("")) {
serviceIntent.putExtra("label", value);
savedContext.startService(serviceIntent);
}
}
break;
case TelephonyManager.CALL_STATE_IDLE:
//Went to idle- this is the end of a call. What type depends on previous state(s)
if (lastState == TelephonyManager.CALL_STATE_RINGING) {
//Ring but no pickup- a miss
savedContext.stopService(serviceIntent);
} else if (isIncoming) {
savedContext.stopService(serviceIntent);
} else {
if (isOutgoing) {
savedContext.stopService(serviceIntent);
isOutgoing = false;
}
}
break;
}
lastState = state;
}
}
在 list 中注册这个接收器,这应该在 api 25 中工作:
<receiver
android:name=".calls.CallReceiver"
android:enabled="true">
<intent-filter android:priority="-1">
<action android:name="android.intent.action.PHONE_STATE" />
<action android:name="android.intent.action.NEW_OUTGOING_CALL"/>
</intent-filter>
</receiver>
或者在代码中注册 BroadcastReceiver,这应该可以在 api 26 中工作:
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("android.intent.action.PHONE_STATE");
CallReceiver receiver = new CallReceiver();
registerReceiver(receiver, intentFilter);
当然,要使用此代码,您需要授予权限。在 api 级别低于 23 的 list 中:
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
对于 api 23 和最新版本,询问用户权限:
Manifest.permission.READ_PHONE_STATE
关于java - 在拨号器应用程序顶部检测来电并在后台打开服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50810552/
本文实例讲述了Android编程实现读取手机联系人、拨号、发送短信及长按菜单操作方法。分享给大家供大家参考,具体如下: 1.Andrid项目结构图↓主要操作图中红色方框内的文件。 2.首先布
我希望用 * 字符来调用。例如> *711313。 目前,我正在使用此代码: NSString *str = [NSString stringWithFormat:@"tel:%@", tmp]; [
问题:创建了 Azure 容器注册表。使用 Jenkins 自动化 CI/CD 。镜像推送到仓库成功。然而,当我们尝试在同一个 Jenkins 盒子上拉取图像时,它会失败并出现错误: docker p
我正在使用 PhoneGap 创建适用于 iOS 的应用程序,phonegap 将 HTML、CSS 和 Javascript 打包到 native iPhone 应用程序中。 该应用程序将在屏幕中央
我正在尝试使用 rild-debug 套接字进行拨号。但是当我这样做时,有时会发生调制解调器崩溃,有时会发生 rild 崩溃。即使禁用电话应用程序,我也无法解决问题。有人请发表您对这个问题的建议。谢谢
我想制作一个 c# 程序,通过 USB 数据线连接到我的手机以调用电话。我找到了如何通过 SerialPort 连接以及如何通过 AT 命令进行调用,但是当我运行我的程序并单击以进行调用时,没有任何反
我想知道是否可以在 R 中做这种仪表板(我的意思是这种图)? 这是我想在 R 中执行的示例(第一个来自 SAS) 编辑:我在 Windows 7(64 位)上工作。 最佳答案 这里是从使用基本图形开始
当我按下 NetBeans 制作的 JButton 时,我正在尝试使 JFreeChart 的拨号工作。问题是,虽然代码在 JButton 之外看起来没问题,但当我将它放入其中时,它会给我带来程序错误
我正在为自己构建一个利用 Twilio 的点击通话网站。在我在 TwiML 应用程序中配置并编写 Twilio JavaScript SDK 客户端向 Twilio 发出请求后,Twilio 将向我的
我正在尝试从 php 调用一个电话号码(我在数据库中有一个客户列表,我想我可以用它在我点击他们的名字时给他们打电话 这是我的代码,它似乎不起作用。我能听到电话线路的咔嗒声,但似乎没有拨通。也许我缺少一
我需要在 iPhone 中使用 PhoneGap 应用程序调用电话号码。这是我正在使用的代码,它不起作用 此外,我还在应用程序中使用了 childbrowser 和 mapkit 插件。谁能告诉我如
我的计算机上有两个网络接口(interface)(eth0 和 eth1),我正在尝试使用特定接口(interface) (eth1) 拨号连接。鉴于我认为 Go 是一种系统语言的说法,但当前的标准库
我正在构建一个用 java 编写的 ISO8583 客户端,我需要发送到 ISO8583 主机,该主机托管在具有专用电话号码(模拟)的 NAC 上。 客户端(PC)正在生成 TCP/IP 数据,理想情
我在带有 Hyper-V 的 Windows 10 Professional 上使用 Docker for Desktop,也没有使用 minikube。我已经通过 Docker for Deskto
我已经在我的办公室 Windows 10 Pro 机器上安装了 docker。我在尝试从注册表中提取时遇到拨号 tcp 查找问题。 来自守护进程的错误响应:获取 https://registry-1.
在我的 ListView 中,我添加了一个带有图标/图像的按钮,并尝试使用 ListView 中的字符串编号从该按钮进行调用。但不知何故它不起作用或显示错误 Caused by: java.lang
我得到了具有 1 个主节点和 3 个工作节点的 Kubernetes 集群。 calico v3.7.3 kubernetes v1.16.0 通过 kubespray 安装 https://gith
我正在尝试在 iOS 和 Android 中使用 ng-click 制作一个 ons-button,以便在单击时调用号码。我使用 Cordova 框架。 我使用了以下方法但没有成功: Call
我正在尝试将EPS WRoom 32板连接到我的计算机上,并编译从主网站提供的ESP-IDF项目的一些示例。。但是,我总是收到这样的错误消息:。当我尝试将我的用户名添加到拨出组时,我收到以下消息:。我
我是一名优秀的程序员,十分优秀!