Giới thiệu
Lấy đường dẫn file APK cài đặt của ứng dụng bằng getPackageResourcePath() hoặc PackageManager.getApplicationInfo(). Đường dẫn thường là /data/app/.
Triển khai
Bước 1: Tạo dự án
Android Studio → New Project → Empty Activity.
Bước 2: Layout (activity_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp"
android:gravity="center"
tools:context=".MainActivity">
<TextView
android:id="@+id/tv_apk_path"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:lineSpacingExtra="4dp"
tools:text="APK path info" />
</LinearLayout>
Bước 3: MainActivity.java
package com.example.myapplication;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
TextView tvApkPath;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvApkPath = findViewById(R.id.tv_apk_path);
// Cách 1: Context.getPackageResourcePath() - đơn giản nhất
String resourcePath = getPackageResourcePath();
// Cách 2: PackageManager - chi tiết hơn
String sourceDir = "";
String publicSourceDir = "";
String[] splitSourceDirs = {};
try {
PackageManager pm = getPackageManager();
ApplicationInfo appInfo = pm.getApplicationInfo(getPackageName(), 0);
sourceDir = appInfo.sourceDir; // base.apk
publicSourceDir = appInfo.publicSourceDir; // base.apk (public)
splitSourceDirs = appInfo.splitSourceDirs; // split APKs (dynamic features)
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
StringBuilder info = new StringBuilder();
info.append("Package Resource Path:\n").append(resourcePath).append("\n\n");
info.append("ApplicationInfo.sourceDir:\n").append(sourceDir).append("\n\n");
info.append("ApplicationInfo.publicSourceDir:\n").append(publicSourceDir).append("\n\n");
if (splitSourceDirs.length > 0) {
info.append("Split APKs (Dynamic Features):\n");
for (String split : splitSourceDirs) {
info.append(" - ").append(split).append("\n");
}
} else {
info.append("Không có Split APK (Dynamic Feature)");
}
tvApkPath.setText(info.toString());
}
}
Giải thích các đường dẫn
| Thuộc tính | Mô tả | Ví dụ |
|---|---|---|
| sourceDir | Đường dẫn base APK (chứa code, resources) | /data/app/com.example-1/base.apk |
| publicSourceDir | Đường dẫn public source (thường giống sourceDir) | /data/app/com.example-1/base.apk |
| splitSourceDirs | Mảng đường dẫn split APK (dynamic delivery) | ["/data/app/com.example-1/split_config.arm64_v8a.apk", ...] |
| nativeLibraryDir | Thư mục native library (.so) | /data/app/com.example-1/lib/arm64 |
| dataDir | Thư mục data riêng (/data/data/pkg) | /data/user/0/com.example |
Ứng dụng thực tế
- Kiểm tra integrity: So sánh checksum APK để phát hiện sửa đổi
- Plugin/Module loading: Load dynamic feature modules
- Debug/Logging: Ghi log đường dẫn APK khi crash
- Security: Verify signature, detect repackaging
Lưu ý quan trọng
- Không hardcode đường dẫn: Đường dẫn thay đổi mỗi lần cài đặt/reinstall
- Split APK (App Bundle): Từ Android App Bundle, base.apk + nhiều split APK
- Scoped Storage: Không thể truy cập APK của app khác
- EPHEMERAL apps: Instant apps có đường dẫn khác
Mẹo: DùnggetPackageResourcePath()cho trường hợp đơn giản. DùngPackageManagerkhi cần thông tin chi tiết về split APK, native lib, flags...