I have two apps App 1 and App 2
https://github.com/Mathew-Potrykus/App1
https://github.com/Mathew-Potrykus/App2
App 1 calls App 2 and passes through some string data that App 2 will use to get a list of Assets, upon selected an asset from the list you go into the details of that asset and can press the 'Submit' button which should then return that asset's details back to App 1.
App 1 is an Android Studio Java app
App 2 is an Xamarin.Forms c# app
My Issue:
Everything but the final step is working as intended;
App 1 opens App 2
App 2 reads the string data and compiles a list
An item is selected in the list and the Details Page is shown
The Submit button is pressed
-------------------------------------------------------------
This is the part that does not work
-------------------------------------------------------------
Close App 2 and send the asset details back to App 1
The line of code that is not working is in my MainActivity on Line 50, 'Finish()'.
It does not close the app or end the process so that the result can return to App 1.
I have noticed that on the rare occasion, the 'Finish()' WILL work but ONLY on the first time when the app was started. Any other attempts that open the app again after that first one do nothing.
There is also the issue that when it DOES get back to App 1, the Result Code is 'Cancelled' and the Intent Data is null
Below is the code for the important parts and that are relvant to the process of getting the data back and forth.
If more code is needed to help figure this out, please let me know, I've been stuck on this for weeks now.
App 2 - Splash Activity - Android
namespace AssetApp.Droid.Activities
{
[Activity(Theme = "@style/MyTheme.Splash", MainLauncher = true, NoHistory = true)]
public class SplashActivity : Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
#region Variables
static readonly string TAG = "X:" + typeof(SplashActivity).Name;
public static bool isConnected;
static PermissionsHandler permissionHandler;
#endregion
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Initialize Xamarin.Essentails
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
Startup();
// Test intent return - Worked!
//TestReturn();
}
//public void ReturnToCaller(SendAsset assetDetails)
//{
// Intent returnAsset = new Intent();
// returnAsset.PutExtra("ID", assetDetails.ID);
// returnAsset.PutExtra("AssetNumber", assetDetails.Code);
// returnAsset.PutExtra("Description", assetDetails.Description);
// returnAsset.PutExtra("Barcode", assetDetails.Barcode);
// returnAsset.PutExtra("Serial", assetDetails.Serial);
// SetResult(Result.Ok, returnAsset);
// Finish();
//}
//public void TestReturn()
//{
// Intent intent = new Intent();
// intent.PutExtra("ID", "This worked!");
// SetResult(Result.Ok, intent);
// Finish();
//}
async void Startup()
{
var appSettings = new ApplicationSettings(new ConfigurationFileProvider());
var appCenterKey = appSettings.AppCenterKey;
// Attach the appcenter logging
AppCenter.Start(appCenterKey, typeof(Analytics), typeof(Crashes));
// Permission Request
permissionHandler = new PermissionsHandler();
await permissionHandler.GetCameraPermissionAsync();
await permissionHandler.GetNetworkStatePermissionAsync();
await permissionHandler.GetPhonePermissionAsync();
await permissionHandler.GetStorageWritePermissionAsync();
await permissionHandler.GetStorageReadPermissionAsync();
Globals.ApiBaseUrl = appSettings.ApiBaseUrl;
// Grab variables passed from caller App
Globals.userID = Intent.GetStringExtra("UserID");
Globals.locationID = Intent.GetStringExtra("LocationID");
Globals.taskID = Intent.GetStringExtra("TaskID");
Globals.deviceID = Intent.GetStringExtra("DeviceID");
// Call database setup
DatabaseStuff();
}
async void DatabaseStuff()
{
/*
Calls to API to load data using received details from caller app....
*/
// Load the MainActivity which will decide whether to display the MainPage or the AccessDeniedPage
Intent main = new Intent(Application.Context, typeof(MainActivity))
StartActivity(main);
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Android.Content.PM.Permission[] grantResults)
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
}
App 2 - Main Activity - Android
namespace AssetApp.Droid
{
[Activity(Label = "@string/ApplicationName", Theme = "@style/MainTheme", LaunchMode = LaunchMode.SingleTop)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
ZXing.Net.Mobile.Forms.Android.Platform.Init();
ReturnHelper.SetReturn(Return);
LoadApplication(new App());
CreateNotificationFromIntent(Intent);
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
global::ZXing.Net.Mobile.Android.PermissionsHandler.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
protected override void OnNewIntent(Intent intent)
{
CreateNotificationFromIntent(intent);
}
void CreateNotificationFromIntent(Intent intent)
{
if (intent?.Extras != null)
{
string title = intent.Extras.GetString(AndroidNotificationManager.TitleKey);
string message = intent.Extras.GetString(AndroidNotificationManager.MessageKey);
DependencyService.Get<INotificationManager>().ReceiveNotification(title, message);
}
}
public void Return(string assetId)
{
var intent = new Intent();
intent.PutExtra("ID", assetId);
SetResult(Result.Ok, intent);
Finish();
}
}
}
App 2 - Return Helper - Forms
namespace AssetApp.Utils
{
public static class ReturnHelper
{
public static Action<string> Return { get; internal set; }
public static void SetReturn(Action<string> returnMethod)
{
if (Return == null)
{
Return = returnMethod;
}
}
}
}
App 2 - Details Page - Forms
(Button Function)
private async void SubmitChanges(object sender, EventArgs args)
{
// Convert ViewModel to SendModel
SendAsset asset = new SendAsset(_updatedAsset);
// return selected asset
//MessagingCenter.Send<DetailsPage, SendAsset>(this, "Asset", asset);
// Return back to Main Page
await Navigation.PopToRootAsync();
// Pass data through to Android to Finish and return to caller
ReturnHelper.Return("id");
}
App 1 - Main Activity - Android
public void CallApp() {
Intent launchIntent = getPackageManager().getLaunchIntentForPackage("com.AssetApp");
// Check if there is an app that can be opened
if (launchIntent != null) {
// Add variables
launchIntent.putExtra("LocationID", "locationID");
launchIntent.putExtra("TaskID", "taskID");
launchIntent.putExtra("UserID", "userID");
launchIntent.putExtra("DeviceID", "deviceID");
launchIntent.setFlags(0);
launchIntent.setType("text/plain");
launchIntent.setAction(Intent.ACTION_SEND_MULTIPLE);
mStartForResult.launch(launchIntent);
}
}
ActivityResultLauncher<Intent> mStartForResult = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() {
@Override
public void onActivityResult(ActivityResult result) {
if (result.getResultCode() == Activity.RESULT_OK) {
Intent intent = result.getData();
if (intent != null) {
String thing1 = intent.getStringExtra("ID");
Toast.makeText(MainActivity.this, thing1, Toast.LENGTH_SHORT).show();
}
}
}
});