Skip to content

Temporary build: Quest KeepAwake APK - #54

Closed
0suu wants to merge 9 commits into
mainfrom
temp/quest-keepawake-build-20260719
Closed

Temporary build: Quest KeepAwake APK#54
0suu wants to merge 9 commits into
mainfrom
temp/quest-keepawake-build-20260719

Conversation

@0suu

@0suu 0suu commented Jul 19, 2026

Copy link
Copy Markdown
Owner

一時的なAndroid APKビルド用PRです。成果物取得後に閉じます。既存アプリのコードは変更せず、専用ディレクトリと一時ワークフローのみ追加しています。

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 19, 2026

Copy link
Copy Markdown

Deploying switchbotcontroller with  Cloudflare Pages  Cloudflare Pages

Latest commit: b1b443e
Status: ✅  Deploy successful!
Preview URL: https://00906b89.switchbotcontroller.pages.dev
Branch Preview URL: https://temp-quest-keepawake-build-2.switchbotcontroller.pages.dev

View logs

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new Android application, Quest KeepAwake, designed to keep Meta Quest devices awake by running a foreground service that holds a partial wake lock, modifies system sleep settings, and periodically broadcasts a proximity sensor event. The review feedback highlights several critical issues and improvement opportunities: adding directBootAware to the service to ensure it can start on boot before unlock, handling potential ForegroundServiceStartNotAllowedException in the boot receiver to prevent crashes on Android 12+, requesting the WRITE_SETTINGS permission at runtime in MainActivity so that system settings can be successfully modified, and adding a null check for PowerManager to prevent a potential NullPointerException.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

<receiver android:name=".BootReceiver" android:exported="true" android:directBootAware="true">
<intent-filter><action android:name="android.intent.action.BOOT_COMPLETED"/><action android:name="android.intent.action.LOCKED_BOOT_COMPLETED"/></intent-filter>
</receiver>
<service android:name=".KeepAwakeService" android:exported="false" />

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

BootReceiverandroid:directBootAware="true" が設定されており、デバイスの起動直後(ロック解除前)に送信される LOCKED_BOOT_COMPLETED を受信した際に KeepAwakeService を起動しようとします。
しかし、起動対象の KeepAwakeService 自体に android:directBootAware="true" が設定されていないため、ロック解除前にサービスを起動しようとするとシステムによって起動が拒否されるか、正常に動作しません。

デバイスの起動直後から確実にサービスを動作させるために、KeepAwakeService にも android:directBootAware="true" を指定することをお勧めします。

Suggested change
<service android:name=".KeepAwakeService" android:exported="false" />
<service android:name=".KeepAwakeService" android:exported="false" android:directBootAware="true" />

Comment on lines +2 to +3
import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent;
public class BootReceiver extends BroadcastReceiver { @Override public void onReceive(Context c, Intent i){ c.startForegroundService(new Intent(c, KeepAwakeService.class)); } }

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Android 12 (API 31) 以降では、バックグラウンドからフォアグラウンドサービスを開始する際、特定の条件下で ForegroundServiceStartNotAllowedExceptionIllegalStateException のサブクラス)がスローされる可能性があります。
ブロードキャストレシーバー内での未キャッチの例外はアプリのクラッシュ(「アプリが繰り返し停止しています」など)を引き起こすため、startForegroundService の呼び出しを try-catch ブロックで囲み、安全に例外を処理することをお勧めします。

Suggested change
import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent;
public class BootReceiver extends BroadcastReceiver { @Override public void onReceive(Context c, Intent i){ c.startForegroundService(new Intent(c, KeepAwakeService.class)); } }
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class BootReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context c, Intent i) {
try {
c.startForegroundService(new Intent(c, KeepAwakeService.class));
} catch (Exception e) {
Log.e("BootReceiver", "Failed to start KeepAwakeService on boot", e);
}
}
}

Comment on lines +2 to +4
import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.widget.TextView;
public class MainActivity extends Activity {
@Override public void onCreate(Bundle b){ super.onCreate(b); startForegroundService(new Intent(this, KeepAwakeService.class)); TextView v=new TextView(this); v.setText("KeepAwake service is running.\nprox_close is sent every 2 seconds."); v.setTextSize(20); v.setPadding(32,32,32,32); setContentView(v); }

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Android 6.0 (API 23) 以降では、Settings.System への書き込み(SCREEN_OFF_TIMEOUT の変更など)を行うために、マニフェストでの宣言に加えて、実行時にユーザーから「システム設定の変更」権限(WRITE_SETTINGS)を明示的に許可してもらう必要があります。
現在、権限がない状態で Settings.System.putInt を呼び出すと SecurityException が発生し、try-catch でキャッチされてサイレントに失敗します(画面消灯時間が変更されません)。

MainActivity の起動時などに Settings.System.canWrite(this) をチェックし、許可されていない場合は設定画面を開いてユーザーに許可を求めるように改善することをお勧めします。

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Settings;
import android.widget.TextView;

public class MainActivity extends Activity {
    @Override
    public void onCreate(Bundle b) {
        super.onCreate(b);
        if (!Settings.System.canWrite(this)) {
            Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
            intent.setData(Uri.parse("package:" + getPackageName()));
            startActivity(intent);
        }
        startForegroundService(new Intent(this, KeepAwakeService.class));
        TextView v = new TextView(this);
        v.setText("KeepAwake service is running.\\nprox_close is sent every 2 seconds.");
        v.setTextSize(20);
        v.setPadding(32, 32, 32, 32);
        setContentView(v);
    }

private final Handler handler=new Handler(Looper.getMainLooper()); private boolean running; private PowerManager.WakeLock wakeLock;
private final Runnable keepAwakeRunnable=new Runnable(){ @Override public void run(){ if(!running)return; sendProxClose(); handler.postDelayed(this,INTERVAL_MS); }};
@Override public void onCreate(){ super.onCreate(); }
@Override public int onStartCommand(Intent intent,int flags,int startId){ if(running)return START_STICKY; running=true; createChannel(); startForeground(1,new Notification.Builder(this,CHANNEL_ID).setContentTitle("Quest KeepAwake").setContentText("Always-on keep-awake is active").setSmallIcon(android.R.drawable.ic_lock_idle_lock).setOngoing(true).build()); PowerManager pm=(PowerManager)getSystemService(POWER_SERVICE); wakeLock=pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,"QuestNavKeepAwake::StayAwake"); wakeLock.acquire(); applySettings(); sendProxClose(); handler.postDelayed(keepAwakeRunnable,INTERVAL_MS); Log.i(TAG,"Always-on service started"); return START_STICKY; }

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

防御的プログラミングの観点から、getSystemService(POWER_SERVICE)null を返した場合に NullPointerException が発生するのを防ぐため、PowerManager のヌルチェックを行うことをお勧めします。また、コードの可読性向上のために適切に改行とインデントを適用しています。

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (running) return START_STICKY;
        running = true;
        createChannel();
        startForeground(1, new Notification.Builder(this, CHANNEL_ID)
                .setContentTitle("Quest KeepAwake")
                .setContentText("Always-on keep-awake is active")
                .setSmallIcon(android.R.drawable.ic_lock_idle_lock)
                .setOngoing(true)
                .build());
        PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
        if (pm != null) {
            wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "QuestNavKeepAwake::StayAwake");
            wakeLock.acquire();
        }
        applySettings();
        sendProxClose();
        handler.postDelayed(keepAwakeRunnable, INTERVAL_MS);
        Log.i(TAG, "Always-on service started");
        return START_STICKY;
    }

@0suu 0suu closed this Jul 19, 2026
@0suu
0suu deleted the temp/quest-keepawake-build-20260719 branch July 19, 2026 13:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant