[英]Starting a service on android platform
我正在使用startService(Intent intent)方法啟動服務。 當我調用此函數時,它會到達服務的onCreate ,但無法調用onStartCommand 。 這是我的代碼-
@Override
public void onReceive(Context context, Intent intent) {
// Send a text notification to the screen.
Log.e("mudit", "Action: " + intent.getAction());
try {
ConnectivityManager connManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = connManager.getActiveNetworkInfo();
Log.e("mudit", "getType: " + info.getType());
Log.e("mudit", "isConnected: " + info.isConnected());
if (info.isConnected()) {
Intent newinIntent = new Intent(context, service.class);
context.startService(newinIntent);
}
} catch (Exception e) {
e.printStackTrace();
Intent newinIntent = new Intent(context, service.class);
context.stopService(newinIntent);
}
}
服務代碼-
package com.android.service;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.widget.Toast;
public class service extends Service {
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onCreate() {
super.onCreate();
Toast.makeText(this, "Service created...", Toast.LENGTH_LONG).show();
}
@Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, "Service destroyed ...", Toast.LENGTH_LONG).show();
}
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "onStartCommand...", Toast.LENGTH_LONG).show();
return 1;
}
}
Manifest.xml-
<receiver class=".AReceiver" android:name=".AReceiver">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
<service class=".service" android:name=".service"
android:enabled="true" android:icon="@drawable/icon">
</service>
- Unbound Service:無限期地在后台運行,即使已啟動的活動也隨服務結束。
- 綁定服務:它將一直運行到活動的生命周期。
活動可以通過
startService()
啟動服務,而將通過stopService()
停止。 如果活動要與服務進行交互,則可以使用bindService()
。首先調用
onCreate()
,然后使用活動提供的意圖數據調用onStartCommand
。
larsVogel 在這篇出色的文章中解決了這個問題(以及許多其他類似的問題)。
這就是我修改他的代碼以創建連接性接收器的方式,該連接器可以監視用戶何時連接到WIFI網絡,以便批量上傳使用情況數據:
在清單文件中,在您的</ application>的結束標記之前放置一個接收器並聲明一個服務:
<receiver android:name=".ConnMonitor" android:enabled="true">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
<service android:name=".BatchUploadGpsData" ></service>
</application>
在名為ConnMonitor.java的單獨文件中創建廣播接收器類(請取消注釋Log調用以能夠正確監視流)
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.util.Log;
public class ConnMonitor extends BroadcastReceiver {
private String TAG = "TGtracker";
@Override
public void onReceive(Context context, Intent intent) {
//String typeName = "";
String state = "";
int type = -1;
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService( Context.CONNECTIVITY_SERVICE );
NetworkInfo test = (NetworkInfo) connectivityManager.getActiveNetworkInfo();
//Log.v(TAG,"there has been a CONNECTION CHANGE -> "+intent.getExtras().get(ConnectivityManager.EXTRA_NETWORK_INFO));
try {
//typeName = test.getTypeName().toString();
type = test.getType();
state = test.getState().toString();
//Log.i(TAG,"type -> '"+typeName +"' state -> '"+state+"'" );
} catch (Exception e) {
//typeName = "null";
type = -1;
state = "DISCONNECTED";
//Log.i(TAG,"type -> error1 "+e.getMessage()+ " cause = "+e.getCause() );
}
if ( (type == 1) && (state == "CONNECTED") ) {
//Log.i(TAG, "I am soooo friggin uploadin on this beautiful WIFI connection ");
Intent batchUploadDataService = new Intent(context, BatchUploadGpsData.class);
context.startService(batchUploadDataService);
} else {
//Log.e(TAG,"NO FOUND MATCH type -> '"+typeName +"' state -> '"+state+"'" );
}
}
}
最后,創建服務BatchUploadGpsData.java,如下所示:
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
public class BatchUploadGpsData extends Service {
final String TAG = "TGtracker";
@Override
public void onCreate() {
Log.e(TAG, "here i am, rockin like a hurricane. onCreate service");
// this service tries to upload and terminates itself whether it is successful or not
// but it only effectively DOES anything while it is created
// (therefore, you can call 1 million times if uploading isnt done, nothing happens)
// if you comment this next line, you will be able to see that it executes onCreate only the first it is called
// the reason i do this is that the broadcast receiver is called at least twice every time you have a new change of connectivity state with successful connection to wifi
this.stopSelf();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//Log.i(TAG, "Received start id " + startId + ": " + intent);
Log.e(TAG, "call me redundant BABY! onStartCommand service");
// this service is NOT supposed to execute anything when it is called
// because it may be called inumerous times in repetition
// all of its action is in the onCreate - so as to force it to happen ONLY once
return 1;
}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
這不是偽代碼,這是實際代碼,已在android 2.2及更高版本上測試並運行。
測試該服務的方法是關閉並重新啟動android上的WIFI服務(關閉wifi路由器電源也可以解決問題)。 但是此代碼無法驗證您是否已有效連接到網絡。 為此,我建議您提出一個httpclient請求並檢查呼叫結果。 超出了本討論范圍。
注意:由於服務在與UI相同的線程上運行,因此我強烈建議您根據您的特定需求,在單獨的線程或asynctask上實現正確的上傳。 您也可以在單獨的線程上運行整個服務,但是盡管在這些情況下是標准做法,但這也不是本文討論的范圍。
首先,你應該添加@Override
之前onStartCommand(..)
然后確保為Android項目的目標是高於2.0。
我相信,您無法訪問服務中的任何UI組件,例如Dialog甚至Toast。
嘗試這個。
public int onStartCommand(Intent intent, int flags, int startId) {
/* Toast.makeText(this, "onStartCommand...", Toast.LENGTH_LONG).show();
return 1; */
Log.i("YourService", "Yes this works.");
}
首先,我建議您將班級命名為其他名稱,以免造成混亂。 其次,這是我明顯調用我擁有的服務的示例。 我在調用服務等時使用完整路徑名,因為它們與我的應用程序不在同一個程序包中。
<service android:name="com.public.service.UploaderService" android:icon="@drawable/vgbio"></service>
這是我服務等級的要點,
package com.public.service;
....
public class UploaderService extends Service{
....
}
第三,確保對onStartCommand()使用@Override。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.