33 votes

Android: Prendre le contrôle complet du téléphone (mode kiosque), est-ce possible? Comment?

Nous avons un programme qui nous installer sur les téléphones et emprunter les téléphones des utilisateurs pour une certaine période. Nous aimerions que les téléphones à être utilisés exclusivement pour l'exécution de notre application(pas de téléphone, pas de jeux, pas rien). Nous allons racine de téléphones, pas de problème avec ça.

Donc, les choses dont nous avons besoin:

  • Exécuter en plein écran, rien d'autre ne sera visible
  • Bouton Home et les autres boutons du périphérique ne fonctionnera pas
  • Notre application va s'exécuter automatiquement sur démarrage

Il n'a pas à être "la preuve de pirates", mais devrait être suffisant pour empêcher l'utilisateur moyen de jouer avec l'appareil.

Est-ce possible? J'ai fait des choses similaires sur Symbian et Windows Mobile, mais je n'ai pas beaucoup d'expérience avec ce genre de choses sur Android. Pouvez vous s'il vous plaît me diriger dans la bonne direction?

Merci.

49voto

Vineet Shukla Points 12926

oui c'est possible, mais vous ne pouvez pas contrôler le comportement de l' Home key et end call key.

pour le plein écran ajouter android:theme="@android:style/Theme.NoTitleBar.Fullscreen" de l'activité de la balise dans le fichier de manifeste.

Pour désactiver l'appel entrant vous avez besoin d'écouter les appels téléphoniques:

import android.app.Service;
import android.os.IBinder;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;

public class MyPhoneStateListener extends Service{

    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
            StateListener phoneStateListener = new StateListener();
            TelephonyManager telephonymanager = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
            telephonymanager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
        }catch(Exception e){ }

    }

    class StateListener extends PhoneStateListener{
        @Override
        public void onCallStateChanged(int state, String incomingNumber) {
            super.onCallStateChanged(state, incomingNumber);
            switch(state){
                case TelephonyManager.CALL_STATE_RINGING:
                    //Disconnect the call here...
                    break;
                case TelephonyManager.CALL_STATE_OFFHOOK:
                    break;
                case TelephonyManager.CALL_STATE_IDLE:
                    break;
            }
        }
    };

    @Override
    public void onDestroy() {

    }
}

Remarque: lors de l'arrêt du service de ne pas foget pour supprimer l'auditeur et ajouter ces autorisations à votre fichier manifeste:

<uses-permission android:name="android.permission.READ_PHONE_STATE" />

et déconnecter l'appel du programme:

try{
    TelephonyManager manager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
    Class c = Class.forName(manager.getClass().getName());
    Method m = c.getDeclaredMethod("getITelephony");
    m.setAccessible(true);
    ITelephony telephony = (ITelephony)m.invoke(manager);
    telephony.endCall();
} catch(Exception e){
    Log.d("",e.getMessage());
}

Remarque: Ajoutez ce fichier pour déconnecter l'appel: http://dl.dropbox.com/u/31740476/ITelephony.aidl

Pour désactiver les touches dont vous avez besoin pour remplacer:

@Override
public boolean dispatchKeyEvent(KeyEvent event) {
    if(KeyEvent.KEYCODE_MENU == event.getKeyCode() || KeyEvent.KEYCODE_DPAD_LEFT==event.getKeyCode()
            || KeyEvent.KEYCODE_DPAD_DOWN==event.getKeyCode() || KeyEvent.KEYCODE_DPAD_RIGHT==event.getKeyCode()
            || KeyEvent.KEYCODE_DPAD_UP==event.getKeyCode() || KeyEvent.KEYCODE_DPAD_CENTER==event.getKeyCode()
            || KeyEvent.KEYCODE_BACK==event.getKeyCode())
    {
        return false;
    }
    return true;
}

Sur la touche d'Accueil, appuyez sur l'écran d'Accueil va venir, afin de surmonter ce problème, vous devez mettre en œuvre un service et là, vous avez besoin pour mettre en œuvre une infinie fil de relancer votre application comme ceci:

public class AppTrackingService extends Service {

    private RunnableThread thread;
    private Context ctx;

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    public void onCreate(){
        super.onCreate();
        ctx = AppTrackingService.this;
        thread = new RunnableThread();
    }

    public void onStart(Intent intent, int startid) {
        try{
            if(thread==null) thread = new RunnableThread();
            thread.startThread();
        }catch(Exception e){  }
    }

    class RunnableThread extends Thread {

        Handler back_handler = new Handler();
        boolean isContinue = false;

        public RunnableThread(){
            isContinue = false;
        }

        public void setIsContinue(boolean val){
            this.isContinue = val;
        }

        public void startThread(){
            isContinue = true;
            start();
        }

        public void run(){
            ActivityManager actMngr = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
            while(isContinue){
                try{
                //Maintain a boolean "isyourapprunning" to know if your app was running or not....
                    if(isyourapprunning){
                    String runningPkg = actMngr.getRunningTasks(1).get(0).topActivity.getPackageName();
                        if (!runningPkg.equals(ctx.getPackageName())){
                                launchApp(ctx.getPackageName());
                            }
                        Thread.sleep(2500);  //2.5 secs
                    }else{
                        isContinue = false;
                        stopSelf();
                    }

                }catch(Exception e){ }
            }//end of while loop
        }

        protected void launchApp(String packageName) {
            Intent mIntent = getPackageManager().getLaunchIntentForPackage(packageName);
            mIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            mIntent.addFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
            if (null != mIntent) {
                try {
                    startActivity(mIntent);
                } catch(Exception e) { }
            }
        }
    }
}

5voto

Zaki Choudhury Points 236

Vineet la solution fonctionne. Cependant, je pense qu'il nécessite deux plus d'autorisations que j'ai trouvé à partir de ici

Si les autorisations nécessaires sont

android.la permission.READ_PHONE_STATE, android.la permission.MODIFY_PHONE_STATE, android.la permission.CALL_PHONE

Bien que cela a fonctionné pour moi comme ça

<uses-permission android:name="android.permission.READ_PHONE_STATE"/>

<uses-permission android:name="android.permission.CALL_PHONE"/>

1voto

ligi Points 8318

vous pouvez également y jeter un coup d'œil: https://github.com/ligi/Setec-Astronomy désolé pour l'auto-plug sans honte mais nous avons des problèmes simmilaires là-bas ;-)

1voto

MDTech.us_MAN Points 193

@Vineet Shukla: L'autorisation READ_PHONE_STATE n'est pas suffisante pour le faire fonctionner. Vous avez également besoin de l'autorisation CALL_PHONE pour mettre fin à l'appel.

 <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.CALL_PHONE"/>
 

Le MODIFY_PHONE_STATE (comme l'a dit Zaki Choudhury) est une autorisation système et ne peut être utilisé que sur des appareils enracinés et n'est requis par aucune partie du code.

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