I have set up a Broadcast that starts up when Application is installed with startActivityForResult(). The installation Intent is created here.
private static Intent getOpenDownloadedApkIntent(Context context, File file) {
String name = getPackageNameForAPK(file.getPath(), context);
if (name != null) {
INSTALL_APK_INFO.put(name, file);
}
// The type of intent to use to open the downloaded apk changed in Android N (7.0)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
Uri path = FileProvider.getUriForFile(context,
context.getApplicationContext().getPackageName() + ".utils.DownloadedFileProvider",
file);
Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.putExtra(Intent.EXTRA_RETURN_RESULT, true);
intent.setData(path);
return intent;
} else {
Uri uri = Uri.fromFile(file);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.putExtra(Intent.EXTRA_RETURN_RESULT, true);
intent.setDataAndType(uri, "application/vnd.android.package-archive");
return intent;
}
}
private static String getPackageNameForAPK(final String archiveFilePath, Context context) {
try {
PackageInfo info = context.getPackageManager().getPackageArchiveInfo(archiveFilePath, PackageManager.GET_META_DATA);
return info.packageName;
} catch (Exception ex) {
ex.printStackTrace();
return null;
}
}
Now if it is Android 7 or higher, then the uninstall works, but if it is Android 6 or lower, then it just seems to delete the icon of the APK but not the APK itself.
Here is the code that should delete the APK:
private static BroadcastReceiver onInstallComplete = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
ApplicationInfo info = null;
try {
info = context.getPackageManager().getApplicationInfo(intent.getDataString().split(":")[1], PackageManager.GET_META_DATA);
} catch (PackageManager.NameNotFoundException ex) {
}
try {
if (info != null) {
File file = INSTALL_APK_INFO.get(info.packageName);
if (file != null) {
file.delete();
INSTALL_APK_INFO.remove(info.packageName);
}
}
} catch (NullPointerException ex) {
}
}
};
I am guessing that is has something to do with the path, but at the same time it seems to delete the icon of the APK. By icon I mean that if i remove the file.delete() then the APK is with icon in downloads folder but if I run the file.delete() then the APK is without the icon.
What am I doing wrong?
Do u mean to say that app is getting installed but without launcher icon?
Related
How to check if app is installed or not on phone. If the app is installed, open the app, otherwise open the appstore link to download the app.
If the app is already there, I used the following code.
Intent LaunchIntent = getPackageManager().getLaunchIntentForPackage("package name");
startActivity(LaunchIntent);
Checking if app is installed having package name:
public static final String PACKAGE_NAME = "com.__.__";
public static boolean isAppInstalled(Context context) {
PackageManager packageManager = context.getPackageManager();
Intent intent = new Intent(Intent.ACTION_VIEW);
if (intent.resolveActivity(packageManager) != null) {
try {
packageManager.getPackageInfo(PACKAGE_NAME, PackageManager.GET_ACTIVITIES);
return true;
} catch (PackageManager.NameNotFoundException ignore) {
}
}
return false;
}
Open Play Market having package name:
try {
startActivity(new Intent(Intent.ACTION_VIEW,
Uri.parse("market://details?id=" + appPackageName)));
} catch (android.content.ActivityNotFoundException anfe) {
startActivity(new Intent(Intent.ACTION_VIEW,
Uri.parse("https://play.google.com/store/apps/details?id=" + appPackageName)));
}
I have a launcher type application from which user can install different apps. It is working completely fine but the apk's from different apps just keep stacking up and taking too much space.
Is there a way that I can detect that application installation has completed when using new Intent(Intent.ACTION_INSTALL_PACKAGE) and then I could delete the previously downloaded apk... after the installation has completed.
Here is some code:
Intent openDownloadIntent = getOpenDownloadedApkIntent(context, file);
try {
context.startActivity(openDownloadIntent);
} catch (ActivityNotFoundException e) {
// TODO
}
private static Intent getOpenDownloadedApkIntent(Context context, File file) {
// The type of intent to use to open the downloaded apk changed in Android N (7.0)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
Uri path = FileProvider.getUriForFile(context,
context.getApplicationContext().getPackageName() + ".utils.DownloadedFileProvider",
file);
Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setData(path);
return intent;
} else {
Uri uri = Uri.fromFile(file);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(uri, "application/vnd.android.package-archive");
return intent;
}
}
I want to check if Acrobat Reader is installed when is not installed I want to open an android market on Adobe Acrobat Reader
This is how I check intalled :
public static boolean canDisplayPdf(Context context)
{
PackageManager packageManager = context.getPackageManager();
Intent testIntent = new Intent(Intent.ACTION_VIEW);
testIntent.setType(MIME_TYPE_PDF);
if (packageManager.queryIntentActivities(testIntent, PackageManager.MATCH_DEFAULT_ONLY).size() > 0) {
return true;
} else {
return false;
}
}
next I when this method return false I want open an andrid market (apk) :
final String appPackageName = getPackageName(); // getPackageName() from Context or Activity object
try
{
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=Adoba Acrobat Reader" + appPackageName)));
} catch (android.content.ActivityNotFoundException anfe)
{
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://play.google.com/store/apps/details?id= Adoba Acrobat Reader" + appPackageName)));
}
But open an android market it doen't work
You can use this method to check for Adobe Acrobat Reader if its installed:
private boolean isPackageInstalled(String packagename, PackageManager packageManager) {
try {
packageManager.getPackageInfo(packagename, 0);
return true;
} catch (NameNotFoundException e) {
return false;
}
}
Usage:
boolean isAdobeInstalled = isPackageInstalled("com.adobe.reader", getPackageManager());
if (isAdobeInstalled) {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://play.google.com/store/apps/details?id=com.adobe.reader")));
}
change
Uri.parse("http://play.google.com/store/apps/details?id= Adoba Acrobat Reader" + appPackageName)));
to
Uri.parse("https://play.google.com/store/apps/details?id=com.adobe.reader)));
This question already has answers here:
Open another application from your own (intent)
(20 answers)
Closed 5 years ago.
i want to open an another app activity from my app, if the app is not installed go to the play store to install the app.
my code is working fine but its only open the app from it's package name, it's not opening activity.
Code:
public void startApplication(String packageName)
{
try
{
Intent intent = new Intent("android.intent.action.MAIN");
intent.addCategory("android.intent.category.LAUNCHER");
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
List<ResolveInfo> resolveInfoList = getPackageManager().queryIntentActivities(intent, 0);
for(ResolveInfo info : resolveInfoList)
if(info.activityInfo.packageName.equalsIgnoreCase(packageName))
{
launchComponent(info.activityInfo.packageName, info.activityInfo.name);
return;
}
// No match, so application is not installed
showInMarket(packageName);
}
catch (Exception e)
{
showInMarket(packageName);
}
}
private void launchComponent(String packageName, String name)
{
Intent intent = new Intent("android.intent.action.MAIN");
intent.addCategory("android.intent.category.LAUNCHER");
intent.setComponent(new ComponentName(packageName, name));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
private void showInMarket(String packageName)
{
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + packageName));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
Try
public void startApplication(String packageName) {
Intent launchIntent = getPackageManager().getLaunchIntentForPackage(packageName);
if (launchIntent != null) {
startActivity(launchIntent);
} else {
showInMarket(packageName);
}
}
The requirements: ensure that the PDF document is deleted from the device after the user has left the PDF viewing screen
The problem: on certain devices (Samsung 4.4.2 and Samsung 4.1.2 for sure, but not Asus 4.2.1) only the first time that the PDF is requested after restarting the application an error message is displayed stating "This document cannot be opened". Thereafter the PDF will load normally. I'm thinking this is a timing issue due to processes that need to be started the first time, but are running after the first attempted load.
The code: note that createFile() is called first, then startActivityForIntentResult()
private File file;
private ArrayList<Uri> uriList = new ArrayList<Uri>();
private void createFile() {
int fileNameLength = pdfFileName[0].length();
String fileName = pdfFileName[0].substring(0, fileNameLength - 4) + DateTime.now();
String fileExtension = pdfFileName[0].substring(fileNameLength - 4, fileNameLength);
byte[] content = Base64.decodeBase64(pdfData[0].getBytes());
BufferedOutputStream outputStream = null;
try {
File path = new File(getExternalFilesDir(null).getAbsolutePath(), "temp");
if (!path.exists()) {
path.mkdirs();
}
file = new File(path, fileName + fileExtension);
outputStream = new BufferedOutputStream(new FileOutputStream(file));
outputStream.write(content);
file.deleteOnExit();
uriList.add(Uri.fromFile(file));
}
catch (FileNotFoundException ex) {
ex.printStackTrace();
}
catch (IOException ex) {
ex.printStackTrace();
}
finally {
try {
if (outputStream != null) {
outputStream.flush();
outputStream.close();
}
}
catch (IOException ex) {
ex.printStackTrace();
}
}
}
private static int REQUEST_CODE = 1;
private Intent intent;
private void startActivityForIntentResult() {
if (file.exists()) {
Uri targetUri = uriList.get(0);
intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(targetUri, "application/pdf");
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
try {
startActivityForResult(intent, REQUEST_CODE);
}
catch (ActivityNotFoundException e) {
toastTitle = "Error Displaying PDF";
toastMessage = "Please make sure you have an application for viewing PDFs installed on your device and try again.";
toast = new GenericCustomToast();
toast.show(toastTitle, toastMessage, QueryForPDF.this);
}
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
if (resultCode == RESULT_CANCELED && requestCode == REQUEST_CODE) {
if(!file.delete()) {
file.delete();
}
}
searchAgain();
}
#Override
public void onBackPressed() {
super.onBackPressed();
if(!file.delete()) {
file.delete();
}
searchAgain();
}
#Override
public void onStop() {
super.onStop();
if(!file.delete()) {
file.delete();
}
}
#Override
public void onDestroy() {
super.onDestroy();
if(!file.delete()) {
file.delete();
}
}
EDIT: I have also tried implementing a callback to be absolutely certain that createFile() has finished it's work. I even tried adding delays (of different time increments) as well as adding (the completely unnecessary) flags for Intent.FLAG_GRANT_READ_URI_PERMISSION, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, and Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION.
I still don't know why this works, but here's the solution in case anyone else runs into this issue:
It's the directory where the file is created. For some reason on the two Samsung devices there was something different in how the files were either accessed or created versus the Asus device. So File path = new File(getExternalFilesDir(null).getAbsolutePath(), "temp"); becomes File path = new File(getExternalCacheDir().getAbsolutePath()); and the problem goes away.