Android服务不会启动

时间:2014-03-18 17:55:16

标签: android android-service

好的,这就是问题所在。我context.startService(serviceIntent),但我没有收到来自OnCreateOnStartCommand的新日志消息。

清单:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.distorted.flashnotifier"
    android:versionCode="0"
    android:versionName="0.6" >

    <uses-sdk
        android:minSdkVersion="16"
        android:targetSdkVersion="19" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.distorted.flashnotifier.Home"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service android:name="FlashService"
            android:exported="true"
            android:enabled="true"
            android:permission="android.permission.READ_PHONE_STATE">
        </service>
    </application>
</manifest>

我已经尝试过:

  • 将服务名称更改为&#34; .FlashService&#34;和&#34; com.distorted.flashnotifier.FlashService&#34;

活动代码:

private Context cont;

protected void onCreate(Bundle savedInstanceState) {
    cont = getApplicationContext();
}

public void setNotificator() {
    Intent serviceIntent = new Intent(cont, FlashService.class);
    if(callNotificator){
        cont.startService(serviceIntent);
        Log.d("LOG", "setNotificator works");
    } else {
        cont.stopService(serviceIntent);
    }
}

我尝试了什么:

  • 改变所有&#34;续&#34;到&#34;这&#34;
  • startService(new Intent(cont,FlashService.class));

FlashService.class:

package com.distorted.flashnotifier;

public class FlashService extends Service{

    public void OnCreate () {
        Log.d("LOG", "onCreate works");
    }

        public int OnStartCommand(Intent intent, int flags, int startId) {
    return START_STICKY;
}

    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return null;
    }
}

我试过了:

  • 将Log.d移动到onStartCommand
  • 将START_STICKY更改为super.onStartCommand(intent,flags,startId)

好的,所以我得到了setNotificator日志消息,但不是onCreate消息。 有谁知道我怎么能做这个工作? (感谢阅读整篇文章)。 LogCat并没有说任何有趣的事情。

更新

完整的活动代码:

package com.distorted.flashnotifier;

import java.util.Calendar;

import android.app.Activity;
import android.app.Dialog;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.Switch;
import android.widget.TimePicker;
import android.widget.Toast;
import android.app.TimePickerDialog;
import android.content.Context;
import android.content.Intent;

public class Home extends Activity {

    private Button timeSelectBut1;
    private Button timeSelectBut2;
    private int hour1;
    private int hour2;
    private int minute1;
    private int minute2;
    static final int TIME_DIALOG_ID1 = 1;
    static final int TIME_DIALOG_ID2 = 2;
    private Switch callSwitch;
    private Switch notificationSwitch;
    private boolean callNotificator;
    private boolean notifNotificator;
    private Context cont;

//IMPORTANT UNTIL timeSelectBut1.setOnClickListener

    @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_home);
            cont = getApplicationContext();
        timeSelectBut1 = (Button) findViewById(R.id.selectTimeButton1);
        timeSelectBut1.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                showDialog(TIME_DIALOG_ID1);
            }
        });
        final Calendar cal1 = Calendar.getInstance();
        hour1 = cal1.get(Calendar.HOUR_OF_DAY);
        minute1 = cal1.get(Calendar.MINUTE);
        updateText(1);

        timeSelectBut2 = (Button) findViewById(R.id.selectTimeButton2);
        timeSelectBut2.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                    showDialog(TIME_DIALOG_ID2);
                }
            });
            final Calendar cal2 = Calendar.getInstance();
            hour2 = cal2.get(Calendar.HOUR_OF_DAY);
            minute2 = cal2.get(Calendar.MINUTE);
            updateText(2);
    }

    @Override
    protected Dialog onCreateDialog(int id){
        if (id == 1) {
            return new TimePickerDialog(this, mTimeSetListener1, hour1, minute1, true);
        }
        if (id == 2) {
            return new TimePickerDialog(this, mTimeSetListener2, hour2, minute2, true);
        }
        return null;
    }

    public void updateText(int id) {
        if (id == 1) timeSelectBut1.setText(pad(hour1) + ":" + pad(minute1));
        if (id == 2) timeSelectBut2.setText(pad(hour2) + ":" + pad(minute2));
    }

    private TimePickerDialog.OnTimeSetListener mTimeSetListener1 = new TimePickerDialog.OnTimeSetListener() {
                public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
                    hour1 = hourOfDay;
                    minute1 = minute;
                    updateText(1);
                }
            };
    private TimePickerDialog.OnTimeSetListener mTimeSetListener2 = new TimePickerDialog.OnTimeSetListener() {
        public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
            hour2 = hourOfDay;
            minute2 = minute;
            updateText(2);
        }
    };

    private static String pad(int c) {
        if (c >= 10)
            return String.valueOf(c);
        else
            return "0" + String.valueOf(c);
    }

//IMPORTANT

    public void onCallSwitchClicked(View view) {
        boolean on = ((Switch) view).isChecked();
        if (on) {
            callNotificator = true;
            setNotificator();
            //timeSelectBut1.setText("callNotifTrue");
        } else {
            callNotificator = false;
            setNotificator();
            //timeSelectBut1.setText("callNotifFalse");
        }
    }

    public void onNotifSwitchClicked(View view) {
        boolean on = ((Switch) view).isChecked();
        if (on) {
            notifNotificator = true;
            //setNotificator();
        } else {
            notifNotificator = false;
            //setNotificator();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.home, menu);
        return true;
    }

//IMPORTANT

    public void setNotificator() {
        Intent serviceIntent = new Intent(this, FlashService.class);
        if(callNotificator){
            startService(serviceIntent);
            Log.d("LOG", "SetNotificator works");
        } else {
            stopService(serviceIntent);
        }
    }
}

2 个答案:

答案 0 :(得分:0)

您没有正确注册该服务。在服务中删除行android:permission 替换你的清单。

 <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.distorted.flashnotifier"
android:versionCode="0"
android:versionName="0.6" >

<uses-sdk
    android:minSdkVersion="16"
    android:targetSdkVersion="19" />
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name="com.distorted.flashnotifier.Home"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <service android:name=".FlashService"
        android:exported="true"
        android:enabled="true"
       >
    </service>
</application>
</manifest>

编辑:

尝试完代码后,我意识到,你没有正确覆盖oncreate和onstart命令。在onCreate()和onStartCommand()方法的名称中,o不是大写的..请将其更改为小o并尝试。

答案 1 :(得分:0)

由于您从Service开始Activity,因此正确的代码为:

public void setNotificator() {
    Intent serviceIntent = new Intent(this, FlashService.class);
    if(callNotificator){
        startService(serviceIntent);
        Log.d("LOG", "setNotificator works");
    } else {
        stopService(serviceIntent);
    }
}

继续,按文档:系统在首次创建服务时调用此方法,以执行一次性设置过程(在调用onStartCommand()onBind()之前)。如果服务已在运行,则不会调用此方法。

所以我最好将Log来电onStartCommand

您的服务正在使用权限,再次来自文档:如果startService()bindService()stopService()的来电者未获得此权限,则此方法无效, Intent对象将不会传递给服务。如果未设置此属性,则<application>元素的权限属性设置的权限将应用于该服务。如果两个属性均未设置,则该服务不受权限保护。