Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

新增daemon分之; #13

Open
wants to merge 1 commit into
base: hao
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,4 @@ lint/generated/
lint/outputs/
lint/tmp/
# lint/reports/
/.idea/
45 changes: 43 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,43 @@
# KeepAlivePerfect
Android4.4到android12.0 完美的保活方案
## 安卓后台保活2022新姿势
适配华为大部分系列手机,vivo,OPPO 部分机型,小米的不支持,可见小米在对抗后台自保上做得最好
本项目原本是给某个公司合作开发的,最后给了对方SDK之后由于付款问题闹得很郁闷,想着这个代码拿在自己手上也没用,就发出来给大家参考参考。目前分析的结果来看,这个是全网目前还能使用的保活方案,曝光之后很有可能活不到明年,如果你的公司恰好使用了这种方案,那么是时候开始研究新的方案了。最后说一下这种想白拿的公司,说实话我不是靠Android技术谋生的,最多就少了点零花钱,但是这个方案被封之后,你还有多少个机会白拿?

# 原理

安卓后台保活前前后后网上出了好多公开的方案,但是到目前为止,还能广泛使用的并没有,我通过了研究了一下网上几个大厂的APP(APP名字就不点名了),整理实现了这个方案
虽然本方案看似集成了好几个保活的方案,比如一像素,JOB,等等,但是对于新版本android真正起作用的还是双进程守护。双进程守护的代码网上一搜一大堆,但是自己试过就知道了,现在的很多ROM已经封杀了这个方案,那些代码只能在原生系统上玩玩。
这里大概说一下双进程守护的逻辑,同时启动A进程和B进程,相互守护,检测到对方退出就再次启动对方,大部分公开的方案都是使用startservice启动,网上有好几个改进版,甚至有的都在native层自己实现和service manger的通信逻辑来启动服务,为的就是能在被杀时候第一时间再次启动。但是,改到native层也没有用,现在大部分rom已经封杀了startservice,我大概研究了下样本,发现样本使用的是startInstrumentation来启动进程,对于Instrumentation不了解的同学可以自行百度。 所以只需要在MarsDaemon基础上做一下小改动即可:
```
@Override
public void onDaemonDead() {
Log.d(TAG, "on daemon dead!");
if (startServiceByAmsBinder()) {

int pid = Process.myPid();
Log.d(TAG, "mPid: " + mPid + " current pid: " + pid);
Daemon.context.startInstrumentation(mApp,null,null);
android.os.Process.killProcess(mPid);
}
}
```

# 2步集成使用
1、 打开library的AndroidManifest.xml找 如下位置:
```<instrumentation
android:name="com.daemon.DInstrumentation"
android:targetPackage="com.daemonLibrary.demo"
android:targetProcesses="com.daemonLibrary.demo,com.daemonLibrary.demo:service" />
<application>
```
将包名替换成自己的包名

2、在app的Application中添加启动代码,并实现配置接口和回调接口
```
override fun attachBaseContext(base: Context?) {
super.attachBaseContext(base)
//DaemonLog.d("Application onCrearte")
Daemon.startWork(this, DaemonConfigurationImplement(this), DaemonCallbackImplement())
}
```


1 change: 1 addition & 0 deletions app/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
44 changes: 44 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
}

android {
compileSdk 33

defaultConfig {
applicationId "com.daemonLibrary.demo"

minSdk 23
targetSdk 31

versionCode 1
versionName "1.0"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}

dependencies {
implementation 'androidx.core:core-ktx:1.9.0'
implementation 'androidx.appcompat:appcompat:1.5.1'
implementation 'com.google.android.material:material:1.7.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.navigation:navigation-fragment-ktx:2.5.3'
implementation 'androidx.navigation:navigation-ui-ktx:2.5.3'
implementation project(path: ':library')
}
21 changes: 21 additions & 0 deletions app/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.daemonLibrary.demo

import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4

import org.junit.Test
import org.junit.runner.RunWith

import org.junit.Assert.*

/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("com.daemonLibrary.demo", appContext.packageName)
}
}
66 changes: 66 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.daemonLibrary.demo">

<instrumentation
android:name="com.daemon.DInstrumentation"
android:targetPackage="com.daemonLibrary.demo"
android:targetProcesses="com.daemonLibrary.demo,com.daemonLibrary.demo:service" />

<application
android:name=".MainApp"
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/Theme.MyApplication">


<activity android:name=".OnRemoveActivity" />

<activity
android:name=".MainActivity"
android:exported="true"
android:label="@string/app_name"
android:theme="@style/Theme.MyApplication.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<receiver
android:name=".SystemBroadcastReceiver"
android:enabled="true"
android:exported="true">

<intent-filter>

<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.CLOSE_SYSTEM_DIALOGS" />
</intent-filter>

<intent-filter>

<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>

<intent-filter>

<action android:name="android.intent.action.PACKAGE_REMOVED" />

<data android:scheme="package" />
</intent-filter>

<intent-filter>

<action android:name="android.intent.action.USER_PRESENT" />
</intent-filter>
</receiver>
</application>

</manifest>
6 changes: 6 additions & 0 deletions app/src/main/java/com/daemonLibrary/demo/ActivityOne.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.daemonLibrary.demo

import androidx.appcompat.app.AppCompatActivity

class ActivityOne: AppCompatActivity() {
}
6 changes: 6 additions & 0 deletions app/src/main/java/com/daemonLibrary/demo/ActivityTow.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.daemonLibrary.demo

import androidx.appcompat.app.AppCompatActivity

class ActivityTow: AppCompatActivity() {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.daemonLibrary.demo;


import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.os.Build;

public class ForegroundNotifyUtils {
private static final String CHANNEL_ID = "BCD41FB3-2EE7-4781-8917-7B8D8DB355DC";

public static Notification getForegroundNotification(Context context, String title, String text) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationChannel Channel = new NotificationChannel(CHANNEL_ID, "可关闭通知", NotificationManager.IMPORTANCE_DEFAULT);
Channel.enableLights(true);
Channel.setLightColor(Color.GREEN);
Channel.setShowBadge(true);
Channel.setDescription("");
Channel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
Channel.enableVibration(false);
Channel.setSound(null, null);
manager.createNotificationChannel(Channel);

Notification notification = new Notification.Builder(context, CHANNEL_ID)
.setContentTitle(title)
.setContentText(text)
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_launcher_foreground))
.build();
return notification;
} else {
Notification notification = new Notification.Builder(context)
.setContentTitle(title)//设置标题
.setContentText(text)//设置内容
.setWhen(System.currentTimeMillis())//设置创建时间
.build();
return notification;
}
}
}
23 changes: 23 additions & 0 deletions app/src/main/java/com/daemonLibrary/demo/MainActivity.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.daemonLibrary.demo

import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.provider.Settings
import androidx.appcompat.app.AppCompatActivity


class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
if (!Settings.canDrawOverlays(this)) {
val intent = Intent(
Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:$packageName")
)
startActivityForResult(intent, 10)
}
}
}
Loading