启动Android平台服务 [英] Starting a service on android platform

查看:99
本文介绍了启动Android平台服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的 startService(意向意图)方式启动服务。当我调用这个函数到达的onCreate 服务,但它是无法调用的 onStartCommand 。这是我的code -

  @覆盖
公共无效的onReceive(上下文的背景下,意图意图){
    //发送文本通知到屏幕上。
    Log.e(mudit,动作+ intent.getAction());

    尝试 {
        ConnectivityManager connManager =(ConnectivityManager)上下文
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        的NetworkInfo信息= connManager.getActiveNetworkInfo();
        Log.e(mudit,的getType:+ info.getType());
        Log.e(mudit,isConnected:+ info.isConnected());
        如果(info.isConnected()){

            意图newinIntent =新的意图(背景下,service.class);
            context.startService(newinIntent);
        }

    }赶上(例外五){
        e.printStackTrace();
        意图newinIntent =新的意图(背景下,service.class);
        context.stopService(newinIntent);

    }

}
 

服务code -

 包com.android.service;

进口android.app.Service;
进口android.content.Intent;
进口android.os.IBinder;
进口android.widget.Toast;

公共类服务延伸服务{

    @覆盖
    公众的IBinder onBind(意向为arg0){
        // TODO自动生成方法存根
        返回null;
    }

    @覆盖
    公共无效的onCreate(){
        super.onCreate();
        Toast.makeText(本,服务创造......,Toast.LENGTH_LONG).show();
    }

    @覆盖
    公共无效的onDestroy(){
        super.onDestroy();
        Toast.makeText(本,服务破坏......,Toast.LENGTH_LONG).show();
    }

    公众诠释onStartCommand(意向意图,诠释标志,诠释startId){

        Toast.makeText(这一点,onStartCommand ......,Toast.LENGTH_LONG).show();
        返回1;
    }

}
 

的Manifest.xml -

 <接收器类=机器人AReceiver。:NAME =。AReceiver>
        <意向滤光器>
            <作用机器人:名称=android.net.conn.CONNECTIVITY_CHANGE/>
        &所述; /意图滤光器>
    < /接收器>
    <服务类=机器人的服务。:服务NAME =
        机器人:启用=真正的机器人:图标=@可绘制/图标>
    < /服务>
 

解决方案

larsVogel解决了这个问题(和许多其他类似)的在这个优秀的帖子

这是我如何适应他的code当用户连接到WIFI网络,以批量上传使用数据来创建一个连接接收器,监视器:

在清单文件,放置一个接收器,并为您和LT结束tag之前宣布的服务; /应用程序>:

 <接收机器人:ConnMonitor名称=机器人:启用=真正的>
        <意向滤光器>
            <作用机器人:名称=android.net.conn.CONNECTIVITY_CHANGE/>
        &所述; /意图滤光器>
    < /接收器>
    <服务机器人:名称=。BatchUploadGpsData>< /服务>

< /用途>
 

在一个称为ConnMonitor.java单独的文件创建的广播接收器类(请取消对记录呼叫,以便能够正确地监视流量)

 进口android.content.BroadcastReceiver;
进口android.content.Context;
进口android.content.Intent;
进口android.net.ConnectivityManager;
进口android.net.NetworkInfo;
进口android.util.Log;

公共类ConnMonitor扩展的BroadcastReceiver {
    私人字符串变量=TGtracker;

    @覆盖
    公共无效的onReceive(上下文的背景下,意图意图){
        //字符串的typeName =;
        字符串状态=;
        整型= -1;
        ConnectivityManager connectivityManager =(ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
        的NetworkInfo测试=(的NetworkInfo)connectivityManager.getActiveNetworkInfo();
        //Log.v(TAG,"there一直是连接改变 - >+ intent.getExtras()得到(ConnectivityManager.EXTRA_NETWORK_INFO));
        尝试 {
            //的typeName = test.getTypeName()的toString();
            TYPE = test.getType();
            。状态= test.getState()的toString();
            //Log.i(TAG,"type  - >'+的typeName +状态 - >'+状态+');
        }赶上(例外五){
            //的typeName =空;
            类型= -1;
            状态=断开连接;
            //Log.i(TAG,"type  - > ERROR1+ e.getMessage()+引起=+ e.getCause());
        }

        如果((类型== 1)及及(状态==已连接)){
            //Log.i(TAG,我对这个美丽的WIFI连接SOOOO受诅咒uploadin);
            意图batchUploadDataService =新的意图(背景下,BatchUploadGpsData.class);
            context.startService(batchUploadDataService);
        } 其他 {
            //Log.e(TAG,"NO找到的匹配类型 - >'+的typeName +状态 - >'+状态+');
        }
    }
}
 

和,最后,创建服务BatchUploadGpsData.java是这样的:

 进口android.app.Service;
进口android.content.Intent;
进口android.os.IBinder;
进口android.util.Log;

公共类BatchUploadGpsData延伸服务{
    最终的字符串变量=TGtracker;

    @覆盖
    公共无效的onCreate(){
        Log.e(TAG,我在这里,摇滚像飓风的onCreate服务。);
    //该服务试图上传和终止本身无论是成功还是失败
    //但它只是有效的,而它创建做任何事情
    //(因此,你可以拨打100万次,如果上传心不是做,什么都不会发生)
    //如果你对此有何评论这下一行,你就可以看到,它执行的onCreate只有第一它被称为
    //我这样做的原因是,广播接收装置,每次你的连接状态,成功地连接到wifi的一个新的变化的时间被称为至少两次
        this.stopSelf();
    }
    @覆盖
    公众诠释onStartCommand(意向意图,诠释标志,诠释startId){
        //Log.i(TAG,收到的起始ID+ startId +:+意图);
        Log.e(TAG,叫我多余的BABY onStartCommand服务!);
        //这个服务是不应该执行任何东西,当它被称为
        //因为它可被称为inumerous在重复次数
        //所有的行动是在OnCreate  - 从而迫使它仅发生一次
        返回1;
    }
    @覆盖
    公众的IBinder onBind(意向意图){
        // TODO自动生成方法存根
        返回null;
    }

}
 

这是不是伪code,这是实际的code,测试,在Android 2.2及更高版本上运行。

要测试这种服务的方式就是关闭和你的android重新启动您的WiFi服务(关闭电源的无线路由器也将这样的伎俩)。但这种code没有验证是否有效地连接到网络。为此,我建议你做一个HttpClient的请求,并检查了调用的结果。超出了本讨论的范围。

请注意:由于在同一个线程的UI运行的服务,我强烈建议你实现上传适当的在一个单独的线程或AsyncTask的,这取决于您的特定需求。你也可以运行在一个单独的线程的全程服务,但是这一次不在本文讨论的范围,尽管是标准的做法在这些情况下。

I am starting a service using startService(Intent intent) method. When i call this function it reaches the onCreate of service but it is unable to call onStartCommand. Here is my code--

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

    }

}

Service Code --

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>

解决方案

larsVogel solves this problem (and many others like it) in this excellent post.

this is how i adapted his code to create a connectivity receiver that monitors when the user connects to a WIFI network so as to batch upload usage data:

in the Manifest file, place a receiver and declare a service right before the end tag for your < / 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>

create a broadcast receiver class in a separate file called ConnMonitor.java (please uncomment the Log calls to be able to properly monitor the flow)

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+"'"   );
        }
    }
}

and, finally, create a service BatchUploadGpsData.java like this:

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

}

this is not pseudocode, this is actual code, tested and running on android 2.2 and up.

the way to test this service is to shut down and restart your WIFI services on your android (powering off the wifi router will also do the trick). BUT this code does not verify if you are effectively connected to the net. for that, i recomend that you make an httpclient request and check out the result of the call. beyond the scope of this discussion.

NOTE: since services run on the same thread as the UI, i highly recommend that you implement the uploading proper on a separate thread or asynctask, depending your specific needs. you can also run the whole service on a separate thread, but that is once again not the scope of this discussion, despite being standard practice in these cases.

这篇关于启动Android平台服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆