How do i use console commands in apps, i have searched google with and did not find anything. And if possible, could someone upload an app with a button that runs a console commands. I am making an app that will start obexserver.
A portion of my Hello World for Android which doubles as a command line evaluator.
Code:
String txt = ((EditText) findViewById(R.id.txtCmd)).getText().toString(); // cmd line
boolean su = ((CheckBox) findViewById(R.id.asRoot)).isChecked(); // run as root
Process p;
try {
if (su) {
p = Runtime.getRuntime().exec("su");
(new DataOutputStream(p.getOutputStream())).writeBytes(txt + "; exit\n"); // you want the shell to terminate itself so you know the command has finished
} else
p = Runtime.getRuntime().exec(txt);
} catch (Exception e) {
e.printStackTrace();
return;
}
try {
StringBuilder sb = new StringBuilder();
InputStreamReader isr = new InputStreamReader(p.getInputStream());
int r;
while ((r = isr.read()) > 0)
sb.append((char) r); // you may want to use a buffer
msg = sb.toString();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
thanks, but i really dont have any idea about how to put this in the app
Basically you use Runtime.getRuntime().exec() to start a shell and Process object to interact with the it. I assume you have to be root to manipulate bluetooth, so you have to execute su first (which launches the default shell as root) and use the input and output streams to simulate user typing. The input stream is just standard. You'll have to use InputStreamReader if you want to read characters, and wrap a BufferedReader around that to read lines. For the output side, we use DataOutputStream to write bytes to the shell (this is cheap, but it works well for ASCII.).
Related
EDIT: Development continued Working hard
Hello everyone
I'm trying to port my WIP Infosode from Android (Adobe AIR) to Windows Phone 7, and I have some big problems figuring out how to access a remote XML service, in this case http://services.tvrage.com/
I've used Visual Basic .NET for both desktop and Windows Mobile applications and now for WP7, so I got some VB.NET experience.
Any help is appreciated and will be noted in the finished application.
Regards
//
IzaacJ
Here is one somewhat dirty way.
Download your data (xml) into the isolated storage. After that process the xml file stored.
Code:
WebClient client = new WebClient();
client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
client.DownloadStringAsync(new Uri("http://path.to/the/" + item + ".xml/"));
static void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
// If we have results
if (!string.IsNullOrEmpty(e.Result))
{
#region Save to Isolated Storage
try
{
// Isolated Storage Directory
string xmlStorageDirectory = "Profiles";
using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication())
{
// File Path
string filePath = Path.Combine(xmlStorageDirectory, String.Format("{0}.xml", ActiveID));
// Check if the Directory exists. If not create it
if (!store.DirectoryExists(xmlStorageDirectory))
{
store.CreateDirectory(xmlStorageDirectory);
}
// Use Isolated Storeage to write the file
using (IsolatedStorageFileStream fileStream = new IsolatedStorageFileStream(filePath, FileMode.Create, store))
{
// Use the stream to write the file
using (StreamWriter stream = new StreamWriter(fileStream))
{
stream.Write(e.Result.Replace(" & ", " & "));
}
}
}
}
// OMG EXCEPTIONS :(
catch (IsolatedStorageException exception)
{
throw exception;
}
#endregion
#region Reading
using (var appStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
using (var file = appStorage.OpenFile("Profiles/" + ActiveID + ".xml", FileMode.Open))
{
XmlReader reader = XmlReader.Create(file);
CharacterDataModel profile = new CharacterDataModel();
List<PlayerTraitsModel> traits = new List<PlayerTraitsModel>();
PlayerTraitsModel trait = new PlayerTraitsModel();
bool isCdata = false;
bool isPdata = false;
// While we read the data
while (reader.Read())
{
#region Character
if (reader.Name == "cdata") isCdata = true;
if (isCdata)
{
if (reader.NodeType == XmlNodeType.Element)
{
#region Check for the following values and shallow copy that to the model
//string item = reader.ReadElementContentAsString();
switch (reader.Name)
{
case "id":
profile.id = reader.ReadElementContentAsString();
break;
}
#endregion
}
}
if (reader.NodeType == XmlNodeType.EndElement && reader.Name.Contains("cdata"))
isCdata = false;
#endregion
}
}
}
#endregion
}
}
Thanks for that
Will try to adopt it to VB.NET and see if it will work
At least it's something that I could use until I find a better way.
Regards
Hi,
Use the OpenReadCompleted event of the WebClient, and then put the result into an XDocument by using an XmlReader; from there it's easy to process it (using LINQ to XML) without having to store the XML anywhere first (i.e. do it all in memory). Here's kind of how I do it C#.
Code:
WebClient client = new WebClient();
// Set up the 'completed' event before loading anything
client.OpenReadCompleted += (sender, e) =>
{
if (e.Error != null)
{
if (e.Error is WebException)
{
... Either a connection error, or an invalid status code has been returned. You can determine which using code.
}
else
... // some other exception
return;
}
// Turn the result into an XDocument and parse using LINQ
try
{
Stream aStream = e.Result;
XmlReader anXmlStream = XmlReader.Create(aStream);
XDocument ourXDocument = XDocument.Load(anXmlStream);
// Parse the XML here - best to use 'Linq to XML' to do it
List<TvShow> TVShows = from aShow in ourXDocument.Descendants("show")
select new TvShow() {
ShowName = aShow.Element("name").Value,
Link = aShow.Element("link").Value
};
//////////////////
str.Close();
// if here it all went to plan
}
catch (XmlException xe)
{
...
}
catch (Exception ge)
{
...
}
};
// Here's the bit that actually sets it going
try
{
client.OpenReadAsync(new Uri(URL, UriKind.Absolute));
}
catch (OutOfMemoryException)
{
... Handle the exception
}
catch (StackOverflowException)
{
... Handle the exception
}
catch (Exception ge)
{
... Handle the exception
}
If you're doing this kind of thing a lot it's good to set it up as reusable class that either has it's own events (e.g. ItemsLoaded, ErrorOccured, and ProcessItems) that can be subscribed to, or if you prefer you can have them as methods to override so that you can use it as a web service loading base class from which you can inherit.
Hope that helps. Good luck with it
Ian
otherworld said:
Hi,
Use the OpenReadCompleted event of the WebClient, and then put the result into an XDocument by using an XmlReader; from there it's easy to process it (using LINQ to XML) without having to store the XML anywhere first (i.e. do it all in memory). Here's kind of how I do it C#.
Code:
WebClient client = new WebClient();
// Set up the 'completed' event before loading anything
client.OpenReadCompleted += (sender, e) =>
{
if (e.Error != null)
{
if (e.Error is WebException)
{
... Either a connection error, or an invalid status code has been returned. You can determine which using code.
}
else
... // some other exception
return;
}
// Turn the result into an XDocument and parse using LINQ
try
{
Stream aStream = e.Result;
XmlReader anXmlStream = XmlReader.Create(aStream);
XDocument ourXDocument = XDocument.Load(anXmlStream);
// Parse the XML here - best to use 'Linq to XML' to do it
List<TvShow> TVShows = from aShow in ourXDocument.Descendants("show")
select new TvShow() {
ShowName = aShow.Element("name").Value,
Link = aShow.Element("link").Value
};
//////////////////
str.Close();
// if here it all went to plan
}
catch (XmlException xe)
{
...
}
catch (Exception ge)
{
...
}
};
// Here's the bit that actually sets it going
try
{
client.OpenReadAsync(new Uri(URL, UriKind.Absolute));
}
catch (OutOfMemoryException)
{
... Handle the exception
}
catch (StackOverflowException)
{
... Handle the exception
}
catch (Exception ge)
{
... Handle the exception
}
If you're doing this kind of thing a lot it's good to set it up as reusable class that either has it's own events (e.g. ItemsLoaded, ErrorOccured, and ProcessItems) that can be subscribed to, or if you prefer you can have them as methods to override so that you can use it as a web service loading base class from which you can inherit.
Hope that helps. Good luck with it
Ian
Click to expand...
Click to collapse
Thanks
I'm building a class with functions for fetching and storing the returned XML requests.
It's smart to store it in the IsoStorage so that the data is available offline as well and it will only download the new XML's if it's updated on the server
I think it will make the application a bit more useful.
Regards
EDIT: I've tried to port the first example from MJCS to VB.Net without success. The app closes itself when it's supposed to search and get results from the server. The URL to the generated XML (including parameters) is http://services.tvrage.com/feeds/search.php?key=[MY_API_KEY]&show=[SHOW_NAME]
The code as for now is this:
Code:
Public Function Search(ByVal SearchString As String) As String
Dim Url As New Uri(XMLUrl & "feeds/search.php?key=" & APIKey & "&show=" & SearchString)
'XMLUrl = http://services.tvrage.com/
'APIKey = My API key from TVRage.com
'SearchString = The showname to be searched for in the database
XML.DownloadStringAsync(Url)
Return 0
End Function
Any ideas?
Regards
I want to control the PC cursor by WP7, so I try to use the ManipulationDelta in WP7 that can help me to calculate the difference between he star tap and the end tap
Code:
public MainPage()
{
InitializeComponent();
this.ManipulationDelta += new EventHandler<ManipulationDeltaEventArgs>(MainPage_ManipulationDelta);
transformG = new TransformGroup();
translation = new TranslateTransform();
transformG.Children.Add(translation);
RenderTransform = transformG; // you see I don't use any transform here because I don't know where I put. If I use the image.RenderTransform of it will move also for the screen of WP if I put this.RenderTransform, So anyone have a solution
SenderSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
}
void MainPage_ManipulationDelta(object sender, ManipulationDeltaEventArgs e)
{
startX = e.ManipulationOrigin.X;
startY = e.ManipulationOrigin.Y;
DeltaX = e.DeltaManipulation.Translation.X;
DeltaY = e.DeltaManipulation.Translation.Y;
translation.X += e.DeltaManipulation.Translation.X;
translation.Y += e.DeltaManipulation.Translation.Y;
EndX = Convert.ToDouble(translation.X);
EndY = Convert.ToDouble(translation.Y);
}
I am juste want to send DeltaX and DeltaY to the server to calculate them to the mouse position in the screen, So I write this code
Code:
void StartSending()
{
while (!stop)
try
{
SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
byte[] buffer = Encoding.UTF8.GetBytes(DeltaX.ToString() + "/" + DeltaY.ToString());
socketEventArg.SetBuffer(buffer, 0, buffer.Length);
SenderSocket.SendToAsync(socketEventArg);
}
catch (Exception) { }
}
I concatenate them in 1 buffer with separate by "/" and in server I use this code to separate
Code:
void Receive(byte[] buffer)
{
string chaine = "";
if (SenderSocket != null)
{
SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object s, SocketAsyncEventArgs e)
{
if (e.SocketError == SocketError.Success)
{
chaine = Encoding.UTF8.GetString(e.Buffer, e.Offset, e.BytesTransferred);
chaine.Trim('\0');
string[] pos = chaine.Split('/');
for (int i = 0; i < pos.Length; i++)
{
pX = Convert.ToInt32(pos[0]);
pY = Convert.ToInt32(pos[1]);
this.Cursor = new Cursor(Cursor.Current.Handle);
Cursor.Position = new Point(Cursor.Position.X + pX, Cursor.Position.Y + pY);
}
}
else
{
}
});
SenderSocket.ReceiveFromAsync(socketEventArg);
}
Just I want to control the cursor, if you have any other methods so plz help me and I am really grateful
Didn't you already have a thread about this? Please re-use existing threads instead of starting new ones. Even if it wasn't you, *somebody* was working on this problem already, and very recently. Always use the Search button before starting a thread.
So... what are you looking for from us? Does your current code work? If not, in what way does it fail? Without knowing what your question is, we can't provide answers.
If you want some advice, though...
Sending as strings is very inefficient on both ends; it would be better to use arrays (which you could convert directly to byte arrays and back again).
You're sending as TCP, which is OK but probably not optimal. For this kind of data, UDP is quite possibly better. If nothing else, it provides clearly delineated packets indicating each update.
Hi, i am trying to write a application that can be used for streaming my phone to my windows desktop running a Java client to receive the images. However when i tried to create a background task following a tutorial by microsoft i am unable to access the UIElement. Does anyone know how to work around this?
the below code in the OnInvoke is able to run in a application however if i were to create it under a Task Agent project , i cant because i cant get the FrameElement.
Code:
using System.Windows;
using Microsoft.Phone.Scheduler;
using Microsoft.Phone.Shell;
using System;
namespace ScheduledTaskAgent1
{
public class ScheduledAgent : ScheduledTaskAgent
{
private static volatile bool _classInitialized;
/// <remarks>
/// ScheduledAgent constructor, initializes the UnhandledException handler
/// </remarks>
public ScheduledAgent()
{
if (!_classInitialized)
{
_classInitialized = true;
// Subscribe to the managed exception handler
Deployment.Current.Dispatcher.BeginInvoke(delegate
{
Application.Current.UnhandledException += ScheduledAgent_UnhandledException;
});
}
}
/// Code to execute on Unhandled Exceptions
private void ScheduledAgent_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
{
if (System.Diagnostics.Debugger.IsAttached)
{
// An unhandled exception has occurred; break into the debugger
System.Diagnostics.Debugger.Break();
}
}
protected override void OnInvoke(ScheduledTask task)
{
var timer = new System.Windows.Threading.DispatcherTimer
{
Interval = System.TimeSpan.FromSeconds(10)
};
timer.Tick += (sender, args) =>
{
Microsoft.Devices.VibrateController.Default.Start(
TimeSpan.FromSeconds(0.1));
var bitmap = new System.Windows.Media.Imaging.WriteableBitmap(this.Parent, null);
var stream = new System.IO.MemoryStream();
System.Windows.Media.Imaging.Extensions.SaveJpeg(bitmap, stream,
bitmap.PixelWidth, bitmap.PixelHeight, 0, 100);
stream.Position = 0;
var mediaLib = new Microsoft.Xna.Framework.Media.MediaLibrary();
var datetime = System.DateTime.Now;
var filename =
System.String.Format("Capture-{0}-{1}-{2}-{3}-{4}-{5}",
datetime.Year % 100, datetime.Month, datetime.Day,
datetime.Hour, datetime.Minute, datetime.Second);
mediaLib.SavePicture(filename, stream);
};
timer.Start();
// Call NotifyComplete to let the system know the agent is done working.
NotifyComplete();
}
}
}
kyrogue said:
i am unable to access the UIElement
Click to expand...
Click to collapse
Hmm... Background agents don't have UIElements at all (and by the sandbox concept you can't access anything not belong to your app).
To capture WP7 screen, you should have an interop-unlock phone and use DllImport library.
Interop-unlock is *not* required to use anything in DllImport, actually - normal dev-unlock works fine.
There actually used to be an app that did what you described (stream the screen contents to a PC in real-time) but I don't think it ever got updated to work on Mango.
I'm pretty new to all this and was hoping to find some help. Eufy has some smart home products like light bulbs, smart plugs, etc that can be controlled directly over the LAN instead of a third party API.
I downloaded the APK for the EufyHome App and decompiled it at javadecompilers.com
That produced some promising results, like exposing that their app makes a socket connection to the devices on port 55556 when on the local network. Outside the local network it uses their API.
Here's some example code:
Code:
public boolean m4560a(String str, byte[] bArr) {
if (bArr == null || bArr.length == 0) {
return false;
}
if (str == null || str.length() == 0) {
return false;
}
try {
Socket socket = new Socket();
socket.connect(new InetSocketAddress(str, 55556), 1000);
socket.setTcpNoDelay(true);
socket.setSoTimeout(1000);
OutputStream outputStream = socket.getOutputStream();
InputStream inputStream = socket.getInputStream();
byte[] a = m4561a(outputStream, inputStream, bArr, C1178b.sendUsrDataToDev);
if (a == null || a.length == 0) {
try {
outputStream.close();
inputStream.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
try {
outputStream.write(a);
outputStream.flush();
outputStream.close();
inputStream.close();
socket.close();
return true;
} catch (IOException e2) {
e2.printStackTrace();
Log.v("DeviceInterfaceClass", e2.toString());
return false;
}
} catch (IOException e22) {
e22.printStackTrace();
return false;
}
}
byte[] m4561a(OutputStream outputStream, InputStream inputStream, byte[] bArr, C1178b c1178b) {
C1176a d = C1179k.m3096d();
d.m3088a(c1178b);
if (bArr != null) {
Log.v("DeviceInterfaceClass", "set data");
d.m3089a(C2839e.m7581a(bArr));
}
C1157a o = C1159c.m3011o();
int a = m4555a(outputStream, inputStream);
if (a < 0) {
return null;
}
o.m2994a(a + 1);
o.m2998a(this.f3294a);
o.m2997a(d);
C1159c c1159c = (C1159c) o.m2793e();
Log.d("config", "msg.toString = " + c1159c.toString());
return C1937a.m4554a(c1159c.m2804s());
}
I know enough about programming to know basically what's happening here, but the additional obfuscated function names are tough to work through. In addition to the APK source, I also ran a packet capture on my device when controlling the bulb. I didn't really understand the output well enough and didn't get very far other than confirming the fact that it's sending short messages to that device and port.
I confirmed via nmap that the only open port is 55556 and I can also open a socket connection to the device and send messages, but that's not really giving me any additional info.
Would love some help or pointers in the right direction here. I can sit down and do the leg work but any resources that would help me better understand what to expect would be really helpful. I don't know if I should be sending simple commands like "enable" or a JSON string or if I need to encode/encrypt it somehow.
Thanks!
I came across your post while googling for strings from decompiling the app myself .
I don't fully understand the communication between the app and the smart-thing, but I'm getting there. In my case, its a smart plug (product code T1201). The communication with all the supported devices is similar.
They are encrypting the command such as "sendUsrDataToDev" and "getDevStatusData" with a fixed AES key and IV. Then connect to the smartThing on tcp port 55556 an write their encrypted command and read data back from the socket. There's another layer of encrypting and decrypting on top of this thats not any sort of standard and just some ghetto homebrew crap the app developers invented.
On my device, and smartplug, the AES uses 244E6D8A56AC879124432D8B6CBCA2C4 for the key and 772456F2A7664CF3392C3597E93E5747 for the IV. I'm not sure yet if those are unique to each user, generated from the username, or used for every user. Your message is padded to a multiple of 16 bytes before encryption. I found those parameters hardcoded directly above the AES encrypt/decrypt code. They'll be the same for everybody using the same app.
As far as the other ghetto encryption/key, I've only seen that code used when talking to product t2103, which I think is a vacuum.
After you get past those, the actual data thats sent back and forth to the smart thing is a protobuf.
Hey Guys, today I will cover about how to create your own android Toolkit in C#. In this tutorial, I will cover some further pieces of stuff to create bit advance Android Tools.
Thanks to QuantumCipher for this amazing guide and RegawMod for his amazing library.
BasicsYou must know the following things before reading this guide
You just need to setup Visual Studio or SharpDevelop in order to create such projects.
You will see in every code, there are comments explaining them. Read them to at least get an idea what's happening. Below is the example of the comments in C#
Code:
// This is a Single line comment
/* This is a multiline
* comment in C#
*/
You should have the basic understanding of Toolbox controls and property box in Visual Studio. See the below image for better understanding!
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
You cannot implicitly convert Integer variable to String in C#, you can do it in python but for C# you have to do following things
Code:
int a = 6;
string demo;
demo = a; // Wrong stuff...
// To Fix this do,
demo = a.ToString();
// Or this,
demo = Convert.ToString(a);
Basic Understanding on How to use GitHub :angel:
Please forgive my bad English
UnderstandingYou need to first understand how actually this thing works (I assume that you have setup Visual studio before reading this guide). Basically, you first create a button like Reboot, set its function and add some process function to run 'adb reboot' through a console (which you can hide if you set process.StartInfo.CreateNoWindow=false). You see every time we add a function (the feature of adb) call adb explicitly and run a shell process. It simply means if you don't know about adb commands or don't know how to deal with cmd or batch files it will be obviously difficult on creating an Android Toolkit.
Let me show you an example, below is the batch file demonstrating an example of Rebooting to recovery using adb.
Code:
@echo off
adb reboot recovery
Using C# we can achieve this by this below code.
Code:
Process.Start("cmd.exe", "/c adb reboot recovery");
See, not much difference in C# we pass adb reboot recovery to cmd.exe, of course, this will create a window but if you don't want we need to set some properties for Process like below. Read comments for better understanding.
Code:
void run_process(string Commands) // Declaring a function for process
{
var p = new Process(); // Declaring new process
// Defining the process, setting its parameters
p.StartInfo.FileName = "cmd.exe"; // Passing main function to cmd.exe
p.StartInfo.Arguments = "/c " + Commands; // Commands string passed here. /c argument is used to passed parameters explicitly.
p.StartInfo.CreateNoWindow = true; // No displaying a window
p.StartInfo.UseShellExecute = false; // No using cmd.exe to execute shell
p.Start(); // Starting the process
do
{
Application.DoEvents(); // This will prevent application from hang
}while(!p.HasExited); // Will wait until process been released from memory
}
void Button_Click(object sender, EventArgs e) // Use Button to achieve it.
{
run_process("adb reboot recovery"); // Running the command safely.
}
We create a function which passing commands explicitly to cmd.exe with which we can run our adb and other stuff. Beside this, we can prevent Application from hang if suppose a long process being executed.
So you might understand this, in order to create Android Toolkits you need to know pretty basics of the batch language and you know what the main part is? They are very easy to learn like you can do it in a day if you will.
Complexity of ProcessThis is the main part, you might actually need to know. You have seen the above example. Writing a simple adb reboot program requires lots of codes down there. For eg, see below
This is the code for detecting android devices using normal Process C#
Code:
string run_process(string Commands) // Creating a function
{
var p = new Process(); // Declaring new process
// Defining the process, setting its parameters
p.StartInfo.FileName = "cmd.exe"; // Passing main function to cmd.exe
p.StartInfo.Arguments = "/c " + Commands; // Commands string passed here. /c argument is used to passed parameters explicitly.
p.StartInfo.CreateNoWindow = true; // No displaying a window
p.StartInfo.UseShellExecute = false; // No using cmd.exe to execute shell
p.StartInfo.RedirectStandardOutput = true;
p.Start(); // Starting the process
do
{
Application.DoEvents(); // This will prevent application from hang
}while(!p.HasExited); // Will wait until process been released from memory
return p.StandardOutput.ReadToEnd(); // This will return the output from the process.
}'
bool isConnected() // Function for detecting Connected Devices
{
var check = run_process("adb.exe get-serialno"); // Will check for connected devices and set it to a string
if (check.Contains("unknown")) // If string Contains 'unknown' means no device connected
{
// If Not Connected
pictureBox1.BackColor = Color.Red; // Change Color of Picture Box
label1.Text = "Device Not Connected!";
status.Text = "---";
return false; // Returning boolean value
}
else
{
// If Connected, we will also check its status
pictureBox1.BackColor = Color.Green;
label1.Text = "Device Connected!";
status.Text = run_process("adb.exe get-state"); // This will check status of device i.e Android, Recovery, Sideload, etc
return true; // Returning boolean value
}
}
void Button_Click(object sender, EventArgs e) // A button click to run connected device function
{
if (isConnected())
{
// TODO: It is Connected, do your stuff in this loop
}
}
See the complexity and length of the code, Now what! Let's rewrite same procedure using a library. For instance, I will be showing usage of AndroidLib created by Recognised XDA Developer, RegawMod. I will teach you later how to use this for now look the code below.
Code:
void Button_Click(object sender, EventArgs e) // A button click to Check connected device
{
AndroidController android=null;// Declaring some variables
android = AndroidController.Instance; // Setting Android instance
if (android.HasConnectedDevices) // Check for connected devices
{
// TODO : That's it, Device is connected. You can run something here.
}
}
What Actually Happened? By using some wrappers we have actually breakdown big code to a short code which only has one function to check connected device.
What I mean by this? I am sure you have understood what you need to do. Using the normal process for running typical adb process we have increased the size and complexity of the code too much, but a wrapper like AndroidLib made our day by decreasing the size and seriously you have to typically remember some few things in this dll and you're done. A cut-down of a big adb process can be done with this wrapper.
So, let us start using the wrapper for creating your own C# Advance Toolkit
Using Actual CodeLet's start creating new Project in Visual Studio or you may use SharpDevelop to Achieve this.
Click on File > New Project > Visual C# > Windows Form Application. Name any solution and OK. Now download AndroidLib from the bottom of the post.
Click on Project > Add Reference > Browse for AndroidLib.dll and 'OKWe gonna create a project like this.
We gonna create a project like this. You can find this project in my sample at the bottom of this page.
What Does this do? It will first detect our device in ADB Mode, show status and model number indicated by changing the back color of pictureBox to Green
Now Add the controls like above we have '1 label' saying that you need to add reference,, bla bla bla... '2 GroupBoxes' with Text=" ". '1 label' with Text=" " and Name=statuslabel , '1 Button' with Text="Check Device using AndroidLib" , '1 TextBox' at the center , '1 Button again' with Text="Go" and finally '1 ComboBox' containing items as 'Normal Reboot, Reboot to Recovery, Reboot to Bootloader' also Set its DropDownStyle=DropDownList from property box.
Coding StuffNow Click on View > Code to see the code of the Form, here we will add the codes for the form.
Declare some imports at the top of the .cs
Code:
using RegawMOD.Android; // Android lib imports
using System.IO; // If dealing with file reading and writing, not necessary for this guide.
Declare some variables just after 'public partial class'
Code:
Device device; AndroidController android=null; string serial;
Add Few lines of code in your Form Constructor, for me my form name is MainForm so my form constructor is MainForm. You have to add codes below InitializeComponents(); Your Final code be like this
Code:
public MainForm()
{
InitializeComponent();
android = AndroidController.Instance; // Setting Android instance
comboBox1.SelectedIndex = 0; // First option will be selected in comboBox which is Normal Reboot, If you don't do this you will get a comboBox with no selection may generate an error if button is clicked.
groupBox2.Enabled = false; // Disabling group box at the start which contains reboot options
}
You may see I have disabled second groupBox, this is because if device is not connected and still it is shown user might try to use it and may generate an exception. That's why disabling it at start and after 'no device connected' for device prevents exceptions
Now Create a Function for checking connected device, same as we did above.
Code:
bool isConnected()
{
bool i=false; // Initialize variable as false
groupBox2.Enabled = false; // Disabling group box so what if there is no connected device, we may not want user to click on reboot button to prevent error
android.UpdateDeviceList(); // Update connected device list
if (android.HasConnectedDevices) // Check for connected devices
{
serial = android.ConnectedDevices[0]; // Get first connected device's serial '0' means first
device = android.GetConnectedDevice(serial); // Use device serial to get device
i=true; // It is connected
groupBox2.Enabled = true; // Enabling groupBox as we know device is connected
}
else
i=false; // It is not connected
return i; // Return as function says
}
Now Go back to designer from View, and double click on button with text 'Check Device using AndroidLib' , this will automatically generate an method for button.
Now add the code for the button in the field, so that finally it looks like this
Code:
void Button1Click(object sender, EventArgs e)
{
if (isConnected())
{
pictureBox1.BackColor = Color.Green; // Setting color to green
statuslabel.Text = device.BuildProp.GetProp("ro.product.device") + ", " + device.State; // Show device name in status label as connected with its state
// Get some Additional details and show in textbox
textBox1.Text="-------Device Connected-------" + Environment.NewLine;
textBox1.AppendText("Product Model: " + device.BuildProp.GetProp("ro.product.model") + Environment.NewLine); // Show device's model, you can use other prop commands to, you will find it in basic device info project
textBox1.AppendText("Battery Status: " + device.Battery.Level.ToString() + Environment.NewLine); // Show battery percentage as string
textBox1.AppendText("Battery Temperature: "+ device.Battery.Temperature + Environment.NewLine); // Show battery temperature
textBox1.AppendText("Encryption: "+ device.BuildProp.GetProp("ro.crypto.state") + Environment.NewLine); // Show encryption state
textBox1.AppendText("Is Rooted: "+ device.HasRoot + Environment.NewLine); // Show if device rooted
textBox1.AppendText("Su Version: " + device.Su.Version + Environment.NewLine); // Show the SU Version installed
textBox1.AppendText("BusyBox: "+device.BusyBox.IsInstalled + ", " + device.BusyBox.Version + Environment.NewLine); // Checks if busybox installed and its version
}
else
{
textBox1.Text = "-------Error No Device Connected--------";
pictureBox1.BackColor = Color.Red; // Setting color to Red as not connected
statuslabel.Text = "---";
}
}
What we just did? In button code, you will see that we used isConnected Function to check if the device is connected or not. If it's connected we will change the status label text and color of picture box to green along with some general information shown in the textBox. If not i.e else we will change color or PictureBox to red.
Now-Again go back to Designer and Double click on Button with the text 'Go' to generate a method for it.
Add the following code to it. This will set reboot Option code for it. Remeber ComboxBox index 0 means the first element and 1 means second element and so on... Its same as an array as it starts from 0.
Code:
void Button2Click(object sender, EventArgs e)
{
switch(comboBox1.SelectedIndex) // Checking which option been selected in comboxBox using integers
{
case 0: // First element been selected
device.Reboot();
break;
case 1: // Second element been selected
device.RebootRecovery();
break;
case 2: // Third element been selected
device.RebootBootloader();
break;
}
}
We have used Switch case loop in this case, to check which one is actually selected and according to it codes have been added.
For instance here is my full code of Main Form
Code:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using RegawMOD.Android; // Android lib imports
namespace UsageOfAndroidLib
{
/// <summary>
/// Description of MainForm.
/// </summary>
public partial class MainForm : Form
{
// Declaring some variables
Device device; AndroidController android=null; string serial;
public MainForm()
{
InitializeComponent();
android = AndroidController.Instance; // Setting Android instance
comboBox1.SelectedIndex = 0; // First option will be selected in comboBox which is Normal Reboot
groupBox2.Enabled = false; // Disabling group box at the start which contains reboot options
}
/// <summary>
/// This will check if device is connected or not
/// </summary>
/// <returns>bool</returns>
bool isConnected()
{
bool i=false; // Initialize variable as false
groupBox2.Enabled = false; // Disabling group box so what if there is no connected device, we may not want user to click on reboot button to prevent error
android.UpdateDeviceList(); // Update connected device list
if (android.HasConnectedDevices) // Check for connected devices
{
serial = android.ConnectedDevices[0]; // Get first connected device's serial '0' means first
device = android.GetConnectedDevice(serial); // Use device serial to get device
i=true; // It is connected
groupBox2.Enabled = true; // Enabling groupBox as we know device is connected
}
else
i=false; // It is not connected
return i; // Return as function says
}
/// <summary>
/// Main click of the button1, you know what it does;
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void Button1Click(object sender, EventArgs e)
{
if (isConnected())
{
pictureBox1.BackColor = Color.Green; // Setting color to green
statuslabel.Text = device.BuildProp.GetProp("ro.product.device") + ", " + device.State; // Show device name in status label as connected with its state
// Get some Additional details and show in textbox
textBox1.Text="-------Device Connected-------" + Environment.NewLine;
textBox1.AppendText("Product Model: " + device.BuildProp.GetProp("ro.product.model") + Environment.NewLine); // Show device's model, you can use other prop commands to, you will find it in basic device info project
textBox1.AppendText("Battery Status: " + device.Battery.Level.ToString() + Environment.NewLine); // Show battery percentage as string
textBox1.AppendText("Battery Temperature: "+ device.Battery.Temperature + Environment.NewLine); // Show battery temperature
textBox1.AppendText("Encryption: "+ device.BuildProp.GetProp("ro.crypto.state") + Environment.NewLine); // Show encryption state
textBox1.AppendText("Is Rooted: "+ device.HasRoot + Environment.NewLine); // Show if device rooted
textBox1.AppendText("Su Version: " + device.Su.Version + Environment.NewLine); // Show the SU Version installed
textBox1.AppendText("BusyBox: "+device.BusyBox.IsInstalled + ", " + device.BusyBox.Version + Environment.NewLine); // Checks if busybox installed and its version
}
else
{
textBox1.Text = "-------Error No Device Connected--------";
pictureBox1.BackColor = Color.Red; // Setting color to Red as not connected
statuslabel.Text = "---";
}
}
void Button2Click(object sender, EventArgs e)
{
switch(comboBox1.SelectedIndex) // Checking which option been selected in comboxBox using integers
{
case 0: // First element been selected
device.Reboot();
break;
case 1: // Second element been selected
device.RebootRecovery();
break;
case 2: // Third element been selected
device.RebootBootloader();
break;
}
}
}
}
That's it, go to Build > Build {your Project} and run it from the button which looks like play (green one)
Some Tips and Helps
My Idea behind the post was to spread the creativity about the Coding you can do. It's not just the project like above one. You have to think constantly about new ideas and find ways to implement it. Ask peoples, search on Google, XDA, StackOverflow these are some best sites for your doubt
clarification but don't just copy and paste code learn from it. Understand what it says, coding and making Tools it not only adding the feature and publish it onto the web, you need to think out of the box and add such thing which is practically hard doing in the normal way. Always remember toolkit make the process easier, don't make them too complex that user may not understand it
Here is below code on how you access Adb and Fastboot shells through the Library
Code:
Adb.ExecuteAdbCommand(Adb.FormAdbCommand("your command")); // Normal Adb Command
Adb.ExecuteAdbCommand(Adb.FormAdbShellCommand(device,false,"your command")); // ADB Shell command, by setting false to true you can access root shell
Fastboot.ExecuteFastbootCommand(Fastboot.FormFastbootCommand("your command")); // Use Fastboot commands
Whenever you fall into a trouble like you don't know what you can do further with this Library or any other in future, always remember a phrase "The Dot Operator tells you everything". Seems pretty funny but this is the truth like I don't know what this "device" (variable I've declared in above code demonstration) does? To find out, write it and add a dot
See it creates a context strip along with some tooltip text which tells me what is it for, from which I can figure out what I've to do.
AndroidLib: https://forum.xda-developers.com/showthread.php?t=1512685
Some other wrappers: AndroidCtrl, Madb
Sample Projects: https://github.com/KaustubhPatange/AdbSamples
Check my samples on github which contains some other demonstration on how to create Android Toolkit very easily. Read Comments in the code and figure out what is it trying to say
Have a Question ask in this websites: XDA,
StackOverFlow, CodeProject
So I think this is the end of the tutorial, I cannot explain everything on how to use this or that. Sometimes it is hard to code for an easy function but there is nothing wrong with asking people for your doubts, create QnA forums, asking in StackOverFlow. We learn from our mistakes, that's how the world works
So Thank you for reading this guide, if you want you can share it with your friends and if you have any doubt comment below :laugh:
Reserved?