Two Android apps in one file - android

I want to "pack" two applications in one Android APK file. Requirements:
When I install an APK fil it installs to separate apps.
If I uninstall an app, the other app would still remain installed.
Can I do it like that?

First upload those apps which you want to be installed at Dropbox (only).
Now obtain links of those APK files and in the link replace dropbox.com/..... with d.dropboxusercontent.com/...
Now, make an app and place the below code at "onCreate" or somewhere,
String destination = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/";
String fileName = "AppName.apk";
destination += FileName;
final Uri uri = Uri.parse("file://" + destination);
String URL = "d.dropboxusercontent.com/...............";
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(URL));
request.setDescription(Main.this.getString(R.string.notification_description));
request.setTitle(Main.this.getString(R.string.app_name));
// Set destination
request.setDestinationUri(uri);
// Get download service and enqueue file
final DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
final long downloadId = manager.enqueue(request);
// Set BroadcastReceiver to install app when .apk is downloaded
BroadcastReceiver onComplete = new BroadcastReceiver() {
public void onReceive(Context ctxt, Intent intent) {
Intent install = new Intent(Intent.ACTION_VIEW);
install.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
install.setDataAndType(uri,
manager.getMimeTypeForDownloadedFile(downloadId));
startActivity(install);
unregisterReceiver(this);
finish();
}
};
// Register receiver for when .apk download is complete
registerReceiver(onComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
If you want to install multiple apps, then you can apply this code multiple times by changing variable names.
Please comment if it worked.

Related

Why does not Application install

I have written a method that check new version of my APP and when it exists, the application download and it should install that. But it can not install the downloaded application and it gives me this error:
There was a problem parsing the package.
But when I uninstall my app and install it again with the downloaded apk file. Everything works fine so my app downloads the file correctly.
But why this could not install it programmatically?
This is my Download code:
public long downloadFromUrl(String url, String fileName, String format) {
String fullFileName = fileName + format;
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url))
.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE)// Visibility of the download Notification
.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fullFileName)// Uri of the destination file
.setTitle(fullFileName)// Title of the Download Notification
.setDescription("Downloading...");// Description of the Download Notification
DownloadManager downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
long id = downloadManager.enqueue(request);
if (format.equals(APK_FORMAT)) {
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), fullFileName);
if(file.exists()){
DownloadReceiver downloadReceiver = new DownloadReceiver(file);
Intent intent = new Intent();
downloadReceiver.onReceive(context,intent);
context.registerReceiver(downloadReceiver,new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
}
}
return id;
}
This is a receiver that when download is completed, runs:
#Override
public void onReceive(Context context, Intent intent) {
long receivedId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
if (file != null) {
Uri uri = FileProvider.getUriForFile(context,context.getApplicationContext().getPackageName()+ ".provider",file);
intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(uri, "application/vnd.android.package-archive");
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
}
Uri uri;
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
uri = FileProvider.getUriForFile(activity, BuildConfig.APPLICATION_ID + ".provider", destination);
} else {
uri = Uri.fromFile(destination);
}
//Log.d("path",uri.getPath());
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(uri, "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
activity.startActivity(intent);
make sure you have added this permission to your manifest file
Also make sure both version of your APKs are signed and with same key.
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
I made it work with this code (destination is file object).

how to share images inside assets folder with intent to other application

i want to share images inside an assets folder using intent to the following applications
hangout
whatsapp
line chat
viber
tango
wechat
i have try this code for whatsapp but it given me file not supported
public void share (){
String file = "file:///android_asset/food/apple.png";
Uri filePath = Uri.fromFile(new File("content://com.example.zainabishaqmusa.postemoji/assets/gestures/aok.png"));
final ComponentName name = new ComponentName("com.whatsapp", "com.whatsapp.ContactPicker");
Intent oShareIntent = new Intent();
oShareIntent.setComponent(name);
//oShareIntent.setType("text/plain");
//oShareIntent.putExtra(android.content.Intent.EXTRA_TEXT, "Website : www.google.com");
oShareIntent.putExtra(Intent.EXTRA_STREAM, filePath);
oShareIntent.setType("image/png");
oShareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
Gesture.this.startActivity(oShareIntent);
}
You would need a ContentProvider that is capable of sharing content from assets. My StreamProvider offers this, or you could write your own.

No Activity found to handle Intent when using FileProvider

In my app I have a custom auto download and install APK it works like this
// auto register for the complete download
activity.registerReceiver(onComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
// Download the file through DownloadManager
String destination = Environment.getExternalStorageDirectory() + "/";
String fileName = "myfile.apk";
destination += fileName;
final Uri uri = Uri.parse("file://" + destination);
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(apkUrl));
request.setDescription("description");
request.setTitle("title");
request.setDestinationUri(uri);
final DownloadManager manager = (DownloadManager) activity.getSystemService(Context.DOWNLOAD_SERVICE);
final long downloadId = manager.enqueue(request);
onComplete = new BroadcastReceiver() {
public void onReceive(Context ctxt, Intent intent) {
Intent install = new Intent(Intent.ACTION_VIEW);
// BEFORE working doing this
//install.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
//install.setDataAndType(uri,
// manager.getMimeTypeForDownloadedFile(downloadId));
// Using file provider it doesnt work
Uri apkUri = FileProvider.getUriForFile(AutoUpdate.this,
"com.myapp", file);
install.setDataAndType(apkUri,manager.getMimeTypeForDownloadedFile(downloadId));
activity.startActivity(install);
activity.unregisterReceiver(this);
}
};
Android manifest:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.myapp"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths"/>
</provider>
Provider_path (Sorry for some reason so cuts the path tag)
external-path name="myfolder" path="."/>
When the file finished to download the onComplete is called but the activiy doesn't start:
No Activity found to handle Intent { act=android.intent.action.VIEW
dat=content://com.myapp/myfolder/myfile.apk
typ=application/vnd.android.package-archive flg=0x4000000 }
When using the normal file:// it does work
Is there something I'm missing when using the file provider? Does the activity doesn't start because the file is not found ?
Do I need extra permission ? (at the moment I have INTERNET, READ and WRITE on external storage)
The package installer only supports content schemes starting on Android 7.0. Prior to that — and despite documentation to the contrary — the package installer only supports file schemes.
You will need to set the Uri on your Intent differently based on whether you are running on Android 7.0+ or not, such as by branching on Build.VERSION.SDK_INT.
Commonware is right,
For those looking for the code:
BroadcastReceiver onComplete = new BroadcastReceiver() {
public void onReceive(Context ctxt, Intent intent) {
downloadButton.setEnabled(true);
downloadButton.setText("Terminado");
progressbar.setVisibility(View.GONE);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
Intent install = new Intent(Intent.ACTION_VIEW);
install.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
Uri apkURI = FileProvider.getUriForFile(
self,
self.getApplicationContext()
.getPackageName() + ".provider", file);
install.setDataAndType(apkURI,
manager.getMimeTypeForDownloadedFile(downloadId));
install.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(install);
} else{
String destination = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/";
String fileName = "surveyevent.apk";
destination += fileName;
Uri uri = Uri.parse("file://" + destination);
Intent install = new Intent(Intent.ACTION_VIEW);
install.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
install.setDataAndType(uri,
manager.getMimeTypeForDownloadedFile(downloadId));
startActivity(install);
}
unregisterReceiver(this);
finish();
}
};
Your provider is not found because
android:enabled="true"
is missing in your manifest.
But then it will not work either reading the other answer of CW.

Android detect when DownloadManager has finished downloading

Hi i'm downloading a file and i'm wanting to fire an ACTION_VIEW Intent once its finished downloading. so does anyone know how to detect when DownloadManager has finished.
heres how i'm running DownloadManager
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
request.setTitle(filename);
// in order for this if to run, you must use the android 3.2 to compile your app
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
request.allowScanningByMediaScanner();
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
}
ContextWrapper c = new ContextWrapper(getBaseContext());
String filePath = c.getFilesDir().getPath();
request.setDestinationInExternalFilesDir(getBaseContext(), filePath, filename);
// get download service and enqueue file
DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
manager.enqueue(request);
Toast.makeText(getBaseContext(), "Downloading...", Toast.LENGTH_LONG).show();
BroadcastReceiver onComplete = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String path = getFilesDir().getPath() +"/" + filename;
File f = new File(path);
Intent myIntent = new Intent(Intent.ACTION_VIEW);
myIntent.setData(Uri.fromFile(f));
startActivity(myIntent);
}
};
registerReceiver(onComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
It looks OK for me. That example is not working? But different thing is how you fire next Intent in onReceive method. Please try use your action in
myIntent = new Intent(YourActionClass.class);
Figured it out myself i needed to set the mimeType so it knows which apps to look for

How do I determine if Android can handle PDF

I know Android cannot handle PDFs natively. However, the Nexus One (and possibly other phones) come pre-installed with QuickOffice Viewer. How would I determine whether the user has a PDF viewer installed?
Currently, the code to start the PDF download looks pretty simple:
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(url));
startActivity(intent);
After the download, the user clicks on the downloaded file to invoke the viewer.
However, if there is no PDF viewer, Android reports "Cannot download. The content is not supported on the phone."
I want to determine if the user will get this message, and if so, direct them to PDF apps in the Android Market.
I have been testing this and found that the following works. First you download the file independently and store it on the device and then you go do this:
File file = new File("/sdcard/download/somepdf.pdf");
PackageManager packageManager = getPackageManager();
Intent testIntent = new Intent(Intent.ACTION_VIEW);
testIntent.setType("application/pdf");
List list = packageManager.queryIntentActivities(testIntent, PackageManager.MATCH_DEFAULT_ONLY);
if (list.size() > 0 && file.isFile()) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
Uri uri = Uri.fromFile(file);
intent.setDataAndType(uri, "application/pdf");
startActivity(intent);
I have tested this on various emulator and a rooted cyanogen phone as well as a HTC Magic. If no pdf renderer is available the list will return zero and nothing will happen.
It seems to be important to set the data type to the pdf mime type to get the correct behaviour.
If you e.g. install droidreader it will react to the intent and display the pdf.
Of course you could do the check before you download the pdf as well depending on your use case or do things like popping up alerts or redirecting do other intents for download or whatever.
Edit: I have since refactored this out into a separate method ..
public static final String MIME_TYPE_PDF = "application/pdf";
/**
* Check if the supplied context can render PDF files via some installed application that reacts to a intent
* with the pdf mime type and viewing action.
*
* #param context
* #return
*/
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;
}
}
You can query the PackageManager to see if there's a package that can handle your Intent. Here's an example: http://www.curious-creature.org/2008/12/15/android-can-i-use-this-intent/
You will probably use asynch task to download any file.so simple way is Just add below code in post execute() method of asynch task.it will ask for choice.
FileOpener.open(context, file);
and file should contain info about filepath and filename.Example
File file = new File(Environment
.getExternalStoragePublicDirectory("/MDroid")
+ filepath + fileName );
Hope it helps

Categories

Resources