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();
}
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? –
Cosa fa 'MyBootReceiver.onReceive()' fare? –
Aggiunta classe ricevitore broadcast. – NYCHippo