17 |
18 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /home/pdroid/android-studio/sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/app/src/main/aidl/android/content/pm/PackageStats.aidl:
--------------------------------------------------------------------------------
1 | /* //device/java/android/android/view/WindowManager.aidl
2 | **
3 | ** Copyright 2007, The Android Open Source Project
4 | **
5 | ** Licensed under the Apache License, Version 2.0 (the "License");
6 | ** you may not use this file except in compliance with the License.
7 | ** You may obtain a copy of the License at
8 | **
9 | ** http://www.apache.org/licenses/LICENSE-2.0
10 | **
11 | ** Unless required by applicable law or agreed to in writing, software
12 | ** distributed under the License is distributed on an "AS IS" BASIS,
13 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | ** See the License for the specific language governing permissions and
15 | ** limitations under the License.
16 | */
17 |
18 | package android.content.pm;
19 |
20 | parcelable PackageStats;
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Settings specified in this file will override any Gradle settings
5 | # configured through the IDE.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/detail_features.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
10 |
11 |
16 |
17 |
22 |
23 |
--------------------------------------------------------------------------------
/ApplicationsInfo.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main_twopane.xml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
19 |
20 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/app/src/main/aidl/android/content/pm/IPackageStatsObserver.aidl:
--------------------------------------------------------------------------------
1 | /*
2 | **
3 | ** Copyright 2007, The Android Open Source Project
4 | **
5 | ** Licensed under the Apache License, Version 2.0 (the "License");
6 | ** you may not use this file except in compliance with the License.
7 | ** You may obtain a copy of the License at
8 | **
9 | ** http://www.apache.org/licenses/LICENSE-2.0
10 | **
11 | ** Unless required by applicable law or agreed to in writing, software
12 | ** distributed under the License is distributed on an "AS IS" BASIS,
13 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | ** See the License for the specific language governing permissions and
15 | ** limitations under the License.
16 | */
17 |
18 | package android.content.pm;
19 |
20 | import android.content.pm.PackageStats;
21 | /**
22 | * API for package data change related callbacks from the Package Manager.
23 | * Some usage scenarios include deletion of cache directory, generate
24 | * statistics related to code, data, cache usage(TODO)
25 | * {@hide}
26 | */
27 | oneway interface IPackageStatsObserver {
28 |
29 | void onGetStatsCompleted(in PackageStats pStats, boolean succeeded);
30 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/majeur/applicationsinfo/DetailActivity.java:
--------------------------------------------------------------------------------
1 | package com.majeur.applicationsinfo;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 | import android.view.MenuItem;
6 | import android.widget.FrameLayout;
7 |
8 | public class DetailActivity extends Activity {
9 |
10 | private final int LAYOUT_ID = 0x8898;
11 |
12 | @Override
13 | protected void onCreate(Bundle savedInstanceState) {
14 | super.onCreate(savedInstanceState);
15 | getActionBar().setDisplayHomeAsUpEnabled(true);
16 | FrameLayout frameLayout = new FrameLayout(this);
17 | frameLayout.setId(LAYOUT_ID);
18 | setContentView(frameLayout);
19 | String packageName = getIntent().getStringExtra(DetailFragment.EXTRA_PACKAGE_NAME);
20 |
21 | getFragmentManager()
22 | .beginTransaction()
23 | .replace(LAYOUT_ID, DetailFragment.getInstance(packageName))
24 | .commit();
25 | }
26 |
27 | @Override
28 | public boolean onOptionsItemSelected(MenuItem item) {
29 | if (item.getItemId() == android.R.id.home) {
30 | finish();
31 | return true;
32 | }
33 | return super.onOptionsItemSelected(item);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/app/src/main/java/com/majeur/xmlapkparser/ChunkUtil.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2008 Android4ME
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.majeur.xmlapkparser;
17 |
18 | import java.io.IOException;
19 |
20 | /**
21 | * @author Dmitry Skiba
22 | */
23 | class ChunkUtil {
24 |
25 | public static final void readCheckType(IntReader reader, int expectedType) throws IOException {
26 | int type = reader.readInt();
27 | if (type != expectedType) {
28 | throw new IOException(
29 | "Expected chunk of type 0x" + Integer.toHexString(expectedType) +
30 | ", read 0x" + Integer.toHexString(type) + ".");
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/fragment_main_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ApplicationsInfo
2 |
3 | ## (Pull request are welcomed, don't hesitate to improve the app !)
4 |
5 | Simple android application that shows all information available about all installed apps.
6 | It can be a good source of inspiration for all beginners. It deals with activities, multi pane, fragments, async tasks ...
7 |
8 | [](https://f-droid.org/app/com.majeur.applicationsinfo)
11 |
12 | [](https://play.google.com/store/apps/details?id=com.majeur.applicationsinfo)
15 |
16 |
17 | 
18 |
19 | ## Changelog
20 |
21 | * 1.4:
22 | * Added size and sort by size in main list
23 | * Changed installation and last update dates format
24 | * Fixed label in detail for tablets
25 | * Fixed minute value that appears instead of month
26 | * 1.3:
27 | * Better display of manifest code
28 | * Design and bug fixies
29 | * 1.2:
30 | * View manifest file
31 | * 1.1:
32 | * Multi pane
33 | * Detailed size
34 | * 1.0:
35 | * Initial release
36 |
37 | This app is using parts of [XmlApkParser](http://code.google.com/p/xml-apk-parser/) library, which is under [Apache License 2.0](http://www.apache.org/licenses/LICENSE-2.0)
38 |
39 |
40 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/main_list_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
13 |
14 |
19 |
20 |
26 |
27 |
33 |
34 |
40 |
41 |
42 |
43 |
48 |
49 |
53 |
54 |
57 |
58 |
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/detail_activities.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
11 |
12 |
19 |
20 |
25 |
26 |
31 |
32 |
36 |
37 |
41 |
42 |
46 |
47 |
51 |
52 |
56 |
57 |
58 |
59 |
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/app/src/main/java/com/majeur/applicationsinfo/DetailOverflowMenu.java:
--------------------------------------------------------------------------------
1 | package com.majeur.applicationsinfo;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 | import android.content.pm.ApplicationInfo;
6 | import android.content.pm.PackageManager;
7 | import android.net.Uri;
8 | import android.view.MenuItem;
9 | import android.view.View;
10 | import android.widget.PopupMenu;
11 |
12 |
13 | public class DetailOverflowMenu implements View.OnClickListener, PopupMenu.OnMenuItemClickListener {
14 |
15 | private Context mContext;
16 | private String mPackageName;
17 |
18 | public DetailOverflowMenu(Context context, String packageName) {
19 | mContext = context;
20 | mPackageName = packageName;
21 | }
22 |
23 | public void setView(View view) {
24 | view.setOnClickListener(this);
25 | }
26 |
27 | @Override
28 | public void onClick(View view) {
29 | PopupMenu popupMenu = new PopupMenu(mContext, view);
30 | popupMenu.inflate(R.menu.fragment_detail);
31 |
32 | //Disable uninstall option for system apps.
33 | popupMenu.getMenu().findItem(R.id.action_uninstall).setEnabled(!isSystemApp());
34 |
35 | popupMenu.setOnMenuItemClickListener(this);
36 | popupMenu.show();
37 |
38 | }
39 |
40 | @Override
41 | public boolean onMenuItemClick(MenuItem menuItem) {
42 | switch (menuItem.getItemId()) {
43 | case R.id.action_uninstall:
44 | Intent uninstallIntent = new Intent(Intent.ACTION_DELETE);
45 | uninstallIntent.setData(Uri.parse("package:" + mPackageName));
46 | mContext.startActivity(uninstallIntent);
47 | return true;
48 | case R.id.action_view_in_settings:
49 | Intent infoIntent = new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
50 | infoIntent.addCategory(Intent.CATEGORY_DEFAULT);
51 | infoIntent.setData(Uri.parse("package:" + mPackageName));
52 | mContext.startActivity(infoIntent);
53 | return true;
54 | case R.id.action_view_manifest:
55 | Intent viewManifestIntent = new Intent(mContext, ViewManifestActivity.class);
56 | viewManifestIntent.putExtra(ViewManifestActivity.EXTRA_PACKAGE_NAME, mPackageName);
57 | mContext.startActivity(viewManifestIntent);
58 | return true;
59 | }
60 | return false;
61 | }
62 |
63 | public boolean isSystemApp() {
64 | try {
65 | return (mContext.getPackageManager().getApplicationInfo(mPackageName, 0).flags & ApplicationInfo.FLAG_SYSTEM) != 0;
66 | } catch (PackageManager.NameNotFoundException e) {
67 | e.printStackTrace();
68 | return false;
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/app/src/main/java/com/majeur/applicationsinfo/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.majeur.applicationsinfo;
2 |
3 | import android.app.Activity;
4 | import android.app.AlertDialog;
5 | import android.content.Intent;
6 | import android.os.Bundle;
7 | import android.view.Menu;
8 | import android.view.MenuItem;
9 | import android.widget.FrameLayout;
10 | import android.widget.ImageView;
11 |
12 | public class MainActivity extends Activity implements MainCallbacks {
13 |
14 | private boolean mIsDualPane;
15 | private boolean mIsArtShowed = false;
16 |
17 | @Override
18 | protected void onCreate(Bundle savedInstanceState) {
19 | super.onCreate(savedInstanceState);
20 | setContentView(R.layout.activity_main);
21 | mIsDualPane = findViewById(R.id.item_detail_container) != null;
22 |
23 | //Show an art when no fragment is showed, we make sure no detail fragment is present.
24 | if (mIsDualPane && getFragmentManager().findFragmentByTag(DetailFragment.FRAGMENT_TAG) == null) {
25 | ImageView imageView = new ImageView(this);
26 | imageView.setImageResource(R.drawable.icon_art);
27 | imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
28 | ((FrameLayout) findViewById(R.id.item_detail_container)).addView(imageView);
29 | mIsArtShowed = true;
30 | }
31 | }
32 |
33 | @Override
34 | public void onItemSelected(String packageName) {
35 | if (mIsDualPane) {
36 | //Hide art when a fragment is showed.
37 | if (mIsArtShowed) {
38 | ((FrameLayout) findViewById(R.id.item_detail_container)).removeAllViews();
39 | mIsArtShowed = false;
40 | }
41 | getFragmentManager()
42 | .beginTransaction()
43 | .replace(R.id.item_detail_container, DetailFragment.getInstance(packageName), DetailFragment.FRAGMENT_TAG)
44 | .commit();
45 | } else {
46 | Intent intent = new Intent(this, DetailActivity.class);
47 | intent.putExtra(DetailFragment.EXTRA_PACKAGE_NAME, packageName);
48 | startActivity(intent);
49 | }
50 | }
51 |
52 | @Override
53 | public boolean onCreateOptionsMenu(Menu menu) {
54 | getMenuInflater().inflate(R.menu.activity_main, menu);
55 | return true;
56 | }
57 |
58 | @Override
59 | public boolean onOptionsItemSelected(MenuItem item) {
60 | if (item.getItemId() == R.id.action_about) {
61 | showAboutDialog();
62 | return true;
63 | }
64 | return super.onOptionsItemSelected(item);
65 | }
66 |
67 | private void showAboutDialog() {
68 | new AlertDialog.Builder(this)
69 | .setTitle(R.string.about)
70 | .setView(getLayoutInflater().inflate(R.layout.about_dialog_message, null))
71 | .setNegativeButton(android.R.string.ok, null)
72 | .show();
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Applications Info
3 | Loading applications
4 | System app
5 | Uninstall
6 | View in settings
7 | Uses permissions
8 | No permission required
9 | Activities
10 | Launch
11 | Unsupported
12 | Refresh
13 | No activities
14 | Receivers
15 | No receivers
16 | Providers
17 | No providers
18 | Launch mode
19 | Task affinity
20 | Installation
21 | Update
22 | Authority
23 | Services
24 | No services
25 | Orientation
26 | Soft input mode
27 | Flags
28 | Grant URI permissions
29 | Path permissions
30 | Read
31 | Write
32 | Patterns allowed
33 | Permissions
34 | Group
35 | Protection level
36 | Uses features
37 | Req. Gles ver.
38 | No features
39 | Shared user id
40 | Signatures
41 | No signatures
42 | Configurations
43 | No configurations
44 | Input features
45 | View Manifest file
46 | Manifest
47 | Error
48 | Loading …
49 | Name
50 | Package
51 | System/User
52 | Size
53 | Data received
54 | Data transmitted
55 | * Data transmitted since last boot
56 |
57 | About
58 | Developed by Majeur.\n\nSource code: https://github.com/MajeurAndroid/Applications-Info
59 |
60 | Size details
61 | Internal
62 | External
63 | Code (apk file)
64 | Data
65 | Cache
66 | Obb
67 | Media
68 |
69 | Application not installed
70 |
71 | System
72 | User
73 | Sort
74 |
75 |
--------------------------------------------------------------------------------
/app/src/main/res/values-pt-rBR/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Applications Info
3 | Carregando aplicativos
4 | Aplicativo do sitema
5 | Desinstalar
6 | Ver em configurações
7 | Permissões de uso
8 | Não requer permissões
9 | Atividades
10 | Lançamento
11 | Não suportado
12 | Regarregar
13 | Sem atividades
14 | Receptores
15 | Sem receptores
16 | Provedores
17 | Sem provedores
18 | Modo de lançamento
19 | Afinidade da tarefa
20 | Instalação
21 | Atualização
22 | Autoridade
23 | Serviços
24 | Sem serviços
25 | Orientação
26 | Soft input mode
27 | Flags
28 | Concede permissões URI
29 | Permissões de caminho
30 | Ler
31 | Escrever
32 | Padrões permitidos
33 | Permissões
34 | Grupo
35 | Nível de proteção
36 | Uses features
37 | Req. Gles ver.
38 | No features
39 | Id de usuário compartilhado
40 | Assinaturas
41 | Sem assinaturas
42 | Configurações
43 | Sem configurações
44 | Input features
45 | Ver arquivo Manifesto
46 | Manifesto
47 | Erro
48 | Carregando …
49 | Nome
50 | Pacote
51 | Sistema/Usuário
52 | Tamanho
53 | Dados recebidos
54 | Dados transmitidos
55 | * Dados transmitidos desde a última inicialização do dispositivo
56 |
57 | Sobre
58 | Desenvolvido por Majeur.\n\nCódigo fonte: https://github.com/MajeurAndroid/Applications-Info
59 |
60 | Detalhes de tamanho
61 | Interno
62 | Externo
63 | Código (arquivo apk)
64 | Dados
65 | Cache
66 | Obb
67 | Mídia
68 |
69 | Aplicativo não instalado
70 |
71 | Sistema
72 | Usuário
73 |
--------------------------------------------------------------------------------
/app/src/main/res/values-ru/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Applications Info
3 | Получаем приложения
4 | Системное приложение
5 | Удалить
6 | Просмотреть в настройках
7 | Используемые разрешения
8 | Разрешения не требуются
9 | Операции
10 | Запустить
11 | Не поддерживается
12 | Обновить
13 | Нет операций
14 | Receivers
15 | No receivers
16 | Провайдеры
17 | Нет провайдеров
18 | Режим запуска
19 | Task affinity
20 | Установлено
21 | Обновить
22 | Authority
23 | Службы
24 | Нет служб
25 | Ориентация
26 | Режим экранного ввода
27 | Флаги
28 | Grant URI permissions
29 | Path permissions
30 | Read
31 | Write
32 | Patterns allowed
33 | Разрешения
34 | Группа
35 | Уровень защиты
36 | Использует свойства
37 | Необх. версия GL ES
38 | No features
39 | Общий пользовательский ID
40 | Подписи
41 | Нет подписей
42 | Конфигурации
43 | Нет конфигураций
44 | Input features
45 | Открыть файл Manifest
46 | Manifest
47 | Ошибка
48 | Загрузка…
49 | Название
50 | Пакет
51 | Системное/Пользовательское
52 | Размер
53 | Загружено
54 | Передано
55 | * Трафик, использованный с момента последнего запуска
56 |
57 | О программе
58 | Разработчик: Majeur\n
59 | \n
60 | Исходный код: https://github.com/MajeurAndroid/Applications-Info
61 |
62 | Размер
63 | Телефон
64 | Внешняя память
65 | Код (файл .apk)
66 | Данные
67 | Кэш
68 | Obb
69 | Медиа
70 |
71 | Приложение не установлено
72 |
73 | Системное
74 | Пользовательское
75 | Сортировать
76 |
77 |
--------------------------------------------------------------------------------
/app/src/main/java/com/majeur/xmlapkparser/IntReader.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2008 Android4ME
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.majeur.xmlapkparser;
17 |
18 | import java.io.EOFException;
19 | import java.io.IOException;
20 | import java.io.InputStream;
21 |
22 | /**
23 | * @author Dmitry Skiba
24 | *
25 | * Simple helper class that allows reading of integers.
26 | *
27 | * TODO:
28 | * * implement buffering
29 | */
30 | public final class IntReader {
31 |
32 | public IntReader() {
33 | }
34 |
35 | public IntReader(InputStream stream, boolean bigEndian) {
36 | reset(stream, bigEndian);
37 | }
38 |
39 | public final void reset(InputStream stream, boolean bigEndian) {
40 | m_stream = stream;
41 | m_bigEndian = bigEndian;
42 | m_position = 0;
43 | }
44 |
45 | public final void close() {
46 | if (m_stream == null) {
47 | return;
48 | }
49 | try {
50 | m_stream.close();
51 | } catch (IOException e) {
52 | }
53 | reset(null, false);
54 | }
55 |
56 | public final InputStream getStream() {
57 | return m_stream;
58 | }
59 |
60 | public final boolean isBigEndian() {
61 | return m_bigEndian;
62 | }
63 |
64 | public final void setBigEndian(boolean bigEndian) {
65 | m_bigEndian = bigEndian;
66 | }
67 |
68 | public final int readByte() throws IOException {
69 | return readInt(1);
70 | }
71 |
72 | public final int readShort() throws IOException {
73 | return readInt(2);
74 | }
75 |
76 | public final int readInt() throws IOException {
77 | return readInt(4);
78 | }
79 |
80 | public final int readInt(int length) throws IOException {
81 | if (length < 0 || length > 4) {
82 | throw new IllegalArgumentException();
83 | }
84 | int result = 0;
85 | if (m_bigEndian) {
86 | for (int i = (length - 1) * 8; i >= 0; i -= 8) {
87 | int b = m_stream.read();
88 | if (b == -1) {
89 | throw new EOFException();
90 | }
91 | m_position += 1;
92 | result |= (b << i);
93 | }
94 | } else {
95 | length *= 8;
96 | for (int i = 0; i != length; i += 8) {
97 | int b = m_stream.read();
98 | if (b == -1) {
99 | throw new EOFException();
100 | }
101 | m_position += 1;
102 | result |= (b << i);
103 | }
104 | }
105 | return result;
106 | }
107 |
108 | public final int[] readIntArray(int length) throws IOException {
109 | int[] array = new int[length];
110 | readIntArray(array, 0, length);
111 | return array;
112 | }
113 |
114 | public final void readIntArray(int[] array, int offset, int length) throws IOException {
115 | for (; length > 0; length -= 1) {
116 | array[offset++] = readInt();
117 | }
118 | }
119 |
120 | public final byte[] readByteArray(int length) throws IOException {
121 | byte[] array = new byte[length];
122 | int read = m_stream.read(array);
123 | m_position += read;
124 | if (read != length) {
125 | throw new EOFException();
126 | }
127 | return array;
128 | }
129 |
130 | public final void skip(int bytes) throws IOException {
131 | if (bytes <= 0) {
132 | return;
133 | }
134 | long skipped = m_stream.skip(bytes);
135 | m_position += skipped;
136 | if (skipped != bytes) {
137 | throw new EOFException();
138 | }
139 | }
140 |
141 | public final void skipInt() throws IOException {
142 | skip(4);
143 | }
144 |
145 | public final int available() throws IOException {
146 | return m_stream.available();
147 | }
148 |
149 | public final int getPosition() {
150 | return m_position;
151 | }
152 |
153 | /////////////////////////////////// data
154 |
155 | private InputStream m_stream;
156 | private boolean m_bigEndian;
157 | private int m_position;
158 | }
159 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # For Cygwin, ensure paths are in UNIX format before anything is touched.
46 | if $cygwin ; then
47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
48 | fi
49 |
50 | # Attempt to set APP_HOME
51 | # Resolve links: $0 may be a link
52 | PRG="$0"
53 | # Need this for relative symlinks.
54 | while [ -h "$PRG" ] ; do
55 | ls=`ls -ld "$PRG"`
56 | link=`expr "$ls" : '.*-> \(.*\)$'`
57 | if expr "$link" : '/.*' > /dev/null; then
58 | PRG="$link"
59 | else
60 | PRG=`dirname "$PRG"`"/$link"
61 | fi
62 | done
63 | SAVED="`pwd`"
64 | cd "`dirname \"$PRG\"`/" >&-
65 | APP_HOME="`pwd -P`"
66 | cd "$SAVED" >&-
67 |
68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
69 |
70 | # Determine the Java command to use to start the JVM.
71 | if [ -n "$JAVA_HOME" ] ; then
72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
73 | # IBM's JDK on AIX uses strange locations for the executables
74 | JAVACMD="$JAVA_HOME/jre/sh/java"
75 | else
76 | JAVACMD="$JAVA_HOME/bin/java"
77 | fi
78 | if [ ! -x "$JAVACMD" ] ; then
79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
80 |
81 | Please set the JAVA_HOME variable in your environment to match the
82 | location of your Java installation."
83 | fi
84 | else
85 | JAVACMD="java"
86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
87 |
88 | Please set the JAVA_HOME variable in your environment to match the
89 | location of your Java installation."
90 | fi
91 |
92 | # Increase the maximum file descriptors if we can.
93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
94 | MAX_FD_LIMIT=`ulimit -H -n`
95 | if [ $? -eq 0 ] ; then
96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
97 | MAX_FD="$MAX_FD_LIMIT"
98 | fi
99 | ulimit -n $MAX_FD
100 | if [ $? -ne 0 ] ; then
101 | warn "Could not set maximum file descriptor limit: $MAX_FD"
102 | fi
103 | else
104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
105 | fi
106 | fi
107 |
108 | # For Darwin, add options to specify how the application appears in the dock
109 | if $darwin; then
110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
111 | fi
112 |
113 | # For Cygwin, switch paths to Windows format before running java
114 | if $cygwin ; then
115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
158 | function splitJvmOpts() {
159 | JVM_OPTS=("$@")
160 | }
161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
163 |
164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
165 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/size_table.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
11 |
12 |
18 |
19 |
25 |
26 |
32 |
33 |
34 |
35 |
38 |
39 |
45 |
46 |
52 |
53 |
59 |
60 |
61 |
62 |
66 |
67 |
73 |
74 |
80 |
81 |
87 |
88 |
89 |
90 |
93 |
94 |
100 |
101 |
107 |
108 |
114 |
115 |
116 |
117 |
121 |
122 |
128 |
129 |
135 |
136 |
142 |
143 |
144 |
145 |
148 |
149 |
155 |
156 |
162 |
163 |
169 |
170 |
171 |
172 |
--------------------------------------------------------------------------------
/app/src/main/java/com/majeur/applicationsinfo/MainLoader.java:
--------------------------------------------------------------------------------
1 | package com.majeur.applicationsinfo;
2 |
3 | import android.content.AsyncTaskLoader;
4 | import android.content.BroadcastReceiver;
5 | import android.content.Context;
6 | import android.content.Intent;
7 | import android.content.IntentFilter;
8 | import android.content.pm.ApplicationInfo;
9 | import android.content.pm.PackageManager;
10 |
11 | import java.util.ArrayList;
12 | import java.util.List;
13 |
14 | public class MainLoader extends AsyncTaskLoader> {
15 |
16 | private List mData;
17 | private PackageIntentReceiver mPackageObserver;
18 | private PackageManager mPackageManager;
19 |
20 | public MainLoader(Context context) {
21 | super(context);
22 |
23 | mPackageManager = getContext().getPackageManager();
24 | }
25 |
26 | @Override
27 | public List loadInBackground() {
28 | List applicationInfos = mPackageManager.getInstalledApplications(PackageManager.GET_META_DATA);
29 |
30 | List itemList = new ArrayList<>(applicationInfos.size());
31 |
32 | for (ApplicationInfo applicationInfo : applicationInfos) {
33 |
34 | ApplicationItem item = new ApplicationItem();
35 | item.applicationInfo = applicationInfo;
36 | item.label = applicationInfo.loadLabel(mPackageManager).toString();
37 | try {
38 | item.date = mPackageManager.getPackageInfo(applicationInfo.packageName, 0).firstInstallTime;
39 | } catch (PackageManager.NameNotFoundException e) {
40 | item.date = 0L;
41 | }
42 | itemList.add(item);
43 | }
44 |
45 | return itemList;
46 | }
47 |
48 | /**
49 | * Called when there is new data to deliver to the client. The
50 | * super class will take care of delivering it; the implementation
51 | * here just adds a little more logic.
52 | */
53 | @Override
54 | public void deliverResult(List data) {
55 | if (isReset()) {
56 | // An async query came in while the loader is stopped. We
57 | // don't need the result.
58 | if (data != null) {
59 | onReleaseResources(data);
60 | }
61 | }
62 | List olddata = mData;
63 | mData = data;
64 |
65 | if (isStarted()) {
66 | // If the Loader is currently started, we can immediately
67 | // deliver its results.
68 | super.deliverResult(data);
69 | }
70 |
71 | // At this point we can release the resources associated with
72 | // 'olddata' if needed; now that the new result is delivered we
73 | // know that it is no longer in use.
74 | if (olddata != null) {
75 | onReleaseResources(olddata);
76 | }
77 | }
78 |
79 | /**
80 | * Handles a request to start the Loader.
81 | */
82 | @Override
83 | protected void onStartLoading() {
84 | if (mData != null) {
85 | // If we currently have a result available, deliver it
86 | // immediately.
87 | deliverResult(mData);
88 | }
89 |
90 | // Start watching for changes in the app data.
91 | if (mPackageObserver == null) {
92 | mPackageObserver = new PackageIntentReceiver(this);
93 | }
94 |
95 | if (takeContentChanged() || mData == null) {
96 | // If the data has changed since the last time it was loaded
97 | // or is not currently available, start a load.
98 | forceLoad();
99 | }
100 | }
101 |
102 | /**
103 | * Handles a request to stop the Loader.
104 | */
105 | @Override
106 | protected void onStopLoading() {
107 | // Attempt to cancel the current load task if possible.
108 | cancelLoad();
109 | }
110 |
111 | /**
112 | * Handles a request to cancel a load.
113 | */
114 | @Override
115 | public void onCanceled(List data) {
116 | super.onCanceled(data);
117 |
118 | // At this point we can release the resources associated with 'data'
119 | // if needed.
120 | onReleaseResources(data);
121 | }
122 |
123 | /**
124 | * Handles a request to completely reset the Loader.
125 | */
126 | @Override
127 | protected void onReset() {
128 | super.onReset();
129 |
130 | // Ensure the loader is stopped
131 | onStopLoading();
132 |
133 | // At this point we can release the resources associated with 'data'
134 | // if needed.
135 | if (mData != null) {
136 | onReleaseResources(mData);
137 | mData = null;
138 | }
139 |
140 | // Stop monitoring for changes.
141 | if (mPackageObserver != null) {
142 | getContext().unregisterReceiver(mPackageObserver);
143 | mPackageObserver = null;
144 | }
145 | }
146 |
147 | /**
148 | * Helper function to take care of releasing resources associated
149 | * with an actively loaded data set.
150 | */
151 | protected void onReleaseResources(List data) {
152 | // For a simple List<> there is nothing to do. For something
153 | // like a Cursor, we would close it here.
154 | }
155 |
156 |
157 | /**
158 | * Helper class to look for interesting changes to the installed apps
159 | * so that the loader can be updated.
160 | */
161 | public static class PackageIntentReceiver extends BroadcastReceiver {
162 |
163 | final MainLoader mLoader;
164 |
165 | public PackageIntentReceiver(MainLoader loader) {
166 | mLoader = loader;
167 | IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
168 | filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
169 | filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
170 | filter.addDataScheme("package");
171 | mLoader.getContext().registerReceiver(this, filter);
172 | // Register for events related to sdcard installation.
173 | IntentFilter sdFilter = new IntentFilter();
174 | sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
175 | sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
176 | filter.addAction(Intent.ACTION_LOCALE_CHANGED);
177 | mLoader.getContext().registerReceiver(this, sdFilter);
178 | }
179 |
180 | @Override
181 | public void onReceive(Context context, Intent intent) {
182 | mLoader.onContentChanged();
183 | }
184 | }
185 |
186 | }
--------------------------------------------------------------------------------
/app/src/main/res/layout/detail_header.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
11 |
12 |
18 |
19 |
25 |
26 |
33 |
34 |
41 |
42 |
49 |
50 |
57 |
58 |
59 |
67 |
68 |
74 |
75 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
91 |
92 |
93 |
94 |
98 |
99 |
104 |
105 |
112 |
113 |
120 |
121 |
128 |
129 |
130 |
131 |
135 |
136 |
140 |
141 |
146 |
147 |
154 |
155 |
162 |
163 |
164 |
165 |
171 |
172 |
173 |
174 |
--------------------------------------------------------------------------------
/app/app.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |