我正试图让我的屏幕开启/关闭以使用我的服务,但到目前为止还没有运气。
目标是:当屏幕变为OFF时,让LED灯(软键)熄灭,当屏幕返回时,软键灯亮,并且用户在我的应用程序中输入的值(您将看到TextXLActivity。 getledC()从主活动中获取Int)
在我的主要活动中,我可以毫无问题地控制LED灯,使用SeekBar等。唯一不起作用的是接收器/服务
现在当我去设置,应用程序,运行服务时,我的应用程序没有列在任何地方,我担心我的服务根本没有启动,也许这就是问题所在。
这是我的接收者:
package com.test.xl;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class ScreenReceiver extends BroadcastReceiver {
private boolean screenOff;
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
screenOff = true;
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
screenOff = false;
}
Intent i = new Intent(context, UpdateService.class);
i.putExtra("screen_state", screenOff);
context.startService(i);
}
}
这是我的服务:
package com.test.xl;
import com.sonyericsson.illumination.IlluminationIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
public class UpdateService extends Service {
@Override
public void onCreate() {
super.onCreate();
// register receiver that handles screen on and screen off logic
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
BroadcastReceiver mReceiver = new ScreenReceiver();
registerReceiver(mReceiver, filter);
}
@Override
public void onStart(Intent intent, int startId) {
boolean screenOn = intent.getBooleanExtra("screen_state", false);
if (!screenOn) {
{
Intent led = new Intent(IlluminationIntent.ACTION_START_LED);
led.putExtra(IlluminationIntent.EXTRA_PACKAGE_NAME, "com.test.xl");
led.putExtra(IlluminationIntent.EXTRA_LED_ID, IlluminationIntent.VALUE_BUTTON_2);
led.putExtra(IlluminationIntent.EXTRA_LED_COLOR, TestXLActivity.getledC());
startService(led);
}
} else {
Intent led = new Intent(IlluminationIntent.ACTION_STOP_LED);
led.putExtra(IlluminationIntent.EXTRA_PACKAGE_NAME, "com.test.xl");
led.putExtra(IlluminationIntent.EXTRA_LED_ID, IlluminationIntent.VALUE_BUTTON_2);
led.putExtra(IlluminationIntent.EXTRA_LED_COLOR, 0xFFFFFFFF);
startService(led);
}
}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
这是一个测试应用程序我开始尝试并了解接收器/服务“关系”,任何帮助将不胜感激! ;)
我还注意到我的服务迫使我实现这一行:
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
我遵循了一个关于如何让我的服务与Receiver进行交互的教程,以及最后没有类似内容的源代码,任何猜测?
祝你好运
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.test.xl"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="10"/>
<uses-permission android:name="com.sonyericsson.illumination.permission.ILLUMINATION"/>
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:name=".TestXLActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<receiver android:name=".ScreenReceiver">
<intent-filter>
<action android:name="android.intent.action..ACTION_SCREEN_ON" />
<action android:name="android.intent.action.ACTION_SCREEN_OFF" />
</intent-filter>
</receiver>
</intent-filter>
</activity>
</application>
</manifest>
编辑: 以下是出现错误的源代码(startService(led)):
package com.test.xl;
import com.sonyericsson.illumination.IlluminationIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class ScreenReceiver extends BroadcastReceiver {
private boolean screenOff;
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
Intent led = new Intent(IlluminationIntent.ACTION_STOP_LED);
led.putExtra(IlluminationIntent.EXTRA_PACKAGE_NAME, "com.test.xl");
led.putExtra(IlluminationIntent.EXTRA_LED_ID, IlluminationIntent.VALUE_BUTTON_2);
led.putExtra(IlluminationIntent.EXTRA_LED_COLOR, 0xFFFFFFFF);
startService(led);
screenOff = true;
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
Intent led = new Intent(IlluminationIntent.ACTION_START_LED);
led.putExtra(IlluminationIntent.EXTRA_PACKAGE_NAME, "com.test.xl");
led.putExtra(IlluminationIntent.EXTRA_LED_ID, IlluminationIntent.VALUE_BUTTON_2);
led.putExtra(IlluminationIntent.EXTRA_LED_COLOR, TestXLActivity.getledC());
startService(led);
screenOff = false;
}
}
}
新代码
public class ScreenReceiver extends BroadcastReceiver {
private boolean screenOff;
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
Intent led = new Intent(IlluminationIntent.ACTION_STOP_LED);
led.putExtra(IlluminationIntent.EXTRA_PACKAGE_NAME, "com.test.xl");
led.putExtra(IlluminationIntent.EXTRA_LED_ID, IlluminationIntent.VALUE_BUTTON_2);
led.putExtra(IlluminationIntent.EXTRA_LED_COLOR, 0xFFFFFFFF);
context.startService(led);
screenOff = true;
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
int ledC = TestXLActivity.getledC();
Intent led = new Intent(IlluminationIntent.ACTION_START_LED);
led.putExtra(IlluminationIntent.EXTRA_PACKAGE_NAME, "com.test.xl");
led.putExtra(IlluminationIntent.EXTRA_LED_ID, IlluminationIntent.VALUE_BUTTON_2);
led.putExtra(IlluminationIntent.EXTRA_LED_COLOR, ledC);
context.startService(led);
screenOff = false;
}
}
public class UpdateService extends Service {
private ScreenReceiver mReceiver = null;
@Override
public void onCreate() {
super.onCreate();
// register receiver that handles screen on and screen off logic
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
if(mReceiver != null)mReceiver = new ScreenReceiver();
registerReceiver(mReceiver, filter);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return Service.START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onDestroy() {
unregisterReceiver(mReceiver);
super.onDestroy();
}
}
答案 0 :(得分:4)
我认为您的问题是您的BroadcastReceiver mReceiver在您的服务的onCreate方法之后无法生存。此外,你没有宣布它是正确的。如果我是你,我会做这样的事情:
public class UpdateService extends Service {
private ScreenReceiver mReceiver = null;
@Override
public void onCreate() {
super.onCreate();
// register receiver that handles screen on and screen off logic
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
if(mReceiver != null)mReceiver = new ScreenReceiver();
registerReceiver(mReceiver, filter);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
*** NOTE HERE THAT I AM OVERRIDING THE ONSTART AS AN INT NOT VOID***
.... do your stuff here....
return Service.START_STICKY;
}
现在你的方法还有另一个问题。您正在服务的onCreate方法中声明并实例化您的接收器,然后您从接收器的onReceive方法中启动AGAIN服务。这不是android服务的工作方式。 正确的方法是从服务的onCreate方法实例化和注册接收器,并从应用程序的另一个点启动服务,例如,如果它是app-widget,您可以从WidgetProvider的onUpdate方法或从一些Activity的onCreate方法。
所以你的代码应该如下:
您的收件人:
public class ScreenReceiver extends BroadcastReceiver {
private boolean screenOff;
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
screenOff = true;
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
screenOff = false;
}
... Do your stuff here for screen on or off ....
... AND DO NOT START A SERVICE FROM HERE ....
}
}
您的服务:
public class UpdateService extends Service {
private ScreenReceiver mReceiver = null;
@Override
public void onCreate() {
super.onCreate();
// register receiver that handles screen on and screen off logic
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
if(mReceiver != null)mReceiver = new ScreenReceiver();
registerReceiver(mReceiver, filter);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
NOTE HERE THAT I AM OVERRIDING THE ONSTART AS AN INT NOT VOID
.... YOU DON'T HAVE TO DO SOMETHING HERE EXCEPT FROM SOME ....
.... INITIALIZATION CODE ...
return Service.START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onDestroy() {
UnregisterReceiver(mReceiver);
super.onDestroy();
}
}
您的活动或其他代码点:
startService(new Intent(context,UpdateService.class));
这里发生的是:
当startService执行时,实例化您的服务并执行onCreate方法,其中接收者已注册并开始监视Intents。然后调用服务的onStart方法并返回START_STICKY,这意味着如果从系统终止服务将重新启动,因此接收器将再次注册,依此类推。 BTW只要你的服务终止onDestroy方法将被调用,接收器将被取消注册(这是一件非常糟糕的事情)。
现在,您已准备好运行服务,以便接收来自系统的通知。
如果您希望在某个时候终止服务,只需拨打
即可context.stopService(new Intent(context, UpdateService.class));
我并不深入了解Android服务,但这项技术与我同时托管BroadcastReceiver和ContentObserver的服务非常有效。
根据您的新进展进行编辑
好了,现在好像我们到了某个地方。我可以在你的onReceive方法中看到
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
Intent led = new Intent(IlluminationIntent.ACTION_STOP_LED);
led.putExtra(IlluminationIntent.EXTRA_PACKAGE_NAME, "com.test.xl");
led.putExtra(IlluminationIntent.EXTRA_LED_ID, IlluminationIntent.VALUE_BUTTON_2);
led.putExtra(IlluminationIntent.EXTRA_LED_COLOR, 0xFFFFFFFF);
context.startService(led);
screenOff = true;
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
int ledC = TestXLActivity.getledC();
Intent led = new Intent(IlluminationIntent.ACTION_START_LED);
led.putExtra(IlluminationIntent.EXTRA_PACKAGE_NAME, "com.test.xl");
led.putExtra(IlluminationIntent.EXTRA_LED_ID, IlluminationIntent.VALUE_BUTTON_2);
led.putExtra(IlluminationIntent.EXTRA_LED_COLOR, ledC);
context.startService(led);
screenOff = false;
}
}
您正在声明一个intent并且您正在使用它来启动服务,但您没有指定要启动的服务。我认为你缺少像led.setClass这样的东西。但为了清楚一点,让我们像这样修改onReceive:
@Override
public void onReceive(Context context, Intent intent) {
Intent led = new Intent(context, your_led_service_name.class);
led.putExtra(IlluminationIntent.EXTRA_PACKAGE_NAME, "com.test.xl");
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
led.addAction(IlluminationIntent.ACTION_STOP_LED);
led.putExtra(IlluminationIntent.EXTRA_LED_ID, IlluminationIntent.VALUE_BUTTON_2);
led.putExtra(IlluminationIntent.EXTRA_LED_COLOR, 0xFFFFFFFF);
context.startService(led);
screenOff = true;
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
int ledC = TestXLActivity.getledC();
led.addAction(IlluminationIntent.ACTION_START_LED);
led.putExtra(IlluminationIntent.EXTRA_LED_ID, IlluminationIntent.VALUE_BUTTON_2);
led.putExtra(IlluminationIntent.EXTRA_LED_COLOR, ledC);
context.startService(led);
screenOff = false;
}
}
看看现在怎么样......
第二次编辑
好的我对Sony Ericsson Illumination API一无所知,但根据您的代码,您可能需要更改onReceive,如下所示:
@Override
public void onReceive(Context context, Intent intent) {
IlluminationIntent led = new IlluminationIntent(??);
//Note: In place of ?? you may need your context on nothing at all
//it depends on sony's API.
led.putExtra(IlluminationIntent.EXTRA_PACKAGE_NAME, "com.test.xl");
led.putExtra(IlluminationIntent.EXTRA_LED_ID, IlluminationIntent.VALUE_BUTTON_2);
//This is only needed once...
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
led.addAction(IlluminationIntent.ACTION_STOP_LED);
led.putExtra(IlluminationIntent.EXTRA_LED_COLOR, 0xFFFFFFFF);
screenOff = true;
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
int ledC = TestXLActivity.getledC();
led.addAction(IlluminationIntent.ACTION_START_LED);
led.putExtra(IlluminationIntent.EXTRA_LED_COLOR, ledC);
screenOff = false;
}
context.startService(led);
}
希望这会有所帮助......