I face an issue while running disconnect from app center via my application. here is my source code.
private boolean disconnet(final String oauthConsumerKey, final String oauthConsumerSecret, final String accessToken, final String accessTokenSecret, final String realmID) {
try {
if (accessToken != null && accessTokenSecret != null
&& realmID != null) {
final IAPlatformClient pClient = new IAPlatformClient();
pClient.disconnect(oauthConsumerKey, oauthConsumerSecret, accessToken, accessTokenSecret);
return true;
}
} catch (Exception e) {
System.err.println("Exception : "+e.getMessage());
return false;
}
return false;
}
I get the exception:
Exception :Failed to disconnect: java.lang.NullPointerException null
Can someone help me? Thanks in advance.
We currently have a defect in the development environment that prevents the disconnect from the app center flow to be executed properly. The defect only affects the development environment, the production environment is working correctly.
The defect presents a pop up with a Close button at the end of the sequence and control is returned to the app center Manage My Apps page rather than directing the user to the application's disconnect URL.
To test this after returning to the app center, simply paste the disconnect URL into the browser address box and manually navigate to the disconnect URL.
Related
I am using below code to access gallery permissions in .net maui but it always returns Granted even on first time launch of the application and I am not able to see the permission popup saying "This app would like to access photos and media on your device"
public static async Task<PermissionStatus> GetMediaPermissionStatus()
{
PermissionStatus mediaResult = PermissionStatus.Disabled;
var tcs = new TaskCompletionSource<PermissionStatus>();
var status = await Permissions.CheckStatusAsync<Permissions.Photos>();
if (status != PermissionStatus.Granted)
{
status = await Permissions.RequestAsync<Permissions.Photos>();
}
tcs.SetResult(status);
return await tcs.Task;
}
Also when I execute below code getting 2 app permission Popups
1st Popup - "Allow application to take pictures and record video"
2nd Popup - "Allow application to access photos and media on your device?"
public async void TakePhoto()
{
if (MediaPicker.Default.IsCaptureSupported)
{
FileResult photo = await Microsoft.Maui.Media.MediaPicker.Default.CapturePhotoAsync();
if (photo != null)
{
// save the file into local storage
string localFilePath = Path.Combine(FileSystem.CacheDirectory, photo.FileName);
using Stream sourceStream = await photo.OpenReadAsync();
using FileStream localFileStream = File.OpenWrite(localFilePath);
await sourceStream.CopyToAsync(localFileStream);
}
}
}
I don't know if it is a bug or I am doing something wrong.
Any help is appreciated!
You can refer to this doc: Permissions of MAUI. There is a table in it. It uses ✔️ to indicate that the permission is supported and ❌ to indicate the permission isn't supported or isn't required
If a permission is marked as ❌, it will always return Granted when checked or requested.
Granted:
The user granted permission or is automatically granted.
Wish it can help you.
How do you get the output written to logcat back into the Flutter app that caused it? Or simpler asked: How to read logcat in Flutter?
The problem is this:
The app uses a stack of Android plugins to communicate with some custom hardware through Bluetooth. Those Android plugins write extensively to logcat. Now, for debugging, it would be very helpful to be able to read all the messages the App (including native plugins) has written to logcat. Question is, is this somehow possible?
How would you tackle that?
Check out the plugin called logcat on pub.dev.
Sadly, it seems to be no longer maintained and isn't updated for null safety.
But you can check out the source code here and see how the plugin gets access to the android logcat.
Because the logcat is a native thing, you'll have to use a MethodChannel to call a Java/Kotlin function:
// define MethodChannel
final platform = const MethodChannel('app.channel.logcat');
// call native method
logs = await platform.invokeMethod('execLogcat');
And the native part:
public class LogcatPlugin implements MethodCallHandler {
public static void registerWith(Registrar registrar) {
final MethodChannel channel = new MethodChannel(registrar.messenger(), "app.channel.logcat");
channel.setMethodCallHandler(new LogcatPlugin());
}
#Override
public void onMethodCall(MethodCall call, Result result) {
if (call.method.equals("execLogcat")) {
String logs = getLogs();
if (logs != null) {
result.success(logs);
} else {
result.error("UNAVAILABLE", "logs not available.", null);
}
} else {
result.notImplemented();
}
}
String getLogs() {
try {
Process process = Runtime.getRuntime().exec("logcat -d");
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
StringBuilder log = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
log.append(line);
}
return log.toString();
} catch (IOException e) {
return "EXCEPTION" + e.toString();
}
}
}
The code samples are from github.com/pharshdev/logcat.
Maybe you can just fork the git repo and migrate it to null safety if needed.
Check the plugin called logcat_monitor on pub.dev.
Its biggest advantage over the other logcat plugin is that it allows continuous monitoring of logcat messages.
Follows a screenshot example:
how to use
Add the dependencies:
dependencies:
logcat_monitor: ^0.0.4
Create a function to consume the logcat messages
void _mylistenStream(dynamic value) {
if (value is String) {
_logBuffer.writeln(value);
}
}
Register your function as a listener to get logs then use it in anyway within your app.
LogcatMonitor.addListen(_mylistenStream);
Start the logcat monitor passing the filter parameters as defined in logcat tool.
await LogcatMonitor.startMonitor("*.*");
clientViaUserConsent opens URL in browser but it said invalid request. this URL is generated internally from lib. I had double-checked my ClientId for both platforms but still face issues for getting AuthClient for create a calendar event.
I used the below packages to create events in the google calender.
googleapis: ^8.1.0
googleapis_auth: ^1.3.0
static final androidClientId = ClientId('xxxxxxxx.apps.googleusercontent.com');
static final iOSClientId = ClientId('xxxxxxx.apps.googleusercontent.com');
final _clientID = Platform.isAndroid ? EventProvider.androidClientId : EventProvider.iOSClientId;
final _scopes = [CalendarApi.calendarScope];
clientViaUserConsent(_clientID, _scopes, prompt).then((AuthClient client) {
var calendar = CalendarApi(client);
}
void prompt(String url) async {
print(" => $url");
if (await canLaunch(url)) {
await launch(URL);
} else {
throw 'Could not launch $url';
}
}
I am referring to this article for creating an event in google calendar.
https://blog.codemagic.io/google-meet-events-in-flutter/
https://medium.com/flutter-community/flutter-use-google-calendar-api-adding-the-events-to-calendar-3d8fcb008493
You are seeing that error because the app hasn't been verified. If you are the app developer I advise you to check the App Verification FAQ to learn more about the verification steps. If you aren't the developer, you could try to enable the less secure app access but please be mindful of the consequences:
Less secure apps can make it easier for hackers to get in to your account, so blocking sign-ins from these apps helps keep your account safe.
I'm using SignalR for push notifications on my Flutter app and that works ok. I get the message from the backend and show notification using flutter_local_notifications. The problem is that the SignalR service would shut down after some time.
How can I make my app stay on in the background? and even start on reboot?
Here's my code:
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:isolate_test/Model/UserMessageModel.dart';
import 'package:signalr_core/signalr_core.dart';
import 'EndPointService.dart';
import 'NotificationService.dart';
class SignalRProvider {
static String appName = "NOTIFICATION";
static String? userName = "";
static String deviceName = "android_app";
static List<UserMessageModel> messages = <UserMessageModel>[];
HubConnection connection = HubConnectionBuilder()
.withUrl(
'my_url',
HttpConnectionOptions(
logging: (level, message) => print(message),
))
.withAutomaticReconnect()
.withHubProtocol(JsonHubProtocol())
.build();
Function(bool update)? onMessagesUpdateCallback;
SignalRProvider({
this.onMessagesUpdateCallback,
});
setUsername(String username) {
userName = username;
}
Future initSignalR(BuildContext context) async {
WidgetsFlutterBinding.ensureInitialized();
await NotificationService().init();
connection.on('SignalRUserReceiveMessage', (message) async {
var data = message!.first;
if (data != null) {
UserMessageModel msg = UserMessageModel.fromJson(data);
messages.add(msg);
msg.showNotification();
}
if (onMessagesUpdateCallback != null) {
onMessagesUpdateCallback!(true);
}
});
connection.on('SignalRMonitoringMessage', (message) async {
var data = message!.first;
if (data != null) {
UserMessageModel msg = UserMessageModel.fromJson(data);
messages.add(msg);
msg.showNotification();
}
if (onMessagesUpdateCallback != null) {
onMessagesUpdateCallback!(true);
}
});
connection.on("SignalRReceiveConnectedMessage", (message) async {
await connection.send(methodName: 'SignalRInit', args: [
userName,
appName,
connection.connectionId,
]);
});
connection.on("SignalRReceiveDisconnectedMessage", (message) async {
if (connection.state == HubConnectionState.disconnected) {
connection.start();
}
});
await connection.start();
}
List<UserMessageModel> getMessages() {
return messages;
}
Future deleteMessage(UserMessageModel _msg) async {
if (_msg == null) return;
var response =
await EndPointService().SetupApi("Message", "", []).httpDelete(
HeaderEnum.BasicHeaderEnum,
ResponseEnum.ResponseModelEnum,
jsonEncode(_msg),
);
}
addOrUpdateMessage(UserMessageModel _msg) {
if (_msg == null) return;
if (messages != null) {
var found =
messages.firstWhere((e) => e.user == _msg.user && e.id == _msg.id);
var index =
messages.indexWhere((e) => e.user == _msg.user && e.id == _msg.id);
if (found != null) {
messages[index] = _msg;
} else {
messages.add(_msg);
}
if (onMessagesUpdateCallback != null) {
onMessagesUpdateCallback!(true);
}
}
}
setMessagesUpdateCallback(Function(bool update) func) {
onMessagesUpdateCallback = func;
}
}
SignalR problems
SignalR for Flutter uses web sockets and SSE to receive messages from the SignalR service. If the app was terminated because the user restarted their phone or the OS shut down the app to save battery, these push notifications would not be received by the app.
To overcome this, app developers (and SignalR) have to use FCM on Android, and APNs on iOS (or FCM which will also use APNs on iOS). All other approaches will be more limited because the operating systems do not allow users to keep background processes running the entire time. This was actually allowed years ago, but the operating systems have made these changes to save the user battery - they enforce that all apps go through the same push notification medium - FCM on Android, APNs on iOS.
SignalR for Flutter uses neither FCM nor APNs. At it's current state, SignalR is not well suited for Android or iOS - take a look at the comments with people struggling with similar problems to you on How to use signalr in Android.
Alternative solution
The simplest / easiest way to get started is to use Firebase Cloud Messaging.
On Android, it will be used directly to send messages to devices, and
on iOS, FCM will use APNs to reach devices reliably
Caveat: On Android, there is a more complicated alternative called unifiedpush, but the limitations include showing a notification to the user at all times to handle background notifications.
My analysis: This is all done based on my quick investigation by reading the pubspec.yaml, the GitHub issues on the original repo, the SignalR documentation, and some experience implementing Push Notifications for Flutter.
Disclosure: I just released a push notification library 2 days ago called push which would be well suited to these types of Push Notification packages making the transformation to using FCM on Android and APNs on iOS. However, as an app developer, in most cases, you should use firebase_messaging, not push.
I worked with SignalR but on native Platform(IOS & Android), I made stock app and get realtime price. When app go to background, I will disconnect with SignalR server after 5 second, and when app go to foreground again, I check if app's current state not connect to server SignalR, I'll connect again. I think it not good if your app still connect and receiver data from signalR server in background state.
I just trying to add add the Facebook integration with my app in Xamarin.Android. For that I found that there is a Component named as Xamarin.Social then I am trying that. Here is my attempt.
Attempt :-
void btnShare_Click(object sender, EventArgs e)
{
try
{
var facebook = new Xamarin.Social.Services.FacebookService()
{
ClientId = AppId,
RedirectUrl = new System.Uri("http://www.facebook.com/connect/login_success.html")
};
// 2. Create an item to share
var item = new Item { Text = "Xamarin.Social is the bomb.com." };
var shareController = facebook.GetShareUI(this, item, result =>
{
if (result.HasFlag(Xamarin.Social.ShareResult.Done))
{
Toast.MakeText(this, "Posted", ToastLength.Long).Show();
}
if (result.HasFlag(Xamarin.Social.ShareResult.Cancelled))
{
Toast.MakeText(this, "Cancelled", ToastLength.Long).Show();
}
});
StartActivity(shareController);
}
catch (Exception exp)
{
}
}
Note :- Facebook login page is opening successfully.
Error :- But I am getting this Forbidded(403) error. the point is this error is not reaching to catch block , but it is shown in a toast notification. so no further details are available.
Does anybody explored this component successfully ?
Any help is appreciated :)
As I mentioned in the comments, I had to many issues using the social plugin, I just used the android share intent, see example below
var shareIntent = new Intent();
shareIntent.SetAction(Intent.ActionSend);
shareIntent.PutExtra(Intent.ExtraText, message); //message is the text you want to share
shareIntent.SetType("text/plain");
StartActivity(shareIntent);