如何发布一个使用Hive存储数据的App ?



我在Play Store上推出了App催钱功能。问题是使用Hive存储数据的部分不能工作。但是当我在发布模式下运行它时,我得到一个错误。我使用Android Studio和Language Flutter。我在google Play主机上发布了这款应用。

这是我得到的错误

adb: failed to install C:UsersNiklasStudioProjectsmoneyreminderbuildappoutputs flap -apkapp.apk: Failure [INSTALL_FAILED_UPDATE_INCOMPATIBLE: Package com.muellerniklas.moneyreminder签名不匹配先前安装的版本;忽略!)

这是我到应用程序的链接

https://play.google.com/store/apps/details?id=com.muellerniklas.moneyreminder& hl = de这是我的主文件夹

import 'package:flutter/material.dart';
import 'package:debt/colors.dart';
import 'package:debt/add.dart';
import 'package:debt/data.dart';
import 'package:flutter/foundation.dart';

import 'package:hive_flutter/hive_flutter.dart';
late Box box;
List<Data>datalist=[];
Future <void> main() async{
WidgetsFlutterBinding.ensureInitialized();
await Hive.initFlutter();
Hive.registerAdapter(DataAdapter());
box = await Hive.openBox("infos");
//wandelt die daten für die Anzeige um
Map<dynamic, dynamic> data2 = box.toMap();
//macht aus map liste
data2.forEach((key, value) {
if(kDebugMode){
Data w =Data (key, value);
datalist.add(w);
}

});
runApp(const MaterialApp(
home: debt(),
debugShowCheckedModeBanner: false,
));}
// ignore: camel_case_types
class debt extends StatefulWidget {
const debt({Key? key}) : super(key: key);

@override
_debtState createState() => _debtState();
}
// ignore: camel_case_types
class _debtState extends State<debt> {
Map<String, dynamic> values = {};
String text = 'Text';
double w = 100;
double h = 20;
Widget quoteTemplate(data){
return ValueListenableBuilder<Box>(
valueListenable: Hive.box('infos').listenable(),
builder: (context, box, widget) {
return
Card(

margin: const EdgeInsets.fromLTRB(16, 16, 16, 0),
child:Row(
mainAxisAlignment: MainAxisAlignment.spaceAround, // x Achse
crossAxisAlignment: CrossAxisAlignment.center,    // y Achse
children: <Widget>[
Column(
mainAxisAlignment: MainAxisAlignment.spaceAround, // x Achse
crossAxisAlignment: CrossAxisAlignment.center,// y Achse
children: <Widget>[
Container(alignment: Alignment.center,
width: 100,
height: h,
child: Text(
data.people,
style: TextStyle(
fontSize:  18,
color: Colors.grey[600],
)
),
),
const SizedBox(height: 6,),
Container(
alignment: Alignment.center,
child: Text(
data.money,
style: TextStyle(
fontSize:  14,
color: Colors.grey[800],
)
),
),
],
)
,Container(//delete
alignment: Alignment.center,
child: TextButton(style: TextButton.styleFrom(
),
onPressed: (){
box.delete(data.people);
setState(() {
Map<dynamic, dynamic> data2 = box.toMap();
datalist=[];
data2.forEach((key, value) {
if(kDebugMode){
Data w =Data (key, value);
datalist.add(w);
}
});
});
},
child: const Icon(Icons.delete,color: lightblue,),
),
),
Container(//minusbutton
alignment: Alignment.center,
child: TextButton(style: TextButton.styleFrom(//Minus Butten
),
onPressed: (){
var zwischenspeicher = box.get(data.people);
double zwischenspeicher2= double.parse(zwischenspeicher) - 1.0;
var schulden = zwischenspeicher2.toString();

box.put(data.people,schulden);
//Updatet das widget
setState(() {
Map<dynamic, dynamic> data2 = box.toMap();
datalist=[];
data2.forEach((key, value) {
if(kDebugMode){
Data w =Data (key, value);
datalist.add(w);
}
});
});
},
child: const Icon(Icons.remove,color: darkblue,),
),
),
Container(//plus Button
alignment: Alignment.center,
child: TextButton(style: TextButton.styleFrom(
),
onPressed: (){
var zwischenspeicher = box.get(data.people);
var zwischenspeicher2= double.parse(zwischenspeicher) + 1;
var schulden = zwischenspeicher2.toString();

box.put(data.people,schulden);
setState(() {
Map<dynamic, dynamic> data2 = box.toMap();
datalist=[];
data2.forEach((key, value) {
if(kDebugMode){
Data w =Data (key, value);
datalist.add(w);
}
});
});
},
child: const Icon(Icons.add,color: darkbrown,),
),
),
],
),
);});
}Widget buttond(){
return
Padding(
padding: const EdgeInsets.all(8.0),
child: Expanded(child: Align(
alignment: FractionalOffset.bottomRight,
child:
FloatingActionButton(
onPressed: () {
_awaitReturnValueFromSecondScreen(context);
},
child: const Icon(Icons.add),backgroundColor: lightbrown,

),),),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
backgroundColor: lightblue ,
title: const Text("Money Reminder"),
centerTitle: true,
),
body:
Padding(
padding: const EdgeInsets.all(8.0),
child: ListView(
children: [
Column(
children: datalist.map((data)=> quoteTemplate(data)).toList(),
),
],
),
),bottomNavigationBar: Padding(
padding: const EdgeInsets.fromLTRB(20,0,20,10),
child:

ElevatedButton(
onPressed: () {
_awaitReturnValueFromSecondScreen(context);
},
//child: const Icon(Icons.add,color: Colors.white,),
child: const Text('add/edit debt',style: TextStyle(fontSize: 18,fontFamily: "Futura",color: Colors.white),),
style: ElevatedButton.styleFrom( backgroundColor:lightbrown,)

)
),

);
}

void _awaitReturnValueFromSecondScreen(BuildContext context) async {
// start the SecondScreen and wait for it to finish with a result
final result = await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const add(),
));
// after the SecondScreen result comes back update the Text widget with it
setState(() {
datalist = result;
});
}
}

这是我使用Hive

的第二个屏幕
import 'package:flutter/material.dart';
import 'package:debt/colors.dart';
import 'package:debt/data.dart';
import 'package:flutter/foundation.dart';
import 'package:debt/main.dart';
// ignore: camel_case_types
class add extends StatefulWidget {
const add({Key? key}) : super(key: key);
@override
State<add> createState() => _addState();
}
// ignore: camel_case_types
class _addState extends State<add> {
String text = "Text2";
Map<String, dynamic> data = {};
double size = 40;
double space = 9;
List<Data>datalist=[];
TextEditingController name = TextEditingController();
TextEditingController debt = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(title: const Text("add debt"), centerTitle: true,backgroundColor: lightblue,),
body: Card(
margin: EdgeInsets.fromLTRB(size, size, size, 300),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
SizedBox(width: 1,height: space,),
TextField(
controller: name,
style: const TextStyle(color: Colors.black54),
decoration: const InputDecoration(
hintText: "Niklas, Peter",
labelText: "Person",
hintStyle: TextStyle(fontFamily: "Futura",),
labelStyle: TextStyle(fontSize: 24, fontFamily: "Futura"),
border: UnderlineInputBorder(),
fillColor: white,
filled: true,
),
keyboardType: TextInputType.name,
obscureText: false,

maxLines: 1,
),
SizedBox(width: 1,height: space,),
TextField(
controller: debt,
style: const TextStyle(color: Colors.black54),
decoration: const InputDecoration(
hintText: "10€",
labelText: "Debt",
hintStyle: TextStyle(fontFamily: "Futura",),
labelStyle: TextStyle(fontSize: 24, fontFamily: "Futura"),
border: UnderlineInputBorder(),
fillColor: white,
filled: true,
),
keyboardType: TextInputType.number,
obscureText: false,
maxLength: 16,
maxLines: 1,
),
const SizedBox(width: 1,height: 70,),
ElevatedButton(onPressed: ()  async{
var _name = name.text;
var _debt = debt.text;
var _debt_ = "";
var split = ", ";
//damit auch "," und nicht nur ", " als Trennung gilt
if (_name.contains(",")){
split =",";
}
var listevonnamen = _name.split(split);
// Wandelt Komma in . um um keine Missverständnisse zu erzeugen
//für doppelte Texteingabe mit Komma
for(var i = 0;i<listevonnamen.length;i++){
//texteingaben Komma zu .
_name = listevonnamen[i];
if(_debt.contains(",")){
for(var f = 0; f<_debt.length; f++){
//geht durch jeden Buchstaben und überprüft ob ein Komma vorhanden ist
if (_debt[f]== ","){
_debt_ = _debt_ + ".";
}
else{
_debt_ = _debt_ + _debt[f];
}
}
_debt = _debt_ ;
}
//var valuecheck = data.containsKey("$_name");
var schulden = "";
var zwischenspeicher = "";
double zwischenspeicher2 = 0;
bool checker = box.containsKey(_name);
//überprüft ob konto schon vorhanden
if (checker == false){

data.addAll({_name: _debt});
schulden = _debt;
}
else  { // wiederholung
zwischenspeicher = box.get(_name);
//addiert alte daten zu neuen
zwischenspeicher2= double.parse(zwischenspeicher) + double.parse(_debt) ;
schulden = zwischenspeicher2.toString();
}
// daten werden gespeichert
box.put(_name,schulden);}
Map<dynamic, dynamic> data2 = box.toMap();
//macht aus map liste
data2.forEach((key, value) {
if(kDebugMode){
Data w =Data (key, value);
datalist.add(w);
}
});
_sendDataBack(context);
},
child: const Text("Send"),
style: ElevatedButton.styleFrom(
minimumSize: const Size(400,70),
textStyle: const TextStyle(fontSize: 24,),
backgroundColor: lightbrown,
foregroundColor: Colors.white,
alignment: Alignment.center
),
),
]
)
)
);
}
//daten zurücksenden
void _sendDataBack(BuildContext context) {
List textToSendBack = datalist;

Navigator.pop(context, textToSendBack,);
}
}

我的项目有更多的文件hive和类名为data。如果你需要的话,我可以寄给你。

不可能。Hive使用的应用程序到商店没有任何特殊要求。我很确定你在程序上做错了什么,但你认为那是因为你发表错了。

解决方案:使用flutter run -— release运行app。并检查是否一切正常。

最新更新