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
Related
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 3 years ago.
Improve this question
I'm Developing an Android Application where it requireds 3 things:-
To keep the App up an running for specific time and then phone will be off (Working Fine)
When phone get charging from outlet, I want phone to power up automatically without hitting any power button. (Not Working with wall Socket, but working when connected to USB cable via Laptop).
After boot my app should start working Automatically (Working Fine)
You Must know :-
My phone is Moto E (rooted) and want 2nd step to be done. Tried some codes but that does not work on moto E.
When Connected with USB it gives 2 as response and when connected with Wall socket charger it says 1
Any help will be Appreciated
P.S :- Auto Boot working with USB cable connected with Laptop but not with Socket Charger
Update-1: 1- Found fastboot oem off-mode-charge 0 working with Nexus 7 but not on Moto e.
2- Moto e boots when connected to Router (USB Dongle Port)
At last I got the solution, you can achieve this by deleting system/bin/charge_only_mode file. Please do that at your own risk and before deleting have backup of that file. I got the desired result that was boot when its connected to wall charger and now its working fine.
All the best!
Moto e4 and Pixel 2 XL:
Get your device into the bootloader (fastboot) and run the following command from a computer connected over USB with Android Tools:
fastboot oem off-mode-charge 0
I was able to get it to work by updating the init.rc file
I found the on charger trigger and added the following lines below it:
setprop ro.bootmode "normal"
setprop sys.powerctl "reboot"
The entire trigger block ends up looking like this
on charger
class_start charger
setprop ro.bootmode "normal"
setprop sys.powerctl "reboot"
You then need to repack and flash the boot image created after the updates.
Connect the device over USB
Power on device and get to bootloader mode
adb reboot bootloader
To flash boot image execute the following command while in fastboot
fastboot flash boot new-boot.img
Note: This fix will cause the device to reboot when its plugged in even when shutting it off using the power button or software shutdown.
Source: https://forum.xda-developers.com/showthread.php?p=77766638#post77766638
You can see the commit that contains these changes for my project here:
https://github.com/darran-kelinske-fivestars/mkbootimg_tools/commit/c8633a2ec2e1924272fd16a8ed7fa7414bb65544#diff-d0007d763b44198f7c22e2c19609d5bbR606
I also tried replacing charge_only_mode with a sh script that rebooted the phone but only got a red circle with the M (on a Motorola Bionic). Changing the script to the below got it working...Now I get the red circle with the M for a few seconds, then a blank screen, the another red circle with the M, and it boots on up.
#!/system/bin/sh
su -c "/system/bin/reboot -n outofcharge"
On my device Lenovo K7000-Plus, the file need to be modified is kpoc_charger located at /system/bin.
Ipod file not working on my phone which using Android 6.0 ROM, but kpoc_charger works pefectly.
Regards
Hadi
For Lenovo A2010 phone,following worked:
Use file manager phone app from playstore like Total commander(on rooted phone) to goto folder /system/bin/
Copy file kpoc_charger and paste it there as kpoc_charger.bak
Now edit the original file kpoc_charger using total-commander, replace all lines with following code:
#!/system/bin/sh
/system/bin/reboot
Save it, goto properties and change UID:0 root, GID:2000 shell and permission as 755 (same as properties of other files in /system/bin folder).
Now shutdown phone and plug to charger.
Bazinga!!!! battery icon shows for a sec but phone sucessfully boots into os.
When phone get charging from outlet, I want phone to power up
automatically without hitting any power button. (Not Working with wall
Socket, but working when connected to USB cable via Laptop).
You can only achieve this by modifying your phone's OS files. Basically there is boot script/binary at /system/bin/chargemon which you can replace with a script that does nothing. Do it at your own risk because this may result in the device being damaged permanently. Also, Manufacturer warranty will become void.
I found another way for this (thanks to DavidThompson256 http://forum.xda-developers.com/showthread.php?t=1187631)
First make sure your phone is rooted (which I found iRoot very good for this), then install RootExplorer.apk (or similar) on your phone.
Try to edit "/system/bin/playlpm" and replace its content with following commands: (do not forget to make a backup first).
#!/system/bin/sh
/system/bin/reboot
(I know the content is in binary, simply remove them and write those two lines and save the file)
NOTE: When you modify that file, no changes will be applied on its permissions but if you are making another file remember to set permissions exactly as it was.
Finally, please do it on your own risk. It worked for me. (Samsung Discovery S730M)
i think there should be power sensor if you can add that in this code i belive it will work
public class Main extends Activity {
private SensorManager mSensorManager;
private PowerManager mPowerManager;
private WindowManager mWindowManager;
private WakeLock mWakeLock;
private Button button;
private TextView textView;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try{
// Get an instance of the SensorManager
mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
// Get an instance of the PowerManager
mPowerManager = (PowerManager) getSystemService(POWER_SERVICE);
// Get an instance of the WindowManager
mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
mWindowManager.getDefaultDisplay();
// Create a bright wake lock
mWakeLock = mPowerManager.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, getClass()
.getName());
setContentView(R.layout.main);
textView = (TextView)findViewById(R.id.textView1);
button = (Button)findViewById(R.id.button1);
button.setOnClickListener(mButtonStopListener);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.e("onCreate", e.getMessage());
}
} // END onCreate
View.OnClickListener mButtonStopListener = new OnClickListener() {
public void onClick(View v) {
try {
mWakeLock.release();
textView.setText("mWakeLock.release()");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.e("onPause",e.getMessage());
}
}
};
#Override
protected void onResume() {
super.onResume();
/*
* when the activity is resumed, we acquire a wake-lock so that the
* screen stays on, since the user will likely not be fiddling with the
* screen or buttons.
*/
try {
mWakeLock.acquire();
textView.setText("mWakeLock.acquire()");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.e("onResume", e.getMessage());
}
}
#Override
protected void onPause() {
super.onPause();
// and release our wake-lock
try {
mWakeLock.release();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.e("onPause",e.getMessage());
}
}
}
So I was trying to achieve this with a 3rd gen Moto G. It has a charge_only_mode file as per Rohit's answer, but simply moving/renaming it did not make the phone reboot on charge. Instead it just sat there with a Motorola logo. I got the same result when replacing charge_only_mode with either of the scripts referenced here.
I did get it to work, however. I copied /system/bin/reboot into /system/bin/charge_only_mode, and that did the trick.
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 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.
I have an application which consists of the native part and higher
layer.
Therefore, it needs to be granted the root privilege to run some
native functions.
As the article I post before, I added a piece of code taken from Bluez
Utils(hidd.c).
if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
close(sk);
return -1;
}
The code has been built to be a .so by NDK.
Unfortunately, It keeps returning -1 and errno is 13 which means
Permission Denied.
Some experienced developers(Thank you here) mentioned about that the
error happens because this application doesnt have enough permission.
It "SHOULD NOT" be something like
Process process = Runtime.getRuntime().exec("su");
I think this means you possess a system permission but your
application doesnt.
(Let me know if I am wrong)
Is there any way to grant the app for having the root privilege?
Any reply/clue/hint will be highly appreciated.
Regards-
Sam
I think i can help you with this.
Here we gooo...
void gainRoot()
{
Process chperm;
try {
chperm=Runtime.getRuntime().exec("su");
DataOutputStream os =
new DataOutputStream(chperm.getOutputStream());
os.writeBytes("chmod 777 /dev/video0\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();
}
}
This is a function i normally use to change the permissions of root files.
When you do su, a new process will be created with root privileges. So using this Process you can do any root operations. There is some specific syntax that needs to be followed. Which is shown in the above example.
so one thing what you can do is build the bind part of the code as a separate executable and place it inside system/bin or at that place where normally executables are kept. Suppose the name of the executable is bind123 then instead of
os.writeBytes("chmod 777 /dev/video0\n");
os.flush();
replace it with
os.writeBytes("bind123\n");
os.flush();
in the above code.
This should work. Probably once this is working we can try integrating it with the application without any dependency on the executable. I hope i am not confusing you. If atall some clarity is neede, let me knowww.... ALL the best...
You don't need root to bind to port >=1024. You only need INTERNET permission in your ApplicationManifest.xml file.