diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index e3cb8c1..9d92c04 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -32,6 +32,9 @@ android:name=".AppManagerActivity" android:label="@string/app_manager"> + + - diff --git a/app/src/main/java/ru/nikita/adb/AppManagerActivity.java b/app/src/main/java/ru/nikita/adb/AppManagerActivity.java index 02d5699..9b41416 100644 --- a/app/src/main/java/ru/nikita/adb/AppManagerActivity.java +++ b/app/src/main/java/ru/nikita/adb/AppManagerActivity.java @@ -10,6 +10,7 @@ import android.app.ListActivity; import android.app.ProgressDialog; import android.content.Context; +import android.content.Intent; import android.widget.ArrayAdapter; import android.widget.TextView; import android.widget.ListView; @@ -25,14 +26,16 @@ import android.util.Log; import ru.nikita.adb.Device; import ru.nikita.adb.Task; +import ru.nikita.adb.PermissionsActivity; public class AppManagerActivity extends ListActivity{ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); sortMode = SORT.TYPE; - adb = (Binary) getIntent().getSerializableExtra("adb"); - device = (Device) getIntent().getSerializableExtra("device"); + Intent intent = getIntent(); + adb = (Binary) intent.getSerializableExtra("adb"); + device = (Device) intent.getSerializableExtra("device"); ListView v = getListView(); registerForContextMenu(v); new AppLoadTask().execute(); @@ -73,16 +76,27 @@ public boolean onContextItemSelected(MenuItem item) { int id = item.getItemId(); App app = apps[info.position]; if(id == R.id.app_uninstall_data){ - new AppTask().execute(R.string.app_uninstalling, "pm uninstall --user 0 " + app.pkg); + new AppTask().uninstallWithData(app); return true; }else if(id == R.id.app_uninstall){ - new AppTask().execute(R.string.app_uninstalling, "pm uninstall -k --user 0 " + app.pkg); + new AppTask().uninstall(app); return true; }else if(id == R.id.app_install){ - new AppTask().execute(R.string.app_installing, "cmd package install-existing " + app.pkg); + new AppTask().install(app); + return true; + }else if(id == R.id.app_clear){ + new AppTask().clear(app); + return true; + }else if(id == R.id.app_permissions){ + Intent intent = new Intent(this, PermissionsActivity.class); + Bundle bundle = new Bundle(); + bundle.putSerializable("adb", adb); + bundle.putSerializable("device", device); + bundle.putString("package", app.pkg); + intent.putExtras(bundle); + startActivity(intent); return true; } - return super.onContextItemSelected(item); } private void sortApps(){ @@ -124,6 +138,7 @@ public int compareTo(App app){ private class AppTask extends ADBTask{ public AppTask(){ super(adb); + update = false; } @Override protected void onPreExecute(){ @@ -139,13 +154,31 @@ protected void onPostExecute(String log){ log = log.trim(); if(log.length() > 0 && log.length() < 200) Toast.makeText(getApplicationContext(), log, Toast.LENGTH_SHORT).show(); + if(update) + new AppLoadTask().execute(); } public void execute(int stringId, String args){ this.stringId=stringId; shell(device, args); } + public void uninstallWithData(App app){ + update = true; + execute(R.string.app_uninstalling, "pm uninstall --user 0 " + app.pkg); + } + public void uninstall(App app){ + update = true; + execute(R.string.app_uninstalling, "pm uninstall -k --user 0 " + app.pkg); + } + public void install(App app){ + update = true; + execute(R.string.app_installing, "cmd package install-existing " + app.pkg); + } + public void clear(App app){ + execute(R.string.app_clearing, "pm clear " + app.pkg); + } int stringId; + boolean update; } private class AppLoadTask extends AppTask{ @Override diff --git a/app/src/main/java/ru/nikita/adb/PermissionsActivity.java b/app/src/main/java/ru/nikita/adb/PermissionsActivity.java new file mode 100644 index 0000000..2f7c2cf --- /dev/null +++ b/app/src/main/java/ru/nikita/adb/PermissionsActivity.java @@ -0,0 +1,162 @@ +package ru.nikita.adb; + +import java.util.ArrayList; +import java.util.Arrays; +import java.lang.Comparable; +import android.os.Bundle; +import android.os.AsyncTask; +import android.app.ListActivity; +import android.app.ProgressDialog; +import android.content.Context; +import android.content.Intent; +import android.view.Menu; +import android.view.MenuItem; +import android.widget.ArrayAdapter; +import android.widget.ListView; +import android.widget.TextView; +import android.widget.CheckBox; +import android.widget.Toast; +import android.R.layout; +import android.util.SparseBooleanArray; +import ru.nikita.adb.Device; +import ru.nikita.adb.Task; + +public class PermissionsActivity extends ListActivity{ + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + Intent intent = getIntent(); + adb = (Binary) intent.getSerializableExtra("adb"); + device = (Device) intent.getSerializableExtra("device"); + pkg = intent.getStringExtra("package"); + new AppPermissionLoadTask().execute(); + } + @Override + public boolean onCreateOptionsMenu(Menu menu){ + getMenuInflater().inflate(R.menu.permissions_activity, menu); + return true; + } + @Override + public boolean onOptionsItemSelected(MenuItem item){ + int id = item.getItemId(); + if(id == R.id.permissions_apply){ + SparseBooleanArray selected = getListView().getCheckedItemPositions(); + boolean granted[] = new boolean[permissions.length]; + for(int i = 0; i < granted.length; i++) + granted[i] = selected.get(i); + new AppPermissionsApplyTask().execute(granted); + return true; + } + return false; + } + private class Permission implements Comparable{ + Permission(String name){ + this.name = name; + granted = false; + } + @Override + public int compareTo(Permission p){ + return this.name.compareTo(p.name); + } + @Override + public String toString(){ + return name; + } + public String name; + public boolean granted; + } + private class AppPermissionLoadTask extends ADBTask{ + AppPermissionLoadTask(){ + super(adb); + } + @Override + protected void onPreExecute(){ + super.onPreExecute(); + pd = new ProgressDialog(PermissionsActivity.this); + pd.setProgressStyle(ProgressDialog.STYLE_SPINNER); + pd.setMessage(getResources().getString(R.string.permissions_loading)); + pd.show(); + } + @Override + protected void onPostExecute(String log){ + super.onPostExecute(log); + pd.dismiss(); + String[] lines = log.split("\n"); + boolean requested = false; + boolean install = false; + ArrayListlist = new ArrayList(); + for(String line : lines){ + line = line.trim(); + if(line.equals("requested permissions:")) + requested = true; + else if(line.equals("install permissions:")) + install = true; + else if(line.contains("User")) + break; + else if(install){ + if(!line.contains("REVOKE_ON_UPGRADE")){ + String name = line.split(":")[0]; + for(Permission p : list) + if(p.name.equals(name)) + p.granted = true; + } + }else if(requested) + list.add(new Permission(line)); + } + permissions = list.toArray(new Permission[0]); + Arrays.sort(permissions); + + setListAdapter(new ArrayAdapter(PermissionsActivity.this, + android.R.layout.simple_list_item_multiple_choice, permissions)); + + ListView listView = getListView(); + listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); + for(int i = 0; i < permissions.length; i++) + listView.setItemChecked(i, permissions[i].granted); + } + + public void execute(){ + shell(device, "dumpsys package " + pkg); + } + private ProgressDialog pd; + } + private class AppPermissionsApplyTask extends ADBTask{ + AppPermissionsApplyTask(){ + super(adb); + } + @Override + protected void onPreExecute(){ + super.onPreExecute(); + pd = new ProgressDialog(PermissionsActivity.this); + pd.setProgressStyle(ProgressDialog.STYLE_SPINNER); + pd.setMessage(getResources().getString(R.string.app_permissions_applying)); + pd.show(); + } + @Override + protected void onPostExecute(String log){ + super.onPostExecute(log); + pd.dismiss(); + if(log.length() > 0) + Toast.makeText(getApplicationContext(), log, Toast.LENGTH_LONG).show(); + new AppPermissionLoadTask().execute(); + } + public void execute(boolean[] granted){ + String command = ""; + for(int i = 0; i < permissions.length; i++){ + Permission permission = permissions[i]; + if(permission.granted != granted[i]) + command += String.format("pm %s %s %s; ", granted[i]?"grant":"revoke", + pkg, permission.name); + } + shell(device, command); + } + private ProgressDialog pd; + } + + + private Binary adb; + private Device device; + private String pkg; + + private Permission[] permissions; +} diff --git a/app/src/main/res/drawable/check.png b/app/src/main/res/drawable/apply.png similarity index 100% rename from app/src/main/res/drawable/check.png rename to app/src/main/res/drawable/apply.png diff --git a/app/src/main/res/menu/app_context_menu.xml b/app/src/main/res/menu/app_context_menu.xml index 827dc42..c4153fb 100644 --- a/app/src/main/res/menu/app_context_menu.xml +++ b/app/src/main/res/menu/app_context_menu.xml @@ -6,4 +6,8 @@ android:title="@string/app_uninstall" /> + + diff --git a/app/src/main/res/menu/permissions_activity.xml b/app/src/main/res/menu/permissions_activity.xml new file mode 100644 index 0000000..d0bd523 --- /dev/null +++ b/app/src/main/res/menu/permissions_activity.xml @@ -0,0 +1,7 @@ + + + + diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index f7c1f58..386edfe 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -18,6 +18,7 @@ Порт Список приложений Загрузка списка приложений... + Загрузка разрешений... Только сторонние Обновить список Менеджер файлов @@ -50,8 +51,12 @@ Удалить с данными Удалить Переустановить + Очистить данные + Установить разрешения Удаление... Установка... + Очистка данных... + Применение разрешений... Командная строка Выполнить Сортировка по имени diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9a95064..3a52683 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -18,6 +18,7 @@ Device port App list Loading applications... + Loading permissions... Show only installed apps Refresh File manager @@ -50,8 +51,12 @@ Uninstall with data Uninstall without data Install + Clear data + Set permissions Uninstalling... Installing... + Clearing data... + Applying permissions... Command line Execute Sort by name