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 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) {
}
});
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();
}
@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" />