Problem updating interface when permissions are approved
I'm having a problem updating the interface, I want when I press the button and then agree to the permissions, and go back to the screen That button disappears But what happens is that it requires me to press the button again for the button to disappear
I don't know what the problem is And when I use the loading and started values, it hides the button before I approve the permissions only once I open the settings Where in the code can I tell that the user has approved the permissions?
I recorded the screen when I run https://drive.google.com/file/d/1ftcUdR_voBZOYE0gMOoEhj9FP37e6ULr/view?usp=sharing
this is the screen code:
class ChildUncombletePSc extends StatelessWidget {
ChildUncompleteController controller = Get.put(ChildUncompleteController());
String iconUrl(Gender gender, bool isActive) { }
calculateAge(DateTime birthDate) { }
bool back = true;
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async => false,
child: Scaffold(
appBar: AppBar(
leading: GetBuilder<ChildUncompleteController>(builder: (controller) {
return controller.backbutton
? IconButton(
alignment: Alignment(-1.0.w, -0.7.w),
icon: Icon(Icons.arrow_back, color: Colors.white),
onPressed: () => Navigator.of(context).pop(),
)
: Text("");
}),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(400.r),
),
),
flexibleSpace: ClipRRect(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(400.r),
),
child: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Theme.of(context).accentColor,
Theme.of(context).primaryColor,
],
),
),
),
),
bottom: PreferredSize(
preferredSize: Size.fromHeight(250.h),
child: Column(
children: [
Image.asset(
'images/whiteLogo.png',
height: 150.h,
),
Padding(
padding:
EdgeInsets.only(top: 28.h, bottom: 30.h, right: 20.w),
child: GetBuilder<ChildUncompleteController>(
builder: (controller) => Row(
children: [
Image.asset(
// iconUrl(gender, isActivated),
ChildAccount.iconUrl(
controller.gender.toString() == 'أنثى'
? Gender.Girl
: Gender.Boy,
controller.isActive == 0 ? false : true),
height: 70.h,
),
SizedBox(
width: 10.w,
),
Text(controller.name ?? "",
style: Theme.of(context).textTheme.headline5),
],
),
),
),
],
),
),
),
body: SingleChildScrollView(
child: GetBuilder<ChildUncompleteController>(
init: ChildUncompleteController(),
builder: (value) => Column(
children: [
Padding(
padding: EdgeInsets.only(bottom: 10.h),
child: Text(
'العمر: ${calculateAge(DateTime.parse(controller.age ?? ""))}',
textAlign: TextAlign.right,
style: Theme.of(context).textTheme.headline5,
),
),
Center(
child: Padding(
padding:
EdgeInsets.symmetric(vertical: 3.h, horizontal: 3.w),
child: !value.flag
? Text(
'لم يتم إنهاء اجراءات هذا الطفل',
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.headline3,
)
: Text(
'تم انهاء إجراءات هذا الطفل ',
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.headline3,
),
),
),
SizedBox(
height: 20.h,
),
Center(
child: !value.flag
? SizedBox(
height: 40.h,
width: 200.w,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Theme.of(context).buttonColor,
),
onPressed: () {
print("message 1 ${value.started}");
value.started
? value.stopListening()
: value.startListening();
},
child: Text(
' إنهاء الاجراءات ',
style: Theme.of(context).textTheme.headline4,
),
),
)
: null,
),
],
),
),
),
),
);
}
}
and this is it's controller:
class ChildUncompleteController extends GetxController {
List<NotificationEvent> _log = [];
bool started = false;
bool _loading = false;
bool flag = false;
ReceivePort port = ReceivePort();
Crud crud = Crud();
bool isLoading = false;
bool backbutton = true;
String? name;
String? age;
int? isActive;
String? gender;
final myServerUrl = 'http://192.168.8.102:5000/';
@override
void onInit() {
initPlatformState();
super.onInit();
}
// we must use static method, to handle in background
static void _callback(NotificationEvent evt) {
// HANDLING BACKGROUND NOTIFICATIONS :
// print('GETTING INFO ');
// print(evt.packageName); // PACKAGE USE TO SEND MESSAGE :
// print(evt.text); // MESSAGE CONTENT :
// print(evt.title); //SENDER NUMBER: OR HEADER
final SendPort? send = IsolateNameServer.lookupPortByName("_listener_");
if (send == null) print("can't find the sender");
send?.send(evt);
}
// Platform messages are asynchronous, so we initialize in an async method.
Future<void> initPlatformState() async {
NotificationsListener.initialize(callbackHandle: _callback);
// this can fix restart<debug> can't handle error
IsolateNameServer.removePortNameMapping("_listener_");
IsolateNameServer.registerPortWithName(port.sendPort, "_listener_");
port.listen((message) => onData(message));
// don't use the default receivePort
// NotificationsListener.receivePort.listen((evt) => onData(evt));
bool? isR = await NotificationsListener.isRunning;
print("""Service is ${isR == false ? "not " : ""}aleary running""");
started = isR!;
update();
}
Future<void> onData(NotificationEvent event) async {
_log.add(event);
update();
if (!event.packageName!.contains("example")) {
// TODO: fix bug
// NotificationsListener.promoteToForeground("");
}
// print('GETTING INFO FRONT APP ');
// print(event.packageName); // PACKAGE USE TO SEND MESSAGE :
// print(event.text); // MESSAGE CONTENT :
// print(event.title); //SENDER NUMBER: OR HEADER
if (event.packageName == 'com.whatsapp' && event.id != 0) {
await processMsg(event);
}
}
void startListening() async {
print("start listening");
_loading = true;
update();
bool? hasPermission = await NotificationsListener.hasPermission;
if (hasPermission == false) {
print("no permission, so open settings");
NotificationsListener.openPermissionSettings();
return;
}
bool? isR = await NotificationsListener.isRunning;
if (isR == false) {
await NotificationsListener.startService(
title: "we still with you ", description: "payai from feelsafe");
}
//if he agree
flag = true;
activateC();
started = true;
_loading = false;
update();
}
void stopListening() async {
print("stop listening");
_loading = true;
update();
await NotificationsListener.stopService();
started = false;
_loading = false;
update();
}
Future<void> processMsg(NotificationEvent msg) async {
//url to send the post request to
final url = myServerUrl;
// print(text);
//sending a post request to the url
final response = await http.post(Uri.parse(url),
body: json.encode({
'content': msg.text,
"sender": msg.title.toString(),
"date_time": msg.createAt.toString().substring(0, 19).toString(),
"parent_id": sharedPref.getString('parent_id'),
"child_name": name,
}));
//converting the fetched data from json to key value pair that can be displayed on the screen
final decoded = json.decode(response.body) as Map<String, dynamic>;
//this for tharaa :)
String label = decoded['label'];
if (label == 'NOT_APROP') {
//Here take the same msg information (line 134 - 138) and deal with it
print("label is $label");
}
}
void storeMsg(NotificationEvent msg) async {
print(
"child_name: $name , parent_id: ${sharedPref.getString('parent_id')}");
var response = await crud.postRequest2(linkStoreMsg, {
"child_name": name,
"sender": msg.title.toString(),
"date_time": msg.createAt.toString().substring(0, 19).toString(),
"content": msg.text,
"parent_id": sharedPref.getString('parent_id'),
});
print("response ${response}");
}
activateC() async {
isLoading = true;
var response = await crud.postRequest(linkactivateChild, {
"child_name": name,
"parent_id": sharedPref.getString("parent_id"),
});
isLoading = false;
if (response != null && response["status"] != "fail") {
backbutton = false;
isActive = 1;
update();
} else {
print("activate fail");
}
}
}
Hi @manarbajafar Thank you for your attention. Do you want the button to disappear automatically after you click Authorize?
Hi @manarbajafar Thank you for your attention. Do you want the button to disappear automatically after you click Authorize?
Hello @jiusanzhou thanks for your reply. Yes, I want the button to disappear after the user clicks on Allow access to notifications
@manarbajafar Sorry for the late reply. I think this requires adding a listener to listen for permission changing events, but I don't currently have it implemented, if I remember correctly. You can still add a timed task to get the latest permission status at regular intervals, this is of course a silly solution