Skip to content
This repository has been archived by the owner on Feb 11, 2022. It is now read-only.

Commit

Permalink
Add a SU explorer sample (not tested with root access)
Browse files Browse the repository at this point in the history
  • Loading branch information
spacecowboy committed May 29, 2016
1 parent c9d7035 commit cc17fc1
Show file tree
Hide file tree
Showing 8 changed files with 219 additions and 0 deletions.
3 changes: 3 additions & 0 deletions sample/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,7 @@ dependencies {

// FTP browser sample
compile 'commons-net:commons-net:3.3'

// Root example
compile 'eu.chainfire:libsuperuser:1.0.0.+'
}
20 changes: 20 additions & 0 deletions sample/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,26 @@
</intent-filter>
</activity>

<activity
android:name=".root.SUPickerActivity"
android:label="@string/title_activity_no_nonsense_file_picker"
android:theme="@style/SampleThemeLight">
<intent-filter>
<action android:name="android.intent.action.GET_CONTENT" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>

<activity
android:name=".root.SUPickerActivity2"
android:label="@string/title_activity_no_nonsense_file_picker"
android:theme="@style/SampleTheme">
<intent-filter>
<action android:name="android.intent.action.GET_CONTENT" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>

<activity
android:name=".MultimediaPickerActivity2"
android:label="@string/title_activity_no_nonsense_file_picker"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
import com.nononsenseapps.filepicker.sample.dropbox.DropboxSyncHelper;
import com.nononsenseapps.filepicker.sample.ftp.FtpPickerActivity;
import com.nononsenseapps.filepicker.sample.ftp.FtpPickerActivity2;
import com.nononsenseapps.filepicker.sample.root.SUPickerActivity;
import com.nononsenseapps.filepicker.sample.root.SUPickerActivity2;

import java.util.ArrayList;

Expand Down Expand Up @@ -235,6 +237,45 @@ public void onClick(final View v) {
}
}
});

findViewById(R.id.button_root).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent i;

if (checkLightTheme.isChecked()) {
i = new Intent(NoNonsenseFilePicker.this,
SUPickerActivity2.class);
} else {
i = new Intent(NoNonsenseFilePicker.this,
SUPickerActivity.class);
}
i.setAction(Intent.ACTION_GET_CONTENT);

i.putExtra(SUPickerActivity.EXTRA_ALLOW_MULTIPLE,
checkAllowMultiple.isChecked());
i.putExtra(SUPickerActivity.EXTRA_ALLOW_CREATE_DIR,
checkAllowCreateDir.isChecked());

// What mode is selected (makes no sense to restrict to folders here)
final int mode;
switch (radioGroup.getCheckedRadioButtonId()) {
case R.id.radioFilesAndDirs:
mode =
AbstractFilePickerFragment.MODE_FILE_AND_DIR;
break;
case R.id.radioFile:
default:
mode = AbstractFilePickerFragment.MODE_FILE;
break;
}

i.putExtra(FilePickerActivity.EXTRA_MODE, mode);


startActivityForResult(i, CODE_SD);
}
});
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.nononsenseapps.filepicker.sample.root;

import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.AlertDialog;

/**
* A dialog which tells the user that no SU binary is available
*/
public class SUErrorFragment extends DialogFragment {

private static final String TAG = "SUErrorFragment";

public static void showDialog(@NonNull final FragmentManager fm) {
SUErrorFragment d = new SUErrorFragment();
d.show(fm, TAG);
}

@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage("No read permisson, root unavailable")
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
return builder.create();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.nononsenseapps.filepicker.sample.root;

import android.os.Environment;
import android.support.annotation.Nullable;

import com.nononsenseapps.filepicker.AbstractFilePickerActivity;
import com.nononsenseapps.filepicker.AbstractFilePickerFragment;

import java.io.File;

public class SUPickerActivity extends AbstractFilePickerActivity<File> {

public SUPickerActivity() {
super();
}

@Override
protected AbstractFilePickerFragment<File> getFragment(@Nullable String startPath,
int mode,
boolean allowMultiple,
boolean allowCreateDir) {
AbstractFilePickerFragment<File> fragment = new SUPickerFragment();
// startPath is allowed to be null. In that case, default folder should be SD-card and
// not "/"
fragment.setArgs(
startPath != null ? startPath : Environment.getExternalStorageDirectory().getPath(),
mode, allowMultiple, allowCreateDir);
return fragment;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.nononsenseapps.filepicker.sample.root;

/**
* Just for second theme
*/
public class SUPickerActivity2 extends SUPickerActivity {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package com.nononsenseapps.filepicker.sample.root;

import android.support.annotation.NonNull;
import android.util.Log;

import com.nononsenseapps.filepicker.FilePickerFragment;

import java.io.File;
import java.util.List;

import eu.chainfire.libsuperuser.Shell;

/**
* An example picker which calls out to LibSU to get Root-permissions to view otherwise hidden files.
*/
public class SUPickerFragment extends FilePickerFragment {

@Override
protected boolean hasPermission(@NonNull File path) {
// Return the combination of normal file permissions and SU permissions
return super.hasPermission(path) & (!needSUPermission(path) | hasSUPermission());
}

@Override
protected void handlePermission(@NonNull File path) {
// Only call super if we don't have normal file permissions
if (!super.hasPermission(path)) {
super.handlePermission(path);
}
// Only if we need SU permissions
if (needSUPermission(path) && !hasSUPermission()) {
handleSUPermission();
}
}

private boolean haveReadPermission(@NonNull File file) {
List<String> result =
Shell.SH.run("test -r " + file.getAbsolutePath() + " && echo \"rootsuccess\"");
return result != null && !result.isEmpty() && "rootsuccess".equals(result.get(0));
}

private boolean needSUPermission(@NonNull File path) {
return !haveReadPermission(path);
}

private boolean isSUAvailable() {
return Shell.SU.available();
}

private boolean hasSUPermission() {
if (isSUAvailable()) {
List<String> result = Shell.SU.run("ls -l /");
if (result != null && !result.isEmpty()) {
return true;
}
}
return false;
}

private void handleSUPermission() {
if (isSUAvailable()) {
// request
String suVersion = Shell.SU.version(false);
String suVersionInternal = Shell.SU.version(true);
Log.d("libsuperuser: ", "suVersion:"+suVersion+" suVersionInternal:"+suVersionInternal);
} else {
// Notify that no root access available
SUErrorFragment.showDialog(getFragmentManager());
}
}
}
11 changes: 11 additions & 0 deletions sample/src/main/res/layout/activity_no_nonsense_file_picker.xml
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,17 @@
android:gravity="center"
android:text="Pick Dropbox" />

<Button
android:id="@+id/button_root"
style="?attr/borderlessButtonStyle"
android:layout_width="match_parent"
android:layout_height="64dp"
android:layout_gravity="center"
android:layout_marginTop="8dp"
android:fontFamily="light"
android:gravity="center"
android:text="Pick With Root Access" />

<TextView
android:id="@+id/text"
style="?android:textAppearanceMedium"
Expand Down

0 comments on commit cc17fc1

Please sign in to comment.