我已经实现了一个小型计时器应用程序,每当我接到一个电话时它就会启动。就像收到来电后我正在启动我的计时器应用程序并在前台显示计时器。
但它正在棒棒糖5.1 版本的低端版本中运行它在后台运行。
我需要在所有设备的前台运行应用程序,如何实现这一目标?
我的代码:
Intent it = new Intent("intent.my.action");
it.setComponent(new ComponentName(context.getPackageName(), timer.class.getName()));
it.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.getApplicationContext().startActivity(it);
我的收件人:
public class CallerToActivity extends BroadcastReceiver {
static boolean wasRinging = false;
static boolean finish = false;
SessionManager session;
private boolean enable;
public void onReceive(Context context, Intent intent) {
session = new SessionManager(context);
String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
enable = session.Is_Enabled();
if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
Log.d("Status", "Phone is Ringing");
} else if (state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
Intent it = new Intent("intent.my.action");
it.putExtra("Call", "true");
it.setComponent(new ComponentName(context.getPackageName(), timer.class.getName()));
it.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.getApplicationContext().startActivity(it);
} else if (state.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
// Call Dropped or rejected
Toast.makeText(context, "phone is neither ringing nor in a call",
Toast.LENGTH_SHORT).show();
// wasRinging = false;
finish = true;
System.exit(0);
Log.d("Status", "Phone is dropped");
}
}
}
答案 0 :(得分:4)
以下是解决问题的步骤
1)创建接收器以收听呼叫( PhoneStatReceiver.java )
2)创建服务以在您的电话呼叫视图上方显示视图(例如,定时器视图)( HBFloatingHead.java )
3)还在 HBFloatingHead服务内创建计时器,并根据计时器更新窗口布局。
4)更新 AndroidManifest.xml
示例代码: 1)PhoneStatReceiver.java
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.TelephonyManager;
import android.util.Log;
public class PhoneStatReceiver extends BroadcastReceiver{
private static final String TAG = "PhoneStatReceiver";
// private static MyPhoneStateListener phoneListener = new MyPhoneStateListener();
private static boolean incomingFlag = false;
private static String incoming_number = null;
@Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)){
incomingFlag = false;
String phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
Log.i(TAG, "call OUT:"+phoneNumber);
startService(context);
}else{
TelephonyManager tm =
(TelephonyManager)context.getSystemService(Service.TELEPHONY_SERVICE);
switch (tm.getCallState()) {
case TelephonyManager.CALL_STATE_RINGING:
incomingFlag = true;
incoming_number = intent.getStringExtra("incoming_number");
Log.i(TAG, "RINGING :"+ incoming_number);
startService(context);
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
if(incomingFlag){
Log.i(TAG, "incoming ACCEPT :"+ incoming_number);
}
break;
case TelephonyManager.CALL_STATE_IDLE:
if(incomingFlag){
Log.i(TAG, "incoming IDLE");
}
break;
}
}
}
public void startService(Context context){
Intent intent = new Intent(context, HBFloatingHead.class);
context.startService(intent);
}
}
2)**更新了 HBFloatingHead.java **
import android.app.Service;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.os.Binder;
import android.os.CountDownTimer;
import android.os.IBinder;
import android.os.Message;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.WindowManager;
import android.widget.TextView;
public class HBFloatingHead extends Service {
private WindowManager mhbWindow;
private TextView mfloatingHead;
private Intent intent;
public static final String BROADCAST_ACTION = "com.fragmentsample";
private final IBinder mBinder = new LocalBinder();
public class LocalBinder extends Binder {
HBFloatingHead getService() {
return HBFloatingHead.this;
}
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
@Override
public void onDestroy() {
super.onDestroy();
if (mfloatingHead != null) {
mhbWindow.removeView(mfloatingHead);
countDownTimer.cancel();
}
}
WindowManager.LayoutParams params;
@Override
public void onCreate() {
super.onCreate();
intent = new Intent(BROADCAST_ACTION);
mhbWindow = (WindowManager) getSystemService(WINDOW_SERVICE);
mfloatingHead = new TextView(this);
mfloatingHead.setBackgroundResource(R.drawable.floating4);
mfloatingHead.setTextColor(Color.WHITE);
mfloatingHead.setTextSize(20f);
mfloatingHead.setHint("00.00 sec");
mfloatingHead.setGravity(Gravity.CENTER);
mfloatingHead.setPadding(20, 20, 20, 20);
params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.TOP | Gravity.LEFT;
params.x = 0;
params.y = 100;
mhbWindow.addView(mfloatingHead, params);
try {
mfloatingHead.setOnTouchListener(new View.OnTouchListener() {
private WindowManager.LayoutParams paramsF = params;
private int initialX;
private int initialY;
private float initialTouchX;
private float initialTouchY;
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
break;
case MotionEvent.ACTION_DOWN:
initialX = paramsF.x;
initialY = paramsF.y;
initialTouchX = event.getRawX();
initialTouchY = event.getRawY();
break;
case MotionEvent.ACTION_MOVE:
paramsF.x = initialX
+ (int) (event.getRawX() - initialTouchX);
paramsF.y = initialY
+ (int) (event.getRawY() - initialTouchY);
mhbWindow.updateViewLayout(mfloatingHead, paramsF);
break;
default:
break;
}
return false;
}
});
} catch (Exception e) {
Log.e("#HB#", e.getMessage().toString());
}
mfloatingHead.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//HBFloatingHead.this.stopSelf();
}
});
startTimer(1);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
android.os.Handler handler = new android.os.Handler(new android.os.Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
try {
long seconds = msg.what;
String text = String.format("%02d", seconds / 60) + ":"
+ String.format("%02d", seconds % 60);
Log.e("TAG", "Updated text : " + text);
mfloatingHead.setText(text);
mhbWindow.updateViewLayout(mfloatingHead, params);
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
});
CountDownTimer countDownTimer;
private void startTimer(final int minuti) {
countDownTimer = new CountDownTimer(60 * minuti * 1000, 500) {
@Override
public void onTick(long millisUntilFinished) {
int seconds = (int) (millisUntilFinished / 1000);
if (seconds > 0)
handler.sendEmptyMessage(seconds);
else
HBFloatingHead.this.stopSelf();
// Log.d("TIME", mTvTime.getText().toString());
}
@Override
public void onFinish() {
}
};
countDownTimer.start();
}
}
3)按照HBFloatingService类中的注释创建布局
4)更新AndroidManifest.xml
添加权限
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.READ_PHONE_STATE"> </uses-permission>
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"></uses-permission>
声明您的Android组件
<receiver android:name=".PhoneStatReceiver">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
</receiver>
<service
android:name=".HBFloatingHead"
android:exported="true" />