2013-05-06 12 views
5

Sto scrivendo un'app per Android con due componenti principali: un servizio che si avvia all'avvio e una GUI che desidero avviare solo all'avvio manuale tramite la sua icona, non quando il dispositivo si avvia. So come avviare il servizio al momento dell'avvio, ma avvia anche la GUI al momento dell'avvio, che non desidero.Android: avviare il servizio all'avvio, ma non avviare la GUI

Presumo che questo abbia qualcosa a che fare con le impostazioni nel mio manifest, ma nonostante abbia provato un certo numero di cose, non ho capito come impedire alla GUI di partire anche all'avvio.

Devo aggiungere che non avvio la GUI al momento del boot al livello di programmazione. Faccio riferimento alle variabili pubbliche statiche all'interno della classe di attività della GUI, ma non faccio alcuna chiamata di metodo o invio alcun intento all'attività della GUI.

Ecco il mio manifesto. Che cosa sto facendo di sbagliato? Grazie mille.

<?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> 

Aggiunta classe ricevitore trasmissione:

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

Aggiunta classe di servizio ...

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

INFO

ho capito qualcosa di quello che sta accadendo. Prima di tutto, mi sono sbagliato a dire che il mio MainActivity stava iniziando. Dopo un debug più dettagliato, vedo che non sono stati chiamati i suoi metodi onCreate() e onResume(). Tuttavia, la vista dell'app era visibile: una schermata nera con il nome dell'app e l'icona predefinita. Inizialmente l'ho scambiato per un'indicazione di un avvio completo.

Questo, naturalmente, solleva la questione del motivo per cui quella vista si è presentata all'avvio, in primo luogo. Ho alcune informazioni su questo, anche se sono ancora confuso su cosa sta succedendo. Ho rimosso il metodo onCreate() della classe RegisterActivity che viene richiamata da MyBootService. Quando viene chiamato this.getIntent(), la vista dell'applicazione viene visualizzata all'avvio. Quando this.getIntent() viene commentato, la vista dell'applicazione non viene visualizzata all'avvio.

Si noti che questo è onCreate() della classe RegisterActivity, NON di MainActivity.

Qualcuno di voi sa cosa potrebbe causare la visualizzazione dell'applicazione quando viene visualizzato this.getIntent()?

@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

inserisci il codice del destinatario della tua trasmissione. Sei sicuro di non aver creato un intento per quell'attività all'interno del tuo codice ricevente? –

+0

Cosa fa 'MyBootReceiver.onReceive()' fare? –

+0

Aggiunta classe ricevitore broadcast. – NYCHippo

risposta

3

Penso che quello che state vedendo è l'anteprima utilizzato da Android per rendere l'avvio app sembra più veloce. Questa anteprima è basata sul tema della tua attività..

Prova a impostare un tema personalizzato per il tuo RegisterActivity che sembra più simile al risultato finale.Per esempio, se la vostra attività è una finestra di dialogo, creare un tema che si estende Theme.Dialog o Theme.Light.Dialog

è possibile ottenere ulteriori informazioni su questo post del blog da Cyril Mottier: Android App Launching Made Gorgeous


EDIT: cambiato in realtà risposta la questione

+0

Sì, ma RegistrationActivity non è il problema. È l'altra attività, chiamata MainActivity. Alcune variabili pubbliche statiche all'interno di MainActivity sono referenziate all'interno di RegistrationActivity, ma non vengono chiamati metodi di MainActivity, né invio alcun Intenti a MainActivity. – NYCHippo

+0

"MyBootReceiver si avvia correttamente all'avvio e richiama correttamente MyBootService. Al momento opportuno, MyBootService richiama RegisterActivity." Il suo problema è il ** MainActivity ** che inizia. –

+0

Grazie, e la tua risposta ha fornito la chiave. Vedi la mia "Risposta reale, reale" per una spiegazione di come ho risolto questo. – NYCHippo

0

il reale, risposta reale

A causa dell'aiuto e del feedback, ho finalmente capito il mio problema e l'ho risolto:

Ho sbagliato a utilizzare un'attività in primo luogo (la mia classe RegisterActivity), perché non voglio il funzionalità che originariamente inserivo in RegisterActivity per essere associata a una GUI. A causa dell'inesperienza con il modello Android e della mancanza di una lettura della documentazione sufficiente, non mi sono reso conto che Activity ha sempre una vista associata ad esso.

Ora che lo so, ho refactored la mia app in modo che tutte le funzionalità precedentemente in RegisterActivity siano state spostate su MyBootService. Ora, all'avvio non appare nessuna vista e la mia app fa quello che voglio.

Grazie a tutti per il vostro aiuto e la vostra pazienza.

Problemi correlati