【问题标题】:How do I make my android app appear in Ultra Power Saving Mode如何让我的 android 应用程序以超省电模式显示
【发布时间】:2016-12-29 05:58:45
【问题描述】:

一些三星设备有一个超级省电模式,它会关闭 wifi,将屏幕灰度化并将使用限制为一些基本应用程序。

但是,它确实允许您添加一些随后可以使用的应用程序。这些应用程序包括 Facebook 和 WhatsApp。如何让我的应用出现在此列表中?我必须对应用程序进行哪些更改才能使其出现在此列表中?还是这个名单是基于三星维护的白名单?

【问题讨论】:

  • 有趣的是 facebook 处于超省电模式列表中 :)
  • 如果您的应用程序执行大量后台工作,三星的内置电池应用程序会自动将其放入。所以,fe,如果您的应用程序在服务中收集位置,或者使用 JobSchedulars 来设置未来的工作,那么您在该列表中的几率会更高。不过,我不太确定你为什么想去那里。
  • 哪些应用上榜似乎取决于制造商,信使 Signal 的 'problem' 相同。

标签: android samsung-mobile power-saving


【解决方案1】:

可能使用权限REQUEST_IGNORE_BATTERY_OPTIMIZATIONS。此权限不需要明确的用户权限。所以将被授予。虽然这不会阻止用户手动停止应用程序。

来自the docs

这是一个正常的权限:请求它的应用程序将始终 授予权限,无需用户批准或查看。

ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS 会将应用加入设备的白名单。

isIgnoringBatteryOptimizations 会通知您该应用是否已列入白名单。

来自the docs的一些笔记:

注意:大多数应用程序不应该使用它;有很多设施 由平台提供,以便应用程序在 各种省电模式。这仅适用于不寻常的应用程序 需要以潜在的代价深入控制自己的执行 用户的电池寿命。请注意,这些应用程序运行良好 向用户展示他们的高功率消费者的风险 设备。

输入:Intent 的数据 URI 必须指定应用程序包名称 要显示,与“包”方案。即“package:com.my.app”。

我不建议滥用它。

有一个Acceptable Use Cases for Whitelisting 的列表。

一般来说,你的应用不应该在白名单上,除非 Doze 或 App 待机破解app核心功能或存在技术问题 您的应用无法使用 FCM 高优先级消息的原因。

感谢adsamcik 提供此最新链接。

【讨论】:

  • 在设备上禁用电池优化需要用户操作。如果您使用 ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS,他们必须确认对话框或自行禁用它。此外,“Google Play 政策禁止应用程序请求直接免除 Android 6.0+(打盹和应用程序待机)中的电源管理功能,除非应用程序的核心功能受到不利影响。” developer.android.com/training/monitoring-device-state/…
  • 我最近不得不自己实现它,所以我知道它是如何工作的第一手资料。您被授予权限,但该权限仅允许您发送“ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS”意图。此意图将向用户显示一个对话框,在该对话框中询问他们是否要禁用电池优化。我找到了这个对话框的一个例子(不同版本的文字不同)commonsware.com/blog/images/ignore-batt-opt-dialog.png
  • 没有刚刚找到的图像。声明是授予您请求优化所需的权限,而不是实际将应用列入白名单的过程是静默的。
  • 这是请求权限的方法:stackoverflow.com/q/33114063/812973
  • 这不会使我的应用程序在三星 Galaxy A5 上的超省电模式下可用。
【解决方案2】:
public class UPSM {

private static SQLiteDatabase db;

synchronized public static void CONFIGURE_UPSM(boolean isEnable, String APP_PACKAGE, String APP_LAUNCHER_ACTIVITY) {
    try {
        final String FILE_PATH = "/data/data/com.sec.android.provider.emergencymode/databases/emergency.db";
        final String FILE_PATH_JOURNAL = "/data/data/com.sec.android.provider.emergencymode/databases/emergency.db-journal";
        String command = "adb shell \"su -c cat " + FILE_PATH + "\" > emergency.db";
        Shell.SU.run("chmod 777 " + FILE_PATH);
        Shell.SU.run(command);
        String command_journal = "adb shell \"su -c cat " + FILE_PATH_JOURNAL + "\" > emergency.db-journal";
        Shell.SU.run("chmod 777 " + FILE_PATH_JOURNAL);
        Shell.SU.run(command_journal);
        String COMMAND_ENABLE = "settings put global low_power 1\n" +
                "am broadcast -a android.os.action.POWER_SAVE_MODE_CHANGED --ez mode true\n";
        String COMMAND_DISABLE = "settings put global low_power 0\n" +
                "am broadcast -a android.os.action.POWER_SAVE_MODE_CHANGED --ez mode false\n";
        if (isEnable) {
            Shell.SU.run(COMMAND_ENABLE);
        } else {
            Shell.SU.run(COMMAND_DISABLE);
        }
        File file = new File(FILE_PATH);
        if (file.exists()) {
            if (db == null) {
                db = SQLiteDatabase.openOrCreateDatabase(FILE_PATH, null);
                db = SQLiteDatabase.openDatabase(FILE_PATH, null, SQLiteDatabase.OPEN_READWRITE);
                db.setLockingEnabled(false);
            } else if (!db.isOpen()) {
                db = SQLiteDatabase.openOrCreateDatabase(FILE_PATH, null);
                db = SQLiteDatabase.openDatabase(FILE_PATH, null, SQLiteDatabase.OPEN_READWRITE);
                db.setLockingEnabled(false);
            }
            if (db != null && db.isOpen()) {
                configureLauncherAdd(isEnable, APP_PACKAGE, APP_LAUNCHER_ACTIVITY, db);
                configureLauncherDefault(isEnable, APP_PACKAGE, APP_LAUNCHER_ACTIVITY, db);
                configureWhiteList(isEnable, APP_PACKAGE, db);
                db.close();
                db = null;
            }
        }
    } catch (NullPointerException e) {
        StackTraceLog.write(e, "CONFIGURE_UPSM_1");
    } catch (RuntimeException e) {
        StackTraceLog.write(e, "CONFIGURE_UPSM_1");
    } catch (OutOfMemoryError e) {
        StackTraceLog.write(e, "CONFIGURE_UPSM_1");
    } catch (Exception e) {
        StackTraceLog.write(e, "CONFIGURE_UPSM_1");
    }
}

private static void configureLauncherAdd(boolean isEnable, String APP_PACKAGE, String APP_LAUNCHER_ACTIVITY, SQLiteDatabase db) {
    try {
        boolean isExist = false;
        Cursor cursor = db.rawQuery("select * from launcheradd where package like '" + APP_PACKAGE + "' and class like '" + APP_LAUNCHER_ACTIVITY + "'", null);
        if (cursor != null) {
            if (!cursor.isAfterLast()) {
                cursor.moveToFirst();
                long count = cursor.getCount();
                if (count > 0) {
                    isExist = true;
                }
            }
            cursor.close();
        }
        if (!isExist) {
            ContentValues contentValues = new ContentValues();
            contentValues.put("package", APP_PACKAGE);
            contentValues.put("class", APP_LAUNCHER_ACTIVITY);
            contentValues.put("permission", "1111");
            if (isEnable) {
                contentValues.put("mode", 1);
            } else {
                contentValues.put("mode", 0);
            }
            db.insert("launcheradd", null, contentValues);
        } else {
            ContentValues contentValues = new ContentValues();
            if (isEnable) {
                contentValues.put("mode", 1);
            } else {
                contentValues.put("mode", 0);
            }
            String where = "package like '" + APP_PACKAGE + "' and class like '" + APP_LAUNCHER_ACTIVITY + "'";
            db.update("launcheradd", contentValues, where, null);
        }
    } catch (NullPointerException e) {
        StackTraceLog.write(e, "CONFIGURE_UPSM_2");
    } catch (RuntimeException e) {
        StackTraceLog.write(e, "CONFIGURE_UPSM_2");
    } catch (OutOfMemoryError e) {
        StackTraceLog.write(e, "CONFIGURE_UPSM_2");
    } catch (Exception e) {
        StackTraceLog.write(e, "CONFIGURE_UPSM_2");
    }
}

private static void configureLauncherDefault(boolean isEnable, String APP_PACKAGE, String APP_LAUNCHER_ACTIVITY, SQLiteDatabase db) {
    try {
        boolean isExist = false;
        Cursor cursor = db.rawQuery("select * from launcherdefault where package like '" + APP_PACKAGE + "' and class like '" + APP_LAUNCHER_ACTIVITY + "'", null);
        if (cursor != null) {
            if (!cursor.isAfterLast()) {
                cursor.moveToFirst();
                long count = cursor.getCount();
                if (count > 0) {
                    isExist = true;
                }
            }
            cursor.close();
        }
        if (!isExist) {
            ContentValues contentValues = new ContentValues();
            contentValues.put("package", APP_PACKAGE);
            contentValues.put("class", APP_LAUNCHER_ACTIVITY);
            contentValues.put("position", 1);
            contentValues.put("fixed", 1);
            if (isEnable) {
                contentValues.put("mode", 1);
            } else {
                contentValues.put("mode", 0);
            }
            db.insert("launcherdefault", null, contentValues);
        } else {
            ContentValues contentValues = new ContentValues();
            if (isEnable) {
                contentValues.put("mode", 1);
            } else {
                contentValues.put("mode", 0);
            }
            String where = "package like '" + APP_PACKAGE + "' and class like '" + APP_LAUNCHER_ACTIVITY + "'";
            db.update("launcherdefault", contentValues, where, null);
        }
    } catch (NullPointerException e) {
        StackTraceLog.write(e, "CONFIGURE_UPSM_3");
    } catch (RuntimeException e) {
        StackTraceLog.write(e, "CONFIGURE_UPSM_3");
    } catch (OutOfMemoryError e) {
        StackTraceLog.write(e, "CONFIGURE_UPSM_3");
    } catch (Exception e) {
        StackTraceLog.write(e, "CONFIGURE_UPSM_3");
    }
}

private static void configureWhiteList(boolean isEnable, String APP_PACKAGE, SQLiteDatabase db) {
    try {
        boolean isExist = false;
        Cursor cursor = db.rawQuery("select * from whitelist where pkg like '" + APP_PACKAGE + "'", null);
        if (cursor != null) {
            if (!cursor.isAfterLast()) {
                cursor.moveToFirst();
                long count = cursor.getCount();
                if (count > 0) {
                    isExist = true;
                }
            }
            cursor.close();
        }
        if (!isExist) {
            ContentValues contentValues = new ContentValues();
            contentValues.put("pkg", APP_PACKAGE);
            if (isEnable) {
                contentValues.put("allowflag", 1);
            } else {
                contentValues.put("allowflag", 0);
            }
            db.insert("whitelist", null, contentValues);
        } else {
            ContentValues contentValues = new ContentValues();
            if (isEnable) {
                contentValues.put("allowflag", 1);
            } else {
                contentValues.put("allowflag", 0);
            }
            String where = "pkg like '" + APP_PACKAGE + "'";
            db.update("whitelist", contentValues, where, null);
        }
    } catch (NullPointerException e) {
        StackTraceLog.write(e, "CONFIGURE_UPSM_4");
    } catch (RuntimeException e) {
        StackTraceLog.write(e, "CONFIGURE_UPSM_4");
    } catch (OutOfMemoryError e) {
        StackTraceLog.write(e, "CONFIGURE_UPSM_4");
    } catch (Exception e) {
        StackTraceLog.write(e, "CONFIGURE_UPSM_4");
    }
}

}

//IGNORE StackTraceLog 

【讨论】:

  • 请通过解释代码如何尝试解决问题中提到的问题来详细说明答案。
  • Shell 类不可用?这需要root手机吗?
【解决方案3】:

一种不是基于代码而是基于第三方应用程序的解决方案,并且最终用户正在安装 UPSM+ 应用程序。

通过这个应用程序,您可以使任何已安装的应用程序可用于 UPSM。 同样在这个应用程序中,您可以使用“始终启用”、“关闭屏幕时不要杀死”等选项来控制行为...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多