S. Koshelnyk
S. Koshelnyk

Reputation: 506

How to start Activity from another project

I`m working at weather application for android and windows-phone. So I write common code in another project in "Weather.Api(Portable)" in "Parsing Class". "Weather.Droid" is used for Android.image

The code of ParsingClass is following:

    public static string tempGlobal;
    public static string cityTextGlobal;
    private static string GovnoTemperature;

    public async  Task<string> dataByCity(string city)
    {
        var url = "http://api.openweathermap.org/data/2.5/weather?q=" + city + "&units=metric&APPID="+AppID;

        //ТОРМОЗИТ ЗДЕСЬ / BRAKES HERE
        await FetchAsync(url);
        return city;
    }

    public async Task<double> Data_down(double lat, double lon)
    {

        var url = String.Format(
          "http://api.openweathermap.org/data/2.5/weather?lat=" + lat + "&lon=" + lon + "&units=metric&APPID=" + AppID);

        //ТОРМОЗИТ ЗДЕСЬ / BRAKES HERE
        await FetchAsync(url);

        return lat;
    }

    public async Task<string> FetchAsync(string url)
    {
        string jsonString;

        using (var httpClient = new System.Net.Http.HttpClient())
        {
            var stream = await httpClient.GetStreamAsync(url);
            StreamReader reader = new StreamReader(stream);
            jsonString = reader.ReadToEnd();
        }

        var json = jsonString;

        JsonValue firstitem = json;
        var mydata = JObject.Parse(json);

        cityTextGlobal = (mydata["name"]).ToString();

        string GovnoData = (mydata["main"]).ToString();

        //spliting string
        string[] values = GovnoData.Split(',');
        for (int i = 0; i < values.Length; i++)
        {
            values[i] = values[i].Trim();
            if (i == 0)
            {
                //tempGlobal = values[i];
                GovnoTemperature = values[i];
            }
        }
        tempGlobal = null;
        foreach (char c in GovnoTemperature)
        {
            if (c == '.')
            {
                break;
            }
            if (c == '-' || char.IsDigit(c) == true || c == '.')
            {
                tempGlobal += c.ToString();
            }
        }

        return jsonString;
    }
}

public class Coord
{
    public double lon { get; set; }
    public double lat { get; set; }
}

public class Weather
{
    public int id { get; set; }
    public string main { get; set; }
    public string description { get; set; }
    public string icon { get; set; }
}

public class Main
{
    public double temp { get; set; }
    public int pressure { get; set; }
    public int humidity { get; set; }
    public int temp_min { get; set; }
    public int temp_max { get; set; }
}

public class Wind
{
    public double speed { get; set; }
    public double deg { get; set; }
}

public class Clouds
{
    public int all { get; set; }
}

public class Sys
{
    public int type { get; set; }
    public int id { get; set; }
    public double message { get; set; }
    public string country { get; set; }
    public int sunrise { get; set; }
    public int sunset { get; set; }
}

public class RootObject
{
    public Coord coord { get; set; }
    public List<Weather> weather { get; set; }
    public string @base { get; set; }
    public Main main { get; set; }
    public int visibility { get; set; }
    public Wind wind { get; set; }
    public Clouds clouds { get; set; }
    public int dt { get; set; }
    public Sys sys { get; set; }
    public int id { get; set; }
    public string name { get; set; }
    public int cod { get; set; }
}

}

I need to start MainActivity of "Weather.Droid" from method:

public async Task FetchAsync(string url)

before it returns:

jsonString

How can I do this?

Upvotes: 1

Views: 685

Answers (2)

SKall
SKall

Reputation: 5234

It seems like what you are after is dependency injection. Declare an interface in the portable project and then implement it in the Droid/iOS/??? projects that you support.

I have created an abstraction of IOC in XLabs community project. Matt Whetton has written some pretty good instructions on how to use it: http://www.codenutz.com/getting-started-xamarin-forms-labs-xaml-mvvm-ioc/

The following method isn't ideal but it is a bit unclear why you would need to call the activity start at least this would give you some idea.

On the portable side:

public class Class1
{
    public static async Task<string> Fetch(string url, Action onComplete = null)
    {
        await Task.Delay(10);


        onComplete?.Invoke();
        return url;
    }
}

On Android side (this would be your splash screen or application if your intent is to do this fetch before the main screen comes up):

[Activity(Label = "App5", MainLauncher = true, Icon = "@drawable/icon")]
public class MainActivity : Activity
{
    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);

        // Set our view from the "main" layout resource
        SetContentView (Resource.Layout.Main);

        Class1.Fetch("test", () =>
        {
            var intent = new Intent(this, typeof(OtherActivity));
            this.RunOnUiThread(() => StartActivity(intent));
        }).ContinueWith(t =>
        {
            if (t.IsCompleted) Log.Debug("Fetch", t.Result);
        });
    }
}

Upvotes: 1

Elvis Xia - MSFT
Elvis Xia - MSFT

Reputation: 10831

I need to start MainActivity of "Weather.Droid" from method:

public async Task FetchAsync(string url)

You can't start the MainActivity from Droid project directly. But as @SKall said, you can use Action<Intent> in your FetchAsync Method:

//add Action<Intent> as and Intent as parameters
public async Task<string> FetchAsync(string url,Action<Intent> navigationFunc,Intent intent)
{
    string jsonString;
    ...
    navigationFunc(intent);//Invoke the action
    return jsonString;
}

Then use it in your Droid Project:

ParsingClass parsing = new ParsingClass();
Intent intent = new Intent(this, typeof(MainActivity));
await parsing.FetchAsync("url", StartActivity, intent);

Upvotes: 0

Related Questions