2011-08-19 23 views
33

Telefonlara kurduğumuz ve telefonları belirli bir süre için kullanıcılara ödünç aldığımız bir programımız var. Telefonların sadece bizim uygulamamızın çalışması için kullanılmasını istiyoruz (telefon yok, oyun yok, hiç bir şey yok). Telefonlar köklenecek.Android: Telefonun tam kontrolünü ele almak (kiosk modu) mümkün mü? Nasıl?

Yani işler ihtiyacımız: Tam ekranda

  • Run, başka bir şey görünür olacaktır
  • Ev düğmesi ve diğer cihaz düğmeleri çalışmayacaktır
  • başlangıçta
  • üzerinde otomatik olarak çalışır Bizim app

"Hacker kanıtı" olmak zorunda değildir, ancak ortalama kullanıcının cihazla uğraşmasını önlemek için yeterli olmalıdır.

Bu mümkün mü? Symbian & Windows Mobile üzerinde benzer şeyler yaptım ama Android'de bu şeylerle çok fazla deneyimim yok. Bu nasıl başarılabilir?

GÜNCELLEME 2015: tek bir telefon satıcıya uygulamanızı sınırlama sakıncası yoksa Samsung Eğer telefon köklendirme olmadan çok daha kolay kiosk modu ve başarmak sağlayan KNOX SDK tanıttı. Ayrıntılar için bkz .: https://seap.samsung.com/developer/sdk/knox-standard-android

cevap

47

Evet, ancak Home key ve end call key davranışlarını kontrol edemezsiniz.

Tüm ekran için bildirim dosyasında etkinlik etiketine android:theme="@android:style/Theme.NoTitleBar.Fullscreen" ekleyin.

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

    } 

    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() { 

    } 
} 

Not:

<uses-permission android:name="android.permission.READ_PHONE_STATE" /> 
: hizmetini durdurma dinleyici kaldırmak ve manifest dosyasında bu izinleri eklemek için foget vermemekle birlikte

telefon görüşmeleri dinlemeye ihtiyacım gelen aramayı devre dışı bırakmak için

ve programlı çağrıyı kesmek:

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

Not: Bu f ekle sen de öyle Bir hizmeti uygulamak gerekir bunun üstesinden oraya, Ev anahtar basın On Ana ekran gelecektir

@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; 
} 

: http://dl.dropbox.com/u/31740476/ITelephony.aidl

geçersiz kılmak için gereken tuşları devre dışı bırakmak için: arama bağlantısını kesmek için Logged böyle uygulamanızı yeniden başlatmasını bir sonsuz iplik uygulamak gerekir:

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) { } 
      } 
     } 
    } 
} 

DÜZENLEME

Aramaları bitirmek muktedir aşağıdaki iznini eklemeniz gerekir:

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

Ve aşağıdaki AIDL dosyasını kullanabilirsiniz: https://github.com/ligi/Setec-Astronomy: Ayrıca bu işe bir göz atabilirsiniz

package com.android.internal.telephony; 

/** 
* Interface used to interact with the phone. Mostly this is used by the 
* TelephonyManager class. A few places are still using this directly. 
* Please clean them up if possible and use TelephonyManager instead. 
* 
* {@hide} 
*/ 
interface ITelephony { 
    /** 
    * End call if there is a call in progress, otherwise does nothing. 
    * 
    * @return whether it hung up 
    */ 
    boolean endCall(); 

    /** 
    * Silence the ringer if an incoming call is currently ringing. 
    * (If vibrating, stop the vibrator also.) 
    * 
    * It's safe to call this if the ringer has already been silenced, or 
    * even if there's no incoming call. (If so, this method will do nothing.) 
    * 
    * TODO: this should be a oneway call too (see above). 
    *  (Actually *all* the methods here that return void can 
    *  probably be oneway.) 
    */ 
    void silenceRinger(); 
} 
+0

.aidl dosyasını kullanamıyorum. Problem var mı? –

+0

projenize .aidl dosyasını eklemeniz gerekiyor. Sorun ne oluyor? Bu bağlantıya bakın: http://developer.android.com/guide/developing/tools/aidl.html –

+2

Bu dosyayı kaynak projeme ekledim, ancak ITelephony'nin tanımlanmadığı ITelephony telefon = (ITelephony) m.invoke (yönetici) satırında hata veriyor. –

1

utanmaz kendinden fişi için özür dileriz ama simmilar problemlerimiz var ;-)

+1

+1. bana biraz yardımcı oluyor! şükran çatal. Böyle yararlı bilgileri paylaşmaya devam edin. Senin gibi geliştiriciler tam olarak ne olduğunu açık kaynak yaparlar. – skygeek

+0

Eğer google pazarını engeller ve birisi yarış gibi herhangi bir oyun oynuyor ve google pazarına kadar yazdığınız kodu yazdığınız kodun ana başlatıcıya çıkmak için iyi çalışıyor varsayalım, ama oyunu yeniden açtığınızda son inapp satın alma ekranını gösteren bir sorun var Kod bunu öldürdüğünde ayrıldım. Bu sorunu çözmek için bana yardımcı olabilir misiniz ?? – skygeek

5

Vineet'in çözüm çalışmaları. Ancak ben Yani gerekli izinler aşağıda bu i here

öğrendim iki fazla izin gerektirir düşünüyorum

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

bu

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

gibi benim için çalıştı rağmen 10

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

1

@Vineet Shukla: READ_PHONE_STATE izni çalışması için yeterli değildir. Aramayı sonlandırmak için CALL_PHONE izne de ihtiyacınız vardır.

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

MODIFY_PHONE_STATE (Zaki Choudhury tarafından bahsedilen gibi), bir sistem izni ve sadece köklü cihazlarda kullanılabilir ve herhangi bir kod parçası tarafından gerekli değildir.