I want to have the abilities to update my app from my application, so I can download my apk file ( each of them are signed ). And when the installation want to start:
First of all: I have preparation of installation popup which appear
Then: another popup appear and told me "A problem occurred while parsing the package"
My error is like this:
So my app, didn't update. Could you help me please ?
I use Xamarin Forms but especially for Android.
Manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.MyCompany.clamexdroid" android:installLocation="preferExternal">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="31" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<application android:label="ClamexDroid" android:theme="#style/MainTheme" android:icon="#mipmap/ic_launcher">
</application>
<queries>
<intent>
<action android:name="android.media.action.IMAGE_CAPTURE" />
</intent>
</queries>
</manifest>
My function when I click on my update Button
private async Task update()
{
this.popupIsVisible = false;
this.IsBusy = true;
string uri = "myLink.apk";
HttpClient cli = new HttpClient();
await cli.DownloadBasicFile(uri, DependencyService.Get<IDeviceDependency>().GetExternalAPKPath());
DependencyService.Get<IDeviceDependency>().InstallApk();
this.IsBusy = false;
}
And my InstallApk() function ( I'm sure that the file is downloaded )
public void InstallApk()
{
Intent promptInstall = new Intent(Intent.ActionView).SetDataAndType(
Android.Net.Uri.Parse($"content:///{this.GetExternalAPKPath()}"),"application/vnd.android.package-archive");
promptInstall.SetFlags(ActivityFlags.NewTask);
promptInstall.AddFlags(ActivityFlags.GrantReadUriPermission);
Android.App.Application.Context.StartActivity(promptInstall);
}
public string GetExternalAPKPath()
{
try
{
return Path.Combine(Android.App.Application.Context.GetExternalFilesDir("").AbsolutePath, "com.MyCompany.clamexdroid.apk");
}
catch (Exception e) { Console.WriteLine(e.Message); }
return "";
}
At first, you can check the apk file you had downloaded has any damage. And then you can try to the following steps to install the apk:
1.Add the provider in the AndroidManifest.xml, such as:
<application android:allowBackup="true" android:icon="#drawable/androidicon" android:label="#string/app_name" android:supportsRtl="true" android:theme="#style/AppTheme">
<provider android:name="androidx.core.content.FileProvider" android:authorities="${applicationId}.provider" android:exported="false" android:grantUriPermissions="true">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="#xml/provider_paths" />
</provider>
</application>
2.Create the provider_paths.xml in the folder named xml below the values folder in the android part.
<paths >
<external-path
name="external_files"
path="." />
</paths>
3.Use the following code to install the apk:
var path = Path.Combine(Android.App.Application.Context.GetExternalFilesDir("").AbsolutePath, "com.MyCompany.clamexdroid.apk");
Java.IO.File file = new Java.IO.File(path);
Intent install = new Intent(Intent.ActionView);
Android.Net.Uri apkURI = FileProvider.GetUriForFile(this, this.ApplicationContext.PackageName + ".provider", file);
install.SetDataAndType(apkURI, "application/vnd.android.package-archive");
install.AddFlags(ActivityFlags.NewTask);
install.AddFlags(ActivityFlags.GrantReadUriPermission);
StartActivity(install);
Related
I am having issues capturing photos on a CAT S42 running Android 11. My code worked fine on older phones so I suspect it is an Android version thing. The following code creates the JPG file but it is always zero bytes:
private void startCamera() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(getPackageManager()) != null) {
File mNewPhoto = new File(getFilesDir(), "data-input-image.jpg");
mNewPhoto.delete();
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mNewPhoto));
startActivityForResult(intent, 1);
}
}
I've been experimenting with using different save locations and permissions but I can't fix it.
I've got these permissions in my manifest:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.NFC" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.READ_SYNC_STATS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
Do not use Uri.fromFile() to get an uri.
Instead use FileProvider.getUriForFile().
AndroidManifest.xml
<application>
...
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths" />
</provider>
</application>
file_paths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths>
<files-path
name="files"
path="." />
<external-path
name="external"
path="." />
</paths>
Java code
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE).addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
String filename = getExternalFilesDir(Environment.DIRECTORY_PICTURES).getPath() + "/wallpaper.jpg";
Uri fileProvider = FileProvider.getUriForFile(this, getPackageName() + ".fileProvider", new File(filename));
cameraIntent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, fileProvider);
Intent chooserIntent = Intent.createChooser(cameraIntent, "Image Chooser");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Parcelable[]{cameraIntent});
chooserIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivityForResult(chooserIntent, 1);
I'm working with GeckoView and met problem with installing AddOns. As suggested on Documentation, I've provided XPI compatible with Android, but nothing changes. Copying file to Assets doesn't make a change. Browser doesn't acknowledge WebExtension.
private fun setupGeckoView() {
geckoSession?.permissionDelegate = object : GeckoSession.PermissionDelegate {
override fun onContentPermissionRequest(
session: GeckoSession,
perm: GeckoSession.PermissionDelegate.ContentPermission
): GeckoResult<Int>? {
return super.onContentPermissionRequest(session, perm)
}
}
geckoView = findViewById(R.id.geckoView)
val runtime = GeckoRuntime.create(this)
runtime.settings.consoleOutputEnabled = true
runtime.webExtensionController.promptDelegate = PromptListener(runtime.webExtensionController)
runtime.webExtensionController
.install("https://addons.mozilla.org/android/downloads/file/3719055/youtube_high_definition-85.0.0-an+fx.xpi")
geckoSession.open(runtime)
geckoView.setSession(geckoSession)
geckoSession.loadUri("https://www.youtube.com")
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.gv.webapp">
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.webapp">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!--<provider
android:authorities="com.gv.webapp"
android:name="com.gv.webapp.Provider">
<grant-uri-permission android:path="string"
android:pathPattern="string"
android:pathPrefix="string" />
</provider>-->
</application>
</manifest>
I'm checking logs and the result is confusing. I've got prompt that WebExtension is installed, but when I looking at controller.list() it's empty.
You may be missing a PermissionDelegate:
geckoSession?.permissionDelegate = object : GeckoSession.PermissionDelegate {
override fun onContentPermissionRequest(
session: GeckoSession,
perm: GeckoSession.PermissionDelegate.ContentPermission
): GeckoResult<Int>? {
return super.onContentPermissionRequest(session, perm)
}
}
Permission delegate allows you to handle requests from Gecko for any permission that needs handling.
I want to install an apk in my application and I'm using this method but all the time I get the errors listed below:
Code
File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/test.apk");
Uri fileUri = Uri.fromFile(file);
if (Build.VERSION.SDK_INT >= 24) {
fileUri = FileProvider.getUriForFile(DLActivity.this, "codenevisha.com.apps.bartarinapp.provider",file);
}
Intent intent = new Intent(Intent.ACTION_VIEW, fileUri);
intent.putExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, true);
intent.setDataAndType(fileUri, "application/vnd.android" + ".package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);
And this is my manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="codenevisha.com.apps.bartarinapp">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
android:name=".utils.G"
android:allowBackup="true"
android:icon="#mipmap/logo_chabok"
android:label="#string/app_name"
android:largeHeap="true"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="codenevisha.com.apps.bartarinapp.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/paths"/>
</provider>
<activity
android:name=".activity.ActivitySplash"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name=".activity.DLActivity">
</activity>
</application>
</manifest>
I used this path.xml file:
<external-files-path
name="share"
path="."/>
But when I run my application get this error:
Process: codenevisha.com.apps.bartarinapp, PID: 21392
java.lang.RuntimeException: Unable to start activity ComponentInfo{codenevisha.com.apps.bartarinapp/codenevisha.com.apps.bartarinapp.activity.DLActivity}: java.lang.IllegalArgumentException: Failed to find configured root that contains /storage/emulated/0/test.apk
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2984)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3045)
at android.app.ActivityThread.-wrap14(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1642)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6776)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1496)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1386)
Caused by: java.lang.IllegalArgumentException: Failed to find configured root that contains /storage/emulated/0/test.apk
at android.support.v4.content.FileProvider$SimplePathStrategy.getUriForFile(FileProvider.java:711)
at android.support.v4.content.FileProvider.getUriForFile(FileProvider.java:400)
at codenevisha.com.apps.bartarinapp.activity.DLActivity.onCreate(DLActivity.java:46)
at android.app.Activity.performCreate(Activity.java:6955)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1126)
Why is this error happening?
Your FileProvider is misconfigured. Your FileProvider metadata needs an <external-path> element, and you do not have one. See the documentation.
I tested the below code.
Add below permission in Menifest
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Below code for installing package
//// TODO: 1/16/18 Check the external storage permission
File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/test.apk");
Uri fileUri = Uri.fromFile(file);
if (Build.VERSION.SDK_INT >= 24) {
String packageId = getApplicationContext().getPackageName();
fileUri = FileProvider.getUriForFile(MainActivity.this, packageId + ".files", file);
}
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.putExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, true);
intent.setDataAndType(fileUri, "application/vnd.android" + ".package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);
Provider in Menifest
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.files"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths" />
</provider>
file_paths.xml
<paths>
<external-path name="external" path="/"/>
Per the Android documentation on EXTRA_NOT_UNKNOWN_SOURCE:
For this to work you must start the installer with startActivityForResult().
This question already has answers here:
How to install Android apk from code in unity
(6 answers)
Error: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.XmlResourceParser
(1 answer)
Closed 5 years ago.
I recently read This post and write below code lines for installing .apk file in my unity application :
AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
AndroidJavaObject unityContext = currentActivity.Call<AndroidJavaObject>("getApplicationContext");
//Get the package Name
string packageName = unityContext.Call<string>("getPackageName");
string authority = packageName + ".fileprovider";
AndroidJavaClass intentObj = new AndroidJavaClass("android.content.Intent");
string ACTION_VIEW = intentObj.GetStatic<string>("ACTION_VIEW");
AndroidJavaObject intent = new AndroidJavaObject("android.content.Intent", ACTION_VIEW);
int FLAG_ACTIVITY_NEW_TASK = intentObj.GetStatic<int>("FLAG_ACTIVITY_NEW_TASK");
int FLAG_GRANT_READ_URI_PERMISSION = intentObj.GetStatic<int>("FLAG_GRANT_READ_URI_PERMISSION");
//File fileObj = new File(String pathname);
AndroidJavaObject fileObj = new AndroidJavaObject("java.io.File", filePath);
//FileProvider object that will be used to call it static function
AndroidJavaClass fileProvider = new AndroidJavaClass("android.support.v4.content.FileProvider");
//getUriForFile(Context context, String authority, File file)
AndroidJavaObject uri = fileProvider.CallStatic<AndroidJavaObject>("getUriForFile", unityContext, authority, fileObj);
intent.Call<AndroidJavaObject>("setDataAndType", uri, "application/vnd.android.package-archive");
intent.Call<AndroidJavaObject>("addFlags", FLAG_ACTIVITY_NEW_TASK);
intent.Call<AndroidJavaObject>("addFlags", FLAG_GRANT_READ_URI_PERMISSION);
currentActivity.Call("startActivity", intent);
but after running and call this function my application forced to stop.
here is my Android manifest :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="Store.Narenjgame.store"
android:versionCode="1.2"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="19"
android:targetSdkVersion="23" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application android:icon="#drawable/app_icon"
android:label="#string/app_name"
android:debuggable="false"
android:supportsRtl="true"
android:allowBackup="true">
<activity android:name="com.unity3d.player.UnityPlayerNativeActivity" android:label="#string/app_name" android:screenOrientation="fullSensor" android:launchMode="singleTask" android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
</intent-filter>
<meta-data android:name="unityplayer.UnityActivity" android:value="true" />
<meta-data android:name="unityplayer.ForwardNativeEventsToDalvik" android:value="false" />
</activity>
</application>
</manifest>
My android device sdk version is 24.
How can I install apk in unity android application?
I am trying to write in file after android device boots. I have checked everything related to this topic here but none of them worked for me. My phone is Huawei Honor (H30-U10) and it's rooted. Android version 4.2.2. Here is my code:
AndroidManifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="bog.ddrc.technicianmobile"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="21" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_INTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application
android:name="bog.ddrc.technicianmobile.App"
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="bog.ddrc.technicianmobile.activities.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver
android:enabled="true"
android:name="bog.ddrc.technicianmobile.StartTMServiceAtBootReceiver"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
</manifest>
StartTMServiceAtBootReceiver.java:
public class StartTMServiceAtBootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String data = "text";
File path = Environment.getExternalStorageDirectory();
File file = new File(path, "test.txt");
try {
OutputStream os = new FileOutputStream(file);
os.write(data.getBytes());
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Remove
android:permission="android.permission.RECEIVE_BOOT_COMPLETED"
from your <receiver> block.
After trying all of mentioned answers and tricks, I finally find why the code is not work in my phone. Some Android phones like "Huawei Honor 3C Android 4.2.2" have a Statup Manager menu in their settings and your app must be checked in the list. :)