Reboot a device from phonegap - android

Is there a way to reboot a device with phonegap/cordova? How would I go about doing this? I think it may not be possible on an ipad/iphone but it would be on androids.

First basically it can't be done unless your device is rooted/jailbreaken (depending are we talking about Android or iOS).
Now comes the fun part even if you have rooted/jailbreaken device you will not be able to do that unless you can do some Java/Objective C development.
Basically Phonegap plugin don't exist simply because this functionality is usually not needed unless you are doing something with your phone on a basic level. But if you have enough knowledge you can do it by your self. Phonegap plugin can be created very easy, and you can find more in this tutorial. What you want to do is create a simple plugin that will execute Java/Objective C code when you need it.
Android/Java example :
try {
Process proc = Runtime.getRuntime().exec(new String[] { "su", "-c", "reboot" });
proc.waitFor();
} catch (Exception ex) {
Log.i(TAG, "Could not reboot", ex);
}
iOS/Objective C example
Unfortunately I don't have that much experience with this functionality on iOS so you will need to trust this answer.

I needed same functionality, made a plugin based on Gajotres example:
cordova-plugin-reboot

Related

android applications interactions

I have a problem and a don't know how to solve it. I saw some tools for automation testing for android apps, like appium and others. They connect to the android device, emulator, from outside the device and open the application to be tested. I want to know how can i build a native android app that can to the same thing. Open another application and start executing different operations on the UI of that app. For a simple example, let's say i have a social app that i want to test. I want another that runs on the phone that opens my social app and starts running some operations like searching inside the app, clicking on different posts, liking post, s.o. Is there a way to do this? Are there any frameworks or methods for doing this?
Regards.
You have two kinds of automation frameworks for Android.
Instrumentation-based:
Robotium
Espresso
And black-box frameworks for functional testing:
Appium
Perfecto
ATMOSPHERE
The instrumentation frameworks work in the following way: As each android application runs in a sandbox and other applications can not change their behavior once they are installed, the instrumentation-based frameworks change the installation package of the application injecting hooks in the method definitions that allow them to interact with the application. This allows bypassing the sandbox in Android systems.
The other three all have UIAutomator Android service as basis for the interaction with the application. UIAutomator is part of hte Android SDK and allows emulation of real user interactions (e.g. click, scroll etc.), rahter than simulating them on lower, code level.
I believe that any of the five listed frameworks will allow you achieve what you want. I personally recommend black-box testing frameworks, as instrumentation can hide defects. My favorite framework is ATMOSPHERE - free to use, open sourced and although very recent a lot easier to use.
You would use an explicit intent to open a separate application.
public void openApplication(Context context, String packageName) {
PackageManager manager = context.getPackageManager();
try {
Intent i = manager.getLaunchIntentForPackage(packageName);
if (i != null) {
i.addCategory(Intent.CATEGORY_LAUNCHER);
context.startActivity(i);
} else {
Log.e(TAG, "Unable to start application");
return;
}
} catch (PackageManager.NameNotFoundException e) {
Log.e(TAG, "Package name not found");
return;
}
}
You would then call this method by providing the context and the package name of the application you want to open. For example, to open Instagram:
openApplication(this, "com.instagram.android");

How to shut down Android phone, programmatically?

How to make shut down in Android programmatically, I searched for the question and I found many answer the strongest answer said your phone must be ROOT, now my phone is root and my code working fine
but when I execute this code below I get an alert like this image below.
Code:
try {
Process proc = Runtime.getRuntime()
.exec(new String[]{ "su", "-c", "reboot" });
proc.waitFor();
} catch (Exception ex) {
ex.printStackTrace();
}
My result:
Now how to eliminate this alert I want to shut down directly when I press my shut down program button, without getting this alert.
Even if your phone is rooted, when apps that require root are accessing these system areas it will prompt for permission from the user atleast once(1st time of using the app). Either you can allow each time which will allow root permissions for your app for specified time limit(usually 15 mins) or you can select the "Remember my choice" and allow permanent access to your app this way.
In case you allowed once with the "Remember my choice" then you will have to manually change this permission from your super user app.
NOTE: Once if your device is rooted, you will get an app named "SuperSU" or "Superuser" in your device which will display all the apps that requires ROOT permission and the default access level of these apps.
Hope this helps:)

In HTML5, how can I keep an Android device’s screen on?

We are developing an App in HTML5 using jQuery.
Is there a way/method, in JavaScript or another technology, to keep the screen "on"?
I think there is another way doing it without any java code. You can add a video of 1 second with infinite repeat and hidden and it will do the trick. I have read it somewhere but i don't remember where.
Maybe you could use one of the blank videos below:
https://github.com/esc0rtd3w/blank-intro-videos
https://github.com/kud/blank-video
IT WORKS!
Google's WebVR polyfill has a way to do this on Chrome. It basically creates a tiny video (with a data URL, so no extra downloads needed) and loops it.
It seems like a hack, so I wouldn't be surprised if it's not reliable in the future.
They have code that achieves the same thing on iOS too, by triggering a location update.
Here's the relevant code for Android:
var Util={};
Util.base64 = function(mimeType, base64) {
return 'data:' + mimeType + ';base64,' + base64;
};
var video = document.createElement('video');
video.setAttribute('loop', '');
function addSourceToVideo(element, type, dataURI) {
var source = document.createElement('source');
source.src = dataURI;
source.type = 'video/' + type;
element.appendChild(source);
}
addSourceToVideo(video,'webm', Util.base64('video/webm', 'GkXfo0AgQoaBAUL3gQFC8oEEQvOBCEKCQAR3ZWJtQoeBAkKFgQIYU4BnQI0VSalmQCgq17FAAw9CQE2AQAZ3aGFtbXlXQUAGd2hhbW15RIlACECPQAAAAAAAFlSua0AxrkAu14EBY8WBAZyBACK1nEADdW5khkAFVl9WUDglhohAA1ZQOIOBAeBABrCBCLqBCB9DtnVAIueBAKNAHIEAAIAwAQCdASoIAAgAAUAmJaQAA3AA/vz0AAA='));
addSourceToVideo(video, 'mp4', Util.base64('video/mp4', 'AAAAHGZ0eXBpc29tAAACAGlzb21pc28ybXA0MQAAAAhmcmVlAAAAG21kYXQAAAGzABAHAAABthADAowdbb9/AAAC6W1vb3YAAABsbXZoZAAAAAB8JbCAfCWwgAAAA+gAAAAAAAEAAAEAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAIVdHJhawAAAFx0a2hkAAAAD3wlsIB8JbCAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAQAAAAAAIAAAACAAAAAABsW1kaWEAAAAgbWRoZAAAAAB8JbCAfCWwgAAAA+gAAAAAVcQAAAAAAC1oZGxyAAAAAAAAAAB2aWRlAAAAAAAAAAAAAAAAVmlkZW9IYW5kbGVyAAAAAVxtaW5mAAAAFHZtaGQAAAABAAAAAAAAAAAAAAAkZGluZgAAABxkcmVmAAAAAAAAAAEAAAAMdXJsIAAAAAEAAAEcc3RibAAAALhzdHNkAAAAAAAAAAEAAACobXA0dgAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAIAAgASAAAAEgAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABj//wAAAFJlc2RzAAAAAANEAAEABDwgEQAAAAADDUAAAAAABS0AAAGwAQAAAbWJEwAAAQAAAAEgAMSNiB9FAEQBFGMAAAGyTGF2YzUyLjg3LjQGAQIAAAAYc3R0cwAAAAAAAAABAAAAAQAAAAAAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAEAAAABAAAAFHN0c3oAAAAAAAAAEwAAAAEAAAAUc3RjbwAAAAAAAAABAAAALAAAAGB1ZHRhAAAAWG1ldGEAAAAAAAAAIWhkbHIAAAAAAAAAAG1kaXJhcHBsAAAAAAAAAAAAAAAAK2lsc3QAAAAjqXRvbwAAABtkYXRhAAAAAQAAAABMYXZmNTIuNzguMw=='));
video.play();
The future answer - because it's experimental now - is to use the new API called: Screen Wake Lock API
I think you can mix it with previous workaround answers
// Create a reference for the Wake Lock.
let wakeLock = null;
// create an async function to request a wake lock
try {
wakeLock = await navigator.wakeLock.request('screen');
statusElem.textContent = 'Wake Lock is active!';
} catch (err) {
// try other solutions here ...
}
You can follow the support of this feature here
There is no way to ONLY write javascript or other web code to keep the screen on, without writing at least a little java code.
To explain why I am so certain, if you are developing a web app through html5 you MUST use a WebView as the main "screen" of your application to host your html,javascript code. So your "web code" does not directly run in the application but uses a View as its holder. As you can guess you can't just lock the screen from some code that is not even running in the native part.
I can provide a very easy and simple way to keep the screen on if you are not an expert in android programming. In the first activity, that uses the WebView I guess, add in onCreate after super:
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
Simplest method is to go to the Settings, Developer Options, and to select "Stay awake while charging". No need to code anything!
This supposes that OP wants to keep the screen on while connected to an external power source, which is reasonable, otherwise no clever coding will prevent the screen from going off soon when the internal battery drains empty.
The external power source can be as simple as a portable usb battery. When that eventually gets empty, the device will go to sleep as usual, but will remain functional on its internal battery.
I found this solution here:
posting about keeping the screen on
Keeping the device on does not depend on the OS but on the browser. Chrome is in the process of implementing Wake Lock API, but it is still experimental.
Until fully available, there is a way to mock the api by playing a base64 video in the background. This locks the sleep mode with all browsers.
You can find a webcomponent implementation here https://github.com/madeInLagny/mil-no-sleep

Run a service with Root privileges or adding permissions with root

I am currently developing an app that reads out SMS/Emails while driving. Many users wished support for WhatsApp / KakaoTalk.
However, as there is no "official" way to receive their messages, there would be only three options, all requiring root:
The easier way of scanning their database in a given intervall.
Easy to implement.
However not battery efficient
Also the messages are not read out immediately.
An other way would be to run a service with root rights and register a receiver that listens for their push notifications. This has to be done with root, as both packages require a signature based permission for receiving their push notifications.
Harder to implement
Better user experience
Also another thing came to my mind: Would it be possible to manually add permissions to an APK after installing? In that case I could add the c2dm permissions to my package.
This would make things very easy
However, I am a little bit scared of changing my app's permissions, as this is completely against the Android Sandbox principle.
Still, if it would be possible, let me know!
The problem is, how exactly do I run a service with root rights (is it actually possible)? I know how to run shell commands or binaries with root, but I have no idea how to start a part of an APK as root.
Also, would it be possible to integrate a BroadcastReceiver into a binary? I have actually no experience with C/C++, especially in an android environment.
Can you help me with that?
Thanks.
edit: Like I said in the comment, I do not want to use an AccesibilityService, as it does not fit my needs (eg it will give me "2 unread messages" if more then one is unread, also it does not include the full body).
edit2: Just to clarify things: I know how to run commands with root. What I need to know is how to register a Broadcastreceiver, that receives a specific broadcast "normal" receivers don't get, as the Broadcast itself requires a signature based permission I don't have.
This is far from trivial but should work when the apps you want to monitor use sqlite databases or, more generically, write messages to a file when they arrive.
You will indeed need to have root access to the device as this violates the android security system:
Write a native process which runs as a daemon using the NDK and spawn it once after boot as root. You have now 3 major problems to solve:
How to find out if something changed?
This is the easy part. You would need to utilize the Linux inotify interface which should be accessible on every Android phone as the SDK has a FileObserver since API 1, so you are on the safe side here.
Another interesting approach may be to catch the C2DM messages. I have found a NDK class called BroadcastReceiver, so the NDK may be able to catch them. But I personally wouldn't do that as it feels wrong to steal intents. Also you would have to redistribute them or let them travel to real recipient, so I will not describe this in detail here. It may work, but it may be harder and should only be a fallback.
So, when you have solved this, the next problem arises:
How to read the changes in a safe way?
You have a problem, a big one, here. The file doesn't belong to the client, and the client doesn't even have the permission to know where it is (normally). So the monitored app is not aware of the client and will act like the file is exclusively owned only by itself. If they use some plain old textfile to write messages to you have to find out a way to read from it safely as it may be overwritten or extended at any time. But you may be lucky when they use sqlite, according to this it's totally valid to have more than one simultaneous reader, just only one writer. We are in the specs, everything fine again. When you have now read out the new data, more problems to solve:
How to get the new data back into the main app?
You should do only the bare minimum in this C/C++ program because it runs as root. You should also protect your app users from security breaches, so please write the program with this in mind. I have no real idea for this could work really good, but here are some thoughts:
Write the collected data into your own sqlite database (easy in C/C++ and Java),
Write the collected data into a plain file (not recommended at all, pain in the rear),
Send an Intent which contains the new data (maybe not that easy in C/C++, but easy in Java)
Use sockets/pipes/..., just every RPC mechanism you could imagine which is brought to you by Linux (same as the file, don't do it)
As stated in the text above, please be careful when you write this daemon as it is a potential security hazard. It may be hard to do this when you have no knowledge about C/C++ at all, even if you have written simple programs this should be a non trivial task.
On my search through the web I have found the NDK C++ classes I mentioned above. It can be found at Google code. I have neither experience with the NDK nor the C++ wrapper but it may be worth a look when you plan to write this.
Force, I must tell you that an Android Service do not require root access instead some actions(i.e. Access, Read, Write system resources) requires Root Permissions. Every Android Service provided in Android SDK can be run without ROOT ACCESS.
You can make the actions to execute with root permissions with the help of shell commands.
I have created an abstract class to help you with that
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import android.util.Log;
public abstract class RootAccess {
private static final String TAG = "RootAccess";
protected abstract ArrayList<String> runCommandsWithRootAccess();
//Check for Root Access
public static boolean hasRootAccess() {
boolean rootBoolean = false;
Process suProcess;
try {
suProcess = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(suProcess.getOutputStream());
DataInputStream is = new DataInputStream(suProcess.getInputStream());
if (os != null && is != null) {
// Getting current user's UID to check for Root Access
os.writeBytes("id\n");
os.flush();
String outputSTR = is.readLine();
boolean exitSu = false;
if (outputSTR == null) {
rootBoolean = false;
exitSu = false;
Log.d(TAG, "Can't get Root Access or Root Access deneid by user");
} else if (outputSTR.contains("uid=0")) {
//If is contains uid=0, It means Root Access is granted
rootBoolean = true;
exitSu = true;
Log.d(TAG, "Root Access Granted");
} else {
rootBoolean = false;
exitSu = true;
Log.d(TAG, "Root Access Rejected: " + is.readLine());
}
if (exitSu) {
os.writeBytes("exit\n");
os.flush();
}
}
} catch (Exception e) {
rootBoolean = false;
Log.d(TAG, "Root access rejected [" + e.getClass().getName() + "] : " + e.getMessage());
}
return rootBoolean;
}
//Execute commands with ROOT Permission
public final boolean execute() {
boolean rootBoolean = false;
try {
ArrayList<String> commands = runCommandsWithRootAccess();
if ( commands != null && commands.size() > 0) {
Process suProcess = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(suProcess.getOutputStream());
// Execute commands with ROOT Permission
for (String currentCommand : commands) {
os.writeBytes(currentCommand + "\n");
os.flush();
}
os.writeBytes("exit\n");
os.flush();
try {
int suProcessRetval = suProcess.waitFor();
if ( suProcessRetval != 255) {
// Root Access granted
rootBoolean = true;
} else {
// Root Access denied
rootBoolean = false;
}
} catch (Exception ex) {
Log.e(TAG, "Error executing Root Action", ex);
}
}
} catch (IOException ex) {
Log.w(TAG, "Can't get Root Access", ex);
} catch (SecurityException ex) {
Log.w(TAG, "Can't get Root Access", ex);
} catch (Exception ex) {
Log.w(TAG, "Error executing operation", ex);
}
return rootBoolean;
}
}
Extend your class with RootAccess or create an instance of RootAccess class and Override runCommandsWithRootAccess() method.
running something as root is not the right way of solving this.
instead, consider an accessibility service that can watch for new notifications:
AccessibilityEvent
It is not possible to run a Service (or any other application component for that matter) as root, if you are targeting unaltered, non-rooted devices. Allowing that would make all security mechanisms in Android pointless.
It is not possible to alter the permissions of an APK at runtime either. Permissions are always granted or rejected at APK install-time. Please refer to http://developer.android.com/guide/topics/security/security.html for some more info on the subject.
"What I need to know is how to register a Broadcastreceiver, that receives a specific broadcast "normal" receivers don't get, as the Broadcast itself requires a signature based permission I don't have."
You can't. Period. End of story. And thank ghod for that.
Yes, if you use the scary rooted device facilities to have some code run as root, you can in theory do whatever you want. In practice, it may be quite hard to get around this restriction, and the platform is often designed to be that way. You will at the very least need to mess around with the state maintained and/or stored by the package manager, and will likely need to cause the user to reboot the device to get changes you make as root to actually have an impact. And of course you are then messing with deeply internal implementation details of the platform, which means breaking all over the place across different versions of the platform and different builds from different manufacturers.
you can use
pm grant your.permission
as a shell command to grant additional permissions to your app.
I think that command was added quite recently, so if you target older versions you may have to directly alter the 'packages.xml'.
It is possible to execute an app/dex file as root with the app_process command, but I haven't figured out yet how to get a valid context (with this you can use the java.io.File api to access all files, but non static android methods like bindService etc. will fail because you are running without an app context).
Of course you can change the permissions of your applications. If the permissions will be changed, the user will just have to manually update the app, and the new permission will be displayed to the user. But I do not exactly know how changing your app permission will help you in solving this problem.
Another thing I can tell you, is that you can not run a Service or whatever as root, only on rooted devices, and it will not be an easy task to root the devices through your application, and also it won't be something that many user will want.
How are you currently accessing the SMS?
If you have a BroadcastReceiveryou could set the MAX_PRIORITY for your receiver and maybe it will intercept the messages before other applications. This can be done as follows:
<receiver android:name=".SmsReceiver" >
<intent-filter android:priority="100" >
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
You could also use the SMS Provider, which is not public now but maybe if you query at a given interval this Provider you can check for new messages. You could also have a look at this thread : Android SMS Provider if you have not done this allready.

Help regarding Runtime.getRuntime().exec() command usage in Android app

I am trying to make use of Runtime.getRuntime.exec() command to copy a
folder from one location to another on sdcard.
But it seems like it doesn't work
Below is the code snippet where I am trying to copy the contents from /
sdcard/etc/data to /sdcard/etc/temp/
try
{
Process process = Runtime.getRuntime().exec("cp -r /sdcard/etc/
data /sdcard/etc/temp");
}catch (IOException e)
{
e.printStackTrace();
}
I also tried creating a soft link as an alternative.. Event that did
not work.
try
{
Process process = Runtime.getRuntime().exec("ln -s /sdcard/etc/
data /sdcard/etc/temp/data");
}catch (IOException e)
{
e.printStackTrace();
}
Could someone please help me on this. Am I using the Runtime in the
proper way if not could you please suggest me an alternative..
Appreciate your help!
Thanks,
Nik..
You probably still need to have the WRITE_EXTERNAL_STORAGE permission, in case you do not have that.
Your bigger problem is that cp is not in any sort of PATH. In fact, I do not see the cp command anywhere on the Android 2.2 emulator, though I have not done an exhaustive search.
The way a savvy programmer would solve this is using Java, since that eliminates your dependency on undocumented/unsupported command-line binaries.

Categories

Resources