Skip to content
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
10 changes: 10 additions & 0 deletions BatteryHookSample/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
<manifest package="com.sample.battery"
xmlns:android="http://schemas.android.com/apk/res/android">

<uses-permission android:name = "android.permission.WAKE_LOCK" />
<uses-permission android:name = "android.permission.ACCESS_FINE_LOCATION"/>


<application
android:name="com.sample.battery.SampleApplication"
android:allowBackup="true"
Expand All @@ -18,6 +22,12 @@
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>

<receiver android:name=".alarm.MyAlarmReceiver">
<intent-filter>
<action android:name="intent_alarm"/>
</intent-filter>
</receiver>
</application>

</manifest>
127 changes: 121 additions & 6 deletions BatteryHookSample/src/main/java/com/sample/battery/MainActivity.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,35 @@
package com.sample.battery;

import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.PowerManager;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.view.View;
import android.widget.Button;

import com.sample.battery.R;
import com.sample.battery.alarm.IAlarmManagerHook;
import com.sample.battery.alarm.MyAlarmReceiver;
import com.sample.battery.gps.ILocationManagerHook;
import com.sample.battery.wakelock.IPowerManagerHook;

import static android.Manifest.permission.ACCESS_FINE_LOCATION;

public class MainActivity extends Activity {
public static Context sContext;

Handler handler = new Handler();
private PowerManager.WakeLock wakeLock;
private LocationManager locationManager;
private LocationListener locationListener;

@Override
protected void onCreate(Bundle savedInstanceState) {
Expand All @@ -23,7 +40,7 @@ protected void onCreate(Bundle savedInstanceState) {
hookAlarm.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {

new IAlarmManagerHook(sContext).onInstall();
}
});

Expand All @@ -32,19 +49,117 @@ public void onClick(View v) {
hookWakelock.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {


new IPowerManagerHook(sContext).onInstall();
}
});

final Button hookGPS = (Button) findViewById(R.id.hook_gps);
hookGPS.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new ILocationManagerHook(sContext).onInstall();
}
});

final Button wakelockAcquire = (Button) findViewById(R.id.wakelock_acquire);
wakelockAcquire.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
PowerManager powerManager = (PowerManager) sContext.getSystemService(POWER_SERVICE);
wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, this.getClass().getName());//持有唤醒锁
wakeLock.setReferenceCounted(false);
wakeLock.acquire(60 * 1000); //亮屏60s

}
});

final Button wakelockRelease = (Button) findViewById(R.id.wakelock_release);
wakelockRelease.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (wakeLock != null){
wakeLock.release();//释放锁,灭屏
}
}
});

final Button alarmSet = (Button) findViewById(R.id.alarm_set);
alarmSet.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AlarmManager alarmService = (AlarmManager) sContext.getSystemService(ALARM_SERVICE);
Intent alarmIntent = new Intent(sContext, MyAlarmReceiver.class).setAction("intent_alarm");
PendingIntent broadcast = PendingIntent.getBroadcast(sContext, 0, alarmIntent, 0);//通过广播接收
alarmService.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 2000, broadcast);//INTERVAL毫秒后触
}
});

final Button alarmCancel = (Button) findViewById(R.id.alarm_cancel);
alarmCancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AlarmManager alarmService = (AlarmManager) sContext.getSystemService(ALARM_SERVICE);
Intent alarmIntent = new Intent(sContext, MyAlarmReceiver.class).setAction("intent_alarm");
PendingIntent broadcast = PendingIntent.getBroadcast(sContext, 0, alarmIntent, 0);
alarmService.cancel(broadcast);
}
});

final Button gpsRequest = (Button) findViewById(R.id.gps_request);
gpsRequest.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {

if (ContextCompat.checkSelfPermission(MainActivity.this, ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{ACCESS_FINE_LOCATION}, 100);
} else {
locationManager = (LocationManager) sContext.getSystemService(LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 3000, 1, locationListener);
}

}
});

final Button gpsRemove = (Button) findViewById(R.id.gps_remove);
gpsRemove.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (locationManager != null && locationListener != null) {
// 关闭程序时将监听器移除
locationManager.removeUpdates(locationListener);
}
}
});

locationListener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
Log.e("HOOOOOOOOK", location.toString());
}

@Override
public void onStatusChanged(String provider, int status, Bundle extras) {

}

@Override
public void onProviderEnabled(String provider) {

}

@Override
public void onProviderDisabled(String provider) {

}
};
}

@Override
public void onRequestPermissionsResult(
int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.sample.battery.alarm;

import android.content.Context;
import android.util.Log;

import com.sample.battery.hook.BaseHookHandle;
import com.sample.battery.hook.ProxyHook;

import java.lang.reflect.Field;
import java.lang.reflect.Proxy;

public class IAlarmManagerHook extends ProxyHook {

public IAlarmManagerHook(Context context) {
super(context);
}

@Override
public BaseHookHandle createBaseHookHandle() {
return new IAlarmManagerHookHandle();
}

@Override
public void onInstall() {
Object oldObj = mHostContext.getSystemService(Context.ALARM_SERVICE);
Class<?> clazz = oldObj.getClass();

try {
Field field = clazz.getDeclaredField("mService");
field.setAccessible(true);

final Object mService = field.get(oldObj);
setProxyObj(mService);

Object newObj = Proxy.newProxyInstance(this.getClass().getClassLoader(), mService.getClass().getInterfaces(), this);
field.set(oldObj, newObj);

} catch (NoSuchFieldException e) {
Log.e("HOOOOOOOOK", "IAlarmManager is null");
} catch (IllegalAccessException e){
e.fillInStackTrace();
}

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package com.sample.battery.alarm;

import android.util.Log;

import com.sample.battery.hook.BaseHookHandle;
import com.sample.battery.hook.HookedMethodHandler;
import com.sample.battery.hook.Utils;

import java.lang.reflect.Method;

public class IAlarmManagerHookHandle extends BaseHookHandle {

@Override
public void init() {
sHookedMethodHandlers.put("set", new setAlarmManagerService());
sHookedMethodHandlers.put("remove", new removeAlarmManagerService());
}

public class setAlarmManagerService extends HookedMethodHandler {

@Override
protected boolean beforeInvoke(Object receiver, Method method, Object[] args) throws Throwable {
// 设置 Alarm
Log.e("HOOOOOOOOK", "--set--");
Log.e("HOOOOOOOOK", Utils.getStackTrace());

// 前台:单个Alarm每小时不能启动超20次
// 后台:单个Alarm每小时不能启动超10次
return super.beforeInvoke(receiver, method, args);
}

@Override
protected void afterInvoke(Object receiver, Method method, Object[] args, Object invokeResult) throws Throwable {
super.afterInvoke(receiver, method, args, invokeResult);
}
}

public class removeAlarmManagerService extends HookedMethodHandler {

@Override
protected boolean beforeInvoke(Object receiver, Method method, Object[] args) throws Throwable {
// 清除 Alarm
Log.e("HOOOOOOOOK", "--remove--");
Log.e("HOOOOOOOOK", Utils.getStackTrace());
return super.beforeInvoke(receiver, method, args);
}

@Override
protected void afterInvoke(Object receiver, Method method, Object[] args, Object invokeResult) throws Throwable {
super.afterInvoke(receiver, method, args, invokeResult);
}
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.sample.battery.alarm;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

public class MyAlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.sample.battery.gps;

import android.content.Context;
import android.util.Log;

import com.sample.battery.hook.BaseHookHandle;
import com.sample.battery.hook.ProxyHook;

import java.lang.reflect.Field;
import java.lang.reflect.Proxy;

public class ILocationManagerHook extends ProxyHook {

public ILocationManagerHook(Context context) {
super(context);
}

@Override
public BaseHookHandle createBaseHookHandle() {
return new ILocationManagerHookHandle();
}

@Override
public void onInstall() {
Object oldObj = mHostContext.getSystemService(Context.LOCATION_SERVICE);
Class<?> clazz = oldObj.getClass();

try {
Field field = clazz.getDeclaredField("mService");
field.setAccessible(true);

final Object mService = field.get(oldObj);
setProxyObj(mService);

Object newObj = Proxy.newProxyInstance(this.getClass().getClassLoader(), mService.getClass().getInterfaces(), this);
field.set(oldObj, newObj);

} catch (NoSuchFieldException e) {
Log.e("HOOOOOOOOK", "ILocationManager is null");
} catch (IllegalAccessException e){
e.fillInStackTrace();
}

}
}
Loading