flutter_install_plugin
flutter_install_plugin copied to clipboard
NullPointerException
here is my code:
void executeDownloadAndInstall(
String platform, String versionName, DownloadModel model) async {
final Directory directory = await getExternalStorageDirectory();
final String saveDir = '${directory.path}';
print(saveDir);
String filePath = '$saveDir/${platform}_$versionName.apk';
File apk = File(filePath);
if (!await apk.exists()) {
model.startDownload();
print('create file ');
apk = await apk.create();
print('start download');
List<int> downloadBytes = [];
Stream.fromFuture(RequestHelper.request(
'http://www.nionco.com:7001/api/smth/downloadApp?platform=$platform&versionName=$versionName',
HttpMethod.get))
.listen((data) {
downloadBytes.addAll(data.bodyBytes);
print(data.bodyBytes.length);
model.download(data.bodyBytes.length);
print(model.downloadSize);
}, onDone: () async {
await apk.writeAsBytes(downloadBytes);
model.downloadFinished = true;
print('start install');
InstallPlugin.installApk(filePath, "com.example.flowersm")
.then((result) {
print('install apk $result');
}).catchError((error) {
print('install apk error:$error');
});
}, onError: (error) {
print('download error $error');
model.errorOccurred = true;
}, cancelOnError: false);
} else {
print('existed');
apk.delete();
}
}
the error info is:
install apk error:PlatformException(NullPointerException, Attempt to invoke virtual method 'android.content.res.XmlResourceParser android.content.pm.ProviderInfo.loadXmlMetaData(android.content.pm.PackageManager, java.lang.String)' on a null object reference, null)
We will check it in this weekday PR is welcome!
We add provider in plugin's AndroidManinfest.xml. It define the authorities android:authorities="${applicationId}.fileProvider"
Check the appId (here is "com.example.flowersm") is the flutter project's android apk's application id
this is my AndroidManinfest.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.flowersm">
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method.
In most cases you can leave this as-is, but you if you want to provide
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. -->
<application
android:name="io.flutter.app.FlutterApplication"
android:label="flowersm"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- This keeps the window background of the activity showing
until Flutter renders its first frame. It can be removed if
there is no splash screen (such as the default splash screen
defined in @style/LaunchTheme). -->
<meta-data
android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
android:value="true" />
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
this is the build.gradle:
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}
def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
}
def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
flutterVersionName = '1.0'
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android {
compileSdkVersion 28
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
lintOptions {
disable 'InvalidPackage'
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.example.flowersm"
minSdkVersion 16
targetSdkVersion 28
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
//testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.debug
}
}
}
flutter {
source '../..'
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
testImplementation 'junit:junit:4.12'
//androidTestImplementation 'com.android.support.test:runner:1.0.2'
//androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
androidTestImplementation 'androidx.test.runner:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
}
@akindone
how to resolve this problem? @hyjfine
@wuyugege missing permission
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
i tried ,but throw the same error, give up
I had same problem.
same problem here
Same problem here
Same problem here. Is this a dead end? Happy to provide further details if needed but it looks like everything has already been provided.
EDIT: Note that the example does work however when implemented in a new project as per the install instructions it fails with the result already noted.
I have updated the plugin here that fixes this issue. Its not a registered plugin as I plan to submit a PR back here when I get a chance.
If you wish to use it for now just download and make a relative reference to it in your pubspec.yaml. For example the following assumes the installer is in that same folder as your projects' folder (ie side by side)
installer:
path: ../installer