Android problem changing app language programmatically - c#

I've built an android application (using Xamarin c#) and it contains a Settings screen where users can change app language.
This language setting is saved also on the server by calling an API.
After changing the language I refresh texts into the settings screen and into other opened activities and all seems work.
The problem is when I close and reopen the app: I sign in the user and I read language data from the server.
I programmatically change the locale language of the app into my main activity: for example, I set a language different than the default smartphone language.
This activity contains 4 fragments into a ViewPager, but sometimes these fragments are in the "old" language and "new" language is not correctly applied.
So, when I open a new activity, the language shown is the "old" and not the "new".
Am I doing something wrong?
Can anyone help me?
Following my code:
In my AppBaseActivity class, OnCreate event:
base.OnCreate(bundle);
if (UserSettings != null
&& !string.IsNullOrWhiteSpace(UserSettings.LanguageCode))
{
LocaleManager.ChangeAppLanguage(this, UserSettings.LanguageCode);
}
In my AppBaseActivity class, OnResume event:
base.OnResume();
if (UserSettings != null
&& !string.IsNullOrWhiteSpace(UserSettings.LanguageCode))
{
LocaleManager.ChangeAppLanguage(this, UserSettings.LanguageCode);
}
My LocaleManager.ChangeAppLanguage method:
public static bool ChangeAppLanguage(Context context, String lang, bool saveInSharedPreferences)
{
Locale newLocale = new Locale(lang);
if (Locale.Default.Language != newLocale.Language)
{
Locale.Default = newLocale;
Android.Content.Res.Configuration config = new Android.Content.Res.Configuration();
if (Build.VERSION.SdkInt >= BuildVersionCodes.Lollipop)
{
config.SetLocale(newLocale);
}
else
{
config.Locale = newLocale;
}
context.Resources.UpdateConfiguration(config, context.Resources.DisplayMetrics);
if (saveInSharedPreferences)
return Helper.SaveInSharedPreferences(context, context.ApplicationContext.PackageName + ".languageCode", lang);
return true;
}
return false;
}

you should load the new Context in the AttachBaseContext method of your AppBaseActivity,you could refer to here

Related

No image tracking subsystem found when you call ARTrackedImageManager.CreateRuntimeLibrary

I am trying to create a RuntimeReferenceImageLibrary and I have always this error:
NotSupportedException: No image tracking subsystem found. This usually
means image tracking is not supported.
UnityEngine.XR.ARFoundation.ARTrackedImageManager.CreateRuntimeLibrary
(UnityEngine.XR.ARSubsystems.XRReferenceImageLibrary
serializedLibrary) (at
Library/PackageCache/com.unity.xr.arfoundation#4.2.6/Runtime/AR/ARTrackedImageManager.cs:95)
Is there any way to change my subsystem and make it possible ?
I used the same project with the same XRReferenceImageLibrary and the ARTrackedImageManager and if you add the picture in the editor everything is working fine.
The problem is when you want to create a RuntimeReferenceImageLibrary for adding pictures in runtime.
//Definition
public XRReferenceImageLibrary serializedLibrary; //Set up in the editor
private ARTrackedImageManager trackedImageManager; //Set up in the awake function
I called this function in the Start function and also I tried to call it afterwards. Always I got the same result
private void TryOut()
{
if (trackedImageManager != null)
{
if (serializedLibrary != null)
{
if (trackedImageManager.enabled == true)
{
Debug.Log("Image manager and XR Reference found");
RuntimeReferenceImageLibrary runtimeLibrary = trackedImageManager.CreateRuntimeLibrary(serializedLibrary);
}
}
}
}

Notification bar appears all white in light mode

I'm using Template 10 and in Windows 10 Mobile when I choose the light mode, the notifications bar appears all white
and can not see the notifications, the hours, etc.
In the dark mode everything seems fine image:
How do I solve this?
I do this in my hamburger's override for UIElement CreateRootElement() after my database setup/migrations are done.
if(Template10.Utils.DeviceUtils.Current().IsPhone()){
var statusBar = Windows.UI.ViewManagement.StatusBar.GetForCurrentView();
if(statusBar != null)
{
if(Application.Current.RequestedTheme == ApplicationTheme.Light)
//background && foreground or combination, and dependent on color choices
statusBar.ForegroundColor = Windows.UI.Colors.Black;
else if(Application.Current.RequestedTheme == ApplicationTheme.Dark
statusBar.ForegroundColor = Windows.UI.Colors.White;
}
}
Template10 already has a lot of the logic built in just have to know where it is. As #Jay Zuo said you have to also include the Mobile reference as well..
As #mvermef said, to solve this problem, we can set the color used in status bar according to application's theme. We can get application's theme by using Application.RequestedTheme property and set status bar's color by using properties in Status​Bar Class. For a simple example:
public MainPage()
{
InitializeComponent();
NavigationCacheMode = Windows.UI.Xaml.Navigation.NavigationCacheMode.Enabled;
if (ApiInformation.IsTypePresent("Windows.UI.ViewManagement.StatusBar"))
{
var statusBar = StatusBar.GetForCurrentView();
if (statusBar != null)
{
if (Application.Current.RequestedTheme == ApplicationTheme.Light)
{
statusBar.ForegroundColor = Windows.UI.Colors.Black;
}
else if (Application.Current.RequestedTheme == ApplicationTheme.Dark)
{
statusBar.ForegroundColor = Windows.UI.Colors.White;
}
}
}
}
Please note to use Status​Bar Class, we need reference Windows Mobile Extensions for the UWP in the project.

Is it possible to activate a tab in another program using an IntPtr?

Thanks in advance.
Is it possible to activate a tab in another program using an IntPtr? If so, how?
SendKeys is not an option.
Perhaps what I need is a fishing lesson. I have exhausted Google and my lead developer.
I would appreciate an outright solution OR a recommendation to continue my Google efforts.
basic process is:
I drag a shortcut icon to the launcher
This opens the target application (Notepad++) and grabs IntPtr, etc.
I would like to programmatically select various items in Notepad++ such as Edit, menu items under Edit, or a doc tab.
The basic code I am running is:
the 'blob'
item 1: IntPtr of item
item 2: IntPtr of itemsChild
item 3: control text of item 1
item 4: is rectangle parameters of item 1
root contains similar info:
As others pointed out, the standard way of doing this is to use UI Automation. Notepad++ does support UI Automation (to some extent, as it's somehow automatically provided by the UI Automation Windows layers).
Here is a sample C# console app that demonstrates the following sceanrio (you need to reference UIAutomationClient.dll, UIAutomationProvider.dll and UIAutomationTypes.dll):
1) get the first running notepad++ process (you must start at least one)
2) open two files (note there may be already other opened tabs in notepad++)
3) selects all tabs in an infinite loop
class Program
{
static void Main(string[] args)
{
// this presumes notepad++ has been started somehow
Process process = Process.GetProcessesByName("notepad++").FirstOrDefault();
if (process == null)
{
Console.WriteLine("Cannot find any notepad++ process.");
return;
}
AutomateNpp(process.MainWindowHandle);
}
static void AutomateNpp(IntPtr handle)
{
// get main window handle
AutomationElement window = AutomationElement.FromHandle(handle);
// display the title
Console.WriteLine("Title: " + window.Current.Name);
// open two arbitrary files (change this!)
OpenFile(window, #"d:\my path\file1.txt");
OpenFile(window, #"d:\my path\file2.txt");
// selects all tabs in sequence for demo purposes
// note the user can interact with n++ (for example close tabs) while all this is working
while (true)
{
var tabs = GetTabsNames(window);
if (tabs.Count == 0)
{
Console.WriteLine("notepad++ process seems to have gone.");
return;
}
for (int i = 0; i < tabs.Count; i++)
{
Console.WriteLine("Selecting tab:" + tabs[i]);
SelectTab(window, tabs[i]);
Thread.Sleep(1000);
}
}
}
static IList<string> GetTabsNames(AutomationElement window)
{
List<string> list = new List<string>();
// get tab bar
var tab = window.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Tab));
if (tab != null)
{
foreach (var item in tab.FindAll(TreeScope.Children, PropertyCondition.TrueCondition).OfType<AutomationElement>())
{
list.Add(item.Current.Name);
}
}
return list;
}
static void SelectTab(AutomationElement window, string name)
{
// get tab bar
var tab = window.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Tab));
// get tab
var item = tab.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.NameProperty, name));
if (item == null)
{
Console.WriteLine("Tab item '" + name + "' has been closed.");
return;
}
// select it
((SelectionItemPattern)item.GetCurrentPattern(SelectionItemPattern.Pattern)).Select();
}
static void OpenFile(AutomationElement window, string filePath)
{
// get menu bar
var menu = window.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.MenuBar));
// get the "file" menu
var fileMenu = menu.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.NameProperty, "File"));
// open it
SafeExpand(fileMenu);
// get the new File menu that appears (this is quite specific to n++)
var subFileMenu = fileMenu.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Menu));
// get the "open" menu
var openMenu = subFileMenu.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.NameProperty, "Open..."));
// click it
((InvokePattern)openMenu.GetCurrentPattern(InvokePattern.Pattern)).Invoke();
// get the new Open dialog (from root)
var openDialog = WaitForDialog(window);
// get the combobox
var cb = openDialog.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.ComboBox));
// fill the filename
((ValuePattern)cb.GetCurrentPattern(ValuePattern.Pattern)).SetValue(filePath);
// get the open button
var openButton = openDialog.FindFirst(TreeScope.Children, new AndCondition(
new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Button),
new PropertyCondition(AutomationElement.NameProperty, "Open")));
// press it
((InvokePattern)openButton.GetCurrentPattern(InvokePattern.Pattern)).Invoke();
}
static AutomationElement WaitForDialog(AutomationElement element)
{
// note: this should be improved for error checking (timeouts, etc.)
while(true)
{
var openDialog = element.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Window));
if (openDialog != null)
return openDialog;
}
}
static void SafeExpand(AutomationElement element)
{
// for some reason, menus in np++ behave badly
while (true)
{
try
{
((ExpandCollapsePattern)element.GetCurrentPattern(ExpandCollapsePattern.Pattern)).Expand();
return;
}
catch
{
}
}
}
}
If you wonder how this has been made, then you must read about UI Automation. The mother of all tools is called Inspect: https://msdn.microsoft.com/library/windows/desktop/dd318521.aspx
Make sure you get version at least 7.2.0.0. Note there is another one called UISpy but inspect is better.
Note, unfortunately, notepad++ tab text content - because it's based on the custom scintilla editor control - does not properly supports automation (we can't read from it easily, I suppose we'd have to use scintilla Windows messages for this), but it could be added to it (hey, scintilla guys, if you read this ... :).
In addition to the answer from Garath, you might also want to investigate the Windows automation API's i.e. the technology used to implement coded UI tests for GUI applications. As part of regular functional testing, I routinely control an external application from a set of NUnit tests using these API's.
Tools like UIAVerify will give you an indication of what controls are available in the application and you can use the Invoke Pattern (and many others) to interact with the controls at run-time.
If you want a detailed example of how to use the automation API's, the open source TestStack White project is pretty handy.
It is almost not possible if SendKeys is not an option but read more
Now more important part of the question- why:
We have to look how win32 application works: it has a WndProc/WindowProc method which is resposible for processing "events" form the UI.
So every event in the windows application must go through above method. SendKeys method is a special of SendMessage (MSDN), so you can use SendMessage to control other exe than your.
Simple code could look like:
IntPtr hwnd = FindWindow("Notepad++", null);
SendMessageA(hwnd, WM_COMMAND, SOMETHING1, SOMETHING2);
There is already on StackOverflow example how to do that with chrome: C# - Sending messages to Google Chrome from C# application , but this is only a start. You will have to find out what exactly message you want to send.
In exactly situation which you described I will try to send WM_MOUSE and WM_KEYBORD events to Notepad++ events, but it is only an idea :)

Unpin from start menu using c# in win8

I am developing a c# desktop application.
We need to unpin our application tile based on number of conditions. this could happen anytime during the application life-cycle, and not only during installation.
I saw this question on how to unpin a tile in CPP. I tried to do that also in C# with no success.
any help?
Update:
I was able to write a C# code that sets the AppUserModel_StartPinOption to APPUSERMODEL_STARTPINOPTION_NOPINONINSTALL but it didn't help :(
this is the code:
private static void InstallShortcut(string linkPath)
{
// Find the path to the current executable
// String exePath = Process.GetCurrentProcess().MainModule.FileName; //Path to the current exe file that is running. C:\\...
IShellLinkW newShortcut = (IShellLinkW)new CShellLink();
// Create a shortcut to the exe
ErrorHelper.VerifySucceeded(newShortcut.SetPath(targetPath));
ErrorHelper.VerifySucceeded(newShortcut.SetArguments(""));
// Open the shortcut property store, set the AppUserModelId property
IPropertyStore newShortcutProperties = (IPropertyStore)newShortcut;
var APPUSERMODEL_STARTPINOPTION_NOPINONINSTALL = new PropVariant(0);
var StartPinOption = new PropertyKey(new Guid("{9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3}"), 12);
ErrorHelper.VerifySucceeded(newShortcutProperties.SetValue(StartPinOption, APPUSERMODEL_STARTPINOPTION_NOPINONINSTALL));
ErrorHelper.VerifySucceeded(newShortcutProperties.Commit());
// Commit the shortcut to disk
IPersistFile newShortcutSave = (IPersistFile)newShortcut;
ErrorHelper.VerifySucceeded(newShortcutSave.Save(linkPath, true));
}
I tried both: removing the tile and then recreating it, and changing the params of an existing tile, but nothing worked, the tile stays pinned to the start menu.
Are you talking about your main application tile or a secondary tile? If you are referring to a secondary tile, there is sample code for unpinning in this article. The meat of it is (and I'm modifying a bit for simplicity; see the article for the full code):
// Check to see if this restaurant exists as a secondary tile and then unpin it
string restaurantKey = this.m_ViewModel.Restaurant.Key;
Button button = sender as Button;
if (button != null)
{
if (Windows.UI.StartScreen.SecondaryTile.Exists(restaurantKey))
{
SecondaryTile secondaryTile = new SecondaryTile(restaurantKey);
bool isUnpinned = await secondaryTile.RequestDeleteForSelectionAsync(GetElementRect((FrameworkElement)sender), Windows.UI.Popups.Placement.Above);
if (!isUnpinned)
{
// Do error handling here
}
}
else
{
// If we ever get to this point, something went wrong or the user manually
// removed the tile from their Start screen.
Debug.WriteLine(restaurantKey + " is not currently pinned.");
}
}
According to the MSDN article: System.AppUserModel.StartPinOption (Windows), the No pin install option should be (1)
var APPUSERMODEL_STARTPINOPTION_NOPINONINSTALL = new PropVariant(1);
I got it working by doing this.

Receiving (dragged and) dropped Outlook contacts in C#?

I'm developing an application that needs to perform some processing on the user's Outlook contacts. I'm currently accessing the list of Outlook contacts by iterating over the result of MAPIFolder.Items.Restrict(somefilter), which can be found in Microsoft.Office.Interop.Outlook.
In my application, my user needs to choose several contacts to apply a certain operation on. I would like to add a feature that will allow the user to drag a contact from Outlook and drop it on a certain ListBox in the UI (I work in WPF but this is probably is more generic issue).
I'm very new to C# and WPF - how can I:
Receive a dropped item on a ListBox
Verify it's a ContactItem (or something that wraps ContactItem)
Cast the dropped item to a ContactItem so I can process it
Thanks
I tried this with a TextBox (no difference with a ListBox in practice).
Summary :
Searching in all outlook contacts for the one recieved dragged as text.
The search here is based on the person's FullName.
condition(s):
When you drag a contact, it must show the FullName when selected in outlook. The only catch is when two persons have the same full names!! If it's the case you can try to find a unique identifier for a person by combining ContactItem properties and searching them in the dragged text.
private void textBox1_DragDrop(object sender, DragEventArgs e)
{
if (e.Data.GetData("Text") != null)
{
ApplicationClass app;
MAPIFolder mapif;
string contactStr;
contactStr = e.Data.GetData("Text").ToString();
app = new ApplicationClass();
mapif = app.GetNamespace("MAPI").GetDefaultFolder(OlDefaultFolders.olFolderContacts);
foreach (ContactItem tci in mapif.Items)
{
if (contactStr.Contains(tci.FullName))
{
draggedContact = tci; //draggedContact is a global variable for example or a property...
break;
}
}
mapif = null;
app.Quit;
app = null;
GC.Collect();
}
}
of course this code is to be organized-optimized, it's only to explain the method used.
You can try using the Explorer.Selection property combined with GetData("Text") [to ensure it's coming from Outlook, or you can use GetData("Object Descriptor") in the DragOver Event, decode the memory stream, search for "outlook", if not found cancel the drag operation] And why not drag multiple contacts!
private void textBox1_DragDrop(object sender, DragEventArgs e)
{
if (e.Data.GetData("Text") != null)
{
ApplicationClass app;
Explorer exp;
List<ContactItem> draggedContacts;
string contactStr;
contactStr = e.Data.GetData("Text").ToString();
draggedContacts = new List<ContactItem>();
app = new ApplicationClass();
exp = app.ActiveExplorer();
if (exp.CurrentFolder.DefaultItemType == OlItemType.olContactItem)
{
if (exp.Selection != null)
{
foreach (ContactItem ci in exp.Selection)
{
if (contactStr.Contains(ci.FullName))
{
draggedContacts.Add(ci);
}
}
}
}
app = null;
GC.Collect();
}
}
An Outlook contact, when dropped, supports the following formats:
(0): "RenPrivateSourceFolder"
(1): "RenPrivateMessages"
(2): "FileGroupDescriptor"
(3): "FileGroupDescriptorW"
(4): "FileContents"
(5): "Object Descriptor"
(6): "System.String"
(7): "UnicodeText"
(8): "Text"
The most interesting looking one on that list (for me) is Object Descriptor, which then led me to someone with a similar sounding problem:
http://bytes.com/topic/visual-basic-net/answers/527320-drag-drop-outlook-vb-net-richtextbox
Where it looks like in that case, they detect that it's an Outlook drop, and then use the Outlook object model to detect what's currently selected, with the implication that that must be the current drop source.
What you could probably do is accept the drag and drop event in your .wpf app and then get the selected item(s) from outlook and pull them into your application.
Update
Add the Outlook PIA references to you app.
Microsoft.Office.Interop.Outlook.Application app = new Microsoft.Office.Interop.Outlook.Application();
Microsoft.Office.Interop.Outlook.Explorer activeExplorer = app.ActiveExplorer();
Microsoft.Office.Interop.Outlook.Selection currentSelection = activeExplorer.Selection;
Then you can iterate over the currentSelection collection to see what the user has dragged over.

Categories