0

画面のオン/オフをサービスで機能させようとしていますが、今のところうまくいきません。

目標は次のとおりです。画面がオフになったときにLEDライト(ソフトキー)を消灯し、ユーザーがアプリに入力した値で画面がオンに戻ったときにソフトキーライトをオンにします(TextXLActivity.getledC()が表示されます)これはメインアクティビティからIntを取得します)

私の主な活動では、SeekBarなどを使用してLEDライトを問題なく制御できます。動作しないのは実際にはレシーバー/サービスだけです

設定、アプリケーション、実行中のサービスに移動すると、アプリがどこにも表示されないので、サービスがまったく開始されないのではないかと心配しています。おそらくそれがここでの問題です。

これが私の受信者です:

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

}

これは私がReceiver/Serviceの「関係」を理解しようと試み始めたテストアプリです。助けていただければ幸いです。;)

私はまた、私のサービスが私にこの行を実装することを強制していることに気づきました:

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

}

4

1 に答える 1

4

あなたの問題は、サービスの onCreate メソッドの後に BroadcastReceiver mReceiver が存続しないことだと思います。さらに、あなたはそれが正しいと宣言していません。私があなただったら、次のようにします。

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 メソッド内からサービスを再度開始しています。これは、Android サービスが機能する方法ではありません。正しいアプローチは、サービスの onCreate メソッドからレシーバーをインスタンス化して登録し、アプリケーションの別のポイントからサービスを開始することです。たとえば、アプリ ウィジェットの場合は、WidgetProvider の onUpdate メソッドから、または一部のアクティビティの onCreate メソッド。

したがって、コードは次のようになります。

  1. あなたのレシーバー:

    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 ....
        }
    }
    
  2. あなたのサービス:

    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();
        }
    }
    
  3. あなたのアクティビティまたは他のコードポイント:

    startService(新しいインテント(コンテキスト、UpdateService.class));

ここで何が起こるかは次のとおりです。

startService が実行されると、サービスがインスタンス化され、 onCreate メソッドが実行され、レシーバーが登録され、インテントの監視が開始されます。次に、サービスの onStart メソッドが呼び出され、START_STICKY が返されます。これは、システムから終了した場合にサービスが再開され、受信者が再度登録されることを意味します。ところで、 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;
    }
}

インテント led を宣言し、それを使用してサービスを開始していますが、開始するサービスを指定していません。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;
    }
}

そして今の様子を見てください...

2回目の編集

OK、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);
}

お役に立てれば...

于 2012-05-09T22:00:48.433 に答える