Как заставить Android apk запускаться после установки (перезагрузки)?

Здравствуйте, я пытаюсь запустить свое приложение для Android (у него нет пользовательского интерфейса, оно просто должно быть фоновой службой) при его установке или, по крайней мере, при перезагрузке устройства. Вот моя работа на данный момент, у кого-нибудь есть идеи, почему он не запускается при установке apk и перезагрузке устройства?

Файл манифеста Android:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="gitlab.project" >
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application android:label="@string/app_name" >
    <activity
        android:name="gitlab.project.MainActivity"
        android:label="@string/app_name"
        android:theme = "@android:style/Theme.NoDisplay">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
    </activity>

    <receiver
            android:name="gitlab.project.AutoStart"
            android:enabled="true"
            android:permission="android.permission.RECEIVE_BOOT_COMPLETED" >
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </receiver>
    <service android:name="gitlab.project.AlphaService"
             android:enabled="true"
             android:exported="true" />
</application>
</manifest>

Основная деятельность:

public class MainActivity extends Activity {

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

    Intent intent = new Intent(this, AlphaService.class);
    this.startService(intent);
}
}

АльфаСервис:

public class AlphaService extends Service implements
    GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {

private Profiler profiler;
private AlphaApiClient alphaApiClient;
private GoogleApiClient googleApiClient;
private int batteryHealth;

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

@Override
public int onStartCommand(final Intent intent, int flags, int startId) {
    batteryHealth = intent.getIntExtra(BatteryManager.EXTRA_HEALTH, 2);

    if (googleApiClient == null) {
        googleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
    }
    googleApiClient.connect();

    return Service.START_STICKY;
}

@Override
public void onConnected(Bundle connectionHint) {
    ProcService procService = new DefaultProcService();
    SystemInformationService systemInformationService = new SystemInformationService(googleApiClient, getContentResolver());
    profiler = new Profiler(procService, systemInformationService);
    alphaApiClient = new AlphaApiClient(getString(R.string.USERNAME), getString(R.string.PASSWORD));
    Thread thread = new Thread(new Runnable(){
        @Override
        public void run() {
            Log.d("Alpha service", "Profiling system info...");
            AndroidSystem androidSystem = profiler.profile(batteryHealth);
            String url = getString(R.string.API_URL);
            alphaApiClient.doPostRequest(androidSystem, url);
        }
    });
    thread.start();

    //Stop service once it finishes its task
    stopSelf();
}

@Override
public void onConnectionSuspended(int i) {

}

@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

}

@Override
public void onDestroy() {
    AlarmManager alarm = (AlarmManager)getSystemService(ALARM_SERVICE);
    alarm.set(
            AlarmManager.RTC_WAKEUP,
            System.currentTimeMillis() + (4000 * 60 * 60),
            PendingIntent.getService(this, 0, new Intent(this, AlphaService.class), 0)
    );
}
}

Автозапуск (вещательный приемник):

public class AutoStart extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
    Intent i = new Intent(context, MainActivity.class);
    i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    context.startActivity(i);

    context.startService(new Intent(context, AlphaService.class));
}
}

Есть идеи, почему мой фоновый сервис не запускается? Я могу запустить его с помощью adb, но не при попытке установить вручную с телефона/планшета. Любая помощь приветствуется.


comment
Приложение не будет запускать какие-либо службы или широковещательные приемники, если оно не находится в запущенном состоянии. Он находится в запущенном состоянии после запуска из лаунчера или через ADB. 1) Создайте действие, которое а) запустит вашу службу и б) отключит себя (заголовок stackoverflow.com/questions/17409907/). 2) Создайте приемник при загрузке (stackoverflow.com/questions/5290141/).   -  person Eugen Pechanec    schedule 11.10.2016
comment
В моем загрузочном приемнике AutoStart чего-то не хватает?   -  person Tuco    schedule 11.10.2016
comment
Почему вы останавливаете службу сразу после создания потока?   -  person Eugen Pechanec    schedule 11.10.2016
comment
Активность NoDisplay должна быть finish() до возврата onCreate().   -  person Eugen Pechanec    schedule 11.10.2016


Ответы (2)


Приложение не будет запускать какие-либо службы или широковещательные приемники, если оно не находится в запущенном состоянии. Он находится в запущенном состоянии после запуска из лаунчера или через ADB.

1) Создайте действие, которое а) запустит вашу службу и б) отключит себя (Как включать и отключать компонент?).

2) Создайте приемник при загрузке (Android BroadcastReceiver при запуске — продолжать работу, когда активность находится в фоновом режиме).


Ваш загрузочный приемник уже запускает службу, ему не нужно запускать активность. Активность нужно запускать только один раз после установки. Вот правильная установка.

AndroidManifest.xml

<activity
    android:name="gitlab.project.MainActivity"
    android:theme = "@android:style/Theme.NoDisplay">
    <intent-filter>
        <!-- Activity needs to show up in launcher. -->
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

<receiver
        android:name="gitlab.project.AutoStart"
        android:enabled="true">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
    </intent-filter>
</receiver>

AutoStart.java

public class AutoStart extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction()) {        
            context.startService(new Intent(context, AlphaService.class));
        }
    }
}
person Eugen Pechanec    schedule 10.10.2016

Я думаю, что проблема в вашем классе AutoStart:

Intent i = new Intent(context, MainActivity.class);

Ваша упаковка намерения с помощью MainActivity. Попробуйте изменить его на AlphaService.

person Karl Jamoralin    schedule 10.10.2016
comment
Я также попытался удалить первые 3 строки из моего класса AutoStart, чтобы он только запускал службу, и это тоже не сработало. Это то, что вы предлагаете? - person Tuco; 11.10.2016
comment
да. Хм. Я реализовал что-то подобное, может быть вам будет полезно проверить: github.com/karljamoralin/internet- измеритель скорости - person Karl Jamoralin; 11.10.2016