53 votes

Fenêtre contextuelle sur l'écran des appels entrants natifs Android, comme une application Android

Mise à jour -- 09 Mai 2013 *j'ai essayé de mettre en œuvre le pain grillé du récepteur de radiodiffusion de la méthode onReceive parce que toast est un composant natif d'Android, mais c'est aussi de ne pas obtenir de apparaît dans Android 4.1 (Jelly Bean).

Mon idée était de mettre en œuvre le pain grillé du récepteur de radiodiffusion de la méthode onReceive et par la suite de changer son design en fonction de nos besoins et de paramétrage de la durée de l'affichage. Mais un autre problème est que findViewById ne fonctionne pas dans le récepteur de radiodiffusion, donc je pense que nous avons à faire à un LinearLayout par programmation pour la personnalisation du pain grillé.*

Mise à jour -- Après bounty aussi je ne suis pas exactement la chose que je cherche, mais je vais revenir à tous, je suis en train de travailler sur elle. De toute façon, ce code fonctionne pour la plupart des téléphones Android. Si quelqu'un va utiliser et attraper la solution pour elle, s'il vous plaît écrire ici afin que tout le monde peut obtenir le bénéfice. Merci pour toutes vos réponses.

Je suis en train d'élaborer un récepteur de radiodiffusion pour en venir à des appels sur Android et sur les appels entrants que je veux gonfler un pop-up sur le natif de l'écran d'appel entrant.

J'ai terminé ce code. Mais maintenant le problème est que dans le système d'exploitation Android 4.1 (Jelly Bean) de l'API de niveau 17 quand un téléphone sonne, l' PHONE_STATE est à venir comme OFF HOOK, et si je suis à l'appel d'une activité, il est appelé, mais le code qu'il ne soit pas exécuté. Je suis d'inscription le code:

Mon récepteur de radiodiffusion

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é qui je l'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 n'est pas en cours d'exécution dans Android 4.1 (Jelly Bean), mais dans d'autres versions, il est de travail.

J'ai essayé presque tous les moyens que je peux faire. Ce code affiche une translucide activité au cours de l'appel des indigènes de l'écran, et il ne bloque pas les contrôles de fond, comme de décrocher le téléphone. Mais je le veux bien comme un véritable interlocuteur. J'ai joint un aperçu de la vraie appelant est l'affichage d'une fenêtre sur l'écran d'appel entrant.

Comment puis-je obtenir cette fonctionnalité pour une application Android?

C'est une véritable appelant fonctionne:

Enter image description here

Mon présent de sortie:

Enter image description here

32voto

Hiren Dabhi Points 1721

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é au bout de 1 à 2 secondes.

 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.

9voto

Jashan PJ Points 1587

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 manœuvre fonctionnait pour moi.

9voto

Sam Adams Points 917

Je viens de tester sur l'émulateur Android 4.2 (Jelly Bean) , et cela fonctionne parfaitement en bloquant la totalité de l'écran des appels entrants, comme à vrai dire:

 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>
 

6voto

bgse Points 1049

Je suis en train d'essayer quelque chose de similaire, l'ajout d'un bouton supplémentaire à l'écran d'appel entrant.

La réponse de Sam Adams affiché est de travailler pour moi, même si je suis d'appeler le code à partir d'un PhoneStateListener. En dehors de cela, la seule vraie différence de son code, c'est que je suis gonfler une mise en page:

overlay = (RelativeLayout) inflater.inflate(R.layout.overlay, null);
wm.addView(overlay, params);

Il travaille sur des émulateurs ainsi que sur un HTC One S (Android 4.1.1).

Quelque chose que vous devez garder à l'esprit est de garder une référence à la superposition de vue que vous ajoutez et supprimez-le de nouveau (appel removeView() sur windowmanager exemple) lorsque le téléphone passe au ralenti (lorsque l'auditeur obtient TelephonyManager.CALL_STATE_IDLE), sinon votre superposition va rester sur l'écran.

        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    if(overlay!=null)
    {
        wm.removeView(overlay);
        overlay = null;
    }

6voto

Andrey Voitenkov Points 525

Je pense que vous ne devriez pas commencer l'activité pour atteindre le décrit résultat. Vous avez besoin d'une vue séparée avoir LayoutParams.TYPE_SYSTEM_OVERLAY "dans sa mise en page params.

Vous pouvez placer ce point de vue où vous le souhaitez sur l'écran, ou tout simplement de couvrir la totalité de 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 code source complet, considère que c'est un échantillon.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X