Problems with Selecting a Gallery Image in OnActivityResult method - c#

I got 2 problems in OnActivityResult method while trying to upload image accoding to this. How can I solve them?
The full code of the class is:
public class AddNewTourActivity : Activity
{
GettingCountry gettingCountry = new GettingCountry();
private static int idOfChosenCountry, IdOfChosenCategory;
private static string status, promptMessage;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.AddNewTour);
//clearing lists
GettingCountry.listOfCountriesRoot.Clear();
GettingCountry.countriesList.Clear();
GettingCategories gc = new GettingCategories();
//Getting list of countries
gettingCountry.Fetch();
//clearing listCategoriesRoot
GettingCategories.categoriesList.Clear();
//getting categories method
gc.GetCategories();
Spinner categories_spinner = FindViewById<Spinner>(Resource.Id.categories_spinner);
Spinner countries = FindViewById<Spinner>(Resource.Id.countries);
//adapter
ArrayAdapter adapter = new ArrayAdapter<string>(this, Android.Resource.Layout.SimpleListItem1, GettingCategories.categoriesList);
ArrayAdapter adapterCountries = new ArrayAdapter<string>(this, Android.Resource.Layout.SimpleListItem1, GettingCountry.countriesList);
categories_spinner.Adapter = adapter;
countries.Adapter = adapterCountries;
countries.ItemSelected += Countries_ItemSelected;
categories_spinner.ItemSelected += Categories_spinner_ItemSelected;
//FindViewById<EditText>(Resource.Id.owner_id).Text = Login.user_id.ToString();
var title = FindViewById<EditText>(Resource.Id.title);
var image = FindViewById<ImageView>(Resource.Id.myImageView);
var location = FindViewById<EditText>(Resource.Id.location);
var description = FindViewById<EditText>(Resource.Id.description);
var price = FindViewById<EditText>(Resource.Id.price);
var min_capacity = FindViewById<EditText>(Resource.Id.min_capacity);
var max_capacity = FindViewById<EditText>(Resource.Id.max_capacity);
var duration = FindViewById<EditText>(Resource.Id.duration);
var meet_place_address = FindViewById<EditText>(Resource.Id.meet_place_address);
var meet_place_city = FindViewById<EditText>(Resource.Id.meet_place_city);
var lat = FindViewById<EditText>(Resource.Id.lat);
var lng = FindViewById<EditText>(Resource.Id.lng);
//uploading image
image.Click += Image_Click;
//uploading image ENDED
FindViewById<Button>(Resource.Id.add_tour_button).Click += delegate
{
//setting prompt message empty
promptMessage = "";
var client = new RestClient("http://api.locopal.com");
var request = new RestRequest("/experience", Method.POST);
//CHECKING THE CORRECTNESS OF THE USER'S INTRODUCTION TO ALL FIELDS
if (title.Text.Length < 3)
{
promptMessage += " Title must have at least 3 symbols.\n";
}
if (location.Text.Length < 3)
{
promptMessage += " Location must have at least 3 symbols.\n";
}
if (description.Text.Length < 30)
{
promptMessage += " Description length must be at least 30 symbols.\n";
}
//checking if price, capacity, etc... are integer values
int res;
bool priceIsInt = false;
priceIsInt = Int32.TryParse(price.Text, out res);
if (priceIsInt == false)
{
promptMessage += " Price must be an integer value.\n";
}
bool minCapacityIsInt = false;
minCapacityIsInt = Int32.TryParse(min_capacity.Text, out res);
if (minCapacityIsInt == false)
{
promptMessage += " Minimum capacity must be an integer value.\n";
}
bool maxCapacityIsInt = false;
maxCapacityIsInt = Int32.TryParse(max_capacity.Text, out res);
if (maxCapacityIsInt == false)
{
promptMessage += " Maximum capacity must be an integer value.\n";
}
bool durationIsInt = false;
durationIsInt = Int32.TryParse(duration.Text, out res);
if (durationIsInt == false)
{
promptMessage += " Duration must be an integer value.\n";
}
//checking if price, capacity, etc... are integer values ENDED
if (meet_place_address.Text.Length < 3)
{
promptMessage += " Address of meeting place must have at least 3 symbols.\n";
}
if (meet_place_city.Text.Length < 3)
{
promptMessage += " City of meeting place must have at least 3 symbols.\n";
}
//checking if lat and lng are doubles
double resDouble;
bool latIsDouble = false;
latIsDouble = Double.TryParse(lat.Text, out resDouble);
if (latIsDouble == false)
{
promptMessage += " Latitude must be a fractional value.\n";
}
bool lngIsDouble = false;
lngIsDouble = Double.TryParse(lng.Text, out resDouble);
if (lngIsDouble == false)
{
promptMessage += " Longitude must be a fractional value.";
}
//checking if lat and lng are doubles ENDED
//CHECKING THE CORRECTNESS OF THE USER'S INTRODUCTION TO ALL FIELDS ENDED
request.AddParameter("api_token", Login.token);
request.AddParameter("title", title.Text);
request.AddParameter("location", location.Text);
request.AddParameter("description", description.Text);
request.AddParameter("price", price.Text);
request.AddParameter("owner_id", Login.user_id);
request.AddParameter("min_capacity", min_capacity.Text);
request.AddParameter("max_capacity", max_capacity.Text);
request.AddParameter("duration", duration.Text);
request.AddParameter("duration_type", 1);
request.AddParameter("meet_place_address", meet_place_address.Text);
request.AddParameter("meet_place_city", meet_place_city.Text);
request.AddParameter("meet_place_country", idOfChosenCountry);
request.AddParameter("category_list[0]", IdOfChosenCategory);
request.AddParameter("lat", lat.Text);
request.AddParameter("lng", lng.Text);
try
{
IRestResponse response = client.Execute(request);
var content = response.Content;
var myContent = JObject.Parse(content);
status = myContent["status"].ToString();
}
catch { }
if (status == "success")
{
Toast.MakeText(this, "Tour added successfully", ToastLength.Short).Show();
//setting status variable to null to prevent issues with adding new places in future
status = null;
StartActivity(typeof(MainActivity));
}
else
{
Toast.MakeText(this, promptMessage, ToastLength.Long).Show();
}
};
}
private void Image_Click(object sender, EventArgs e)
{
var imageIntent = new Intent();
imageIntent.SetType("image/*");
imageIntent.SetAction(Intent.ActionGetContent);
StartActivityForResult(
Intent.CreateChooser(imageIntent, "Select photo"), 0);
}
private void Categories_spinner_ItemSelected(object sender, AdapterView.ItemSelectedEventArgs e)
{
IdOfChosenCategory = e.Position;
}
private void Countries_ItemSelected(object sender, AdapterView.ItemSelectedEventArgs e)
{
idOfChosenCountry = gettingCountry.retrievingChoosenCountryId(GettingCountry.countriesList[e.Position].ToString());
}
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
if (resultCode == Result.Ok)
{
var imageView = FindViewById<ImageView>(Resource.Id.myImageView);
imageView.SetImageURI(data.Data);
}
}
}

I changed the namespace from RecyclerViewSample to RecyclerViewSampl. I deleted only one letter. Then I added full path RecyclerViewSample.Resource.Id.min_capacity as an example to all elements of previous namespace.
For example:
SetContentView(RecyclerViewSample.Resource.Layout.AddNewTour);
In another classes I did analogical references to this new namespace.
Such as:
StartActivity(new Intent(this, typeof(RecyclerViewSampl.AddNewTourActivity)));

Related

Updating app to support Android API 33 and OnActivityResult always retuns a resultcode of Result.Cancelled

I'm updating a working app that targeted API 9 (Pie) to API 33 (Tiramisu) and the camera always returns Result.Cancelled to the OnActivityResult code. I'm using Visual Studio 2022 Version 17.3.6 on a Windows 11 pro machine. This is my camera code:
camerabutton.Click += (sender, evt) =>
{
var cameraispresent = checkCameraHardware(this);
if (cameraispresent)
{
try
{
CreateDirectoryForPictures();
MySubjectInfo.Name = MySubjectInfo.Name.Replace(",", "");
MySubjectInfo.Name = MySubjectInfo.Name.Replace(" ", "");
MySubjectInfo.Name = MySubjectInfo.Name.Replace(".", "");
var filename = MySubjectInfo.Name + ".jpg";
Intent intent = new Intent(MediaStore.ActionImageCapture);
App._file = new File(App._dir, String.Format(filename, Guid.NewGuid()));
intent.PutExtra(MediaStore.ExtraOutput, Uri.FromFile(App._file));
StartActivityForResult(intent, TakePictureRequestCode);
}
catch (Exception e)
{
var result = e.Message;
};
}
};
The create directory code, this code was also updated to reflect changes in API 33, however I can't find the folder on my test device via file explorer where the photos should be stored yet App._dir.Exists() returns true saying it's there:
private void CreateDirectoryForPictures()
{
int version = (int)Android.OS.Build.VERSION.SdkInt;
var root = "";
if (Android.OS.Environment.IsExternalStorageEmulated)
{
root = Android.OS.Environment.ExternalStorageDirectory.ToString();
}
else
{
root = System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyPictures);
}
if (version >= Convert.ToInt32(BuildVersionCodes.Q))
{
App._dir = new File(root + "/PhotoManager");
}
else
{
App._dir = new File(
Environment.GetExternalStoragePublicDirectory(
Environment.DirectoryPictures), "PhotoManager");
}
if (!App._dir.Exists())
{
App._dir.Mkdirs();
}
}
This is the app class where I store the data:
public static class App
{
public static File _file;
public static File _dir;
public static Bitmap bitmap;
}
This is the OnActivityResult1 code, I left my API 9 code in there commented out so you can see where I was and where I'm going. With API 9 I needed to resize the picture to scale it down to 160 X 100 as these photos are used for ID cards, I commented that code out until I can figure out why the camera intent is returning null:
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
if (requestCode == TakePictureRequestCode && resultCode == Result.Ok)
{
//Intent mediaScanIntent = new Intent(Intent.ActionMediaScannerScanFile);
//Uri contentUri = Uri.FromFile(App._file);
//mediaScanIntent.SetData(contentUri);
//SendBroadcast(mediaScanIntent);
Bitmap photo = (Bitmap)data.GetByteArrayExtra("data");
App.bitmap = photo;
//int height = 160; //Resources.DisplayMetrics.HeightPixels;
//int width = 100; //MyImageView.Height;
//App.bitmap = App._file.Path.LoadAndResizeBitmap(width, height);
if (App.bitmap != null)
{
MyImageView.SetImageBitmap(App.bitmap);
Bitmap bitmap = App.bitmap;
var filePath = App._file.AbsolutePath;
var stream = new System.IO.FileStream(filePath, System.IO.FileMode.Create);
bitmap.Compress(Bitmap.CompressFormat.Jpeg, 100, stream);
stream.Close();
bitmap = null;
App.bitmap = null;
PictureTaken = true;
}
// Dispose of the Java side bitmap.
GC.Collect();
}
}
So what am I doing wrong?
You cannot use Uri.FromFile anymore since Android 7.
Use FileProvider to serve a writable uri for the camera app.
Example: EnsureBluetoothEnabled called from a permission request
Setup
activityResultCallback = new ActivityResultCallback();
activityResultCallback.OnActivityResultCalled += ActivityResultCallback_ActivityResultCalled;
activityResultLauncher = RegisterForActivityResult(new ActivityResultContracts.StartActivityForResult(), activityResultCallback);
private void EnsureBluetoothEnabled()
{
if ((bluetoothAdapter != null) && (!bluetoothAdapter.IsEnabled))
activityResultLauncher.Launch(new Intent(BluetoothAdapter.ActionRequestEnable));
}
Handler:
private void ActivityResultCallback_ActivityResultCalled(object sender, ActivityResult result)
{
if (result.ResultCode == (int)Result.Ok)
{
if (bluetoothAdapter.State == State.On)
ShowBluetoothConfirmationDialog(true);
}
else if (result.ResultCode == (int)Result.Canceled)
ShowBluetoothConfirmationDialog(false);
}
ActivityResultCallback class
public class ActivityResultCallback : Java.Lang.Object, IActivityResultCallback
{
public EventHandler<ActivityResult> OnActivityResultCalled;
public void OnActivityResult(Java.Lang.Object result)
{
ActivityResult activityResult = result as ActivityResult;
OnActivityResultCalled?.Invoke(this, activityResult);
}
}

ReceiveDetections Method is Calling Multiple Times

I am scanning QR CODE but the problem is ReceiveDetections method is calling multiple times even after a successful scan.How can I prevent calling the api multiple times after a successful call.
here is the code snippet
public void ReceiveDetections(Detections detections)
{
SparseArray qrcodes = detections.DetectedItems;
if (qrcodes.Size() != 0)
{
txtscankanbancloseResult.Post(async () =>
{
Vibrator vibrator = (Vibrator)GetSystemService(Context.VibratorService);
vibrator.Vibrate(1000);
txtscankanbancloseResult.Text = ((Barcode)qrcodes.ValueAt(0)).RawValue;
try
{
var client = new HttpClient();
var uri = new Uri(string.Format(AppStatics.clsStatic.url + "//Kanban/SaveKanbanStatus"));
List<string> lstskanban = new List<string>();
String myDate = DateTime.Now.ToString("dd-MMM-yyyy");
string adateddate = DateTime.Now.ToString("dd-MMM-yyyy hh:mm:ss");
JsonScankanbanclose objjscan = new JsonScankanbanclose();
lstskanban.Add(txtscankanbancloseResult.Text);
objjscan.UpdateBy = SingletonSession.Instance().getUsername();
objjscan.KANBANNOList = lstskanban;
objjscan.IsKANBANClosed = true;
string jsonData = JsonConvert.SerializeObject(objjscan);
var content = new StringContent(jsonData, Encoding.UTF8, "application/json");
HttpResponseMessage response = await client.PostAsync(uri, content);
var result = await response.Content.ReadAsStringAsync();
if (response.ReasonPhrase == "OK")
{
JArray scanresult = JArray.Parse(result);
Scanlist objscan = new Scanlist();
if (ScanSucessfull.Count == 0)
{
objscan.KanbanID = "Kanban NO";
objscan.KanbanQty = "Kanban Qty";
ScanSucessfull.Add(objscan);
objscan = new Scanlist();
}
// Scanlist item = ScanSucessfull.Find(c => c.KanbanID == scanresult[0]["KANBANID"].ToString());
//int itemPosition = ScanSucessfull.BinarySearch(scanresult[0]["KANBANID"].ToString());
//if (itemPosition.cou=="")
//{
objscan.KanbanID = scanresult[0]["KANBANNumber"].ToString();
objscan.KanbanQty = scanresult[0]["Qty"].ToString();
ScanSucessfull.Add(objscan);
//}
var adapter = new CustomAdapterScan(this, ScanSucessfull);
lstviewscankanbanclose.SetAdapter(adapter);
lstviewscankanbanclose.Clickable = false;
//lstview.Enabled = false;
lstviewscankanbanclose.ItemSelected += null;
mPlayer = Android.Media.MediaPlayer.Create(this, Resource.Raw.successful);
currentSong = Resource.Raw.successful;
mPlayer.SeekTo(1);
mPlayer.Start();
//Toast.MakeText(this, , ToastLength.Short).Show();
Helper.ShowToastMessage(this, Color.DarkGreen, "Data Save Sucessfully..", ToastLength.Short);
_kanbancount++;
txtscankanbanclosekanbancount.Text = "Kanban Count:" + " " + _kanbancount;
txtscankanbanclosekanbancount.Visibility = ViewStates.Visible;
}
else
{
string[] result1 = result.Split(':');
string[] result2 = result1[1].Split('"');
string[] result3 = result2[1].Split('"');
mPlayer = Android.Media.MediaPlayer.Create(this, Resource.Raw.fail);
// mPlayer.SeekTo(2);
currentSong = Resource.Raw.fail;
mPlayer.Start();
//Toast.MakeText(this, result3[0].ToString(), ToastLength.Short).Show();
Helper.ShowToastMessage(this, Color.DarkRed, result3[0].ToString(), ToastLength.Short);
}
// dialog.Hide();
cameraSource.Start(surfaceView.Holder);
//txtResult.Text = "";
}
catch (System.Exception ex)
{
Helper.ShowToastMessage(this, Color.DarkRed, ex.Message, ToastLength.Short);
//Toast.MakeText(this, ex.Message.ToString(), ToastLength.Short).Show();
// txtResult.Text = "";
txtscankanbancloseResult.Visibility = ViewStates.Invisible;
//cameraSource.Start(surfaceView.Holder);
}
});
using (var h = new Handler(Looper.MainLooper))
h.Post(() =>
{
cameraSource.Stop();
// Toast.MakeText(this, "This Kanban Already Scanned....", ToastLength.Short).Show();
});
}
}
Here is the code where I crate and open the camera source to scan the QR code
private void btnkanbanscan_Click(object sender, EventArgs e)
{
try
{
#region validation
if (spnSiteID.SelectedItemPosition < 0)
{
throw new Exception("Please Select Site...");
}
if (spnLocation.SelectedItemPosition < 0)
{
throw new Exception("Please Select Location..");
}
if (spnInspactionType.SelectedItemPosition < 0)
{
throw new Exception("Please Select Inspection Type..");
}
#endregion
LayoutInflater layoutInflater = LayoutInflater.From(this);
View scanview = LayoutInflater.Inflate(Resource.Layout.scan_popup, null);
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.SetView(scanview);
surfaceView = scanview.FindViewById<SurfaceView>(Resource.Id.spvscan);
dialog = alertDialogBuilder.Create();
dialog.SetCanceledOnTouchOutside(false);
dialog.Show();
barcodeDetector = new BarcodeDetector.Builder(this)
.SetBarcodeFormats(BarcodeFormat.Code128 | BarcodeFormat.QrCode)
.Build();
cameraSource = new CameraSource.Builder(this, barcodeDetector)
.SetRequestedPreviewSize(480, 480)
.SetAutoFocusEnabled(true)
.Build();
surfaceView.Holder.AddCallback(this);
barcodeDetector.SetProcessor(this);
surfaceView.Visibility = ViewStates.Visible;
_definemethod = "KANBAN";
}
catch (Exception ex)
{
Helper.ShowToastMessage(this, Color.DarkRed, ex.Message, ToastLength.Short);
//Toast.MakeText(this, ex.Message.ToString(), ToastLength.Short).Show();
}
}
NCTB: I noticed that after opening the dialog to scan the QR CODE the ReceiveDetections method get called frequently and the scanned value comes in detections parameter .which is normal and it supposed to do so.But the problem is after a successful scan it should not call anymore.

C# and ArcMaps: How do i pass ui inputs to background thread without getting SERVERFAULT?

I'm helping a colleague debug a tool he is creating for ArcGis. It is used to create Replicas, and is done through selecting some different inputs from dropdowns in a winform.
The issue is that when running all the code on the UI-thread, our ui freezes. This is what he wants me to solve. The code causing this is the following, the relevant code is just the button1_Click_1() method, but i provided the second class for contex:
public partial class FrmReplicaAdmin : Form
{
private void button1_Click_1(object sender, EventArgs e)
{
DataConnectionConfig selectedDatabase = cmboxDatabase.SelectedItem as DataConnectionConfig;
if (selectedDatabase.PlWorkspace == null)
{
statusLabel.Text = "Could not open GeoDatabase (PL)";
return;
}
if (selectedDatabase.DataWorkspace == null)
{
statusLabel.Text = "Could not open GeoDatabase (NIS)";
return;
}
int scaleBand = int.Parse(cmboxScale.SelectedItem.ToString());
string gridName = cmboxGridNr.SelectedItem as string;
IGeometry shapeOfSelectedAOI = getSelectedPolygon(gridName, scaleBand, selectedDatabase);
(ArcMap.Application as IMxApplication2).PauseDrawing = true;
replica.CheckOutReplica(selectedDatabase.PlWorkspace, selectedDatabase.DataWorkspace, selectedDatabase.TemplateGdb, gridName, scaleBand, shapeOfSelectedAOI, selectedDatabase.DatasetName);
(ArcMap.Application as IMxApplication2).PauseDrawing = false;
}
}
public class Replica
{
public void CheckOutReplica(IWorkspace plWorkspace, IWorkspace parentWorkspace, string pathToDatabaseTemplate, string gridName, int scaleBand, IGeometry shapeOfSelectedAOI, string datasetName = "NIS.Nautical")
{
try
{
string replicaName = string.Format("{0}_{1}_r", Environment.UserName, gridName);
string versionName = string.Format("{0}_{1}", Environment.UserName, gridName);
string pathToLocalChildDatabase = System.IO.Path.Combine(ReplicationPath, $"{replicaName}.gdb");
Directory.CreateDirectory(pathToLocalChildDatabase);
foreach (string newPath in Directory.GetFiles(pathToDatabaseTemplate, "*.*", SearchOption.AllDirectories))
File.Copy(newPath, newPath.Replace(pathToDatabaseTemplate, pathToLocalChildDatabase), true);
IWorkspace childWorkspace = OpenWorkspace(pathToLocalChildDatabase);
// Create Version in ParentDatabase
IEnumVersionInfo versionEnum = (parentWorkspace as IVersionedWorkspace).Versions;
versionEnum.Reset();
for (IVersionInfo versionInfo = versionEnum.Next(); versionInfo != null; versionInfo = versionEnum.Next())
{
if (versionInfo.VersionName.EndsWith(versionName))
{
System.Windows.Forms.MessageBox.Show("A version named '" + versionName + "' has already been created", "map...", System.Windows.Forms.MessageBoxButtons.OK);
return;
}
}
Marshal.ReleaseComObject(versionEnum);
IVersion newVersion = (parentWorkspace as IVersionedWorkspace).DefaultVersion.CreateVersion(versionName);
newVersion.Access = esriVersionAccess.esriVersionAccessPublic;
string defQuery = "((IS_CONFLATE=1 AND PLTS_COMP_SCALE >= " + scaleBand + ") OR ((IS_CONFLATE=0 OR IS_CONFLATE IS NULL) AND PLTS_COMP_SCALE = " + scaleBand + "))";
ReplicateData(parentWorkspace, newVersion.VersionInfo, replicaName, shapeOfSelectedAOI, childWorkspace, defQuery, datasetName);
// Update map. Show replica data
ILayerFile nauticalLyrFile = new LayerFileClass();
nauticalLyrFile.Open(ReplicationPath + #"\Nautical.lyr");
AddDataToMap((ArcMap.Application.Document as IMxDocument), childWorkspace as IFeatureWorkspace, nauticalLyrFile, gridName, datasetName);
(ArcMap.Application.Document as IMxDocument).ActiveView.Extent = shapeOfSelectedAOI.Envelope;
Marshal.ReleaseComObject(childWorkspace);
}
catch (Exception err)
{
System.Windows.Forms.MessageBox.Show($"Unexpected error. {Environment.NewLine}{err.Message}", "map...", System.Windows.Forms.MessageBoxButtons.OK);
}
}
}
private void ReplicateData(IWorkspace parentWorkspace, IVersionInfo versionInfo, string replicaName, IGeometry area, IWorkspace childWorkspace, string definitionQuery, string featureDataset)
{
if (childWorkspace == null)
throw new ArgumentNullException("Child workspace is null.");
if (parentWorkspace == null)
throw new ArgumentNullException("Parent workspace is null.");
if (versionInfo == null)
throw new ArgumentNullException("Version name is null.");
if (string.IsNullOrEmpty(replicaName))
throw new ArgumentNullException("Replica name is null.");
if (area == null)
throw new ArgumentNullException("Area geometry is null.");
IVersion oVersion = (parentWorkspace as IVersionedWorkspace).FindVersion(versionInfo.VersionName);
IWorkspace sdeVersionWorkspace = oVersion as IWorkspace;
IGeoDataServer parentGds = InitGeoDataServer(sdeVersionWorkspace),
childGds = InitGeoDataServer(childWorkspace);
CreateFeatureDatasetReplica(parentGds, childGds, versionInfo, replicaName, parentWorkspace, childWorkspace, area, definitionQuery, featureDataset);
Marshal.ReleaseComObject(parentGds);
Marshal.ReleaseComObject(childGds);
}
//Function to create the replica, based on this link http://help.arcgis.com/en/sdk/10.0/arcobjects_net/conceptualhelp/index.html#//0001000003r5000000
private void CreateFeatureDatasetReplica(IGeoDataServer parentGDS, IGeoDataServer childGDS, IVersionInfo versionInfo, string replicaName, IWorkspace parentWorkspace, IWorkspace childWorkspace, IGeometry geometry, string definitionQuery, string featureDatasetName)
{
IList<string> existingReplicas = ReadExistingReplicas(parentGDS);
if (existingReplicas.Contains(replicaName.ToUpper()))
{
throw new Exception("A replica with the following name has already been created: " + replicaName);
}
IEnumDataset datasets = null;
if (!string.IsNullOrEmpty(featureDatasetName))
{
IEnumDataset featureDatasets = parentWorkspace.get_Datasets(esriDatasetType.esriDTFeatureDataset);
IFeatureDataset featureDataset;
while ((featureDataset = featureDatasets.Next() as IFeatureDataset) != null)
{
if (featureDataset.Name == featureDatasetName)
{
datasets = featureDataset.Subsets;
break;
}
}
if (datasets == null)
throw new Exception("Didn't find FeatureDataset " + featureDatasetName + " in the db");
}
else
{
datasets = parentWorkspace.get_Datasets(esriDatasetType.esriDTFeatureClass);
}
IGPReplicaDatasets gpReplicaDatasets = new GPReplicaDatasetsClass();
IDataset dataset;
while ((dataset = datasets.Next()) != null)
{
//temporary workaround to not include a view that is on the feature classes :^)
if (dataset.Name.Contains("VW_") || dataset.Name.Contains("_EVW"))
continue;
if (m_ListExcludedTables.Contains(dataset.Name.Substring(dataset.Name.LastIndexOf(".") + 1).ToUpper()))
continue;
if (!(childWorkspace as IWorkspace2).NameExists[dataset.Type, dataset.Name.Substring(dataset.Name.LastIndexOf(".") + 1)])
continue;
IGPReplicaDataset gpReplicaDataset = new GPReplicaDatasetClass();
gpReplicaDataset.DatasetType = dataset.Type;
gpReplicaDataset.Name = dataset.Name.ToUpper();
gpReplicaDataset.IsPrivate = false;
gpReplicaDataset.UseGeometry = true;
gpReplicaDataset.RowsType = esriRowsType.esriRowsTypeFilter;
if ((dataset as ITable).Fields.FindField("PLTS_COMP_SCALE") != -1)
gpReplicaDataset.DefQuery = definitionQuery; //DefQuery here
else
gpReplicaDataset.DefQuery = "";
gpReplicaDatasets.Add(gpReplicaDataset);
}
IGPReplicaDescription gpReplicaDesc = new GPReplicaDescriptionClass();
gpReplicaDesc.QueryGeometry = geometry;
gpReplicaDesc.SpatialRelation = esriSpatialRelEnum.esriSpatialRelIntersects;
gpReplicaDesc.ModelType = esriReplicaModelType.esriModelTypeSimple;
gpReplicaDesc.SingleGeneration = true;
gpReplicaDesc.ReplicaDatasets = gpReplicaDatasets;
IGPReplicaOptions2 replicaOptions = new GPReplicaOptionsClass();
replicaOptions.AccessType = esriReplicaAccessType.esriReplicaAccessNone;
replicaOptions.RegisterReplicaOnly = true;
ExtractData(datasets, childWorkspace, geometry, definitionQuery);
IReplicationAgent replicationAgent = new ReplicationAgentClass();
replicationAgent.CreateReplica(versionInfo.VersionName, parentGDS, childGDS, replicaName, gpReplicaDesc, replicaOptions);
}
}
For fixing the UI freeze i made the following changes to the button1_Click_1() method:
public partial class FrmReplicaAdmin : Form
{
private void button1_Click_1(object sender, EventArgs e)
{
DataConnectionConfig selectedDatabase = cmboxDatabase.SelectedItem as DataConnectionConfig;
if (selectedDatabase.PlWorkspace == null)
{
statusLabel.Text = "Could not open GeoDatabase (PL)";
return;
}
if (selectedDatabase.DataWorkspace == null)
{
statusLabel.Text = "Could not open GeoDatabase (NIS)";
return;
}
int scaleBand = int.Parse(cmboxScale.SelectedItem.ToString());
string gridName = cmboxGridNr.SelectedItem as string;
IGeometry shapeOfSelectedAOI = getSelectedPolygon(gridName, scaleBand, selectedDatabase);
// adding inputs to list i can pass onto the backgroundWorker
List<object> arguments = new List<object>();
arguments.Add(selectedDatabase.PlWorkspace);
arguments.Add(selectedDatabase.DataWorkspace);
arguments.Add(selectedDatabase.TemplateGdb);
arguments.Add(gridName);
arguments.Add(scaleBand);
arguments.Add(shapeOfSelectedAOI);
arguments.Add(selectedDatabase.DatasetName);
backgroundWorker1.RunWorkerAsync(arguments);
// starting progress bar
progressBarReplica.Visible = true;
lblReplica.Text = "Checking out replica...";
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
List<object> genericlist = e.Argument as List<object>;
IWorkspace ws = (IWorkspace)genericlist[0];
IWorkspace pWs = (IWorkspace)genericlist[1];
string pathToDbTemplate = genericlist[2].ToString();
string gName = genericlist[3].ToString();
int sBand = (int)genericlist[4];
IGeometry shape = (IGeometry)genericlist[5];
string dsName = genericlist[6].ToString();
(ArcMap.Application as IMxApplication2).PauseDrawing = true;
replica.CheckOutReplica(ws, pWs, pathToDbTemplate, gName, sBand, shape, dsName);
(ArcMap.Application as IMxApplication2).PauseDrawing = false;
}
}
This is causing a: "RPC_E_SERVERFAULT(0X80010105)", but the UI isn't freezing anymore. My guess is that it's because i'm initiating the database in the first thread, and then using it in the second. I also sort of get that i can't use a backgroundWorker due to the entire STA and COM-object things with ArcGis, but i'm still not getting all this 100%.
Any help of a possible solution to making my UI responsive, or at least showing some sort of progressbar while the task is running would be nice. The entire process can take a few minutes at times, and the program feels like it's crashed meanwhile due to the freeze.
Edit: I'm referring to ArcMap, forgot to mention that.

How to get current country location and possibly the CountryCode from a Windows Phone 8.1

How to get current country location and possibly the CountryCode from a Windows Phone 8.1? I did this, but FindLocationsAsync throws me an exception "Value does not fall within the expected range"
private async void LocateMe()
{
Geolocator GeoLoc = new Geolocator();
GeoLoc.DesiredAccuracyInMeters = 50;
try
{
Geoposition GeoPosition = await GeoLoc.GetGeopositionAsync();
MapLocationFinderResult result = await MapLocationFinder.FindLocationsAsync("", GeoPosition.Coordinate.Point, 5);
if (result.Status == MapLocationFinderStatus.Success)
{
foreach (MapLocation mapLocation in result.Locations)
{
string strCountryCode = mapLocation.Address.CountryCode;
}
}
}
catch(Exception e)
{
System.Diagnostics.Debug.WriteLine(e.Message);
}
}
Its called reverse geolocation try this
var geolocator = new Geolocator();
geolocator.DesiredAccuracyInMeters = 100;
Geoposition position = await geolocator.GetGeopositionAsync();
//reverse geocoding
BasicGeoposition myLocation = new BasicGeoposition
{
Longitude = position.Coordinate.Longitude,
Latitude = position.Coordinate.Latitude
};
Geopoint pointToReverseGeocode = new Geopoint(myLocation);
MapLocationFinderResult result = await MapLocationFinder.FindLocationsAtAsync(pointToReverseGeocode);
//here also it should be checked if there result isn't null and what to do in such a case
string country = result.Locations[0].Address.Region;
You should try this .. I declare Map_Tapped event
private async void
private async void mapNearByUser_MapTapped(Windows.UI.Xaml.Controls.Maps.MapControl sender, Windows.UI.Xaml.Controls.Maps.MapInputEventArgs args)
{
//Your Map Tapped
Geopoint pointToReverseGeocode = new Geopoint(args.Location.Position);
// Reverse geocode the specified geographic location.
MapLocationFinderResult result =
await MapLocationFinder.FindLocationsAtAsync(pointToReverseGeocode);
var resultText = new StringBuilder();
try
{
if (result.Status == MapLocationFinderStatus.Success)
{
resultText.AppendLine(result.Locations[0].Address.District + ", " + result.Locations[0].Address.Town + ", " + result.Locations[0].Address.Country);
}
MessageBox(resultText.ToString());
}
catch
{
//MessageBox(resultText.ToString());
MessageBox("Please wait..");
}
}
mapNearByUser_MapTapped(Windows.UI.Xaml.Controls.Maps.MapControl sender, Windows.UI.Xaml.Controls.Maps.MapInputEventArgs args)
{
//Your Map Tapped
Geopoint pointToReverseGeocode = new Geopoint(args.Location.Position);
// Reverse geocode the specified geographic location.
MapLocationFinderResult result =
await MapLocationFinder.FindLocationsAtAsync(pointToReverseGeocode);
var resultText = new StringBuilder();
try
{
if (result.Status == MapLocationFinderStatus.Success)
{
resultText.AppendLine(result.Locations[0].Address.District + ", " + result.Locations[0].Address.Town + ", " + result.Locations[0].Address.Country);
}
MessageBox(resultText.ToString());
}
catch
{
//MessageBox(resultText.ToString());
MessageBox("Please wait..");
}
}

How to deal with multiple EventHandlers to AsyncQuery

I am working on Windows Phone 8 project. In my project there are 10 Events with 10 EventHandlers ReverseGeocodeQuery_QueryCompleted (1 to 10). When first EventHandler is completed it turn on second event.
What should I implement to manage those Events without so much code.
code
myReverseGeocodeQuery = new ReverseGeocodeQuery();
myReverseGeocodeQuery.GeoCoordinate = mySimulationCoordinates.ElementAt(0);
myReverseGeocodeQuery.QueryCompleted += ReverseGeocodeQuery_QueryCompleted_1;
myReverseGeocodeQuery.QueryAsync();
private void ReverseGeocodeQuery_QueryCompleted_1(object sender, QueryCompletedEventArgs<IList<MapLocation>> e)
{
if (e.Error == null)
{
if (e.Result.Count > 0)
{
MapAddress address = e.Result[0].Information.Address;
label8txt.Text = address.City.ToString() + "\n" + address.Street.ToString();
StringBuilder str = new StringBuilder();
str.AppendLine("Pierwszy");
str.AppendLine("11" + address.HouseNumber);
str.AppendLine("17" + address.Street);
MessageBox.Show(str.ToString());
}
myReverseGeocodeQuery = new ReverseGeocodeQuery();
myReverseGeocodeQuery.GeoCoordinate = mySimulationCoordinates.ElementAt(1);
myReverseGeocodeQuery.QueryCompleted += ReverseGeocodeQuery_QueryCompleted_2;
myReverseGeocodeQuery.QueryAsync();
}
}
private void ReverseGeocodeQuery_QueryCompleted_2(object sender, QueryCompletedEventArgs<IList<MapLocation>> e)
{
if (e.Error == null)
{
if (e.Result.Count > 0)
{
MapAddress address = e.Result[0].Information.Address;
label8txt.Text = address.City.ToString() + "\n" + address.Street.ToString();
StringBuilder str = new StringBuilder();
str.AppendLine("Drugi");
str.AppendLine("11" + address.HouseNumber);
str.AppendLine("17" + address.Street);
MessageBox.Show(str.ToString());
myReverseGeocodeQuery = new ReverseGeocodeQuery();
myReverseGeocodeQuery.GeoCoordinate = mySimulationCoordinates.ElementAt(2);
myReverseGeocodeQuery.QueryCompleted += ReverseGeocodeQuery_QueryCompleted_3;
myReverseGeocodeQuery.QueryAsync();
}
}
}
Example Solution 1
public class DataContainer
{
public string Description { get; set; }
public GeoCoordinate Coordinate { get; set; }
//public List<GeoCoordinate> mySimulationCoordinates { get; set; }
public String EnterSimulation() {
StringBuilder strRet = new StringBuilder();
List<GeoCoordinate> mySimulationCoordinates = new List<GeoCoordinate>();
mySimulationCoordinates.Add(new GeoCoordinate(51.760752, 19.458216));
mySimulationCoordinates.Add(new GeoCoordinate(51.760757, 19.458356));
mySimulationCoordinates.Add(new GeoCoordinate(51.760738, 19.458442));
mySimulationCoordinates.Add(new GeoCoordinate(51.7607, 19.458501));
mySimulationCoordinates.Add(new GeoCoordinate(51.760662, 19.458533));
var descriptions = new[] { "Pierwszy", "Drugi", "Trzeci", "Czwarty", "PiÄ…ty" }; //etc
var zipped = mySimulationCoordinates.Zip(descriptions, (coord, desc) => new DataContainer { Description = desc, Coordinate = coord });
int k = zipped.Count();
foreach (var item in zipped)
{
var currentItem = item;
using (var waitHandle = new AutoResetEvent(false))
{
var geocodeQuery = new ReverseGeocodeQuery();
geocodeQuery.GeoCoordinate = item.Coordinate;
geocodeQuery.QueryCompleted += (sender, args) =>
{
if (args.Error == null)
{
if (args.Result.Count > 0)
{
MapAddress address = args.Result[0].Information.Address;
//label8txt.Text = address.City.ToString() + "\n" + address.Street.ToString();
StringBuilder str = new StringBuilder();
str.AppendLine(currentItem.Description);
str.AppendLine("House Number" + address.HouseNumber);
str.AppendLine("Street " + address.Street);
strRet.AppendLine("->");
strRet.Append(str);
waitHandle.Set();
}
}
};
geocodeQuery.QueryAsync();
waitHandle.WaitOne();
}
}
return strRet.ToString();
}
It stuck on 1st item. Is inside and wait ... wait ... can't pass to next element.
Umm... Let's see, shouldn't that be easier?
Warning: untested
public class DataContainer
{
public string Description {get;set;}
public GeoCoordinate Coordinate {get;set;}
}
var descriptions = new[] {"Pierwszy" , "Drugi" , "Trzeci" }; //etc
var zipped = mySimulationCoordinates.Zip(descriptions, (coord, desc) => new DataContainer { Description = desc, Coordinate = coord });
foreach(var item in zipped)
{
var currentItem = item;
using(var waitHandle = new AutoResetEvent(false))
{
var geocodeQuery = new ReverseGeocodeQuery();
geocodeQuery.GeoCoordinate = currentItem.Coordinates;
geocodeQuery.QueryCompleted += (sender, args) => {
if (e.Error == null)
{
if (e.Result.Count > 0)
{
MapAddress address = args.Result[0].Information.Address;
label8txt.Text = address.City.ToString() + "\n" + address.Street.ToString();
StringBuilder str = new StringBuilder();
str.AppendLine(currentItem.Description);
str.AppendLine("11" + address.HouseNumber);
str.AppendLine("17" + address.Street);
MessageBox.Show(str.ToString());
waitHandle.Set();
}
}
};
geoCodeQuery.QueryAsync();
waitHandle.WaitOne();
}
}
That should guarantee you that one event is handled after another in order.

Categories

Resources