Cómo ejecutar una aplicación en primer plano en las versiones de Android inferiores a 5.1

He implementado una pequeña aplicación de temporizador y se inicia cada vez que recibí una llamada, Al igual que después de recibir una llamada entrante estoy comenzando mi aplicación de temporizador y mostrar el temporizador en primer plano.

Pero está trabajando en la versión lollipop 5.1 en la versión de gama baja que se está ejecutando en segundo plano.

Tengo que ejecutar la aplicación en primer plano en todos los dispositivos, ¿cómo lograr esto?

Mi código:

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); 

Mi receptor:

 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"); } } } 

Estos son los pasos para resolver su problema
1) Crear Receptor para escuchar la llamada ( PhoneStatReceiver.java )
2) Crear servicio para mostrar la vista (Ex. Timer View) encima de la vista de llamada telefónica ( HBFloatingHead.java )
3) También crea el contador de tiempo dentro del servicio de HBFloatingHead y la disposición de la ventana de la actualización según el contador de tiempo.
4) Actualiza tu AndroidManifest.xml

Ejemplo de código: 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) ** Actualizado 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) Cree su disposición según lo comentado en la clase de HBFloatingService
4) Actualiza tu AndroidManifest.xml

Añadir permisos

 <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> 

Declare sus componentes de 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" /> 
  • Registrar el dispositivo en el archivo
  • Tiempo desde el primer arranque
  • Obtener la altura de un TextView
  • Arreglar botones en forma de diamante en android xml
  • Android: cambiar los elementos del menú de opciones mediante programación
  • Cómo obtener datos de cordova-plugin-nativestorage en android java
  • ¿Cuál sería un método para crear un contador de números en Android?
  • Convertir lista a matriz en Java
  • Cómo convertir una fecha dd / mm / aaaa a aaaa-MM-dd HH: mm: ss Android
  • La carga de archivos zip por FTP está dañada a veces
  • ViewPager ¿Fragmentos que se destruyen con el tiempo?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.