Skip to content

Commit 44deaa1

Browse files
committed
android 6+: ask for storage permission
1 parent 633b042 commit 44deaa1

File tree

6 files changed

+167
-8
lines changed

6 files changed

+167
-8
lines changed

AndroidManifest.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<?xml version="1.0" encoding="utf-8" standalone="no"?>
22
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
33
package="axp.tool.apkextractor"
4-
android:versionCode="2"
5-
android:versionName="1.1">
4+
android:versionCode="3"
5+
android:versionName="1.2">
66

77
<uses-permission android:name="android.permission.ACCESS_SUPERUSER" />
88
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

build.gradle

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ buildscript {
33
jcenter()
44
}
55
dependencies {
6-
classpath 'com.android.tools.build:gradle:2.2.2'
6+
classpath 'com.android.tools.build:gradle:2.3.3'
77
}
88
}
99

@@ -15,7 +15,7 @@ repositories {
1515

1616
android {
1717
compileSdkVersion 25
18-
buildToolsVersion "25.0.3"
18+
buildToolsVersion "26.0.2"
1919

2020
compileOptions {
2121
sourceCompatibility JavaVersion.VERSION_1_6
@@ -47,7 +47,6 @@ android {
4747
}
4848

4949
dependencies {
50-
compile fileTree(dir: 'libs', include: ['*.jar'])
5150
compile 'com.android.support:appcompat-v7:25.3.1'
5251
compile 'com.android.support:recyclerview-v7:25.3.1'
5352
compile 'com.android.support:cardview-v7:25.3.1'

res/values/strings.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,8 @@
1313
<string name="alert_root_body">It seems that this application cannot be extracted through regular way. It is okay for paid apps: android tries to protect them from copying. However they are still extractable on rooted devices. If your device is rooted, apkExtractor could try to extract it using root.</string>
1414
<string name="alert_root_yes">Lets try with root</string>
1515
<string name="alert_root_no">Not now</string>
16+
<string name="alert_perm_title">Permission required</string>
17+
<string name="alert_perm_body">In order to write apk file application must be granted with \"Storage\" permission.\nPlease, open app\'s settings and grant \"Storage\" permission to it.</string>
18+
<string name="alert_perm_btn">Open settings</string>
1619

1720
</resources>

src/axp/tool/apkextractor/ApkListAdapter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ public ViewHolder(View v, ApkListAdapter adapter) {
136136

137137
@Override
138138
public void onClick(View v) {
139-
ApplicationInfo info = adapter.getItem(getPosition());
139+
ApplicationInfo info = adapter.getItem(getAdapterPosition());
140140
adapter.mActivity.doExctract(info);
141141
}
142142

src/axp/tool/apkextractor/MainActivity.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@
99
import android.content.pm.PackageManager;
1010
import android.os.AsyncTask;
1111
import android.os.Bundle;
12+
import android.support.annotation.NonNull;
1213
import android.support.v4.view.MenuItemCompat;
13-
import android.support.v7.app.ActionBarActivity;
14+
import android.support.v7.app.AppCompatActivity;
1415
import android.support.v7.widget.LinearLayoutManager;
1516
import android.support.v7.widget.RecyclerView;
1617
import android.support.v7.widget.SearchView;
@@ -22,10 +23,11 @@
2223

2324
import java.util.List;
2425

25-
public class MainActivity extends ActionBarActivity {
26+
public class MainActivity extends AppCompatActivity {
2627
private ApkListAdapter apkListAdapter;
2728

2829
private ProgressBar progressBar;
30+
private PermissionResolver permissionResolver;
2931

3032
@Override
3133
protected void onCreate(Bundle savedInstanceState) {
@@ -44,6 +46,17 @@ protected void onCreate(Bundle savedInstanceState) {
4446
progressBar.setVisibility(View.VISIBLE);
4547

4648
new Loader(this).execute();
49+
50+
permissionResolver = new PermissionResolver(this);
51+
}
52+
53+
54+
55+
@Override
56+
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
57+
if (!permissionResolver.onRequestPermissionsResult(requestCode, permissions, grantResults)) {
58+
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
59+
}
4760
}
4861

4962
public void hideProgressBar() {
@@ -86,6 +99,8 @@ public boolean onQueryTextChange(String s) {
8699
}
87100

88101
public void doExctract(final ApplicationInfo info) {
102+
if (!permissionResolver.resolve()) return;
103+
89104
final Extractor extractor = new Extractor();
90105
try {
91106
String dst = extractor.extractWithoutRoot(info);
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
package axp.tool.apkextractor;
2+
3+
import android.annotation.SuppressLint;
4+
import android.app.Activity;
5+
import android.content.DialogInterface;
6+
import android.content.Intent;
7+
import android.content.pm.PackageInfo;
8+
import android.content.pm.PackageManager;
9+
import android.net.Uri;
10+
import android.os.Build;
11+
import android.provider.Settings;
12+
import android.support.annotation.NonNull;
13+
import android.support.v7.app.AlertDialog;
14+
15+
import java.util.Arrays;
16+
import java.util.LinkedList;
17+
import java.util.List;
18+
19+
public class PermissionResolver {
20+
private static final int REQUEST_CODE = 100500;
21+
22+
private static final String[] DEFAULT_PERMISSIONS = new String[] {
23+
"android.permission.ACCESS_LOCATION_EXTRA_COMMANDS",
24+
"android.permission.ACCESS_NETWORK_STATE",
25+
"android.permission.ACCESS_NOTIFICATION_POLICY",
26+
"android.permission.ACCESS_WIFI_STATE",
27+
"android.permission.ACCESS_WIMAX_STATE",
28+
"android.permission.BLUETOOTH",
29+
"android.permission.BLUETOOTH_ADMIN",
30+
"android.permission.BROADCAST_STICKY",
31+
"android.permission.CHANGE_NETWORK_STATE",
32+
"android.permission.CHANGE_WIFI_MULTICAST_STATE",
33+
"android.permission.CHANGE_WIFI_STATE",
34+
"android.permission.CHANGE_WIMAX_STATE",
35+
"android.permission.DISABLE_KEYGUARD",
36+
"android.permission.EXPAND_STATUS_BAR",
37+
"android.permission.FLASHLIGHT",
38+
"android.permission.GET_ACCOUNTS",
39+
"android.permission.GET_PACKAGE_SIZE",
40+
"android.permission.INTERNET",
41+
"android.permission.KILL_BACKGROUND_PROCESSES",
42+
"android.permission.MODIFY_AUDIO_SETTINGS",
43+
"android.permission.NFC",
44+
"android.permission.READ_SYNC_SETTINGS",
45+
"android.permission.READ_SYNC_STATS",
46+
"android.permission.RECEIVE_BOOT_COMPLETED",
47+
"android.permission.REORDER_TASKS",
48+
"android.permission.REQUEST_INSTALL_PACKAGES",
49+
"android.permission.SET_TIME_ZONE",
50+
"android.permission.SET_WALLPAPER",
51+
"android.permission.SET_WALLPAPER_HINTS",
52+
"android.permission.SUBSCRIBED_FEEDS_READ",
53+
"android.permission.TRANSMIT_IR",
54+
"android.permission.USE_FINGERPRINT",
55+
"android.permission.VIBRATE",
56+
"android.permission.WAKE_LOCK",
57+
"android.permission.WRITE_SYNC_SETTINGS",
58+
"com.android.alarm.permission.SET_ALARM",
59+
"com.android.launcher.permission.INSTALL_SHORTCUT",
60+
"com.android.launcher.permission.UNINSTALL_SHORTCUT",
61+
"android.permission.ACCESS_SUPERUSER"
62+
};
63+
64+
private Activity activity;
65+
66+
public PermissionResolver(Activity a) {
67+
this.activity = a;
68+
}
69+
70+
public boolean resolve() {
71+
if (Build.VERSION.SDK_INT < 23) return true;
72+
73+
String[] unmet_permissions = getUnmetPermissions();
74+
if (unmet_permissions.length < 1) return true;
75+
76+
activity.requestPermissions(unmet_permissions, REQUEST_CODE);
77+
78+
return false;
79+
}
80+
81+
@SuppressLint("NewApi")
82+
private String[] getUnmetPermissions() {
83+
List<String> unmet_permissions = new LinkedList<String>();
84+
try {
85+
List<String> def = Arrays.asList(DEFAULT_PERMISSIONS);
86+
PackageInfo info = activity.getPackageManager().getPackageInfo(activity.getPackageName(), PackageManager.GET_PERMISSIONS);
87+
for (String perm : info.requestedPermissions) {
88+
if (def.contains(perm)) continue;
89+
if (activity.checkSelfPermission(perm) == PackageManager.PERMISSION_GRANTED) continue;
90+
unmet_permissions.add(perm);
91+
}
92+
} catch (PackageManager.NameNotFoundException e) {
93+
e.printStackTrace();
94+
return new String[0];
95+
}
96+
97+
if (unmet_permissions.size() < 1) return new String[0];
98+
99+
String[] arr = new String[unmet_permissions.size()];
100+
unmet_permissions.toArray(arr);
101+
return arr;
102+
}
103+
104+
public boolean onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
105+
if (requestCode != REQUEST_CODE) return false;
106+
107+
boolean granted = true;
108+
for (int result : grantResults) {
109+
if (result != PackageManager.PERMISSION_GRANTED) {
110+
granted = false;
111+
break;
112+
}
113+
}
114+
115+
if (granted) return true;
116+
117+
showPermissionDialog();
118+
119+
return true;
120+
}
121+
122+
private void showPermissionDialog() {
123+
new AlertDialog.Builder(activity)
124+
.setMessage(R.string.alert_perm_body)
125+
.setTitle(R.string.alert_perm_title)
126+
.setPositiveButton(R.string.alert_perm_btn, new DialogInterface.OnClickListener() {
127+
@Override
128+
public void onClick(DialogInterface dialogInterface, int i) {
129+
activity.startActivity(new Intent()
130+
.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
131+
.addCategory(Intent.CATEGORY_DEFAULT)
132+
.setData(Uri.parse("package:" + activity.getApplicationContext().getPackageName()))
133+
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
134+
.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY)
135+
.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
136+
);
137+
}
138+
})
139+
.create()
140+
.show();
141+
}
142+
}

0 commit comments

Comments
 (0)