安卓引导用户设置APP运行后台保活

随着Android版本的更新, 又是基于安全!安全! 非系统层APP想要正大光明的或搞点小手段在后台长时间或者"永久"保活是愈发不可实现了(当然排除一些"黑技术"),大陆定制化的OS又为了更好的保证UI的流畅性也更是把此拿捏的死死的(除了QQ,微信,支付宝等这类占据市场主导地位的APP手机厂商加入了白名单).这对于一个闻不见经传的中小企业为了能让自家的智能外设能与APP之间的连接建立的长久一些, 数据通信能尽可能不出现中断, 引导用户自行设置APP后台运行和避免APP被清除已成单选项.

直接上代码

1. 首先创建一个service

package com.example.testone.service;

import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.PixelFormat;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.IBinder;
import androidx.core.app.NotificationCompat;

import com.example.testone.R;

import static androidx.core.app.NotificationCompat.PRIORITY_HIGH;
import static androidx.core.app.NotificationCompat.VISIBILITY_PUBLIC;

public class TestService extends Service {

    private final String CHANNEL_ONE_ID = "100";

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public boolean onUnbind(Intent intent) {
        return super.onUnbind(intent);
    }

    @Override
    public void onCreate() {
        super.onCreate();
        /****************第一点*******************/
        //创建通知栏常驻通知
        initNotif("title", "text");
    }

    @Override
    public void onDestroy() {
        stopForeground(true);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
//        return super.onStartCommand(intent, flags, startId);
        /****************第二点*******************/
        //返回START_STICKY,被系统或手动清理后可重启
        return START_STICKY;
    }

    public void initNotif(String title, String context) {
        NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        //RemoteViews remoteView = new RemoteViews(getPackageName(), R.layout.RemoteView); 
        Intent nfIntent = new Intent(this, MainActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, nfIntent, PendingIntent.FLAG_IMMUTABLE);
        @SuppressLint("WrongConstant") NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext(), CHANNEL_ONE_ID)
                .setContentIntent(pendingIntent) // 设置PendingIntent
                .setSmallIcon(R.mipmap.ic_launcher) // 设置状态栏内的小图标
                //.setLargeIcon(bitmapIcon)// 设置大图标
                .setContentTitle(title)
                .setContentText(context) // 设置内容
                //.setWhen(System.currentTimeMillis())// 设置该通知发生的时间
                .setVisibility(VISIBILITY_PUBLIC)// 锁屏显示全部通知
                //.setDefaults(Notification.DEFAULT_ALL)// //使用默认的声音、振动、闪光
                .setCategory(Notification.CATEGORY_SERVICE)//设置类别
                .setPriority(PRIORITY_MAX);// 优先级为:重要通知

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            //安卓8.0以上系统要求通知设置Channel,否则会报错
            NotificationChannel notificationChannel = new NotificationChannel(CHANNEL_ONE_ID, "服务常驻通知", NotificationManager.IMPORTANCE_HIGH);
            notificationChannel.setLockscreenVisibility(VISIBILITY_PUBLIC);//锁屏显示全部通知
            manager.createNotificationChannel(notificationChannel);
            builder.setChannelId(CHANNEL_ONE_ID);
        }
        Notification notification = builder.build(); // 获取构建好的Notification
        //notification.defaults = Notification.DEFAULT_SOUND; //设置为默认的声音
        notification.flags = Notification.FLAG_NO_CLEAR;//不消失的常驻通知
        startForeground(1, notification);//设置常驻通知
    }

}

2. 再创建个Service继承NotificationListenerService先在AndroidManifest.xml中声明,方可在MainActivity中调用方法isNotificationListenerEnabled跳转到系统设置-->获取通知使用权的应用列表里出现当前APP。

package com.example.testone.service;

import android.app.Notification;
import android.content.Intent;
import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
import android.util.Log;

public class TestNotificationListenerService extends NotificationListenerService {

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onNotificationPosted(StatusBarNotification sbn) {
        super.onNotificationPosted(sbn);
        //Notification notification = sbn.getNotification();
        Log.d(LiveTaskApplication.TAG, "sbn.getPackageName: " + sbn.getPackageName());
    }
}

3. 创建Application

package com.example.testone.service;

import android.app.Application;
import android.content.Intent;
import android.os.Build;

public class TestApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        startService();
    }

    /**
     * 启动服务
     */
    private void startService() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            /****************第三点*******************/
            //安卓8.0以上开启为前台服务
            startForegroundService(new Intent(this, TestService.class));
        } else {
            startService(new Intent(this, TestService.class));
        }
        startService(new Intent(this, TestNotificationListenerService.class));
    }

}

4. AndroidManifest.xml中

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.testone">
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
    <!-- 厂商自启动权限 -->
    <uses-permission android:name="oppo.permission.OPPO_COMPONENT_SAFE" />
    <uses-permission android:name="com.huawei.permission.external_app_settings.USE_COMPONENT" />

    <application
        android:name=".service.TestApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".activity.MainActivity"
            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=".service.TestNotificationListenerService"
            android:enabled="true"
            android:exported="true"
            android:label="@string/app_name"
            android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"><!--必要的绑定权限-->
            <intent-filter>
                <action android:name="android.service.notification.NotificationListenerService" /><!--必要的action-->
            </intent-filter>
        </service>
        <service
            android:name=".service.TestService"
            android:directBootAware="true"
            android:enabled="true"
            android:exported="true"
            android:label="@string/app_name"
            android:foregroundServiceType="phoneCall|mediaPlayback|dataSync|mediaProjection|connectedDevice|location" />
    </application>

</manifest>

5. activity_main.xml

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/titleBar"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:clipToPadding="true"
        tools:context=".activity.BaseActivity">
        <!--android:fitsSystemWindows="true"-->

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:orientation="horizontal"
            android:padding="10dp">

            <TextView
                android:id="@+id/left"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerVertical="true"
                android:gravity="center"
                android:text="返回"
                android:textColor="@android:color/black"
                android:visibility="visible" />

            <TextView
                android:id="@+id/title"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"
                android:gravity="center"
                android:text="后台运行设置"
                android:textColor="@android:color/black"
                android:textSize="20sp"
                android:textStyle="bold" />

            <TextView
                android:id="@+id/right"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentEnd="true"
                android:layout_centerVertical="true"
                android:gravity="center"
                android:text=""
                android:textColor="@android:color/black"
                android:visibility="gone" />

        </RelativeLayout>

        <View
            android:id="@+id/line"
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:layout_alignParentBottom="true"
            android:background="?android:attr/listDivider"
            android:visibility="visible" />
    </RelativeLayout>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <ScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical">

                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:gravity="center"
                    android:orientation="horizontal"
                    android:padding="20dp">

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:gravity="center_vertical"
                        android:text="你的手机"
                        android:textColor="@android:color/black"
                        android:textSize="18sp" />

                    <TextView
                        android:id="@+id/bandName"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginStart="10dp"
                        android:gravity="center_vertical"
                        android:text="HUAWEI"
                        android:textColor="@android:color/holo_orange_dark"
                        android:textSize="18sp" />
                </LinearLayout>

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:gravity="center"
                    android:padding="20dp"
                    android:text="为什么要让应用程序在后台运行?"
                    android:textColor="@android:color/black"
                    android:textSize="14sp"
                    android:textStyle="bold" />

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:gravity="center"
                    android:paddingStart="40dp"
                    android:paddingTop="20dp"
                    android:paddingEnd="40dp"
                    android:paddingBottom="20dp"
                    android:text="接收通知需要应用在后台持续运行,以避免进程被系统终止。 这可能会错过来电和信息。"
                    android:textColor="@android:color/black"
                    android:textSize="14sp" />

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:gravity="center"
                    android:paddingStart="40dp"
                    android:paddingEnd="40dp"
                    android:text="注意:如果您的手机上安装了第三方安全管理应用,请将IMFitPro添加到它们的例外中, 不受其约束。"
                    android:textColor="@android:color/black"
                    android:textSize="14sp" />

                <RelativeLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="40dp">

                    <TextView
                        android:id="@+id/tutorials"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_centerInParent="true"
                        android:drawablePadding="20dp"
                        android:gravity="center"
                        android:text="查看自启动教程"
                        android:textColor="@android:color/holo_orange_dark"
                        android:textSize="18sp" />
                </RelativeLayout>

                <RelativeLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="20dp">

                    <TextView
                        android:id="@+id/autoStart"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_centerInParent="true"
                        android:drawablePadding="20dp"
                        android:gravity="center"
                        android:text="设置自启动"
                        android:textColor="@android:color/holo_orange_dark"
                        android:textSize="18sp" />
                </RelativeLayout>

                <RelativeLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="20dp">

                    <TextView
                        android:id="@+id/lockApp"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_centerInParent="true"
                        android:drawablePadding="20dp"
                        android:gravity="center"
                        android:text="在后台锁定应用程序"
                        android:textColor="@android:color/holo_orange_dark"
                        android:textSize="18sp" />
                </RelativeLayout>

                <RelativeLayout
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginTop="20dp">

                    <TextView
                        android:id="@+id/battery_optimization"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_centerInParent="true"
                        android:background="@drawable/btn_white_ripple"
                        android:drawableEnd="@drawable/girl_enter"
                        android:drawablePadding="20dp"
                        android:gravity="center"
                        android:text="忽略电池优化"
                        android:textColor="@android:color/holo_orange_dark"
                        android:textSize="18sp" />
                </RelativeLayout>

            </LinearLayout>
        </ScrollView>

        <WebView
            android:id="@+id/webView1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@android:color/white"
            android:visibility="gone" />

        <WebView
            android:id="@+id/webView2"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@android:color/white"
            android:visibility="gone" />
    </RelativeLayout>
</LinearLayout>

6. MainActivity

package com.example.testone.service;

import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Settings;
import android.util.Log;
import android.view.View;
import android.webkit.WebView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;

import com.example.testone.R;

import java.util.Locale;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private TextView mLeft;
    private TextView mBandName;
    private TextView mAutoStart;
    private TextView mTutorials;
    private TextView mLockApp;
    private TextView mBatteryOptimization;
    private WebView mWebView1, mWebView2;

    private boolean isWeb = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        //提示: 需要与服务共享数据自行绑定服务
        initView();
        /****************第四点*******************/
        //开启通知使用权限(有的手机需要开启才能在APP被kill掉后重启APP进程)
        if(!isNotificationListenerEnabled(this)) {
           openNotificationListenSettings(this);
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 200) {
            if (isNotificationListenerEnabled(this)) {//已经开启通知使用权
                //未开启APP通知,去开启
                if (!isNotificationEnabledForApp(this))
                    openNotificationSettingsForApp(this);
            }
        } else if (requestCode == 100) {
            if (isNotificationEnabledForApp(this)) {//已经开启APP通知
                //绑定了TestService再调用一下TestService中的initNotif()方法弹出通知。
            }
        }
    }

    /**
     * 是否开启APP通知
     *
     * @param context
     * @return
     */
    public static boolean isNotificationEnabledForApp(Context context) {
        return NotificationManagerCompat.from(context).areNotificationsEnabled();
    }

    /**
     * 开启APP通知
     *
     * @param context
     */
    public static void openNotificationSettingsForApp(Activity context) {
        try {
            // 锤子不能单个打开自己APP的 通知设置 界面 (打开界面方式有时间可以研究一下)
            if (getDeviceBrand().equalsIgnoreCase("SMARTISAN")) {
                Toast.makeText(context, "锤子手机请手动打开 设置--通知中心--开启IMFitPro通知开关", Toast.LENGTH_LONG).show();
                return;
            }
            // Links to this app's notification settings.
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {//8.0
                Intent intent = new Intent();
                intent.setAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
                intent.putExtra("android.provider.extra.APP_PACKAGE", context.getPackageName());
                intent.putExtra("app_package", context.getPackageName());
                intent.putExtra("app_uid", context.getApplicationInfo().uid);
                context.startActivityForResult(intent, 100);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 是否开启通知使用权限
     *
     * @param context
     * @return
     */
    public static boolean isNotificationListenerEnabled(Context context) {
        Set<String> packageNames = NotificationManagerCompat.getEnabledListenerPackages(context);
        if (packageNames.contains(context.getPackageName())) {
            return true;
        }
        return false;
    }

    /**
     * 开启通知使用权限
     */
    public static void openNotificationListenSettings(Activity context) {
        try {
            Intent intent = new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS);
            context.startActivityForResult(intent, 200);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void initView() {
        mBandName = (TextView) findViewById(R.id.bandName);
        mLeft = (TextView) findViewById(R.id.left);
        mLeft.setOnClickListener(this);
        mAutoStart = (TextView) findViewById(R.id.autoStart);
        mAutoStart.setOnClickListener(this);
        mTutorials = (TextView) findViewById(R.id.tutorials);
        mTutorials.setOnClickListener(this);
        mLockApp = (TextView) findViewById(R.id.lockApp);
        mLockApp.setOnClickListener(this);
        mBatteryOptimization = (TextView) findViewById(R.id.battery_optimization);
        mBatteryOptimization.setOnClickListener(this);
        mWebView1 = (WebView) findViewById(R.id.webView1);
        mWebView1.setOnClickListener(this);
        mWebView2 = (WebView) findViewById(R.id.webView2);
        mWebView2.setOnClickListener(this);

        mBandName.setText(getDeviceBrand());
    }

    @Override
    public void onClick(View v) {
        if (v == mLeft) {
            if (isWeb) {
                isWeb = false;
                mWebView1.setVisibility(View.GONE);
                mWebView2.setVisibility(View.GONE);
                return;
            }
            finish();
        } else if (v == mTutorials) {
            isWeb = true;
            mWebView1.setVisibility(View.VISIBLE);
            String brand = getDeviceBrand();
            String htmlName = "";
            if (brand.equalsIgnoreCase("huawei")) {
                htmlName = "huawei";
            } else if (brand.equalsIgnoreCase("honor")) {
                htmlName = "honor";
            } else if (brand.equalsIgnoreCase("infinix")) {
                htmlName = "infinix";
            } else if (brand.equalsIgnoreCase("meizu")) {
                htmlName = "meizu";
            } else if (brand.equalsIgnoreCase("xiaomi")) {
                htmlName = "xiaomi";
            } else if (brand.equalsIgnoreCase("redmi")) {
                htmlName = "redmi";
            } else if (brand.equalsIgnoreCase("oppo")) {
                htmlName = "oppo";
            } else if (brand.equalsIgnoreCase("realme")) {
                htmlName = "realme";
            } else if (brand.equalsIgnoreCase("onePlus")) {
                htmlName = "onePlus";
            } else if (brand.equalsIgnoreCase("vivo")) {
                htmlName = "vivo";
            } else if (brand.equalsIgnoreCase("iqoo")) {
                htmlName = "iqoo";
            } else if (brand.equalsIgnoreCase("smartisan")) {
                htmlName = "smartisan";
            } else if (brand.equalsIgnoreCase("sumsang")) {
                htmlName = "sumsang";
            } else if (brand.equalsIgnoreCase("asus")) {
                htmlName = "asus";
            } else if (brand.equalsIgnoreCase("lenovo")) {
                htmlName = "lenovo";
            } else if (brand.equalsIgnoreCase("nubia")) {
                htmlName = "nubia";
            }
            if (!getSystemLanguage().contains("zh")) {// 非中文
                htmlName = htmlName + "_e";
            }
            mWebView1.loadUrl("http://服务器接口地址/autostart/autostart_" + htmlName + ".html");

        } else if (v == mAutoStart) {
            Intent intents = null;
            for (Intent intent : AutoStartAppUtil.POWERMANAGER_INTENTS)
                if (getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY) != null) {
                    intents = intent;
                    break;
                }
            Log.e("gy", "手机品牌 device brand:" + getDeviceBrand());
            if (intents != null) {
                if (getDeviceBrand().equalsIgnoreCase("Infinix")) {
                    Toast.makeText(this, "无权打开系统界面, 请点击查看教程手动设置", Toast.LENGTH_SHORT).show();
                    return;
                }
                if (getDeviceBrand().equalsIgnoreCase("OPPO") || getDeviceBrand().equalsIgnoreCase("realme")) {
                    if (ContextCompat.checkSelfPermission(MainActivity.this, "oppo.permission.OPPO_COMPONENT_SAFE") != PackageManager.PERMISSION_GRANTED) {
                        // oppo 为系统权限不对外开放
                        Toast.makeText(this, "无权打开系统界面, 请点击查看教程手动设置", Toast.LENGTH_SHORT).show();
//                        ActivityCompat.requestPermissions(PermissionsDescriptionActivity.this, new
//                                String[]{"oppo.permission.OPPO_COMPONENT_SAFE"}, 1);
                    } else {
                        startActivity(intents);
                    }
                    return;
                }

                startActivity(intents);
            } else {
                if (getDeviceBrand().equalsIgnoreCase("OnePlus")) {
                    intents = new Intent("com.android.settings.action.BACKGROUND_OPTIMIZE");
                    startActivity(intents);
                    return;
                }
//                if (SystemUtil.getDeviceBrand().equalsIgnoreCase("SMARTISAN")) {
//                    intents = new Intent("com.smartisanos.security.action.SWITCHED_PERMISSIONS_NEW");//无效
//                    startActivity(intents);
//                    return;
//                }
                Toast.makeText(this, "无权打开系统界面, 请点击查看教程手动设置", Toast.LENGTH_SHORT).show();
            }
        } else if (v == mLockApp) {
            isWeb = true;
            mWebView2.setVisibility(View.VISIBLE);
            if (getSystemLanguage().contains("zh")) {// 中文
                mWebView2.loadUrl("http://服务器接口地址/locktask/lockApp.html");
            } else {
                mWebView2.loadUrl("http://服务器接口地址/locktask/lockApp_e.html");
            }
        } else if (v == mBatteryOptimization) {
            // 显示屏幕以控制哪些应用可以忽略电池优化
            // 您可以PowerManager.isIgnoringBatteryOptimizations()用来确定应用程序是否已经忽略优化。
            // 您可以 ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS用来要求用户将您放在此列表中。
            //android.settings.IGNORE_BATTERY_OPTIMIZATION_SETTINGS
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setIcon(R.mipmap.ic_launcher)
                    .setTitle("忽略电池优化")
                    .setMessage("参考说明:\n在手机&#160;设置&#160;-->&#160;电池&#160;-->&#160;耗电管理&#160;中找到" + getString(R.string.app_name) + ",&#160;设置&#160;允许后台运行&#160;或&#160;允许后台启动 等")
                    .setPositiveButton("设置忽略", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(final DialogInterface dialog, final int which) {
                            if (!isIgnoringBatteryOptimizations()) {
                                try {
                                    Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
                                    intent.setData(Uri.parse("package:" + getPackageName()));
                                    //跳转之前判断intent是否存在,否则有的机型会报找不到activity
                                    if (intent.resolveActivity(getPackageManager()) == null) {
                                        intent = new Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS);
                                        intent.setData(Uri.parse("package:" + getPackageName()));
                                        if (intent.resolveActivity(getPackageManager()) == null) {
                                            showToast("无法启动系统界面,请以参考说明操作");
                                        } else {
                                            startActivity(intent);
                                        }
                                    } else {
                                        startActivity(intent);
                                    }
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                            }
                        }
                    })
                    .show();
        }
    }

    /**
     * 确定应用程序是否已经忽略电池优化
     *
     * @return
     */
    private boolean isIgnoringBatteryOptimizations() {
        boolean isIgnoring = false;
        PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
        if (powerManager != null) {
            isIgnoring = powerManager.isIgnoringBatteryOptimizations(getPackageName());
        }
        return isIgnoring;
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        //super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case 1:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    Intent intents = null;
                    for (Intent intent : AutoStartAppUtil.POWERMANAGER_INTENTS)
                        if (getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY) != null) {
                            intents = intent;
                            break;
                        }
                    if (intents != null) {
                        startActivity(intents);
                    }
                } else {
                    Toast.makeText(this, "无权打开系统界面, 请点击查看教程手动设置", Toast.LENGTH_SHORT).show();
                }
                break;
            default:
        }
    }

    /**
     * 原生Android系统 开启后台运行调用这里
     */
    public void requestIgnoreBatteryOptimizations() {
        try {
            Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
            intent.setData(Uri.parse("package:" + getPackageName()));
            startActivity(intent);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            moveTaskToBack(true);//按返回键,不 finish activity
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

    /**
     * 获取当前手机系统语言。
     *
     * @return 返回当前系统语言。例如:当前设置的是“中文-中国”,则返回“zh-CN”
     */
    public static String getSystemLanguage() {
        return Locale.getDefault().getLanguage();
    }

    /**
     * 获取当前系统上的语言列表(Locale列表)
     *
     * @return  语言列表
     */
    public static Locale[] getSystemLanguageList() {
        return Locale.getAvailableLocales();
    }

    /**
     * 获取当前手机系统版本号
     *
     * @return  系统版本号
     */
    public static String getSystemVersion() {
        return android.os.Build.VERSION.RELEASE;
    }

    /**
     * 获取手机型号
     *
     * @return  手机型号
     */
    public static String getSystemModel() {
        return android.os.Build.MODEL;
    }

    /**
     * 获取手机厂商
     *
     * @return  手机厂商
     */
    public static String getDeviceBrand() {
        return android.os.Build.BRAND;
    }

}
mWebView1.loadUrl(), mWebView2.loadUrl() 的 HTML 文件资源地址:
链接:  https://pan.baidu.com/s/1vmRHsQDOHMw7iY-7OlA65Q 提取码: n83x

7. AutoStartAppUtil

package com.example.testone.service;

import android.content.ComponentName;
import android.content.Intent;

/**
 * 自启动跳转界面清单
 */
public class AutoStartAppUtil {

    public static final Intent[] POWERMANAGER_INTENTS = {
            new Intent().setComponent(new ComponentName("com.miui.securitycenter", "com.miui.permcenter.autostart.AutoStartManagementActivity")),
            new Intent().setComponent(new ComponentName("com.letv.android.letvsafe", "com.letv.android.letvsafe.AutobootManageActivity")),
            new Intent().setComponent(new ComponentName("com.huawei.systemmanager", "com.huawei.systemmanager.startupmgr.ui.StartupNormalAppListActivity")),
            new Intent().setComponent(new ComponentName("com.huawei.systemmanager", "com.huawei.systemmanager.optimize.process.ProtectActivity")),
            new Intent().setComponent(new ComponentName("com.huawei.systemmanager", "com.huawei.systemmanager.appcontrol.activity.StartupAppControlActivity")),
            //new Intent().setComponent(new ComponentName("com.coloros.safecenter", "com.coloros.privacypermissionsentry.PermissionTopActivity")),
            new Intent().setComponent(new ComponentName("com.coloros.safecenter", "com.coloros.safecenter.permission.startup.StartupAppListActivity")),
            new Intent().setComponent(new ComponentName("com.coloros.safecenter", "com.coloros.safecenter.startupapp.StartupAppListActivity")),
            new Intent().setComponent(new ComponentName("com.oppo.safe", "com.oppo.safe.permission.startup.StartupAppListActivity")),
            new Intent().setComponent(new ComponentName("com.iqoo.secure", "com.iqoo.secure.ui.phoneoptimize.AddWhiteListActivity")),
            new Intent().setComponent(new ComponentName("com.iqoo.secure", "com.iqoo.secure.ui.phoneoptimize.BgStartUpManager")),
            new Intent().setComponent(new ComponentName("com.vivo.permissionmanager", "com.vivo.permissionmanager.activity.BgStartUpManagerActivity")),
            new Intent().setComponent(new ComponentName("com.samsung.android.lool", "com.samsung.android.sm.battery.ui.BatteryActivity")),
            new Intent().setComponent(new ComponentName("com.samsung.android.lool", "com.samsung.android.sm.ui.battery.BatteryActivity")),
            new Intent().setComponent(new ComponentName("com.htc.pitroad", "com.htc.pitroad.landingpage.activity.LandingPageActivity")),
            new Intent().setComponent(new ComponentName("com.asus.mobilemanager", "com.asus.mobilemanager.MainActivity")),
            new Intent().setComponent(new ComponentName("com.transsion.phonemanager", "com.itel.autobootmanager.activity.AutoBootMgrActivity")),
            new Intent().setComponent(new ComponentName("com.meizu.safe", "com.meizu.safe.permission.SmartBGActivity")),
            new Intent().setComponent(new ComponentName("cn.nubia.security2", "cn.nubia.security.appmanage.selfstart.ui.SelfStartActivity")),
            new Intent().setComponent(new ComponentName("com.transsion.phonemaster", "com.cyin.himgr.applicationmanager.view.activities.AutoStartActivity")),
    };

}

效果:

APP后台运行设置

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值