Je développe un récepteur de diffusion pour les appels entrants dans Android et lors de la réception d'appels entrants, je souhaite faire apparaître une fenêtre contextuelle sur l'écran des appels entrants natifs.
J'ai complété ce code. Mais maintenant, le problème est que dans le l'API Android 4.1 (Jelly Bean) de niveau 17 lorsqu'un téléphone sonne, le PHONE_STATE
se présente sous la forme OFF HOOK
et, si j'appelle une activité, elle est appelée, mais le code correspondant ne soit pas exécuté. Je liste le code:
package com.example.popwindowonincomingcallscreen;
import Java.util.concurrent.Executors;
import Java.util.concurrent.ScheduledExecutorService;
import Android.content.BroadcastReceiver;
import Android.content.Context;
import Android.content.Intent;
import Android.telephony.TelephonyManager;
import Android.util.Log;
public class IncomingBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.d("IncomingBroadcastReceiver: onReceive: ", "flag1");
String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
Log.d("IncomingBroadcastReceiver: onReceive: ", state);
if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)
|| state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
Log.d("Ringing", "Phone is ringing");
Intent i = new Intent(context, IncomingCallActivity.class);
i.putExtras(intent);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
Wait.oneSec();
context.startActivity(i);
}
}
}
Une activité que j'appelle:
import Android.app.Activity;
import Android.os.Bundle;
import Android.telephony.TelephonyManager;
import Android.util.Log;
import Android.view.View.MeasureSpec;
import Android.view.Window;
import Android.view.WindowManager;
import Android.widget.TextView;
public class IncomingCallActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
try {
Log.d("IncomingCallActivity: onCreate: ", "flag2");
*/ After this line, the code is not executed in Android 4.1 (Jelly bean) only/*
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
getWindow().addFlags(
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
Log.d("IncomingCallActivity: onCreate: ", "flagy");
setContentView(R.layout.main);
Log.d("IncomingCallActivity: onCreate: ", "flagz");
String number = getIntent().getStringExtra(
TelephonyManager.EXTRA_INCOMING_NUMBER);
TextView text = (TextView) findViewById(R.id.text);
text.setText("Incoming call from " + number);
}
catch (Exception e) {
Log.d("Exception", e.toString());
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Après
try {
Log.d("IncomingCallActivity: onCreate: ", "flag2");
}
Le code ne s'exécute pas dans Android 4.1 (Jelly Bean), mais dans d'autres versions, il fonctionne.
J'ai essayé presque tous les moyens que je peux faire. Ce code affiche une activité translucide sur l'écran d'appel natif et ne bloque pas les contrôles en arrière-plan, comme pour prendre le téléphone. Mais je le veux comme un vrai appelant. J'ai joint un instantané indiquant comment le véritable appelant affiche une fenêtre sur l'écran des appels entrants.
Comment puis-je obtenir cette fonctionnalité pour une application Android?
Voici comment fonctionne un véritable appelant:
Ma sortie actuelle:
Après la prime, je ne reçois pas exactement ce que je cherche, mais je reviendrai à tous. Je travaille dessus. Quoi qu'il en soit, ce code fonctionne pour la plupart des téléphones Android. Si quelqu'un veut utiliser et trouver la solution, écrivez ici pour que tout le monde puisse en tirer profit.
J'ai essayé d'implémenter Toast dans la méthode onReceive du récepteur de diffusion, car toast est un composant natif d'Android, mais il ne s'affiche pas non plus dans Android 4.1 (Jelly Bean).
Mon idée était d'implémenter Toast dans la méthode onReceive du récepteur de diffusion, puis de modifier sa conception en fonction de nos besoins et d'ajuster sa durée d'affichage. Mais un autre problème est que findViewById ne fonctionne pas dans le récepteur de diffusion. Je pense donc que nous devons créer un LinearLayout par programme pour personnaliser le pain grillé.
Je ne suis pas sûr que votre interface graphique personnalisée sera toujours au-dessus de celle par défaut, car le récepteur de diffusion système et votre récepteur essaient tous deux d'afficher leur interface graphique en haut de l'écran. Nous ne savons pas lequel est appelé en premier, mais la tâche la plus difficile pour afficher votre interface graphique en haut de l'écran est lorsque le téléphone sonne, appelez votre activité après 1 à 2 seconde (s).
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
Intent intent = new Intent(context, AcceptReject.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
}, 2000);
J'espère que cela peut vous aider.
Essayez le code avant la méthode super.onCreate
. Je pense qu'après avoir appelé le super, le code est sauté. Parfois, ce type de ruse fonctionnait pour moi.
Je viens de tester sur Android 4.2 (Jelly bean) emulator, et cela fonctionne parfaitement en bloquant l’écran d’appel entrant dans son intégralité, comme à l’avance:
public void onReceive(Context context, Intent intent) {
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.TYPE_SYSTEM_ALERT |
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSPARENT);
params.height = LayoutParams.MATCH_PARENT;
params.width = LayoutParams.MATCH_PARENT;
params.format = PixelFormat.TRANSLUCENT;
params.gravity = Gravity.TOP;
LinearLayout ly = new LinearLayout(context);
ly.setBackgroundColor(Color.RED);
ly.setOrientation(LinearLayout.VERTICAL);
wm.addView(ly, params);
}
Dans le manifeste:
<receiver Android:name="" Android:enabled="true" >
<intent-filter Android:priority="-1">
<action Android:name="Android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
J'essaie quelque chose de similaire, en ajoutant un bouton supplémentaire à l'écran des appels entrants.
La réponse affichée par Sam Adams fonctionne pour moi, bien que j'appelle le code à partir d'un PhoneStateListener. En dehors de cela, la seule différence réelle par rapport à son code est que je gonfle une mise en page:
overlay = (RelativeLayout) inflater.inflate(R.layout.overlay, null);
wm.addView(overlay, params);
Il fonctionne sur les émulateurs ainsi que sur un HTC One S (sous Android 4.1.1).
N'oubliez pas de garder une référence à la vue de superposition que vous ajoutez et de la supprimer à nouveau (appelez removeView () sur l'instance de windowmanager) lorsque le téléphone redevient inactif (lorsque l'écouteur obtient TelephonyManager.CALL_STATE_IDLE), sinon votre incrustation restera à l'écran.
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
if(overlay!=null)
{
wm.removeView(overlay);
overlay = null;
}
Je pense que vous ne devriez pas commencer l'activité pour atteindre le résultat décrit. Vous avez besoin d'une vue séparée dans laquelle LayoutParams.TYPE_SYSTEM_OVERLAY
est défini dans ses paramètres de présentation.
Vous pouvez positionner cette vue où vous voulez sur l'écran, ou simplement couvrir tout l'écran.
Voici quelques lignes de code:
_av = new ActivatorView(this);
_avLayoutParams = new WindowManager.LayoutParams(0, 0, 0, 0,
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
PixelFormat.OPAQUE);
_avLayoutParams.screenBrightness = _fScreenBrightness = 20f;
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
wm.addView(_av, _avLayoutParams);
https://bitbucket.org/gyrussolutions/yaab/src/f01cc8aff690cae1b1107287cb17835b8a3c1643/src/biz/gyrus/yaab/LightMonitorService.java?at=default#cl-338 - le mot de passe complet.
Je travaille aussi dessus (j'ai peut-être tort de vous comprendre ici). Ce que vous voulez réaliser, c'est afficher cette activité dans Android 4.2 (Jelly Bean). Je viens de placer un délai pour afficher l'activité. J'ai utilisé PhoneStateListener dans différentes classes. Je suis capable d'afficher une nouvelle activité sur l'écran de l'appelant. Voici mon code complet:
public class MyBroadcastReceiver extends BroadcastReceiver {
static CustomPhoneStateListener phoneStateListener;
Context context;
Intent intent;
@Override
public void onReceive(Context context, Intent intent) {
this.context = context;
this.intent = intent;
// TODO Auto-generated method stub
TelephonyManager telephonyManager = (TelephonyManager) context
.getSystemService(Context.TELEPHONY_SERVICE);
phoneStateListener = new CustomPhoneStateListener(context);
telephonyManager.listen(phoneStateListener,
PhoneStateListener.LISTEN_CALL_STATE);
}
}
public class CustomPhoneStateListener extends PhoneStateListener {
// private static final String TAG = "PhoneStateChanged";
Context context; // Context to make Toast if required
private AudioManager amanager;
Intent i1;
public CustomPhoneStateListener(Context context) {
super();
this.context = context;
i1 = new Intent(context, YourActivity.class);
i1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i1.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
}
@Override
public void onCallStateChanged(int state, String incomingNumber) {
super.onCallStateChanged(state, incomingNumber);
switch (state) {
case TelephonyManager.CALL_STATE_IDLE:
Toast.makeText(context, "Phone state Idle", Toast.LENGTH_LONG)
.show();
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
Toast.makeText(context, "Phone state Off hook", Toast.LENGTH_LONG)
.show();
break;
case TelephonyManager.CALL_STATE_RINGING:
try {
Thread.sleep(3000);
context.startActivity(i1);
} catch (Exception e) {
e.getLocalizedMessage();
}
default:
break;
}
}
et Votre activité restera telle que vous l'avez créée .... Note: je suis confronté à des problèmes également dans ce code, ils sont ici.
(Aide acceptée pour ces problèmes. Merci. Pourrait aider quelqu'un)
METTRE &AGRAVE; JOUR
ICI IS LIEN DE PETITE DEMO COMMENT Y ARRIVER.
Nous étions également confrontés à un problème similaire, à savoir que la superposition ne soit pas affichée sur un périphérique avec verrouillage des broches. La solution qui a fonctionné pour nous est la suivante:
mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
mParams = new LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT,
LayoutParams.TYPE_SYSTEM_ERROR,
LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
C'est LayoutParams.TYPE_SYSTEM_ERROR
qui a fait la différence.
Ma méthode:
utiliser le service pour faire la superposition
ps:wmParams.type = WindowManager.LayoutParams.TYPE_PHONE;
essaye ça
AlertDialog.Builder builder = new AlertDialog.Builder(context.getApplicationContext());
LayoutInflater inflater = LayoutInflater.from(context);
View dialogView = inflater.inflate(R.layout.caller_dialog, null);
ImageView button = dialogView.findViewById(R.id.close_btn);
builder.setView(dialogView);
final AlertDialog alert = builder.create();
alert.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
alert.getWindow().setType(WindowManager.LayoutParams.TYPE_PHONE);
alert.setCanceledOnTouchOutside(true);
alert.show();
WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
Window window = alert.getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
window.setGravity(Gravity.TOP);
lp.copyFrom(window.getAttributes());
//This makes the dialog take up the full width
lp.width = WindowManager.LayoutParams.MATCH_PARENT;
lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
window.setAttributes(lp);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//close the service and remove the from from the window
alert.dismiss();
}
});
Utilisez un simple récepteur de diffusion et mettez ce code dans le récepteur de diffusion:
public void onReceive(final Context context, final Intent intent) {
Log.v(LOG_TAG, "Receieved notification about network status");
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.TYPE_SYSTEM_ALERT |
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSPARENT);
params.height = WindowManager.LayoutParams.MATCH_PARENT;
params.width = WindowManager.LayoutParams.MATCH_PARENT;
params.format = PixelFormat.TRANSLUCENT;
params.gravity = Gravity.TOP;
LinearLayout ly = new LinearLayout(context);
ly.setBackgroundColor(Color.RED);
ly.setOrientation(LinearLayout.VERTICAL);
wm.addView(ly, params);
}
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
Intent i = new Intent(context, CallingIncoming.class);
i.putExtras(intent);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK /*| Intent.FLAG_ACTIVITY_CLEAR_TASK*/);
context.startActivity(i);
}
}, 450);//It will help you to delay your screen and after it your screen will be top of default app screen