Урок 100. Service. IntentService. Foreground. Автозагрузка сервиса

Обсуждение уроков
BlkDem
Сообщения: 2
Зарегистрирован: 08 ноя 2012, 06:22

Re: Урок 100. Service. IntentService. Foreground. Автозагруз

Сообщение BlkDem » 13 ноя 2012, 05:14

У меня, конечно, получилось. Но тема до конца не раскрыта.

Код: Выделить всё

notif.flags |= Notification.FLAG_FOREGROUND_SERVICE;
startForeground(1, notif);

Аватара пользователя
powercat
Сообщения: 508
Зарегистрирован: 20 июл 2012, 11:31

Re: Урок 100. Service. IntentService. Foreground. Автозагруз

Сообщение powercat » 20 ноя 2012, 14:50

А можно пояснить? Взял из Инета пример

<receiver android:name=".MyReceiver " android:enabled="true" android:exported="false">

Что тут значит enable и exported?

И что вообще сюда можно засунуть и для чего?

Аватара пользователя
damager82
Администратор
Сообщения: 1383
Зарегистрирован: 07 янв 2012, 11:32
Контактная информация:

Re: Урок 100. Service. IntentService. Foreground. Автозагруз

Сообщение damager82 » 21 ноя 2012, 10:22

powercat писал(а):А можно пояснить? Взял из Инета пример

<receiver android:name=".MyReceiver " android:enabled="true" android:exported="false">

Что тут значит enable и exported?

И что вообще сюда можно засунуть и для чего?
Тут смотрели? http://developer.android.com/guide/topi ... ement.html

android:enabled - походу и есть enabled, т.е. будет работать или нет
android:exported поинтереснее, я так понял эта настройка управляет тем, что ресивер будет/не будет получать бродкасты извне, т.е. из других приложений
Добро пожаловать на форум сайта StartAndroid
ИзображениеИзображение

Andy_ua
Сообщения: 21
Зарегистрирован: 06 июл 2012, 17:23

Re: Урок 100. Service. IntentService. Foreground. Автозагруз

Сообщение Andy_ua » 02 фев 2013, 15:38

вопрос по поводу автозагрузкт сервиса
почему нельзя сразу прописать в интенет фильтре сервиса в манифесте
<action android:name="android.intent.action.BOOT_COMPLETED" />
?

Аватара пользователя
damager82
Администратор
Сообщения: 1383
Зарегистрирован: 07 янв 2012, 11:32
Контактная информация:

Re: Урок 100. Service. IntentService. Foreground. Автозагруз

Сообщение damager82 » 05 фев 2013, 12:50

Andy_ua писал(а):вопрос по поводу автозагрузкт сервиса
почему нельзя сразу прописать в интенет фильтре сервиса в манифесте
<action android:name="android.intent.action.BOOT_COMPLETED" />
?
Хелп сообщает, что это только для бродкастов фишка:
Broadcast Action: This is broadcast once, after the system has finished booting.
Добро пожаловать на форум сайта StartAndroid
ИзображениеИзображение

G_O_R
Сообщения: 57
Зарегистрирован: 13 ноя 2012, 08:02

Re: Урок 100. Service. IntentService. Foreground. Автозагруз

Сообщение G_O_R » 05 фев 2013, 17:08

Помогите с написанием сервиса. нужно чтобы сервис сам запустился и не умирал. был в автозагрузке. при остановке сразу же запустился. еще проверка интернет включен или нет и нахождение gps координат. при запуске на эмуляторе нет сервиса. но после запуска запускается сервис gps/ вот код программы. вроде из книг и статей ставил все но не работает. если кто может подскажите как надо.

package com.sample.family_safety;


import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;


public class FAMILY_SAFETY extends Service {
// FamilySafety fSafety;


@Override
public void onCreate() {
// инициализация службы при создании

startService(new Intent(this, FAMILY_SAFETY.class));

}

@Override
public IBinder onBind(Intent intent) {
// действия при связывании клиента со службой
return null;
}



@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// действия при запуске .службы
if ((flags & START_FLAG_RETRY) == 0) {
// TODO Если это повторный запуск, выполнить какие-то действия.
}
else {
// TODO Альтернативные действия в фоновом режиме.
}
return Service.START_STICKY;
}





/////////////////////////////////////////////////////////////
// получение gps координат

LocationManager locationManager;
String context = Context.LOCATION_SERVICE;
locationManager = (LocationManager)getSystemService(context);
String provider = LocationManager.GPS_PROVIDER;
Location location =
locationManager.getLastKnownLocation(provider);
updateWithNewLocation(location);
}
private void updateWithNewLocation(Location location) {}

String latLongString;
// TextView myLocationText;
myLocationText = findViewById(R.id.myLocationText);
if (location != null) {
double lat = location.getLatitude();
double lng = location.getLongitude();
latLongString = "Lat:" + lat + "\nLong:" + lng;
} else {
latLongString = "No location found";
}
myLocationText.setText("Your Current Position is:\n" +
latLongString);

}


///////////////////////////////////////////////////////////////////
// обновление данных gps каждый 10 минут или 10 метров

String provider = LocationManager.GPS_PROVIDER;
int t = 3000000; // миллисекунды
int distance = 10; // meters
LocationListener myLocationListener = new LocationListener() {
public void onLocationChanged(Location location) {
// Обновите приложение, основываясь на данных местоположения.
}
public void onProviderDisabled(String provider){
// Обновите приложение, если источник отключен.
}
public void onProviderEnabled(String provider){
// Обновите приложение, если источник включен.
}
public void onStatusChanged(String provider, int status,
Bundle extras){
// Обновите приложение, если состояние аппаратного обеспечения
источника изменилось.
}
};
locationManager.requestLocationUpdates(provider, t, distance,
myLocationListener);

///////////////////////////////////////////////////////////////////////////
// проверка состояния интернета(вкл/выкл)

public boolean isOnline() {
ConnectivityManager cm = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo nInfo = cm.getActiveNetworkInfo();
if (nInfo != null && nInfo.isConnected()) {
Log.v("status", "ONLINE");
return true;
}
else {
Log.v("status", "OFFLINE");
return false;
}
}

//////////////////////////////////////////////////////////////////////////////////////
// добавление сервиса в автозагрузку

public class MyBroadReceiv extends BroadcastReceiver {

final String LOG_TAG = "myLogs";

public void onReceive(Context context, Intent intent) {
Log.d(LOG_TAG, "onReceive " + intent.getAction());
context.startService(new Intent(context, FAMILY_SAFETY.class));
}
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
// повышение приоритета сервиса, чтобы система не убиывала


private static final Class<?>[] mSetForegroundSignature = new Class[] {
boolean.class};
private static final Class<?>[] mStartForegroundSignature = new Class[] {
int.class, Notification.class};
private static final Class<?>[] mStopForegroundSignature = new Class[] {
boolean.class};

private NotificationManager mNM;
private Method mSetForeground;
private Method mStartForeground;
private Method mStopForeground;
private Object[] mSetForegroundArgs = new Object[1];
private Object[] mStartForegroundArgs = new Object[2];
private Object[] mStopForegroundArgs = new Object[1];

void invokeMethod(Method method, Object[] args) {
try {
method.invoke(this, args);
} catch (InvocationTargetException e) {
// Should not happen.
Log.w("ApiDemos", "Unable to invoke method", e);
} catch (IllegalAccessException e) {
// Should not happen.
Log.w("ApiDemos", "Unable to invoke method", e);
}
}

/**
* This is a wrapper around the new startForeground method, using the older
* APIs if it is not available.
*/
void startForegroundCompat(int id, Notification notification) {
// If we have the new startForeground API, then use it.
if (mStartForeground != null) {
mStartForegroundArgs[0] = Integer.valueOf(id);
mStartForegroundArgs[1] = notification;
invokeMethod(mStartForeground, mStartForegroundArgs);
return;
}

// Fall back on the old API.
mSetForegroundArgs[0] = Boolean.TRUE;
invokeMethod(mSetForeground, mSetForegroundArgs);
mNM.notify(id, notification);
}

/**
* This is a wrapper around the new stopForeground method, using the older
* APIs if it is not available.
*/
/*
void stopForegroundCompat(int id) {
// If we have the new stopForeground API, then use it.
if (mStopForeground != null) {
mStopForegroundArgs[0] = Boolean.TRUE;
invokeMethod(mStopForeground, mStopForegroundArgs);
return;
}

// Fall back on the old API. Note to cancel BEFORE changing the
// foreground state, since we could be killed at that point.
mNM.cancel(id);
mSetForegroundArgs[0] = Boolean.FALSE;
invokeMethod(mSetForeground, mSetForegroundArgs);
}

*/
@Override
public void onCreate() {
mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
try {
mStartForeground = getClass().getMethod("startForeground",
mStartForegroundSignature);
mStopForeground = getClass().getMethod("stopForeground",
mStopForegroundSignature);
return;
} catch (NoSuchMethodException e) {
// Running on an older platform.
mStartForeground = mStopForeground = null;
}
try {
mSetForeground = getClass().getMethod("setForeground",
mSetForegroundSignature);
} catch (NoSuchMethodException e) {
throw new IllegalStateException(
"OS doesn't have Service.startForeground OR Service.setForeground!");
}
}

@Override
public void onDestroy() {
// Make sure our notification is gone.
stopForegroundCompat(R.string.foreground_service_started);
}


////////////////////////////////////////////////////////////////////////////////////////////////////
}

}

Аватара пользователя
neoksi
Сообщения: 712
Зарегистрирован: 26 июл 2012, 10:42
Контактная информация:

Re: Урок 100. Service. IntentService. Foreground. Автозагруз

Сообщение neoksi » 05 фев 2013, 19:56

G_O_R
Первое, что хочу сказать, оформляйте код с помощью соответствующих bb тегов, а то неудобно читать. Я лично, как и многие тут, просто не читаю такой код.

Второе, по существу вопроса, вам необходимо создать броудкаст ресивер, который поймает сообщение о запуске устройства и запустит сам сервис. При создании сервиса, вам необходимо его отправить в Foreground, тогда система не сможет его прибить.

Аватара пользователя
Mikhail_dev
Сообщения: 2386
Зарегистрирован: 09 янв 2012, 14:45
Откуда: Самара

Re: Урок 100. Service. IntentService. Foreground. Автозагруз

Сообщение Mikhail_dev » 05 фев 2013, 23:37

нужно чтобы сервис сам запустился. был в автозагрузке.

Код: Выделить всё

public class BootUpReceiver extends BroadcastReceiver{
	
    @Override
    public void onReceive(Context context, Intent intent) {
            //для Activity 
//            Intent ativivtyIntent = new Intent(context, GPSSampleActivity.class);  
//            ativivtyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//            context.startActivity(ativivtyIntent);  
          
//    	String mountState = Environment.getExternalStorageState();
//    	int tries = 7;
//    	do {
//    	    if (!mountState.equals(Environment.MEDIA_MOUNTED)) {
//    	        Log.i("BootUpReceiver", "External media present but not mounted. Waiting 7 seconds for mount...");
//    	        try {
//    	            Thread.sleep(1000); // sleep for a second
//    	        } catch (InterruptedException e) {
//    	            Log.w("BootUpReceiver", "Interrupted!");
//    	            break;
//    	        }
//    	        mountState = Environment.getExternalStorageState();
//    	    } else {
//    	        Log.i("BootUpReceiver", "External media mounted");
//    	        break;
//    	    }
//    	} while (--tries > 0);
    	
    	//для Service
    	Intent serviceIntent = new Intent(context, YourServiceName.class);
    	context.startService(serviceIntent);
    }
И в манифесте прописать

Код: Выделить всё

<application
...
        <receiver
            android:name="your.package.BootUpReceiver"
            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>
Но что-то мне кажется в манифесте многовато информации, но стоит так у меня.
Теперь о том, что делает закомментированный код в классе. Флешка не сразу монтируется, поэтому если нужна работа с флешкой, то стоит включить такую задержку. У меня в коде она до 7 секунд выставлена. Больше 10 не ставить! Иначе андроид убьет сервис просто так и вообще ничего не запустится.
при остановке сразу же запустился.

Код: Выделить всё

Листинг 9.7. Повышение приоритета  для Сервиса
int NOTIFICATION_ID = 1;
Intent intent = new Intent(this, MyActivity.class);
PendingIntent pi = PendingIntent.getActivity(this, 1, intent, 0));
Notification notification = new Notification(R.drawable.icon, "Running in the Foreground", System.currentTimeMillis());
notification.setLatestEventInfo(this, "Title", "Text", pi);
notification.flags = notification.flags | Notification.FLAG_ONGOING_EVENT;
startForeground(NOTIFICATION_ID, notification);
за подробностями сюда, что это за повышение и т.д.
http://src-code.net/naznachenie-priorit ... -servisov/
Вкратце скажу, что сервис при падении и выгрузке будет сам подниматься, ибо у него приоритет высокий. Ну лично у меня поднимается почти моментально и почти всегда висит в системе.
еще проверка интернет включен или нет

Код: Выделить всё

    private void createInternetStatusReceiver() {
    	
    	networkStateReceiver = new BroadcastReceiver() {
			@Override
			public void onReceive(Context context, Intent intent) {
				try { 
					if ( ( (connectManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE)!=null)
							&& (connectManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState() == NetworkInfo.State.CONNECTED) ) 
						|| ( (connectManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI)!=null)
							&& (connectManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI  ).getState() == NetworkInfo.State.CONNECTED) ) )  
								internetAvailable = true;
								else 
									internetAvailable = false;
				} catch (Exception e) { 
					internetAvailable = true;
				}
			}
		};
    	IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
    	registerReceiver(networkStateReceiver, filter);
    }
internetAvailable это булева переменная. По дефолту ставь false. При старте сервиса запусти createInternetStatusReceiver();
и нахождение gps координат.
Смотреть LocationListener

И да, на счет кода верно заметили. Я тоже его не читал, ибо не читабельно. Используйте тег code
Последний раз редактировалось Mikhail_dev 06 фев 2013, 10:02, всего редактировалось 1 раз.

G_O_R
Сообщения: 57
Зарегистрирован: 13 ноя 2012, 08:02

Re: Урок 100. Service. IntentService. Foreground. Автозагруз

Сообщение G_O_R » 06 фев 2013, 08:42

у меня в манифесте написано так
<service
android:enabled="true"
android:name=".FAMILY_SAFETY">
</service>
<receiver android:name="FAMILY_SAFETY$MyBroadReceiv">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>

это из урока тут взял. его поменять?

Аватара пользователя
Mikhail_dev
Сообщения: 2386
Зарегистрирован: 09 янв 2012, 14:45
Откуда: Самара

Re: Урок 100. Service. IntentService. Foreground. Автозагруз

Сообщение Mikhail_dev » 06 фев 2013, 08:52

>receiver android:name="FAMILY_SAFETY$MyBroadReceiv">
Это что, внутренний класс?
>android:name=".FAMILY_SAFETY
Это что?

G_O_R
Сообщения: 57
Зарегистрирован: 13 ноя 2012, 08:02

Re: Урок 100. Service. IntentService. Foreground. Автозагруз

Сообщение G_O_R » 06 фев 2013, 09:03

поставил ваш вариант. но пишет что нужен $ место .

<receiver
android:name="FAMILY_SAFETY$BootUpReceiver"

может из аз апи. у меня последняя 17 стоит

G_O_R
Сообщения: 57
Зарегистрирован: 13 ноя 2012, 08:02

Re: Урок 100. Service. IntentService. Foreground. Автозагруз

Сообщение G_O_R » 06 фев 2013, 09:04

я когда создал сервис он сам все это прописал в манифесте.

receiver android:name="FAMILY_SAFETY$MyBroadReceiv">
а это я из урока сделал. тут урок добавление сервиса в автозагрузку

G_O_R
Сообщения: 57
Зарегистрирован: 13 ноя 2012, 08:02

Re: Урок 100. Service. IntentService. Foreground. Автозагруз

Сообщение G_O_R » 06 фев 2013, 09:06

можно вопрос глупый? как в эклипсе включить эти теги ну чтоб код читать нормально. я что то не могу найти.


и еще в манифесте нужно поставить что программа с интернетом взаимодействует. не знаю куда ставить. куда не ставлю ошибку выдает.

вот весь манифест

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.sample.family_safety"
android:versionCode="1"
android:versionName="1.0.0" >

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

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



<service
android:enabled="true"
android:name=".FAMILY_SAFETY">
</service>

<receiver
android:name="FAMILY_SAFETY$BootUpReceiver"

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>



</application>



</manifest>

Аватара пользователя
Mikhail_dev
Сообщения: 2386
Зарегистрирован: 09 янв 2012, 14:45
Откуда: Самара

Re: Урок 100. Service. IntentService. Foreground. Автозагруз

Сообщение Mikhail_dev » 06 фев 2013, 09:14

Доллар пишет правильно, ибо у вас MyBroadReceiv скорее всего это внутренний класс. который создан в другом классе. Он должен быть создан отдельно в проекте, ПАРАЛЛЕЛЬНО сервису.
как в эклипсе включить эти теги ну чтоб код читать нормально. я что то не могу найти.
какие теги? Подчеркивание переменных или что? Что делать он должен?

G_O_R
Сообщения: 57
Зарегистрирован: 13 ноя 2012, 08:02

Re: Урок 100. Service. IntentService. Foreground. Автозагруз

Сообщение G_O_R » 06 фев 2013, 09:52

а разница между апи большая??? а то у меня не распознает

Intent serviceIntent = new Intent(context, GPSService.class); вернее GPSService его нету. он предлагает или это
Intent serviceIntent = new Intent(context, GpsStatus.class);
или это

Intent serviceIntent = new Intent(context, GpsSatellite.class);

еще ругается на

public class FAMILY_SAFETY extends Service {

internetAvailable=false;

на internetAvailable пишет
Syntax error on token "internetAvailable", VariableDeclaratorId expected after this token

блин все время из за разниц апи не работает. из книги коды даже не работают. почему нет поддержка старой версий

Аватара пользователя
Mikhail_dev
Сообщения: 2386
Зарегистрирован: 09 янв 2012, 14:45
Откуда: Самара

Re: Урок 100. Service. IntentService. Foreground. Автозагруз

Сообщение Mikhail_dev » 06 фев 2013, 10:01

Блин, это опечатка. Там должно быть естественно название твоего сервиса (FAMILY_SAFETY). Это раз. Второе. Никто не пишет такие названия классов никогда.
Названия классов пишутся с большой буквы - NewClass
Названия переменных всегда пишутся с маленькой буквы - newVariable
Названия констант пишутся всегда заглавными, с разделением на знаки подчеркивания - NEW_CONSTANT
Т.е. у тебя название сервиса (а он есть и класс) ассоциируется с названием константы

GPSService - это мой класс. Я случайно забыл сменить название.
P.S. советую почитать азы Java (Хорстманн java основы том 1)

И у меня API 7. Ниже него книги не пишут. Я имел дело с 6 книгами, нигде ниже не было. Дело не в API. Ищи ошибки

G_O_R
Сообщения: 57
Зарегистрирован: 13 ноя 2012, 08:02

Re: Урок 100. Service. IntentService. Foreground. Автозагруз

Сообщение G_O_R » 06 фев 2013, 11:16

вроде разобрался. если у программы нет форм вообще, то как запустить сервис при установке??? обычная программа при тесте в эмуляторе сразу после установки запускался. это не запускается. ошибок не выдает. выдает это

[2013-02-06 15:14:36 - FAMILY_SAFETY] ------------------------------
[2013-02-06 15:14:36 - FAMILY_SAFETY] Android Launch!
[2013-02-06 15:14:36 - FAMILY_SAFETY] adb is running normally.
[2013-02-06 15:14:36 - FAMILY_SAFETY] No Launcher activity found!
[2013-02-06 15:14:36 - FAMILY_SAFETY] The launch will only sync the application package on the device!

[2013-02-06 15:14:36 - FAMILY_SAFETY] Performing sync
[2013-02-06 15:14:36 - FAMILY_SAFETY] Automatic Target Mode: using existing emulator 'emulator-5556' running compatible AVD '13'
[2013-02-06 15:14:39 - FAMILY_SAFETY] Application already deployed. No need to reinstall.
[2013-02-06 15:14:39 - FAMILY_SAFETY] \FAMILY_SAFETY\bin\FAMILY_SAFETY.apk installed on device
[2013-02-06 15:14:39 - FAMILY_SAFETY] Done!

Аватара пользователя
Mikhail_dev
Сообщения: 2386
Зарегистрирован: 09 янв 2012, 14:45
Откуда: Самара

Re: Урок 100. Service. IntentService. Foreground. Автозагруз

Сообщение Mikhail_dev » 06 фев 2013, 22:15

Честно не знаю. Я не задавался вопросом как ставить только сервис, без активити (формы). Можешь сделать активность, её поставить как главную, но в бут загрузке стартовать сразу сервис. Но тогда будет видна установка приложения. Наверное именно по этой причине и нужна она, активность

G_O_R
Сообщения: 57
Зарегистрирован: 13 ноя 2012, 08:02

Re: Урок 100. Service. IntentService. Foreground. Автозагруз

Сообщение G_O_R » 07 фев 2013, 10:33

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

Аватара пользователя
neoksi
Сообщения: 712
Зарегистрирован: 26 июл 2012, 10:42
Контактная информация:

Re: Урок 100. Service. IntentService. Foreground. Автозагруз

Сообщение neoksi » 18 апр 2013, 04:23

Тут думал, ломал голову, над очередностью вызовов сервиса в отдельном процессе. Гуглил долго, потом залез в статью и прочитал про IntentService, пара строк и все встало на свои места.
Спасибо автору за такое понятное и хорошее изложение материала =).

Ответить