I would like to take or select a picture, in order to use it for an ImageView, like it is shown here: http://gluonhq.com/handling-android-native-activities-like-a-pro/.
The problem that I'm facing is that when the according Intent is started, my app gets closed, the camera / galery shows up, and I'm not able to get the result of the intent, i.e. after taking / selecting a picture my app is restartet, and shows the HomeView.
android version 4.1.1
javafxports 8.60.6 (also tried 8.60.7)
UPDATE:
On Android 5.0 and javafxports 8.60.7 it is working as expected. Just had to add the lines which check if storageDir exists:
private File createImageFile() throws IOException {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
if (!storageDir.exists()) {
storageDir.mkdirs();
}
return File.createTempFile(imageFileName, ".jpg", storageDir);
}
Related
This is a very strange issue we are having. We have a data processing service that posts a message to Teams channel using webhook every night. Everything was working fine until few days ago. The full message used to show up in the channel conversations.
But now the channel shows only the first line of the post. Please see the attached screenshot. All the previous posts from months ago also show only one line. This only happens on the desktop client and web portal.
The Teams app on both Android and iOS displays the full message, which is usually 7-8 lines long.
If I click on "New Conversation" and paste the same 7-8 lines it does show full message.
I have sifted through all settings of the desktop client and cannot find a solution. Cleared all caches also without success.
Appreciate any help.
Thank you
Edit - 12-9-22
Please see the JSON code below, but this is happening with older messages as well, that were posted months ago, which used to display fully. So I am guessing this has nothing to do with JSON itself and has to do with channel/chat window settings. As I mentioned before the posts show fully on both Android and IOS apps.
public async void SendTeamsMessage(string body, string projectName) {
string webhookUrl = MailSettings.Current.TeamsWebHookURL;
System.Net.Http.HttpClient client = new System.Net.Http.HttpClient();
client.BaseAddress = new Uri(webhookUrl);
TeamsMessage message = new TeamsMessage();
System.Text.StringBuilder sb = new System.Text.StringBuilder();
sb.AppendLine("Batch " + batch.BatchId.ToString() + " finished processing.");sb.AppendLine("Alert - " + projectName);
sb.AppendLine("Message from Service at " + DateTime.Now.ToString() + "\r\n");
sb.AppendLine("Message :" + body);
message.text = sb.ToString();
string serializeJson = JsonConvert.SerializeObject(message);
System.Net.Http.StringContent content = new System.Net.Http.StringContent(serializeJson, System.Text.Encoding.UTF8, "application/json");
await client.PostAsync(client.BaseAddress, content);
}
private class TeamsMessage {
public string text { get; set; }
}
Not sure what happened, but we can see the full messages now. Started working few minutes ago.
In my Vaadin Flow web app (version 14 or later), I want to present to my user a link that will download a data file to them. The default name of the file to be downloaded should be determined at the moment the user initiates the download.
I am aware of the Anchor widget in Vaadin Flow. With an Anchor, the default name for the downloaded file will be the resource name given in the URL of the link. Unfortunately, that is determined when the page loads rather than later when the user clicks the link. So this approach fails to meet my need to label the download with the date-time captured at the moment the user initiates the download.
String when = Instant.now().toString().replace( "-" , "" ).replace( ":" , "" ); // Use "basic" version of standard ISO 8601 format for date-time.
StreamResource streamResource = new StreamResource( "rows_" + when + ".txt" , ( ) -> this.makeContent() );
Anchor anchor = new Anchor( streamResource , "Download generated data" );
Perhaps the solution would be the use of a Button widget rather than an Anchor. Using a button for dynamically-created content is shown in the manual in the Advanced Topics > Dynamic Content page. Unfortunately, the example there loads a resource on the page rather than doing a download for the user.
➥ Can a Button in Vaadin Flow be used to initiate a download?
➥ Is there some other approach to initiating a download with a URL determined when the user initiates the download rather than when the page loads?
Can a Button in Vaadin Flow be used to initiate a download?
Sort of yes, but it requires some client side implementation. There is File Download Wrapper add-on in Directory, which does this. With it is possible to wrap e.g. Button. However I think it will not solve problem of yours fully. I suspect that the setting the filename in click event wont apply (it comes too late). But I do think, that it would be possible to add filename provider callback feature to this add-on.
Consider this HACK that simulates a click on a dynamically added Anchor on client-side:
private void downloadWorkaround(Component anyComponent, int delay) {
Anchor hiddenDownloadLink = new Anchor(createStreamResource(), "Workaround");
hiddenDownloadLink.setId("ExportLinkWorkaround_" + System.currentTimeMillis());
hiddenDownloadLink.getElement().setAttribute("style", "display: none");
var parent = anyComponent.getParent().orElseThrow();
var parenthc = (HasComponents) parent;
for (Component c : parent.getChildren().collect(Collectors.toList())) {
if (c.getId().orElse("").startsWith("ExportLinkWorkaround_")) {
// clean up old download link
parenthc.remove(c);
}
}
parenthc.add(hiddenDownloadLink);
UI.getCurrent().getPage().executeJs("setTimeout(function(){" + // delay as workaround for bug when dialog open before
"document.getElementById('" + hiddenDownloadLink.getId().orElseThrow() + "').click();"
+ "}, " + delay + ");"
);
}
Call the method on button click event or something. The additional delay is required sometimes. For me the delay was necessary to start the download from a modal dialog OK button that also closed the dialog. But perhaps you don't even need that.
I had no luck with the file download wrapper add-on mentioned by Tatu for my specific use case: I wanted to show a dialog under some circumstances before providing the download to user.
Based on the question of Clearing up Vaadin StreamResource after file download (which is partly the same as the answer of Steffen Harbich here in this question) I came to this solution (Vaadin 23):
Just provide a normal button with a normal clickHandler.
In the clickHandler you determine the file name, create a local StreamResource, add it to an invisible UI element and trigger a click event on this element.
Clickhandler:
private void doOnDownloadBtnClicked( Event e )
{
String filename = createFileName(); // implementation left to you
downloadFile( filename, this::inputStreamProvider );
}
InputStream provider:
private InputStream inputStreamProvider()
{
....
}
File download (may be extracted to an Utility class):
private final StreamResourceRegistry myStreamResourceRegistry;
private void downloadFile( String aFileName, InputStreamFactory aInputStreamFactory )
{
myStreamResourceRegistry = new StreamResourceRegistry(VaadinSession.getCurrent());
var executor = new DownloadExecutor( aInputStreamFactory );
var sr = new StreamResource( aFileName, executor );
StreamRegistration reg = myStreamResourceRegistry.registerResource( sr );
executor.myRegistration = reg;
var hiddenDownloadLink = new Anchor(sr, "Hidden");
var hiddenDownloadLinkId =
StringUtils.replaceChars( "DownloadLinkWorkaroundId-" + new SecureRandom().nextLong(),
'-',
'_' ) ;
hiddenDownloadLink.setId( hiddenDownloadLinkId);
var hiddenElement = hiddenDownloadLink.getElement();
executor.myHiddenElement = hiddenElement;
hiddenElement.setAttribute("style", "display: none");
var uiParent = UI.getCurrent().getElement();
executor.myParentElement = uiParent;
uiParent.appendChild(hiddenElement);
LOG.debug( "Going to simulate click event" );
UI.getCurrent().getPage().executeJs("$0.click();", hiddenElement );
}
/**
* Wrapper for the given InputStreamFactory.
* <p>
* It is needed to let Vaadin first give a chance to call the InputStream provider, before the
* temporary added hidden anchor is removed and the StreamRegistration is unregistered.
*/
private static final class DownloadExecutor implements InputStreamFactory
{
private InputStreamFactory myInputStreamFactory;
private StreamRegistration myRegistration;
private Element myHiddenElement;
private Element myParentElement;
private DownloadExecutor( InputStreamFactory aInputStreamFactory )
{
super();
myInputStreamFactory = aInputStreamFactory;
}
#Override
public InputStream createInputStream()
{
var result = myInputStreamFactory.createInputStream();
myParentElement.removeChild( myHiddenElement );
myRegistration.unregister();
return result;
}
}
Note: If the above fileDownload is extracted to an own helper class (e.g. a spring bean with #SessionScope), the initialization of myStreamResourceRegistry should be done in the constructor of the bean.
I am using ZXing nuget for scan QR code in my Xamarin Android application. I have added loader after scanned. I am calling api based on scanned data. But api takes time. I had written code for display loader it's not displaying properly on android 8 or android 9. But it's not rotating in android 7. What's wrong with my code?
My code is :
serverProgressDialog = new ProgressDialog(this);
serverProgressDialog.SetProgressStyle(ProgressDialogStyle.Spinner);
serverProgressDialog.SetMessage("Contacting server. Please wait...");
serverProgressDialog.Indeterminate = true;
serverProgressDialog.SetCancelable(false);
serverProgressDialog.Create();
serverProgressDialog.ShowEvent += ServerProgressDialog_ShowEvent;
For show :
internal void ShowServerProgressDialog()
{
serverProgressDialog.Show();
}
On ScanButton Click code :
imageBtn.Click += async delegate
{
scanner.AutoFocus();
var result = await scanner.Scan(options);
scanner.Cancel();
if (result != null)
{
SetTextboxValue(result.Text);
new Handler().PostDelayed(new Runnable(() =>
ShowServerProgressDialog()), 10);
}
else
{
HideServerProgressDialog();
}
};
On event show I am displaying dialog. Some how it's not rotating on android device os version 7.
So, either I am asking incorrectly, or it isn't possible, let's see which...
If my app (Xamarin.Forms) is launched from another app, in order to get a url from my app, how do I return that data to the calling app? I wrongly assumed SetResult and Finish, I also wrongly assumed StartActivityForResult, but there has to be a way to do this. I know how to get data INTO my app from another app, but not the same in return.
POSSIBLE PARTIAL SOLUTION -- UPDATE, FAILS
So I have to setup an interface in my PCL, and call the method from the listview item selected handler, in the Android app I can then do this:
Intent result = new Intent("com.example.RESULT_ACTION", Uri.parse("content://result_url"));
setResult(Activity.RESULT_OK, result);
finish();
(source: https://developer.android.com/training/basics/intents/filters.html)
Is this looking right, and how would I implement the same thing on iOS?
END
I deleted my previous question because I couldn't explain the problem clearly, so here goes.
I have a Xamarin Forms app, I want to use a section of this app as a gallery. Currently I have images displayed in a list, and I have an Intent filter set that launches this page when you select the app as the source for an image (such as upload image on Facebook).
My issue is that I don't know how to return the data (the selected image) back to the app / webpage that made the request. In android I understand that you would use StartActivityForResult and OnActivityResult to handle this, but I am using Xamarin Forms (Android, iOS, UWP) and can't really find a solution that could be used cross-platform.
Just a link to documentation that covers this would be great, but if you have an example then even better.
Thanks
EDIT
Here is the code used to launch the app, I am interested in getting data back from the Intent.ActionPick after the user has selected an image from a ListView, which is in a ContentPage in the PCL.
[Activity(Label = "", Icon = "#drawable/icon", Theme = "#style/DefaultTheme", MainLauncher = true, LaunchMode = LaunchMode.SingleTop,
ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
[IntentFilter(new[] { Intent.ActionSend }, Categories = new[] { Intent.CategoryDefault }, DataMimeType = #"*/*")]
[IntentFilter(new[] { Intent.ActionView, Intent.ActionPick, Intent.ActionGetContent }, Categories = new[] { Intent.CategoryDefault, Intent.CategoryOpenable }, DataMimeType = #"*/*")]
public class MainActivity : FormsAppCompatActivity
{
protected override void OnCreate(Bundle bundle)
{
try
{
base.OnCreate(bundle);
CurrentPlatform.Init();
Xamarin.Forms.Forms.Init(this, bundle);
App _app = new App();
LoadApplication(_app);
if (Intent.Action == Intent.ActionSend)
{
var image = Intent.ClipData.GetItemAt(0);
var imageStream = ContentResolver.OpenInputStream(image.Uri);
var memOfImage = new System.IO.MemoryStream();
imageStream.CopyTo(memOfImage);
_app.UploadManager(memOfImage.ToArray()); //This allows me to upload images to my app
}
else if (Intent.Action == Intent.ActionPick)
{
_app.SelectManager(); //here is where I need help
}
else
{
_app.AuthManager(); //this is the default route
}
}
catch (Exception e)
{
}
}
It seems you cannot use remote URI to provide to calling app. Some posts I checked suggest to store the file locally and provide it's path to calling app. To avoid memory leak with many files stored I suggest to use the same file name then you will have only one file at any moment.
One more note. I tested this solution in facebook. Skype doesn't seem to accept that and, again, the posts I checked saying that Skype doesn't handle Intent properly (not sure what that means).
Now to solution. In main activity for example in OnCreate method add the follow.
ReturnImagePage is the name of my page class where I select an image
Xamarin.Forms.MessagingCenter.Subscribe<ReturnImagePage, string>(this, "imageUri", (sender, requestedUri) => {
Intent share = new Intent();
string uri = "file://" + requestedUri;
share.SetData(Android.Net.Uri.Parse(uri));
// OR
//Android.Net.Uri uri = Android.Net.Uri.Parse(requestedUri);
//Intent share = new Intent(Intent.ActionSend);
//share.PutExtra(Intent.ExtraStream, uri);
//share.SetType("image/*");
//share.AddFlags(ActivityFlags.GrantReadUriPermission);
SetResult(Result.Ok, share);
Finish();
});
Above will listen for the message when the image is selected.
Then in XFroms code when image is selected dowload it, store it, get path and send to Activity using it's path. Below is my test path
MessagingCenter.Send<ReturnImagePage, string>(this, "imageUri", "/storage/emulated/0/Android/data/ButtonRendererDemo.Droid/files/Pictures/temp/IMG_20170207_174559_21.jpg");
You can use static public class to save and access results like:
public static class StaticClass
{
public static int Result;
}
I am trying to create an event using the C# SDK. I am using the code from the following blog:
http://facebooksdk.blogspot.co.uk/2011/05/facebook-create-event.html
And I am using an image that I copied from an existing event on Facebook.
I am getting however the following error:
(OAuthException) (#324) Missing or invalid image file
Does anyone have an idea how to make it work?
Many thanks!
The code is as follows:
public string CreateEvent()
{
var fb = new FacebookWebClient();
Dictionary<string, object> createEventParameters = new Dictionary<string, object>();
createEventParameters.Add("name", "My birthday party )");
createEventParameters.Add("start_time", DateTime.Now.AddDays(2).ToUniversalTime().ToString(new CultureInfo("en-US")));
createEventParameters.Add("end_time", DateTime.Now.AddDays(2).AddHours(4).ToUniversalTime().ToString(new CultureInfo("en-US")));
createEventParameters.Add("owner", "Balaji Birajdar");
createEventParameters.Add("description", " ( a long description can be used here..)");
//Add the "venue" details for the event
JsonObject venueParameters = new JsonObject();
venueParameters.Add("street", "dggdfgg");
venueParameters.Add("city", "gdfgf");
venueParameters.Add("state", "gfgdfgfg");
venueParameters.Add("zip", "gfdgdfg");
venueParameters.Add("country", "gfdgfg");
venueParameters.Add("latitude", "100.0");
venueParameters.Add("longitude", "100.0");
createEventParameters.Add("venue", venueParameters);
createEventParameters.Add("privacy", "OPEN");
createEventParameters.Add("location", "fhdhdfghgh");
//Add the event logo image
//You can add the event logo too
FacebookMediaObject logo = new FacebookMediaObject()
{
ContentType = "image/jpeg",
FileName = #"C:\DevProjects\O2\o2PriorityFB\o2PriorityFB.Web\Images\logo.jpg"
};
logo.SetValue(System.IO.File.ReadAllBytes(logo.FileName));
createEventParameters["#file.jpg"] = logo;
JsonObject resul = fb.Post("/me/events", createEventParameters) as JsonObject;
return resul["id"].ToString();
}
You need to include a valid access token in the request. Also, I would recommend upgrading to V6 of the Facebook C# SDK. For the version you are using though you need to pass the access token into the constructor of FacebookWebClient as follows:
var fb = new FacebookWebClient("valid_facebook_access_token");