diff --git a/libsuperuser_example/.classpath b/libsuperuser_example/.classpath
new file mode 100644
index 0000000..a4f1e40
--- /dev/null
+++ b/libsuperuser_example/.classpath
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/libsuperuser_example/.project b/libsuperuser_example/.project
new file mode 100644
index 0000000..62792e3
--- /dev/null
+++ b/libsuperuser_example/.project
@@ -0,0 +1,33 @@
+
+
+ libsuperuser_example
+
+
+
+
+
+ com.android.ide.eclipse.adt.ResourceManagerBuilder
+
+
+
+
+ com.android.ide.eclipse.adt.PreCompilerBuilder
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ com.android.ide.eclipse.adt.ApkBuilder
+
+
+
+
+
+ com.android.ide.eclipse.adt.AndroidNature
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/libsuperuser_example/AndroidManifest.xml b/libsuperuser_example/AndroidManifest.xml
new file mode 100644
index 0000000..01c7ab7
--- /dev/null
+++ b/libsuperuser_example/AndroidManifest.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ "
+
+
+
\ No newline at end of file
diff --git a/libsuperuser_example/proguard-project.txt b/libsuperuser_example/proguard-project.txt
new file mode 100644
index 0000000..f2fe155
--- /dev/null
+++ b/libsuperuser_example/proguard-project.txt
@@ -0,0 +1,20 @@
+# To enable ProGuard in your project, edit project.properties
+# to define the proguard.config property as described in that file.
+#
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in ${sdk.dir}/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the ProGuard
+# include property in project.properties.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
diff --git a/libsuperuser_example/project.properties b/libsuperuser_example/project.properties
new file mode 100644
index 0000000..e0f8539
--- /dev/null
+++ b/libsuperuser_example/project.properties
@@ -0,0 +1,15 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system edit
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+#
+# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
+#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
+
+# Project target.
+target=android-4
+android.library.reference.1=../libsuperuser
diff --git a/libsuperuser_example/res/drawable-hdpi/ic_launcher.png b/libsuperuser_example/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..96a442e
Binary files /dev/null and b/libsuperuser_example/res/drawable-hdpi/ic_launcher.png differ
diff --git a/libsuperuser_example/res/drawable-mdpi/ic_launcher.png b/libsuperuser_example/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..359047d
Binary files /dev/null and b/libsuperuser_example/res/drawable-mdpi/ic_launcher.png differ
diff --git a/libsuperuser_example/res/drawable-xhdpi/ic_launcher.png b/libsuperuser_example/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..71c6d76
Binary files /dev/null and b/libsuperuser_example/res/drawable-xhdpi/ic_launcher.png differ
diff --git a/libsuperuser_example/res/layout/activity_main.xml b/libsuperuser_example/res/layout/activity_main.xml
new file mode 100644
index 0000000..e05ab21
--- /dev/null
+++ b/libsuperuser_example/res/layout/activity_main.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
diff --git a/libsuperuser_example/res/values/strings.xml b/libsuperuser_example/res/values/strings.xml
new file mode 100644
index 0000000..342b90e
--- /dev/null
+++ b/libsuperuser_example/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ libsuperuser_example
+
\ No newline at end of file
diff --git a/libsuperuser_example/src/eu/chainfire/libsuperuser_example/BackgroundIntentService.java b/libsuperuser_example/src/eu/chainfire/libsuperuser_example/BackgroundIntentService.java
new file mode 100644
index 0000000..4cafcca
--- /dev/null
+++ b/libsuperuser_example/src/eu/chainfire/libsuperuser_example/BackgroundIntentService.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2012 Jorrit "Chainfire" Jongma
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package eu.chainfire.libsuperuser_example;
+
+import eu.chainfire.libsuperuser.Application;
+import eu.chainfire.libsuperuser.Shell;
+import android.app.IntentService;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+
+/**
+ * Example IntentService based class, to execute tasks in a background
+ * thread. This would typically be used by BroadcastReceivers and other
+ * fire-and-forget type calls.
+ *
+ * For most background calls that would occur when the UI is visible, in
+ * response to some user action and/or something you are waiting for,
+ * you would typically use an AsyncTask instead of a service like this.
+ * (See MainActivity.java for that example)
+ *
+ * Note that the IntentService's onHandleIntent call runs in a background
+ * thread, while a normal service's calls would run in the main thread,
+ * unless you put in the extra work. This is an important distinction
+ * that is often overlooked by beginners.
+ *
+ * This service starts running when needed, and stops running when the
+ * task is done, automagically.
+ *
+ * Please also see BootCompleteReceiver.java, and AndroidManifest.xml for
+ * how and when this service is instantiated.
+ *
+ * This code leaves some room for extension - if you really wanted to
+ * respond only to a single event that always does the same, this code
+ * could have been a lot shorter.
+ */
+public class BackgroundIntentService extends IntentService {
+ // you could provide more options here, should you need them
+ public static final String ACTION_BOOT_COMPLETE = "boot_complete";
+
+ public static void performAction(Context context, String action) {
+ performAction(context, action, null);
+ }
+
+ public static void performAction(Context context, String action, Bundle extras) {
+ // this is utility call to easy starting the service and performing a task
+ // pass parameters in an bundle to be added to the intent as extras
+ // See BootCompleteReceiver.java
+
+ if ((context == null) || (action == null) || action.equals("")) return;
+
+ Intent svc = new Intent(context, BackgroundIntentService.class);
+ svc.setAction(action);
+ if (extras != null) svc.putExtras(extras);
+ context.startService(svc);
+ }
+
+ public BackgroundIntentService() {
+ // If you forget this one, the app will crash
+ super("BackgroundIntentService");
+ }
+
+ @Override
+ protected void onHandleIntent(Intent intent) {
+ String action = intent.getAction();
+ if ((action == null) || (action.equals(""))) return;
+
+ if (action.equals(ACTION_BOOT_COMPLETE)) {
+ onBootComplete();
+ }
+ // you can define more options here... pass parameters through the "extra" values
+ }
+
+ protected void onBootComplete() {
+ // We are running in a background thread here!
+
+ // This would crash (when debugging) if it was called from the main thread:
+ Shell.SU.run("ls -l /");
+
+ // Let's toast that we're done, using the work-arounds and utility function in
+ // out Application class. Without those modifications there would be a very high
+ // chance of crashing the app in various Android versions. The modifications are
+ // simple and easily ported to your own Application class, if you can't use the
+ // one from libsuperuser.
+ Application.toast(this, "This toast will self-destruct in five seconds");
+ }
+}
diff --git a/libsuperuser_example/src/eu/chainfire/libsuperuser_example/BootCompleteReceiver.java b/libsuperuser_example/src/eu/chainfire/libsuperuser_example/BootCompleteReceiver.java
new file mode 100644
index 0000000..f85a159
--- /dev/null
+++ b/libsuperuser_example/src/eu/chainfire/libsuperuser_example/BootCompleteReceiver.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2012 Jorrit "Chainfire" Jongma
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package eu.chainfire.libsuperuser_example;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+/**
+ * Example BootCompleteReceiver that starts MyIntentService
+ * (please see MyIntentService.java) to handle the task
+ * in a background thread
+ */
+public class BootCompleteReceiver extends BroadcastReceiver{
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ // What many beginners don't realize is that BroadcastReceivers like these
+ // usually run in the application's main thread, and can thus generate
+ // ANRs. This is increasingly likely with the BOOT_COMPLETED receiver, as
+ // the system is likely very busy when this receiver is called.
+
+ // In this example we are starting our MyIntentService to actually do the
+ // work we want to happen, not only because "su" should specifically NEVER
+ // be called from a BroadcastReceiver, but also because you should be doing
+ // this even if you aren't calling "su". It's a good practise, and using
+ // IntentService is really easy.
+
+ BackgroundIntentService.performAction(context, BackgroundIntentService.ACTION_BOOT_COMPLETE);
+ }
+}
\ No newline at end of file
diff --git a/libsuperuser_example/src/eu/chainfire/libsuperuser_example/MainActivity.java b/libsuperuser_example/src/eu/chainfire/libsuperuser_example/MainActivity.java
new file mode 100644
index 0000000..666bba5
--- /dev/null
+++ b/libsuperuser_example/src/eu/chainfire/libsuperuser_example/MainActivity.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2012 Jorrit "Chainfire" Jongma
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package eu.chainfire.libsuperuser_example;
+
+import java.util.List;
+
+import eu.chainfire.libsuperuser.Shell;
+
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.app.Activity;
+import android.app.ProgressDialog;
+import android.content.Context;
+import android.widget.EditText;
+
+public class MainActivity extends Activity {
+ private class Startup extends AsyncTask {
+ private ProgressDialog dialog = null;
+ private Context context = null;
+ private boolean suAvailable = false;
+ private String suVersion = null;
+ private String suVersionInternal = null;
+ private List suResult = null;
+
+ public Startup setContext(Context context) {
+ this.context = context;
+ return this;
+ }
+
+ @Override
+ protected void onPreExecute() {
+ // We're creating a progress dialog here because we want the user to wait.
+ // If in your app your user can just continue on with clicking other things,
+ // don't do the dialog thing.
+
+ dialog = new ProgressDialog(context);
+ dialog.setTitle("Some title");
+ dialog.setMessage("Doing something interesting ...");
+ dialog.setIndeterminate(true);
+ dialog.setCancelable(false);
+ dialog.show();
+ }
+
+ @Override
+ protected Void doInBackground(Void... params) {
+ // Let's do some SU stuff
+ suAvailable = Shell.SU.available();
+ if (suAvailable) {
+ suVersion = Shell.SU.version(false);
+ suVersionInternal = Shell.SU.version(true);
+ suResult = Shell.SU.run(new String[] {
+ "id",
+ "ls -l /"
+ });
+ }
+
+ // This is just so you see we had a progress dialog,
+ // don't do this in production code
+ try { Thread.sleep(5000); } catch(Exception e) { }
+
+ return null;
+ }
+
+ @Override
+ protected void onPostExecute(Void result) {
+ dialog.dismiss();
+
+ // output
+ StringBuilder sb = (new StringBuilder()).
+ append("Root? ").append(suAvailable ? "Yes" : "No").append((char)10).
+ append("Version: ").append(suVersion == null ? "N/A" : suVersion).append((char)10).
+ append("Version (internal): ").append(suVersionInternal == null ? "N/A" : suVersionInternal).append((char)10).
+ append((char)10);
+ if (suResult != null) {
+ for (String line : suResult) {
+ sb.append(line).append((char)10);
+ }
+ }
+ ((EditText)findViewById(R.id.text)).setText(sb.toString());
+ }
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ // Let's do some background stuff
+ (new Startup()).setContext(this).execute();
+ }
+}