[APP Dev] Shells Java Class for Android App Devs ! Send Commands Easily ! - Android Software Development

Hi There Everybody ! I am Seaskyways and I am back with a surprise ! My Android Java Class "Shells" !
App Devs ! Shells Java Class
My Java class Shells is a class to simplify the use of sending normal commands (Shell Commands) and capturing their output ! The Reason its called Shells because it is not a single shell , its not only two or three methods , its a wide variety of methods that helps you complete your wanting easily ! Whoever , it is not totally stable and I need some help from app / java devs to fix some Exceptions , please anybody who knows contact me . The functions and uses of the class will be provided gradually in this thread (because I will have my term tests nearly) .... I might be updating this class about weekly , because I am busy , sorry
This Class will provide mainly a root shell for rooted devices , and a non-root shell for non-rooted devices , and free single command sending which returns the output , more info down
____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Functions (Methods):
Start(): public void , returns nothing , used to start both the Root shell and Non-root Shell.
Stop(): public void , returns nothing , used to stop both the Root shell and Non-root Shell , plus it resets the variables used in those shells.
____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Logsh(): public String , returns a String showing all the output of the commands sent using the Non-root shell , may cause the Non-root shell to stop , if an error occurs , please call Start() before using it . (please help here a small bug)
Logsu(): public String , returns a String showing all the output of the commands sent using the Root shell , may cause the Root shell to stop , if an error occurs , please call Start() before using it . (please help here a small bug)
____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Readsh(): public String , returns a String showing the last command's output sent using the Non-Root shell , may cause the Non-root shell to stop , if an error occurs , please call Start() before using it .
Readsu(): public String , returns a String showing the last command's output sent using the Root shell , may cause the Root shell to stop , if an error occurs , please call Start() before using it .
____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
su(String): public void , returns nothing , this is the Root shell, it executes the command given as root , it is used in the following form
Code:
Start();
su("My command");
sh(String): public void , returns nothing , this is the Non-Root shell, it executes the command given as normal user , it is used in the following form
Code:
Start();
sh("My command");
____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
su(String[]): public void , returns nothing , this is the Root shell,it converts the array to a String then it executes the command given as root , it is used in the following form
Code:
Start();
su("My", "command");
sh(String[]): public void , returns nothing , this is the Non-Root shell,it converts the array to a String then it executes the command given as normal user , it is used in the following form
Code:
Start();
sh("My", "command");
____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Shells(); public static Shells , it returns new Shells()
____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Download Dev-host
More Explanations coming later​

Reserved in case needed !

Looks usable!
Sent from my Galaxy Nexus running Android 4.2 JB

Its Very usable , but I need help in fixing it ! Plus I tried posting this on the portal , but seemed uninteresting to XDA

seaskyways said:
Its Very usable , but I need help in fixing it ! Plus I tried posting this on the portal , but seemed uninteresting to XDA
Click to expand...
Click to collapse
This is almost a year old, but this looks like exactly what I need! Seems the link is down Can you PM me or reply ? If you have time of course.

Related

Getting serious about root: FIOASYNC bug

Presently we're running a little short on kernel exploits, with the following being the only one that looks remotely plausible:
http://xorl.wordpress.com/2010/01/14/cve-2009-4141-linux-kernel-fasync-locked-file-use-after-free/
Big hold-up? For all that we have a trigger, we don't have an exploit. I believe it's up to us at this point to make that happen.
If I'm reading it right, it looks like the bug initially rears its head right here:
Code:
void __kill_fasync(struct fasync_struct *fa, int sig, int band)
{
while (fa) {
struct fown_struct * fown;
if (fa->magic != FASYNC_MAGIC) {
printk(KERN_ERR "kill_fasync: bad magic number in "
"fasync_struct!\n");
return;
}
[B]fown = &fa->fa_file->f_owner;[/B]
/* Don't send SIGURG to processes which have not set a
queued signum: SIGURG has its own default signalling
mechanism. */
if (!(sig == SIGURG && fown->signum == 0))
send_sigio(fown, fa->fa_fd, band);
fa = fa->fa_next;
}
}
... as fa_file now points to invalid memory (having been free'd earlier). The f_owner member gets shot out to send_sigio, which look like this:
Code:
void send_sigio(struct fown_struct *fown, int fd, int band)
{
struct task_struct *p;
enum pid_type type;
struct pid *pid;
int group = 1;
read_lock(&fown->lock);
type = fown->pid_type;
if (type == PIDTYPE_MAX) {
group = 0;
type = PIDTYPE_PID;
}
[B]pid = fown->pid;[/B]
if (!pid)
goto out_unlock_fown;
read_lock(&tasklist_lock);
do_each_pid_task(pid, type, p) {
send_sigio_to_task(p, fown, fd, band, group);
} while_each_pid_task(pid, type, p);
read_unlock(&tasklist_lock);
out_unlock_fown:
read_unlock(&fown->lock);
}
... in which we see the f_owner member being dereferenced. Also it gets pushed through several other functions which may be exploitable.
There are several questions to be answered before we can start attacking this:
Can we resolve the address of the fa_file data structure so we can overwrite the f_owner value?
Can we do anything with it once we've done that? (Presumably we can set it to zero to cause a null-pointer dereference, but we're mmap_min_addr = 32768 on the most recent versions, so unless we can flag the mmap region to grow down and apply memory pressure to reach page 0 this will do us no good.)
Failing the plan above: are any of the functions that f_owner gets pushed into vulnerable? I evaluated this over the weekend, but without the help of a trained kernel dev I'm not going to get very far.
While I studied a lot of this in uni, I'll admit I'm green when it comes to actually writing these exploits. I'm hoping that this will get the creative juices flowing, and perhaps provide a more comprehensive resource in case any hard-core kernel hackers want to take a look at what we're doing or give us pointers (harhar) in the right direction.
Thanks, guys. Great work up to this point.
In the original POC if you change /bin/true to /system/bin/sh you can get a new shell to open just not as root. So I'm guessing that their needs to be more added to the POC to make it a full exploit.
Right, the fork()'s in the PoC exist only to cause the file descriptor's fasync_struct to be erroneously killed, not start a root session. The root session would need to be started (presumably) by the kernel doing something to our maliciously crafted fown_struct.
The tough part is figuring out exactly where and what that fown_struct needs to be.
Well I definetly agree with you that this seems to be our best best bet I am some what of a newbie when it comes to linux allthough i am learning as i go. Do you know of any good sites to read up on kernel hacking?
Sorry Guys just got the word that this one is dead for us.....
Here is the explantion i got.
some_person said:
Nope, the bug didn't exist in 2.6.27. That's why they say >= 2.6.28 are vulnerable.
As far as how the bug works, there are 2 other issues. 1) our kernel probably wasn't compiled with AT_RANDOM 2) we don't have an elf executable.
The exploit you found does not give us root access, it crashes the system. Basically, you open the "random number generator" file, lock it, and close it... but the lock release when you close it. Then you have to call an elf executable because that generates a random number (running an elf executable) provided the kernel was compiled AT_RANDOM. you continue to call that executable (and generating random numbers) until the the lock is released on the "random number generator" file... then it's your program's turn... the kernel tries to send your program notification that the file is available, but your program has moved on. BLAM the kernel stops (or "oops").
Click to expand...
Click to collapse
Sorry to dredge up an old thread:
This exploit *will* work. According to Zanfur, the hole is in our kernel. We need to use it without AT_RANDOM (which I dont know how to do).
http://sourceware.org/ml/libc-alpha/2008-10/msg00016.html
I am pretty sure we do have elf executables, here is proof:
% file m6
m6: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), not stripped
If our kernel is susceptible to this bug then it should work, as long as there is a way to do it without at random.
Though I do not in any way represent my self as a hacker or developer I was wondering if I could throw in my 2 cents. I notice that this bug/exploit won't work because it requires AT RANDOM. I was wondering if it s possible to write code that does what the function does and insert it in. Is root required to do this (i.e. insert code into the kernel that wasn't there before) or is this a matter of know-how? Just some brainstorming I thought that I would throw in.
jballz0682 said:
Though I do not in any way represent my self as a hacker or developer I was wondering if I could throw in my 2 cents. I notice that this bug/exploit won't work because it requires AT RANDOM. I was wondering if it s possible to write code that does what the function does and insert it in. Is root required to do this (i.e. insert code into the kernel that wasn't there before) or is this a matter of know-how? Just some brainstorming I thought that I would throw in.
Click to expand...
Click to collapse
This won't get us root. Even zanfur said it. Moving on....
Framework43 said:
This won't get us root. Even zanfur said it. Moving on....
Click to expand...
Click to collapse
To clarify, even if we get AT_RANDOM functionality working, we can't use this to exploit our kernel. All we can do with this is get data from a file that was recently closed. The point of this exploit is to send a signal to a process, but there are no processes we could send a signal to that would give us root.
Our kernel seems practically invulnerable, it appears that almost all exploits are patched

App with root access // Bluetooth

Hi everyone,
I have a few questions. First of all, I've got a rooted HTC Magic with Super E.
I'm developing an app and, as far as I know, it is not possible to execute Java code as root. Is this correct? If there is a way, tell me. The only way I've found is by using shell comands:
Process p;
try {
// Preform su to get root privledges
p = Runtime.getRuntime().exec("su");
(...)
I would need root access for example to avoid the dialog asking for permission when I enable bluetooth discoverability, or the dialog asking for permission when installing a secondary app from the market.
Another question: is there a way to make the device permanently discoverable (bluetooth)?
By the way, how can I enable bluetooth and discoverability using shell comands?
Thanks!

2G/3G Preferred Network Mode with root?

I'm trying to access the hidden API for Phone.class to switch the preferred network mode via reflection.
I know this is not safe for porting to other android versions/roms and requires a system app to hold permission WRITE_SECURE_SETTINGS.
I Already managed to switch data via reflection and toggle gps via Settings.Secure.putString() by moving my app to system partition, so i think this should work too.
Does anyone have experience with reflection and/or root and is willing to help?
Of course I will share all my code/findings here.
Thanks in advance!
Links:
http://stackoverflow.com/questions/8607263/android-4-0-4g-toggle
http://stackoverflow.com/questions/5436251/how-to-access-setpreferrednetworktype-in-android-source
You can achieve this with a simple sqlite3 query instead of bothering with java reflection
Here's how :
In a terminal :
To enable 2G only
Code:
su
sqlite3 /data/data/com.android.providers.settings/databases/settings.db
insert into global values(null, 'preferred_network_mode', 1);
.exit
To enable 2G & 3G :
Code:
su
sqlite3 /data/data/com.android.providers.settings/databases/settings.db
insert into global values(null, 'preferred_network_mode', 0);
.exit
In java :
Example to enable 2G only (just replace the 1 with a 0 in the insert into to enable 2G & 3G)
Code:
try {
Process process = null;
process = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(
process.getOutputStream());
os.writeBytes("sqlite3 /data/data/com.android.providers.settings/databases/settings.db" + "\n");
os.writeBytes("insert into global values(null, 'preferred_network_mode', 1);" + "\n");
os.writeBytes(".exit" + "\n");
os.writeBytes("exit\n");
os.flush();
process.waitFor();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
It might require a reboot to be active though, not sure
If it doesn't work on your rom (tested on cm10.1), it might be a different row name, try investigating your settings.db like this :
Code:
sqlite3 /data/data/com.android.providers.settings/databases/settings.db
.tables [COLOR="Green"]// returns all the tables[/COLOR]
select * from [I]tablename[/I]; [COLOR="green"]// in cm10.1 it's in [I]global[/I] but otherwise look in [I]secure[/I] and/or [I]system[/I]
// this command returns all the rows from the selected table, the names are usually explicit, so you should find the setting you're looking for[/COLOR]
Then, when you found it :
Code:
insert into [I]tablename[/I] values(null, [I]'row name'[/I], value);
Thanks, this is very helpful!
I think you are right, one will need to tell the system to update the settings or send a broadcast that this setting has changed (like for airplane mode).
I will look at the CM sources to find out what i can do.
superkoal said:
Thanks, this is very helpful!
I think you are right, one will need to tell the system to update the settings or send a broadcast that this setting has changed (like for airplane mode).
I will look at the CM sources to find out what i can do.
Click to expand...
Click to collapse
Glad it helped.
If you manage to find a way to make the settings read the db without a reboot, please share your findings, would be very useful.
Androguide.fr said:
Glad it helped.
If you manage to find a way to make the settings read the db without a reboot, please share your findings, would be very useful.
Click to expand...
Click to collapse
Of course i will!
Buddy... you can toggle network mode with intent, no root needed, nor permissions!!
Here´s entire sample:
Code:
package com.serajr.togglenetworkmode;
import android.os.Bundle;
import android.provider.Settings.Secure;
import android.provider.Settings.SettingNotFoundException;
import android.app.Activity;
import android.content.Intent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button bnt = (Button) findViewById(R.id.button1);
bnt.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// toggle
toggleNetworkMode();
}
});
}
private void toggleNetworkMode() {
int mode = getCurrentNetworkMode() + 1;
if (mode > 2) {
mode = 0;
}
// 0 = 3G_ONLY
// 1 = 3GSM_ONLY
// 2 = 3G_PREFERRED
// change mode
Intent intent = new Intent("com.android.phone.CHANGE_NETWORK_MODE");
intent.putExtra("com.android.phone.NEW_NETWORK_MODE", mode);
sendBroadcast(intent);
}
private int getCurrentNetworkMode() {
try {
int current = Secure.getInt(getContentResolver(), "preferred_network_mode");
return current;
} catch (SettingNotFoundException ex) {
return 0;
}
}
}
Try it and tell me later!!!
Thanks, but this will only work if your phone.apk has an exported receiver for this intent.
This is only the case if you or your rom dev modded it to be so.
Some custom ROMs also have this kind of "mod/bug" in the power widget, allowing you to toggle gps.
I tried it with slim bean 4.2 build 3 on i9000 and as expected it didn't work (and so will most likely in CM10.1 too).
Just too good to be true!
If youre following the root method Use RootTools for that
sak-venom1997 said:
If youre following the root method Use RootTools for that
Click to expand...
Click to collapse
Thanks, I already do.
Really helpful library!
And yes, I will do it by sql injection to settings.db
I only need to figure out what broadcasts have to be sent / methods called and if this is possible.
Argh I am kinda lost in CM sources.
Can anyone point me to the place where this is handled?
I managed to toggle flight mode by using this in a SU shell:
Code:
if(settingenabled)
{
executeCommand("settings put global airplane_mode_on 1");
executeCommand("am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true");
}
else
{
executeCommand("settings put global airplane_mode_on 0");
executeCommand("am broadcast -a android.intent.action.AIRPLANE_MODE --ez state false");
}
Interstingly enough it didn't work if i manually injected the value and then sent the broadcast.
I have no idea why.
So atm I'm trying to do the same thing for preferred_network_mode. I can write the value to settings.db, but I just don't know what i have to do to make the system apply the setting yet.
EDIT: shell binary "settings" only works in android 4.2 (and probably upwards)
So i finally found it in CM Sources.
Seems like we need to get the currently running Instance of the Phone class to notify it about the change.
Also seems like we are back to reflection, as this is an internal system class.
I also killed com.android.phone process after updating the setting, but that didn't change anything.
EDIT:
1st step towards reflection:
I figured out that i need a jar file from the cm build to use system classes via reflection.
Does anyone have more information about this?
superkoal said:
So i finally found it in CM Sources.
Seems like we need to get the currently running Instance of the Phone class to notify it about the change.
Also seems like we are back to reflection, as this is an internal system class.
I also killed com.android.phone process after updating the setting, but that didn't change anything.
EDIT:
1st step towards reflection:
I figured out that i need a jar file from the cm build to use system classes via reflection.
Does anyone have more information about this?
Click to expand...
Click to collapse
Just a far fetched guess, but maybe try to add /system/framework/framework.jar from your rom to your app's build path
Is a reboot that unacceptable in your case ?
Maybe it's just the challenge, but i wanna change it like every other setting
A reboot is very far from what i call comfortable
superkoal said:
Maybe it's just the challenge, but i wanna change it like every other setting
A reboot is very far from what i call comfortable
Click to expand...
Click to collapse
Yeah, I get what you mean^^^
Here's a good (but old, 2009^^) official Android tutorial from the Android devs on reflection if it can help you : http://android-developers.blogspot.fr/2009/04/backward-compatibility-for-android.html
So i got some news
1. This setting is heavily protected by android system and can only be modified by the phone process itself
2. Some roms have a modified phone apk listening to a broadcast, enabling 3rd party apps to toggle
http://forum.xda-developers.com/showthread.php?t=1731187
3. His Majesty Chainfire started an app project which could amongst other features also toggle 2g/3g, but he gave up development. Regarding 2g/3g he implemented several methods, one of them being RIL injection, which he described as a really hard hack and highly experimental.
http://forum.xda-developers.com/showthread.php?t=807989
Seems this task is not that easy
But i found out that tasker can toggle 2g/3g on my phone (running slim bean 4.2.2), this is when i found out about the modified phone.apk from 2). So I'mcomfortable that it's working on my phone and i can at least develop an app for myself
Sent from my GT-I9000 using xda app-developers app

How to search StorageFiles

I need a way to search in StorageFiles with dynamically pattern, which comes from a TextBox. The directive "Windows.Storage.Search" doesnt exist in windows phone 8.1 runtime, as i saw. Now my question is, how can i do this in alternative way?
The only way to do it with WP 8.1 since Microsoft ALWAYS fails to implement the important things are to query using LINQ.
Ex:
Code:
var result = (await Windows.Storage.ApplicationData.Current.LocalFolder.GetFilesAsync(Windows.Storage.Search.CommonFileQuery.OrderByName)).
Where(x => x.Name.
Contains(x => txtBox.Text));
That's about all you can do pretty much. (Thanks Microsoft).
Thank you for the example. But it wont work for me, it shows me the following error(s):
Code:
A local variable named 'x' cannot be declared in this scope because it would give a different meaning to 'x', which is already used in a 'parent or current' scope to denote something else
and
Code:
Cannot convert lambda expression to type 'string' because it is not a delegate type
Thats really odd from Microsoft, that they havent implementet the search function like in WinRT (Windows Store App).
The first error is pretty simple. You already have the variable named "x" and it would be very bad if compiler didn't give you that error.
Change the name of the variable to something else that you don't use in that scope and it will work.
And for second problem, try this one:
Code:
private List<string> Result()
{
var result = ((List<Windows.Storage.Search.CommonFileQuery>)Windows.Storage.ApplicationData.Current.LocalFolder.GetFilesAsync(Windows.Storage.Search.CommonFileQuery.OrderByName)).Where(x => x.ToString().Contains(txtBox.Text));
return result as List<string>;
}
private async Task<List<string>> ResultAsync()
{
return await Task.Run(() => Result()).ConfigureAwait(continueOnCapturedContext: false);
}
You should call ResultAsync method and get the result in this way:
Code:
List<string> myList = ResultAsync().Result;
That's not going to work. You can't cast a StorageFile as a string.
To fix my code (simple lambda typo)
Code:
var result = (await Windows.Storage.ApplicationData.Current.LocalFolder.GetFilesAsync(Windows.Storage.Search.CommonFileQuery.OrderByName)).
Where(x => x.Name.
Contains(txtBox.Text));
if(result.Any())
{
// Do shtuff
}
Also, you should never access the .Result of an async task because you never know if it completed yet.
Ok, first error is done, but the second error is still here
Code:
Cannot convert lambda expression to type 'string' because it is not a delegate type
You are missing the point of the TAP (Task Async Pattern).
Both main thread and async method will be in execution in the same time. When the async method finish his work, main thread will stop and catch the result trough the Result property.
TAP is the recommended way of asynchronous programming in C#. The only thing with TAP is to use ConfigureAwait method in non-console type of apps to avoid deadlock.
Sooner or later you will get the result from TAP method. Nothing will get in the conflict with the main thread.
Oh wait, @andy123456 I updated my response. I forgot String.Contains ISNT a lambda .
@Tonchi91, I know all about the TAP. I've been using it since it was CTP. I've seen the awkward situations with threading in WP .
Now... if he did
Code:
List<string> myList;
ResultAsync().ContinueWith(t=> { myList = t.Result; });
I wouldn't be worried .
Ok the errors are gone, but the debugger show me the following exception:
Code:
Value does not fall within the expected range
Is this search method case-sensitive? I tried with an exact input in the TextBox.
Hmmm. Let's see your full code.
its actually only for testing, so i added your code to a button (asnyc) and will show the output in a textBlock.
Code:
private async void buttonTest_Click(object sender, RoutedEventArgs e)
{
//Result();
var result = (await Windows.Storage.KnownFolders.CameraRoll.GetFilesAsync(Windows.Storage.Search.CommonFileQuery.OrderByName)).
Where(x => x.Name.
Contains(textBox_test.Text));
if (result.Any())
{
// Do shtuff
textBlock_test.Text = result.ToString();
}
}
The error is coming from here
Code:
var result = (await Windows.Storage.KnownFolders.CameraRoll.GetFilesAsync(Windows.Storage.Search.CommonFileQuery.OrderByName))
andy123456 said:
its actually only for testing, so i added your code to a button (asnyc) and will show the output in a textBlock.
Code:
private async void buttonTest_Click(object sender, RoutedEventArgs e)
{
//Result();
var result = (await Windows.Storage.KnownFolders.CameraRoll.GetFilesAsync(Windows.Storage.Search.CommonFileQuery.OrderByName)).
Where(x => x.Name.
Contains(textBox_test.Text));
if (result.Any())
{
// Do shtuff
textBlock_test.Text = result.ToString();
}
}
The error is coming from here
Code:
var result = (await Windows.Storage.KnownFolders.CameraRoll.GetFilesAsync(Windows.Storage.Search.CommonFileQuery.OrderByName))
Click to expand...
Click to collapse
Oh Camera Roll.. You MIGHT need to have the capability to view the camera roll enabled. I forget what it's called, but you need a specific cap in order to view from there. Also, I would try to see if you can use a generic folder instead.
I would try Windows.Storage.ApplicationData.Current.LocalFolder.GetFilesAsync() as your method after the await just to test whether you can read correctly.
Yes but in wp8.1 runtime app, there arent caps anymore. The capability for access to the pictures is simply calles pictures library and is enabled. I have tested it as you said, but it gives me the same exception.
A quick tip: another way to do this is to use the Win32 C runtime API. You can, for example, use the FindFirst/NextFile functions (http://msdn.microsoft.com/en-us/library/windows/desktop/aa364418(v=vs.85).aspx) which support searches using wildcards (* and ? characters in the first parameter). These functions are wrapped in my NativeLibraries classes, but are also just publicly available for third0party developers to call from their own C++ DLLs.
Alternatively, you can use the .NET System.IO.Directory class, which has functions like EnumerateFiles(String path, String searchPattern). This is probably the better way to do it, actually.
Of course, if you want these operations to not block the current thread, you'll need to explicitly put them in their own thread or async function.
EDIT: This also assumes you have read access to the relevant directories. You application data directory works fine, for example (you can get its path from the relevant StorageFolder object). Other directories that can be accessed via WinRT functions may go through a broker function instead of being directly readable.
The point is, that i have an array with filenames. Now i need the StorageFile files which contains these filenames. My idea was to search for these files and return the files as StorageFile, so i can work with these. Or is there a simpler / another way?
http://msicc.net/?p=4182 <-- try this
Thank you, i have already done this and its working. But how can i compare the Files to read, with already read files and take only the not yet read files?

[Tutorial] Manage System Permissions in Android Marshmallow

Hello,
I create that thread to offer you a new tutorial aiming to learn how to manage System Permissions in Android Marshmallow. You can discover the tutorial in video also :
Manage System Permissions on Android 6 Marshmallow
Beginning in Android 6 Marshmallow, users grand permissions to apps while the app is running, not when they install the app. This approach gives the user more control over the app's functionality. Thus, he can choose to give the access to read contacts but not to the device location. Furthermore, users can revoke the permissions at any time, by going to the app's Settings screen.
Note that system permissions are divided into two categories : normal and dangerous. Normal permissions are granted automatically. For dangerous permissions, the user has to give approval to your application at runtime. So, developers must manage permissions at runtime before using some dangerous features.
To manage permissions inside an application, we're going to imagine we want to read contacts. This feature will use the READ_CONTACTS permission that is marked as dangerous. So, the first step is to check for READ_CONTACTS permission. If the permission has already been granted, you can use the feature that read contacts. If not, you have to request for permissions with a custom request code that will be named MY_PERMISSIONS_REQUEST_READ_CONTACTS in our example.
Code:
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[] { Manifest.permission.READ_CONTACTS },
MY_PERMISSIONS_REQUEST_READ_CONTACTS);
} else {
readContacts();
}
Note that when your application requests for permissions, the system shows a standard dialog box to user that cannot be customized. Now, you need to handle the permissions request response by overriding the onRequestPermissionsResult method :
Code:
@Override
public void onRequestPermissionsResult(int requestCode,
@NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_READ_CONTACTS :
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
readContacts();
} else {
if(ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.READ_CONTACTS)) {
new AlertDialog.Builder(this).
setTitle("Read Contacts permission").
setMessage("You need to grant read contacts permission to use read" +
" contacts feature. Retry and grant it !").show();
} else {
new AlertDialog.Builder(this).
setTitle("Read Contacts permission denied").
setMessage("You denied read contacts permission." +
" So, the feature will be disabled. To enable it" +
", go on settings and " +
"grant read contacts for the application").show();
}
}
break;
}
}
Like you can see, managing permissions in your Android application is not really hard.
Don't hesitate to give me your feedbacks or ideas for new tutorials.
Thanks.
Sylvain
Nice Tutorial.
Keep them coming
Black_Eyes said:
Nice Tutorial.
Keep them coming
Click to expand...
Click to collapse
Thanks
Hello,
The tutorial is now also available on my blog : http://www.ssaurel.com/blog/manage-permissions-on-android-6-marshmallow/ .
Don't hesitate to give me your advice and ideas for future tutorials.
Thanks.
Sylvain
They were intimidating at first but once you do it once, you've pretty much got the hang of it.
Jay Rock said:
They were intimidating at first but once you do it once, you've pretty much got the hang of it.
Click to expand...
Click to collapse
True. When you understand the mechanism, it becomes simple to use permissions in your Android code.
Christie37 said:
As I'm new mobile developer this tutorial helped me lot. Thanks keep going!!
Click to expand...
Click to collapse
Great . I made some other tutorials that could be interesting for you. Don't hesitate to look at them
Thanks man awsome
nice bro
@DSttr said:
nice bro
Click to expand...
Click to collapse
Thanks
@sylsau Thanks..
BTW, does this work properly on Android 5.1.1 and below?
I mean, what does this below code do for 5.1.1 and below? :
Code:
ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)
Does it always return true, or is there a chance of exceptions or errors?
I'm asking this because I don't have Android Device below 5.1 to test it..
Or should I wrap it up like this:
Code:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions();
}

Categories

Resources