I was curious if there is any library to work with the capacitive buttons of Samsung phones??
I mean to light them up when an event occurs, or blink them, stuffs like that...
Thanks,
rohitkg
There is nothing in the Android SDK for this, as there is no assumption that such buttons exist, have backlights, etc. You are welcome to contact device manufacturers to see if they have a documented and supported means of doing this for their specific devices.
Here's a code snippet I grabbed from samsung-moment-notifications.
Process process = null;
DataOutputStream os = null;
try {
// get root
process = Runtime.getRuntime().exec("su");
os = new DataOutputStream(process.getOutputStream());
// write the command
os.writeBytes("echo 100 > /sys/class/leds/button-backlight/brightness\n");
os.writeBytes("exit\n");
// clear the buffer
os.flush();
Toast.makeText(NotificationLights.this, "Lights are on", Toast.LENGTH_SHORT).show();
// wait for complete
process.waitFor();
// won't catch an error with root, but it has to have an exception catcher to execute
} catch (Exception e) {
Toast.makeText(NotificationLights.this, "Couldn't get SU, are you rooted?", Toast.LENGTH_SHORT).show();
return;
}
1- You must have a rooted device.
2- You must know the location of the script which turns the lights on/off for each device.
/sys/class/leds/button-backlight/brightness is specific to the Samsung Moment.
If you were to try it on another device it wouldn't work.
Related
I'm writing an android app that sets the max frequency, governor etc.. when the screen turns off. To do it i have a service running that receives screen on/off broadcast intents. When the screen off event fires, I read from the shared preferences and set whatever is set by the user with this function
public static void writeFile(String file, String content) {
try {
Process suProcess = Runtime.getRuntime().exec("su");
DataOutputStream out = new DataOutputStream(suProcess.getOutputStream());
out.writeBytes("echo '" + content + "' > '" + file + "'");
out.flush();
out.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
Then when the screen turns back on, i revert the system to its previous state by rewriting the files. Everything is working nicely, working as intended.
The problem is i'm noticing some lag when turning the screen on/off. Also when i turn the screen on, i see the toast message from SuperUser "App was granted su access", and it pops up once for every command. Is there a way to hide that toast message? I haven't found any way to hide a toast message from another activity. I know they can be disabled in the superuser app, but that's not ideal. I read you can write your own superuser binary but that sounds alot more complicated than simple java programming... also sounds like it could lead to security problems.
Basically i'm asking what's the best way to do this, so that it's as non-invasive to the user as possible?
I haven't used su, but I think if you don't close the stream every time it should only display toast once.
Is is possible to run getevent from an Android service and get output similar to what you see when running adb to call getevent from a command prompt on a development machine? When I try something like:
ProcessBuilder builder = new ProcessBuilder()
.command("getevent")
.redirectErrorStream(true)
.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(builder.getInputStream()));
...
the output I get for each device looks like:
could not open /dev/input/event[n], Permission denied
Is it just not possible to access low level information like this because of Android's security protections? Would it be possible on a "rooted" device?
Why I am trying to do this:
I would like to record a user's actions (touch and gesture events) on an Android device for the purpose of usability testing. An accessibility service seems to be the way to go, but the information is not detailed enough. For a swipe gesture, for example, I cannot get the screen coordinates of where the user swiped. I was thinking that getting the low-level input from the touch screen might let me get more detailed information. Maybe there is a better way to do this?
(I'm a newbie in the Android world. This kind of thing is easy on Windows.)
You can do like this.
th = new Thread(new Runnable(){
private Process exec;
#Override
public void run() {
try {
exec = Runtime.getRuntime().exec(new String[]{"su","-c","getevent -t " + device});
InputStreamReader is = new InputStreamReader(
exec.getInputStream());
String s;
BufferedReader br = new BufferedReader(is);
while(((s = br.readLine()) != null) && run){
...
}
is.close();
exec.destroy();
} catch (IOException e) {
e.printStackTrace();
}
}
You must use 'su' to get the root permission, but by this way you can't get the real time event, because there is a buffer size of 4k, you could get data only after contained 4k data.
Search for UIAutomator. This does what you want to do.
Your phone must be rooted to execute getevent/sendevent command.
One way is to install any terminal emulator from play store like Qute: Command Console & Terminal Emulator.
In terminal enter following:
1) su (it'll gain the root access required for getevent)
2) getevent (or getevent -c 8 to output only 8 lines else it would flood the terminal)
I am developing an Android-App with "Aide".Aide is an app for developing android apps with android devices. When i start the app, i have created, i get an error like "the app has aborted unfortunately". how can i resolve what happened wrong ? is there a log-file where i can see the stack trace ? is ist possible that everytime an error happens a dialog apperas with the stack trace instead of the message "the app has aborted" ? thanks for everybody who can help me.
Greets
Arne
If you want to observe the stack trace, all you need is a LogCat reader, like CatLog, for instance. Note that if your device is Jelly Bean of higher, you'll need root permissions to read the logs.
EDIT:
Further research indicates that there is a LogCat reader built into AIDE. The root permission issue still applies.
I have never used Aide, but the concept will be the same. You need to be able to debug your app on your phone via your IDE. As an example in Eclipse I would connect my phone via usb and in Eclipse it then shows up as an Android Device in AVD. I then run my App in Debug mode on my phone and all your error output will be in Logcat. Otherwise you will have to code debug logic into your app so that it writes it's own logging onto your fs on you phone.
If you have the Android SDK installed (I guess it's the case), then you can use the adb utility to access the log :
adb logcat
This will show you stacktrace in case of error, and many very other useful informations.
You got 3 options:
Upgrade into a stable Pro version to use the working LogCat on AIDE
Use USB debugging as mentioned by apesa
Use following function to log to local file:
public void appendLog(String text)
// https://stackoverflow.com/a/6209739/8800831
{
File logFile = new File("sdcard/log.file");
if (!logFile.exists())
{
try
{
logFile.createNewFile();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try
{
//BufferedWriter for performance, true to set append to file flag
BufferedWriter buf = new BufferedWriter(new FileWriter(logFile, true));
buf.append(text);
buf.newLine();
buf. flush();
buf.close();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Use it like this:
try{
// your code goes here
}catch (Exception e){
appendLog(e);
}
You need to add permission for writing_external_storage in Manifest.
To clarify, I use this code to get superuser permission for my app so I can access root and whatnot:
public String runProcess(String[] functs) {
DataOutputStream dos;
DataInputStream dis;
StringBuffer contents = new StringBuffer("");
String tempInput;
Process process;
try {
process = Runtime.getRuntime().exec(functs);
dos = new DataOutputStream(process.getOutputStream());
dis = new DataInputStream(process.getInputStream());
for (String command : functs) {
dos.writeBytes(command + "\n");
dos.flush();
while ((tempInput = dis.readLine()) != null)
contents.append(tempInput + "\n");
}
dos.writeBytes("exit\n");
dos.flush();
process.waitFor();
} catch (Exception e) {
e.printStackTrace();
}
return contents.toString();
}
And although it works just fine, whenever I call runProcess(new String[] { "su", "-c", "some other command" }); it always asks for superuser permission. I see a lot of root apps on the market who just have to gain superuser permission once at each startup of the app, but I don't think I'd need to ask the user for superuser permission every single time the app calls an function that requires SU. So my question would be, how would I prompt the user to give me SU permission once at the startup of an app without having to continually ask for it for every SU-related action?
EDIT: I know I could run my method/the Runtime.getRuntime().exec() method without typing "su" in it every time but that only works with non-su related actions (i.e. exec("ps") or exec("ls"). Any ideas?
You can use my Library which does this.
https://code.google.com/p/roottools/
Also, if you don't want to use the library the source is available so you can just rip out my code and use it in your application.
Here is a link to the source:
https://code.google.com/p/roottools/source/browse/#svn%2Ftrunk%2FStable%2FRootTools-sdk3-generic%2Fsrc%2Fcom%2Fstericson%2FRootTools
If you are just looking for the permission from a "superUser" app which is already running in your device, you just need the following code in your main java file.
try {
process p= Runtime.getRuntime().exec(su);
}
catch (IOException e) {
e.printStackTrace();
}
Yes, no need to mention that the device has to be already rooted!!!
Every time you open a console asking for root access, i.e. start it with su, the corresponding super user app will either prompt you or allow/deny it, if you checked something like "Don't ask me again" on the previous prompt.
If you only want to have ask (the super user app) once, you will have to keep your root console open, by not calling dos.writeBytes("exit\n");.
Then keep this session in a background thread and use it when necessary.
So either make sure the user checks "Don't ask me again" on the first prompt or keep the session open.
I have taken Code Aurora's FM Radio code and merged with my Android Gingerbread codebase.
The FM app framework tries to access the fm radio device ( /dev/radio ) using JNI which is implemented in a file by name android_hardware_fm.cpp . There is a function in this file which tries to acquire a file descriptor to the device node using open() in the read/write mode. However, the call fails with error code -13 : Permission denied.
I also made a small C executable which tries to open the /dev/radio file ( in RDWR mode), prints its fd and closes it. It runs from /system/bin in the target system and displays a valid fd.
Btw, the JNI implementation is part of the android core library. It is located in frameworks/base/core/jni and is compiled as part of libandroid_runtime.so
Any ideas/solutions? Thanks in advance.
Clearly you donot have permissions to open the device from user space. In the second case when you are running the executable from terminal, you are having permissions probably because you have done su before running the executable.
For your problem here, two things can be done.
1) Change the permissions of the node from terimnal.
Steps involved:
Open the terminal (adb shell)
Do su(In order to do this your device must be rooted)
Do chmod 777 /dev/radio in the terminal
Once this is done, your radio node is having proper permissions for the user to read and write. So you can now do open() call and it will work.
2) Programmatically you can achieve this (assuming your device is rooted and su is running on your device) by calling the below function - changePerm(). This is a small function I have written which will change the permissions of the device nodes or rather any system file that does not have user access. Once you have permissions, you can open it from user space. open() call will work properly after this.
void changePerm()
{
Process chperm;
try {
chperm=Runtime.getRuntime().exec("su");
DataOutputStream os =
new DataOutputStream(chperm.getOutputStream());
os.writeBytes("chmod 777 /dev/radio\n");
os.flush();
os.writeBytes("exit\n");
os.flush();
chperm.waitFor();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I have tested this for other nodes. So it should also work for radio aswell. Let me know in case yo are facing any difficulty. Thanks