I'm trying to add my package in doze whitelist.
With ($ adb shell dumpsys deviceidle whitelist +PACKAGE), I can add my package in whitelist,
and this command makes change in the file /data/system/deviceidle.xml.
Now, I'm curious about who generate deviceidle.xml.
Is there anyone who knows about deviceidle.xml?
I found a clue in framework module,
IDeviceController.addPowerSaveWhitelistApp(String name) helps to add my package into ;
also, /data/system/deviceidle.xml is updated.
You can check with adb dumpsys
$ adb shell dumpsys deviceidle
$ adb shell cat /data/system/deviceidle.xml
As far as I know, doze whitelisting is done by system creators.
You can ask user for whitelisting via intent action: Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS.
In the DeviceIdleController soruce code you can see that it reads deviceidle.xml
in constructor. It might be that, if you know the file structure and have rooted device you can manually create and edit this file.
#VisibleForTesting DeviceIdleController(Context context, Injector injector) {
super(context);
mInjector = injector;
mConfigFile = new AtomicFile(new File(getSystemDir(), "deviceidle.xml"));
[...]
}
Related
my environment:
cpu:rk3288
os:android7.1
transfer method:sftp
I wrote android code to do these things below:
get the logcat with code "adb logcat -d -v time -f /mnt/sdcard/logcat.txt"
pull the file logcat.tx to the server with sftp
in 1st step I coding some java language with android studio like below, if anyone can help me, thanks!
Process p = Runtime.getRuntime().exec("adb logcat -d -v time -f /mnt/sdcard/logcat.txt");
error massage:
java.io.IOException: Cannot run program "adb": error=13, Permission denied
You can't use adb commands from inside the device, even if you somehow have it in the device you would need root permissions. The adb is the bridge between the PC and the device. Take a look here: https://developer.android.com/studio/command-line/adb
Although you probably can just remove the adb and use logcat directly, like:
Process p = Runtime.getRuntime().exec("logcat -d -v time -f /mnt/sdcard/logcat.txt");
Here you can see some more options about using the logcat command: Read logcat programmatically within application, including Reetpreet Brar's answer, that I think will be better for you:
Process pq=Runtime.getRuntime().exec("logcat v main"); //adapt the command for yourself
BufferedReader brq = new BufferedReader(new InputStreamReader(pq.getInputStream()));
String sq="";
while ((sq = brq.readLine()) != null)
{
//here you can do what you want with the log, like writing in a file to
//send to the server later.
}
Here you can choose methods to write your file: How to Read/Write String from a File in Android
Then, just send the file to the server.
I try to enable/disable wifi programmatically within my Xamarin Ui Test.
I already found this: Android: How to Enable/Disable Wifi or Internet Connection Programmatically. But it seems not to work within the UiTest.
I also tried something like this:
Context appContext = Android.App.Application.Context;
var wifiManager = (WifiManager)appContext.GetSystemService(Context.WifiService);
bool status = false;
wifiManager.SetWifiEnabled(status);
The first line (Android.App.Application.Context) throws an exception:
Message: System.IO.FileNotFoundException : Could not load file or assembly 'Java.Interop, Version=0.1.0.0, Culture=neutral, PublicKeyToken=84e04ff9cfb79065' or one of its dependencies. The system cannot find the file specified.
I'm using following namespaces:
using Android.Net.Wifi;
using Android.Content;
My project has a reference to Mono.Android.
The backdoor approach works fine for me.
The solution that works for me was a combination of:
Android: How to Enable/Disable Wifi or Internet Connection Programmatically
https://learn.microsoft.com/en-us/appcenter/test-cloud/uitest/working-with-backdoors
Some small own changes (for appcontext/context). Just context did not work for me.
1.: Add following line to the AndroidManifest.xml file of the Android project:
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
2.: Add following lines to the MainActivity.cs of the Android project:
using Java.Interop;
using Android.Net.Wifi;
[Export("ChangeWifiState")]
public void ChangeWifiState(bool state)
{
Context appContext = Android.App.Application.Context;
var wifiManager = (WifiManager)appContext.GetSystemService(WifiService);
wifiManager.SetWifiEnabled(state);
}
3.: Call following method out of the Xamarin Ui Test:
app.Invoke("ChangeWifiState", false); // true to enable wifi, false to disable wifi
PS: I use Xamarin Forms. I've got four different projects: a core project, an Android project, a Ui project, and a test project.
I just found a second solution without using the actual app.
It uses ADB commands to enable/disable wifi:
var process = new System.Diagnostics.Process();
var startInfo = new System.Diagnostics.ProcessStartInfo
{
WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden,
FileName = "cmd.exe",
Arguments = "/C adb shell am start -a android.intent.action.MAIN -n com.android.settings/.wifi.WifiSettings adb shell input keyevent 19 & adb shell input keyevent 19 & adb shell input keyevent 23 & adb shell input keyevent 82 & adb shell input tap 500 1000"
};
process.StartInfo = startInfo;
process.Start();
This can be used without a rooted device :).
Steps explained:
adb shell am start -a android.intent.action.MAIN -n com.android.settings/.wifi.WifiSettings opens the wifi settings.
adb shell input keyevent 23 enables/disables wifi.
I'm not sure why the command adb shell input keyevent 19 is used, but it works.
adb shell input keyevent 82 clicks the menu button to change back to the original app.
adb shell input tap 500 1000 clicks the coordinate x=500, y=1000 (center of screen).This may need be changed for different solutions.
Sources for this solution:
How to turn off Wifi via ADB?
ADB Shell Input Events
Run Command Prompt Commands
I have tried to make script to reboot tablet from charging mode to normal if it's started by pluging usb charger. Android init language is quite straightforward but actually how it's then parced is quite mystery to me.
so i have my_script.sh implemented on root.
Added to the system file my_script.sh initrd/my_script.sh 0750
and repacked boot.img. Verified that everything is it place and access rights should be correct.
#!/system/bin/sh
/system/bin/reboot -c reboot now
Then i have in init.rc
service rebootit /system/bin/sh /my_script.sh
class main
user root
oneshot
then i have put following under "on charger" at init.rc
start rebootit
Any idea how this could be achieved?
Edit 1.
Tried following.
service rebootit /system/bin/reboot -c reboot now
class main
user root
oneshot
This was the outcome.
[4.648753] init: cannot execve('/system/bin/reboot'): Permission denied
[4.649167] type=1400 audit(85946.779:4): avc: denied { execute_no_trans } for pid=331 comm="init" path="/system/bin/reboot" dev="mmcblk0p21" ino=730 scontext=u:r:init:s0 tcontext=u:object_r:system_file:s0 tclass=file permissive=0
Edit 2.
Ok. Some progress. echo b > /proc/sysrq-trigger seems to reboot but now i need to found some variable which i can use to separate script running when booting to normal mode. I have tried to use this kind of script which i found from another init file. just modifid it suit my needs but still no luck.
#!/system/bin/sh
bootmode=`getprop ro.bootmode`
if [ "$bootmode" = "charger" ]; then # Reboot the tablet
echo b > /proc/sysrq-trigger
fi
Edit 3. The Solution
Now i finally got it.
On init.rc i have added following:
#Check if chargermode and start rebootit service.
on property:ro.bootmode=charger
start rebootit
and after it added following:
#rebootit service which command reboot
service rebootit /su/bin/su /system/bin/reboot -c reboot now
user root
oneshot
You need to have SU installed to work.
Is there an API to enable an Xposed module in Android from the shell (using ADB) and not through the device's UI.
This is constantly a bother for automation, when we need to install our module on a clean test emulator. This is currently the only step that we are required to do manually.
A simple google search + overview of the XPosed documentation didn't yield anything worth while.
As you already know, this is approach disfavored for end-users, but for testing, you have to echo the path of the apk to Xposed config file:
Pre-Lollipop:
adb shell "echo '/data/app/com.xyz.example-1.apk' >> /data/data/de.robv.android.xposed.installer/conf/modules.list"
Lollipop and newer:
adb shell "echo '/data/app/com.xyz.example-1 OR -2/base.apk' >> /data/data/de.robv.android.xposed.installer/conf/modules.list"
For these commands you need to have your emulator support root adb, type
adb root
into the command line. If your emulator doesn't support rooted/insecure adbd, you can also add a su -c before the echo to get root rights.
EDIT: the easiest way to find which number you have to use in directory name would be what #brendan suggested.
This worked for me on KitKat:
(1) Update shared_pres xml file:
If you look at the /data/data/de.robv.android.xposed.installer/shared_prefs/ directory. You will see an enabled_modules.xml file.
In my case I was only working with a single module so I would just overwrite the file. If you have several modules you may wish to do an edit/update.
I would have a local enabled_modules.xml file that looked like this:
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<map>
<int name="com.companyname.xposedmodule" value="1" />
</map>
...where com.companyname.xposedmodule is the name of your module.
Then post build you can execute a simple:
adb push enabled_modules.xml /data/data/de.robv.android.xposed.installer/shared_prefs/
(2) Update modules.list config file:
You also need to do what #Maxr1998 suggested. I scripted it this way:
adb shell "[ -f /data/app/com.companyname.xposedmodule-1.apk ] && echo '/data/app/com.companyname.xposedmodule-1.apk' >> /data/data/de.robv.android.xposed.installer/conf/modules.list
adb shell "[ -f /data/app/com.companyname.xposedmodule-2.apk ] && echo '/data/app/com.companyname.xposedmodule-2.apk' >> /data/data/de.robv.android.xposed.installer/conf/modules.list
I use slf4j-android in my Android application.
The doc says if I write log.trace then it's the almost the same as I write Log.v.
But the default logging level seems to be INFO, and logcat shows only log.info and above, and I can't see how can I change the defaults.
1) How can I configure slf4j-android
2) If I can't: are there any other slf4j implementations for Android, more configurable
For example if your tag is MyClass type in command line
adb shell setprop log.tag.MyClass DEBUG
The way I found is this procedure
Find logger slf4j-android source here
You should see that all methods are preceded by if (isLoggable(...)) that in turn call android.util.Log isLoggable which can be found on opengrok
The description of this method explains how to set a proper property.
Note that slf4j-android will rename longer tags i.e. WiFiDirectBroadcastReceiver will be changed to sth like *directBroadcastReceiver.
As far as I know you cannot use * in setprop calls so you need to manage your tags carefully.
It's a pain, but I won't give up on slf4j. This is what I ended up doing:
In my source code, I instantiate a logger per activity:
public class MyActivity extends AppCompatActivity {
private final Logger LOGGER = org.slf4j.LoggerFactory.getLogger(this.getClass().getName());
...
}
In the project root, I place a shell script for setting the logging level of all activities in one go:
#!/bin/sh
# Add as many lines as needed to set the logging for
# all the activities in your app
adb shell setprop log.tag.MyActivity "$1"
Then, whenever I need to set the logging level for a session, I switch to the Terminal view in Android Studio and just run the script:
$ sh adb-setloglevel VERBOSE