[Android Software Development] kishorerprem:
​

Note:- After modifying your framework files by following the below tutorial all system & user apps will have the permission to write external SD Card without asking to user. Please keep backup of your ROM before doing anything. I will not be responsible for any damage or boot loop.

Method 1 : Automatic patch

Auto Patcher app :

I have developed an android application to do all the patching work automatically. To download please click here- https://xdaforums.com/showpost.php?p=73854657&postcount=84

Method 2 : Manual patch

Requirements :-

a) framework.jar & services.jar of your ROM.

b) Apktool to decompile & recompile jar files.

c) Notepad++ to edite smali files.

d) 7zip to add modded .dex files into original .jar files.
​

Step 1:- Giving write permission to External SD card.

a) Decompile services.jar with APKTool. Go to com/android/server/pm/ directory.

b) Open PackageManagerService.smali with Notepad++ & find the below method.

.method private grantPermissionsLPw(Landroid/content/pm/PackageParser$Package;ZLjava/lang/String;)V

c) Go to end of this method & add below Red color marked lines of code accordingly in their corresponding place.
​

.method private grantPermissionsLPw(Landroid/content/pm/PackageParser$Package;ZLjava/lang/String;)V
...........
....

const-wide/32 v24, 0x40000

invoke-static/range {v24 .. v25}, Landroid/os/Trace;->traceEnd(J)V

[COLOR=Red]move-object/from16 v2, p0

move-object/from16 v3, p1

invoke-direct {v2, v3}, Lcom/android/server/pm/PackageManagerService;->allowSDWrite(Landroid/content/pm/PackageParser$Package;)V[/COLOR]

return-void

:pswitch_data_4cc
....
...
.end method

[COLOR=Red].method private allowSDWrite(Landroid/content/pm/PackageParser$Package;)V
.registers 8

move-object/from16 v0, p1

iget-object v0, v0, Landroid/content/pm/PackageParser$Package;->mExtras:Ljava/lang/Object;

move-object/from16 v1, v0

check-cast v1, Lcom/android/server/pm/PackageSetting;

if-nez v1, :cond_b

return-void

:cond_b
invoke-virtual {v1}, Lcom/android/server/pm/PackageSetting;->getPermissionsState()Lcom/android/server/pm/PermissionsState;

move-result-object v1

move-object/from16 v2, v1

move-object/from16 v0, p0

iget-object v0, v0, Lcom/android/server/pm/PackageManagerService;->mSettings:Lcom/android/server/pm/Settings;

move-object/from16 v1, v0

move-object/from16 v0, v1

iget-object v0, v0, Lcom/android/server/pm/Settings;->mPermissions:Landroid/util/ArrayMap;

move-object/from16 v1, v0

move-object/from16 v0, v1

const-string/jumbo v1, "android.permission.WRITE_MEDIA_STORAGE"

invoke-virtual {v2, v1}, Lcom/android/server/pm/PermissionsState;->hasInstallPermission(Ljava/lang/String;)Z

move-result v3

if-eqz v3, :cond_29

return-void

:cond_29
invoke-virtual {v0, v1}, Landroid/util/ArrayMap;->get(Ljava/lang/Object;)Ljava/lang/Object;

move-result-object v4

check-cast v4, Lcom/android/server/pm/BasePermission;

if-nez v4, :cond_32

return-void

:cond_32
invoke-virtual {v2, v4}, Lcom/android/server/pm/PermissionsState;->grantInstallPermission(Lcom/android/server/pm/BasePermission;)I

move-result v5

return-void
.end method[/COLOR]

.method private grantRequestedRuntimePermissions(Landroid/content/pm/PackageParser$Package;[I[Ljava/lang/String;)V
.......
....
....
..
.end method

d) Recompile services.jar. Open original services.jar & modded services.jar with 7zip in side-by-side window. Drag N Drop classes.dex file from modded services.jar to original services.jar window. Now keep the services.jar in a safe place.

​

Step 2:- Switch SD Path.

a) Decompile framework.jar with Apktool. Go to android/os/ directory.
​

b) Open Environment$UserEnvironment.smali with Notepad++ & find the below method.

.method public getExternalDirs()[Ljava/io/File;

c) Add Red color marked lines of code accordingly in their corresponding place.
​

.method public getExternalDirs()[Ljava/io/File;
.registers 6

iget v3, p0, Landroid/os/Environment$UserEnvironment;->mUserId:I

const/16 v4, 0x100

invoke-static {v3, v4}, Landroid/os/storage/StorageManager;->getVolumeList(II)[Landroid/os/storage/StorageVolume;

move-result-object v2

array-length v3, v2

new-array v0, v3, [Ljava/io/File;

const/4 v1, 0x0

:goto_c
array-length v3, v2

if-ge v1, v3, :cond_1a

aget-object v3, v2, v1

invoke-virtual {v3}, Landroid/os/storage/StorageVolume;->getPathFile()Ljava/io/File;

move-result-object v3

aput-object v3, v0, v1

add-int/lit8 v1, v1, 0x1

goto :goto_c

:cond_1a
[COLOR=Red] invoke-virtual {p0, v0}, Landroid/os/Environment$UserEnvironment;->getExternalSD([Ljava/io/File;)[Ljava/io/File;

move-result-object v0[/COLOR]

return-object v0
.end method

[COLOR=Red].method public getExternalSD([Ljava/io/File;)[Ljava/io/File;
.registers 16

move-object v0, p0

move-object v1, p1

new-instance v8, Ljava/util/ArrayList;

move-object v13, v8

move-object v8, v13

move-object v9, v13

invoke-direct {v9}, Ljava/util/ArrayList;-><init>()V

move-object v3, v8

:try_start_b
new-instance v8, Ljava/io/BufferedReader;

move-object v13, v8

move-object v8, v13

move-object v9, v13

new-instance v10, Ljava/io/FileReader;

move-object v13, v10

move-object v10, v13

move-object v11, v13

const-string v12, "data/SDPath"

invoke-direct {v11, v12}, Ljava/io/FileReader;-><init>(Ljava/lang/String;)V

invoke-direct {v9, v10}, Ljava/io/BufferedReader;-><init>(Ljava/io/Reader;)V

move-object v4, v8

:goto_1e
move-object v8, v4

invoke-virtual {v8}, Ljava/io/BufferedReader;->readLine()Ljava/lang/String;
:try_end_22
.catch Ljava/lang/Exception; {:try_start_b .. :try_end_22} :catch_76

move-result-object v8

move-object v13, v8

move-object v8, v13

move-object v9, v13

move-object v5, v9

if-nez v8, :cond_58

move-object v8, v3

invoke-interface {v8}, Ljava/util/List;->isEmpty()Z

move-result v8

if-nez v8, :cond_81

move-object v8, v3

const-string v9, "ext_SD=1"

invoke-interface {v8, v9}, Ljava/util/List;->contains(Ljava/lang/Object;)Z

move-result v8

if-eqz v8, :cond_7e

move-object v8, v1

if-eqz v8, :cond_7b

move-object v8, v1

array-length v8, v8

const/4 v9, 0x1

if-le v8, v9, :cond_7b

move-object v8, v1

move-object v4, v8

move-object v8, v4

const/4 v9, 0x0

aget-object v8, v8, v9

move-object v5, v8

move-object v8, v4

const/4 v9, 0x0

move-object v10, v4

const/4 v11, 0x1

aget-object v10, v10, v11

aput-object v10, v8, v9

move-object v8, v4

const/4 v9, 0x1

move-object v10, v5

aput-object v10, v8, v9

move-object v8, v4

move-object v0, v8

:goto_57
return-object v0

:cond_58
move-object v8, v5

:try_start_59
invoke-virtual {v8}, Ljava/lang/String;->trim()Ljava/lang/String;

move-result-object v8

move-object v6, v8

move-object v8, v6

invoke-virtual {v8}, Ljava/lang/String;->isEmpty()Z

move-result v8

if-nez v8, :cond_6e

move-object v8, v6

const-string v9, "#"

invoke-virtual {v8, v9}, Ljava/lang/String;->startsWith(Ljava/lang/String;)Z

move-result v8

if-eqz v8, :cond_6f

:cond_6e
goto :goto_1e

:cond_6f
move-object v8, v3

move-object v9, v6

invoke-interface {v8, v9}, Ljava/util/List;->add(Ljava/lang/Object;)Z
:try_end_74
.catch Ljava/lang/Exception; {:try_start_59 .. :try_end_74} :catch_76

move-result v8

goto :goto_1e

:catch_76
move-exception v8

move-object v4, v8

move-object v8, v1

move-object v0, v8

goto :goto_57

:cond_7b
move-object v8, v1

move-object v0, v8

goto :goto_57

:cond_7e
move-object v8, v1

move-object v0, v8

goto :goto_57

:cond_81
move-object v8, v1

move-object v0, v8

goto :goto_57
.end method[/COLOR]

.method public getExternalStorageDirectory()Ljava/io/File;
......
.....
.end method

d) Recompile framework.jar. Open original framework.jar & modded framework.jar with 7zip in side-by-side window. Drag N Drop classes.dex file from modded framework.jar to original framework.jar window. Now keep the framework.jar in a safe place.
​

Flashing modified files.

Create a flashable zip with moded framework.jar & services.jar. If you are using Redmi Note 4G. Then download attached zip file from attachment, open with 7zip, Add both jar file into "system/framework/". Then flash with custom recovery, wipe dalvik-cache & reboot. It will take up to 5 min.

​

Creating setting file.

a) Create a new file in "/data" directory. Rename it to "SDPath".

b) Then open the file "SDPath" with text editor. Then add the following line & save.
​

ext_SD=1

If you want to switch back the SD Path to default, just change the value from 1 to 0.

​

Enjoy.....