2013-05-06 10 views
5

Ich schreibe eine Android-App, die zwei Hauptkomponenten hat: einen Dienst, der beim Booten startet, und eine GUI, die ich nur starten möchte, wenn ich manuell starte es über sein Symbol, nicht wenn das Gerät bootet. Ich weiß, wie man den Dienst beim Booten startet, aber es startet auch die GUI beim Booten, was ich nicht will.Android: Dienst beim Booten starten, aber GUI nicht starten

Ich nehme an, dass dies etwas mit den Einstellungen in meinem Manifest zu tun hat, aber trotz einiger Versuche habe ich nicht herausgefunden, wie man verhindert, dass die GUI auch beim Booten startet.

Ich sollte hinzufügen, dass ich die GUI nicht programmatisch beim Booten starten. Ich referenziere statische öffentliche Variablen innerhalb der Aktivitätsklasse der GUI, aber ich mache keine Methodenaufrufe oder sende keine Absichten an die Aktivitäten der GUI.

Hier ist mein Manifest. Was mache ich falsch? Vielen Dank.

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
     package="my.package.name" 
     android:versionCode="0" 
     android:versionName="0.1.0"> 

    <uses-sdk 
     android:minSdkVersion="11" 
     android:targetSdkVersion="17"/> 

    <uses-permission android:name="android.permission.RECEIVE_SMS"/> 
    <uses-permission android:name="android.permission.READ_SMS"/> 
    <uses-permission android:name="android.permission.WRITE_SMS"/> 
    <uses-permission android:name="android.permission.SEND_SMS"/> 
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/> 
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 
    <uses-permission android:name="android.permission.INTERNET" /> 
    <uses-permission android:name="android.permission.GET_ACCOUNTS" /> 
    <uses-permission android:name="android.permission.WAKE_LOCK" /> 
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 
    <uses-permission android:name="android.permission.VIBRATE" /> 
    <uses-permission android:name="android.permission.GET_ACCOUNTS" /> 
    <uses-permission android:name="android.permission.MANAGE_ACCOUNTS" /> 
    <uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" /> 
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> 

    <application android:icon="@drawable/icon" 
       android:label="@string/app_name" 
       android:allowBackup="true" > 

     <!-- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 
       I want MainActivity to only start when I 
       select its icon, NOT at boot time. However, 
       it always starts up at boot. 
      XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 
     --> 
     <activity 
      android:name=".MainActivity" 
      android:label="@string/app_name" 
      android:launchMode="singleTop"> 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 
       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 

     <!-- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 
       MyBootReceiver properly starts up at boot time, 
       and it properly invokes MyBootService. At 
       the appropriate time, MyBootService invokes 
       RegisterActivity. 
      XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 
     --> 
     <activity android:name=".RegisterActivity" 
        android:label="@string/app_name"> 
     </activity> 
     <receiver 
      android:name=".MyBootReceiver" 
      android:enabled="true" 
      android:exported="false"> 
      <intent-filter> 
       <action android:name="android.intent.action.BOOT_COMPLETED" /> 
       <category android:name="android.intent.category.DEFAULT"/> 
       <category android:name="my.package.name" /> 
      </intent-filter> 
     </receiver> 
     <service android:name=".MyBootService" /> 

    </application> 
</manifest> 

Hinzufügen von Rundfunkempfänger Klasse:

package my.package.name; 

import android.content.BroadcastReceiver; 
import android.content.Context; 
import android.content.Intent; 

public class MyBootReceiver extends BroadcastReceiver { 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     Intent bootIntent = new Intent(context, MyBootService.class); 
     bootIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
     context.startService(bootIntent); 
    } 
} 

Hinzufügen von Serviceklasse ...

package my.package.name; 

import java.util.ArrayList; 

import android.accounts.Account; 
import android.accounts.AccountManager; 
import android.accounts.AccountManagerCallback; 
import android.accounts.AccountManagerFuture; 
import android.app.Service; 
import android.content.Context; 
import android.content.Intent; 
import android.os.IBinder; 
import android.telephony.TelephonyManager; 

public class MyBootService extends Service { 

    private static final String GOOGLE_ACCOUNT_TYPE = "com.google"; 
    private static final String GOOGLE_ACCOUNT_FEATURE = "service_ah"; 

    private Context context = null; 

    @Override 
    public IBinder onBind(Intent intent) { 
     this.display("onBind"); 
     return (null); 
    } 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
    } 

    @Override 
    public void onStart(Intent intent, int startId) { 
     super.onStart(intent, startId); 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     super.onStartCommand(intent, flags, startId); 

     AccountManager am = AccountManager.get(this); 
     am.getAccountsByTypeAndFeatures(GOOGLE_ACCOUNT_TYPE, new String[]{GOOGLE_ACCOUNT_FEATURE}, 
       new AccountManagerCallback<Account[]>() { 
        @Override 
        public void run(AccountManagerFuture<Account[]> acclist) { 
         MyBootService parent = MyBootService.this; 
         Intent regIntent = new Intent(parent.getApplicationContext(), RegisterActivity.class); 
         try { 
          ArrayList<String> accountNameList = new ArrayList<String>(); 
          for (Account a: acclist.getResult()) { 
           accountNameList.add(a.name); 
          } 
          regIntent.putStringArrayListExtra("accountNames", accountNameList); 
          try { 
           TelephonyManager tmgr = (TelephonyManager) parent.getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE); 
           String phoneNo = tmgr.getLine1Number(); 
           regIntent.putExtra("phoneNumber", phoneNo); 
          } 
          catch (Throwable t) { 
          } 
         } 
         catch (Throwable t) { 
          // put error message here 
         } 
         regIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
         parent.startActivity(regIntent); 
        } 
       }, null); 

     return (START_STICKY); 
    } 

    @Override 
    public void onDestroy() { 
     this.display("onDestroy"); 
     super.onDestroy(); 
    } 
} 

MEHR INFO

dachte ich einige heraus, was los ist. Zuerst habe ich mich geirrt, dass meine MainActivity gestartet wurde. Bei detaillierteren Debuggen, ich sehe, dass sein onCreate() und onResume() Methoden wurden nicht genannt zu werden. Die Ansicht der App wurde jedoch angezeigt: ein schwarzer Bildschirm mit dem Namen der App und dem Standardsymbol. Ich habe das ursprünglich für einen Hinweis auf einen vollständigen Start gehalten.

Dies wirft natürlich die Frage auf, warum diese Ansicht auf Boot erschien, in erster Linie. Ich habe einige Informationen darüber, obwohl ich immer noch verwirrt bin, was vor sich geht. Ich abgespeckte die onCreate() Methode der RegisterActivity Klasse, die von MyBootService aufgerufen wird. Wenn this.getIntent() aufgerufen wird, wird die Ansicht der Anwendung beim Booten angezeigt. Wenn this.getIntent() Kommentar gesetzt ist, nach Ansicht der Anwendung zeigt nicht auf Booten.

Hinweis, dass dies onCreate() der RegisterActivity Klasse, NICHT von MainActivity.

Weiß einer von Ihnen, was dazu führen könnte, dass die Ansicht der Anwendung angezeigt wird, wenn this.getIntent() aufgerufen wird?

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    // If the following line is commented out, the 
    // application's view does not show up on boot; 
    // if the following line is not commented out, 
    // the application's view shows up. 

    Intent intent = this.getIntent(); 
} 
+0

senden Sie Ihren Broadcast-Empfängercode. Sind Sie sicher, dass Sie keine Absicht für diese Aktivität in Ihrem Empfängercode erstellen? –

+0

Was macht 'MyBootReceiver.onReceive()'? –

+0

Broadcast-Empfänger-Klasse hinzugefügt. – NYCHippo

Antwort

3

Ich denke, was Sie sehen, die Vorschau von Android verwendet wird, ist die App Startup scheint schneller zu machen. Diese Vorschau basiert auf dem Thema Ihrer Tätigkeit gemacht.

Versuchen Sie, ein eigenes Thema für Ihre RegisterActivity Einstellung, die wie das Endergebnis mehr sieht eng.Zum Beispiel, wenn Sie Ihre Aktivität ein Dialog ist, erstellen Sie ein Thema erstreckt Theme.Dialog oder Theme.Light.Dialog

Sie können weitere Informationen zu dieser Blog-Post von Cyril Mottier erhalten: Android App Launching Made Gorgeous


EDIT: geändert, um tatsächlich Antwort die Frage

+0

Ja, aber die RegistrationActivity ist nicht das Problem. Es ist die andere Aktivität, MainActivity genannt. Einige öffentliche statische Variablen innerhalb von MainActivity werden in RegistrationActivity referenziert, aber es werden keine Methoden von MainActivity aufgerufen, und auch keine Intents werden an MainActivity gesendet. – NYCHippo

+0

"MyBootReceiver startet ordnungsgemäß beim Systemstart und ruft MyBootService ordnungsgemäß auf. Zum richtigen Zeitpunkt ruft MyBootService RegisterActivity auf." Sein Problem ist der Beginn der ** MainActivity **. –

+0

Danke, und Ihre Antwort lieferte den Schlüssel. Siehe meine "Reale, tatsächliche Antwort" für eine Erklärung, wie ich das gelöst habe. – NYCHippo

0

THE REAL, IST ANTWORT

Wegen der Hilfe und Feedbacks, das ich hier ankam, dachte ich, endlich mein Problem und es gelöst:

ich eine Aktivität in erster Linie (meine RegisterActivity Klasse) bei der Verwendung falsch war, weil ich das nicht will Funktionalität, die ich ursprünglich in RegisterActivity eingegeben habe, um mit einer GUI verknüpft zu werden. Aufgrund der Unerfahrenheit mit dem Android-Modell und des Mangels an ausreichendem Dokumentationsmaterial war mir nicht klar, dass Activity immer eine Ansicht zugeordnet hat.

Nun, da ich das weiß, habe ich meine App so umgestaltet, dass die gesamte Funktionalität von RegisterActivity in MyBootService verschoben wurde. Jetzt erscheint beim Booten keine Ansicht und meine App macht was ich will.

Vielen Dank an alle für Ihre Hilfe und Geduld.