Flutter- 在模拟器上运行但不在设备上运行的应用程序(使用 http 包)

Flutter- 在模拟器上运行但不在设备上运行的应用程序(使用 http 包)

问题描述:

我的应用程序在模拟器 Nexus 5 (API 28) 上运行良好,但是当我构建一个 apk 在真实设备上尝试它时却没有,登录按钮什么也不做.

My application works fine on emulator Nexus 5 (API 28) but when i build an apk to try it on real device it doesn't, The login button does nothing at all.

我已经从应用程序中删除了所有功能,现在它只是通过 http 包登录,它使用一个 php 文件与 Mysql 数据库通信并以 Json 格式返回值.

I've removed all features from the app, now it just logs in through http package, it uses a php file that communicates with the Mysql database and return values in Json format.

应用程序登录用户并将他发送到另一个显示成功"的屏幕

The app logs in user and send him to another screen that says "Success"

界面部分:

    child: Material(
    color: Colors.transparent,
    child: InkWell(
    onTap: () {
    Services.logIn(_usernameController.text.trim(),
    _passwordController.text.trim(), context);
    },

服务登录:

 static Future<bool> logIn(
      String username, String password, BuildContext context) async {
    var map = Map<String, dynamic>();
    map['action'] = _LOGIN;
    map['username'] = username;
    map['password'] = password;
    final response = await http.post(ROOT, body: map);

    if (response.body.isNotEmpty) {
      Navigator.push(
          context, MaterialPageRoute(builder: (context) => LoginSuccesed()));
      return true;
    } else {
      return false;
    }
  }

AndroidManifest:

AndroidManifest:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="manshore.apk_testing">
    <!-- 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="apk_testing"
        android:icon="@mipmap/ic_launcher">
        <activity
            android:name=".MainActivity"
            android:launchMode="singleTop"
            android:theme="@style/LaunchTheme"
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
            android:hardwareAccelerated="true"
            android:windowSoftInputMode="adjustResize">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <!-- Don't delete the meta-data below.
             This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
        <meta-data
            android:name="flutterEmbedding"
            android:value="2" />
    </application>
</manifest>

Android > App > build.gradle (它在属性"上显示错误并且GradleException"无法解析符号)

Android > App > build.gradle (it shows error on 'Properties' and 'GradleException' cannot resolve symbole)

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).
        multiDexEnabled true
        applicationId "manshore.apk_testing"
        minSdkVersion 16
        targetSdkVersion 28
        versionCode flutterVersionCode.toInteger()
        versionName flutterVersionName
        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 'androidx.test:runner:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
}

完整的用户界面:

import 'package:flutter/material.dart';
import 'Services.dart';

void main() => runApp(MaterialApp(home: LoginUI()));

class LoginUI extends StatefulWidget {
  @override
  _LoginUIState createState() => new _LoginUIState();
}

class _LoginUIState extends State<LoginUI> {
  final _usernameController = TextEditingController();
  final _passwordController = TextEditingController();

  Widget build(BuildContext context) {
    return MaterialApp(
      home: new Scaffold(
        backgroundColor: Colors.white,
        resizeToAvoidBottomPadding: true,
        body: Stack(
          children: <Widget>[
            SingleChildScrollView(
              child: Column(
                children: <Widget>[
                  Container(
                    width: double.infinity,
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: <Widget>[
                        SizedBox(height: 50),
                        TextField(
                          controller: _usernameController,
                          decoration: InputDecoration(
                              hintText: "username",
                              hintStyle: TextStyle(
                                  color: Colors.grey, fontSize: 12.0)),
                        ),
                        SizedBox(),
                        TextField(
                          controller: _passwordController,
                          obscureText: true,
                          decoration: InputDecoration(
                              hintText: "Password",
                              hintStyle: TextStyle(
                                  color: Colors.grey, fontSize: 12.0)),
                        ),
                        SizedBox(),
                      ],
                    ),
                  ),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: <Widget>[
                      InkWell(
                        child: Container(
                          decoration: BoxDecoration(
                              gradient: LinearGradient(colors: [
                                Color(0xFF17ead9),
                                Color(0xFF6078ea)
                              ]),
                              borderRadius: BorderRadius.circular(6.0),
                              boxShadow: [
                                BoxShadow(
                                    color: Color(0xFF6078ea).withOpacity(.3),
                                    offset: Offset(0.0, 8.0),
                                    blurRadius: 8.0)
                              ]),
                          child: Material(
                            color: Colors.transparent,
                            child: InkWell(
                              onTap: () {
                                Services.logIn(_usernameController.text.trim(),
                                    _passwordController.text.trim(), context);
                              },
                              child: Center(
                                child: Text("SIGNIN",
                                    style: TextStyle(
                                        color: Colors.white,
                                        fontFamily: "Poppins-Bold",
                                        fontSize: 18,
                                        letterSpacing: 1.0)),
                              ),
                            ),
                          ),
                        ),
                      ),
                    ],
                  ),
                  SizedBox(),
                ],
              ),
            )
          ],
        ),
      ),
    );
  }
}

您需要 AndroidManifest.xml 文件中的 Internet 权限.添加以下行:

You need internet permission in your AndroidManifest.xml file. Add following line:

<uses-permission android:name="android.permission.INTERNET"/>