I have a custom local notification implementing remoteview comprising of three buttons and a textview. Button click in notification changes volume of ringer but I want to increment a variable count each time the up button click or decrement then count each time downbutton click. I have problem updating textview as the broadcaster class can't access it directly. I tried a method from a post, but I can't make it work.
I get null exception at tvUpdate.text=t;
Any idea would be appreaciated. Thanks
RemoteView
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="75dp"
android:weightSum="100"
android:padding="5dp"
android:background="#969696"
android:minWidth="25px"
android:minHeight="25px">
<Button
android:text="Vol_Up"
android:layout_width="0dp"
android:layout_weight="25"
android:background="#drawable/roundcnr"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:textColor="#FFFFFF"
android:id="#+id/btnVolUp" />
<Button
android:text="V_Down"
android:layout_width="0dp"
android:layout_weight="25"
android:layout_margin="5dp"
android:textColor="#FFFFFF"
android:background="#drawable/roundcnr"
android:layout_height="wrap_content"
android:id="#+id/btnVolDown" />
<Button
android:text="Silent"
android:layout_width="0dp"
android:layout_weight="25"
android:layout_margin="5dp"
android:background="#drawable/roundcnr"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:id="#+id/btnVolSilent" />
<TextView
android:text="Status"
android:layout_width="0dp"
android:layout_weight="25"
android:textColor="#FFFFFF"
android:layout_height="wrap_content"
android:id="#+id/tvVol" />
</LinearLayout>
Broadcaster Class
namespace RingerTest
{
[BroadcastReceiver]
public class myBroadCastR : BroadcastReceiver
{
public double counter { get; set; }
public override void OnReceive(Context context, Intent intent)
{
if(intent.Action== "VolumeUp")
{
counter += 6;
// Toast.MakeText(context,"VolumeUp",ToastLength.Long).Show();
AudioManager audioManager = (AudioManager)context.GetSystemService(Context.AudioService);
audioManager.AdjustSuggestedStreamVolume(Adjust.Raise, Stream.Ring, VolumeNotificationFlags.PlaySound);
try
{
MainActivity.getinstance().updateTextView(counter.ToString() + "%");
}
catch (Exception ex)
{
}
}
else if (intent.Action == "VolumeDown")
{
counter -= 6;
// Toast.MakeText(context, "VolumeDown",ToastLength.Long).Show();
AudioManager audioManager = (AudioManager)context.GetSystemService(Context.AudioService);
audioManager.AdjustSuggestedStreamVolume(Adjust.Lower, Stream.Ring, VolumeNotificationFlags.PlaySound);
try
{
MainActivity.getinstance().updateTextView(counter.ToString() + "%");
}
catch (Exception ex)
{
}
}
else if (intent.Action == "Silent")
{
counter = 0;
// Toast.MakeText(context, "VolumeDown",ToastLength.Long).Show();
AudioManager audioManager = (AudioManager)context.GetSystemService(Context.AudioService);
audioManager.RingerMode = RingerMode.Silent;
MainActivity.getinstance().updateTextView(counter.ToString()+"%");
}
}
}
}
MainActivity
namespace RingerTest
{
[Activity(Label = "RingerTest", MainLauncher = true)]
public class MainActivity : Activity
{
public static MainActivity ins;
private myBroadCastR myBroadl;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
ins = this;
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
var myreceiver = new myBroadCastR();
var intentfilter = new IntentFilter();
intentfilter.AddAction("VolumeUp");
intentfilter.AddAction("VolumeDown");
intentfilter.AddAction("Silent");
RegisterReceiver(myreceiver, intentfilter);
Button btnNotify = FindViewById<Button>(Resource.Id.button1);
btnNotify.Click += BtnNotify_Click;
}
public static MainActivity getinstance()
{
return ins;
}
public void updateTextView(string t)
{
MainActivity.ins.RunOnUiThread(() =>
{
TextView tvUpdate = FindViewById<TextView>(Resource.Id.tvVol);
tvUpdate.Text = t;
});
}
private void BtnNotify_Click(object sender, System.EventArgs e)
{
const int requestID = 1;
//Volume Up
Intent intent_V_UP = new Intent("VolumeUp");
PendingIntent pIntent_V_UP = PendingIntent.GetBroadcast(this, requestID, intent_V_UP, PendingIntentFlags.UpdateCurrent);
//Volume Down
Intent intent_V_Down = new Intent("VolumeDown");
PendingIntent pIntent_V_Down = PendingIntent.GetBroadcast(this, requestID, intent_V_Down, PendingIntentFlags.UpdateCurrent);
//Silent
Intent intent_Silent = new Intent("Silent");
PendingIntent pIntent_Silent = PendingIntent.GetBroadcast(this, requestID, intent_Silent, PendingIntentFlags.UpdateCurrent);
Notification.Builder builder = new Notification.Builder(this);
builder.SetSmallIcon(Resource.Drawable.addContact);
/*
builder.SetContentTitle("VolControl");
builder.AddAction(Resource.Drawable.addContact, "VolDown", pIntent_V_Down);
builder.AddAction(Resource.Drawable.addContact, "VolUP", pIntent_V_UP);*/
//Custom View for Notification
RemoteViews remoteViews = new RemoteViews(this.PackageName, Resource.Layout.customNotification);
//On Button Click in CustomView
remoteViews.SetOnClickPendingIntent(Resource.Id.btnVolUp, pIntent_V_UP);
remoteViews.SetOnClickPendingIntent(Resource.Id.btnVolDown, pIntent_V_Down);
remoteViews.SetOnClickPendingIntent(Resource.Id.btnVolSilent, pIntent_Silent);
Notification notification = builder.Build();
notification.BigContentView = remoteViews;
notification.Flags = NotificationFlags.NoClear;
NotificationManager notificationManager = (NotificationManager)GetSystemService(NotificationService);
notificationManager.Notify(1, notification);
}
}
}
Related
I hope everyone is doing great. Can someone help me on how can I remove the 'cancel' and 'Ok' buttons and allow/raise an event selection if I release the mouse on the item on the screen, Secondly I need help with changing the color of the borderlines and background color? I will appreciate your help thanks.
Picker :
public class BorderlessPickerRenderer : PickerRenderer
{
public static void Init() { }
protected override void OnElementChanged(ElementChangedEventArgs<Picker> e)
{
base.OnElementChanged(e);
if (e.OldElement == null)
{
Control.Background = Android.Graphics.Color.Rgb();
string fontFamily = e.NewElement?.FontFamily;
var layoutParams = new MarginLayoutParams(Control.LayoutParameters);
layoutParams.SetMargins(0, 0, 0, 0);
LayoutParameters = layoutParams;
Control.LayoutParameters = layoutParams;
Control.SetPadding(0, 0, 0, 0);
SetPadding(0, 0, 0, 0);
}
}
}
You could use Custon Remderer to define a custom Dialog.
how can I remove the 'cancel' and 'Ok' buttons and allow/raise an event selection if I release the mouse on the item on the screen,
The AlertDialog provides SetNegativeButton event to set the cancel and Ok button. Remove both in the view would be okay. The custom view is a listview. You could use the ItemClick of ListView.
Secondly I need help with changing the color of the borderlines and background color?
You could set the background color of the dialog to change. Add the android:divider to set the borderline color. And add the android:dividerHeight to set the borderline height.
Custom Renderer:
[assembly: ExportRenderer(typeof(Picker), typeof(BorderlessPickerRenderer))]
namespace App15.Droid
{
public class BorderlessPickerRenderer : PickerRenderer
{
AlertDialog listDialog;
string[] items;
public BorderlessPickerRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Picker> e)
{
base.OnElementChanged(e);
if (Control != null)
{
Control.Click += Control_Click1; ;
}
}
private void Control_Click1(object sender, EventArgs e)
{
Picker model = Element;
items = model.Items.ToArray();
AlertDialog.Builder builder = new AlertDialog.Builder(this.Context);
builder.SetTitle(model.Title ?? "");
//builder.SetNegativeButton("Cancel", (s, a) =>
//{
// Control?.ClearFocus();
// builder = null;
//});
Android.Views.View view = LayoutInflater.From(this.Context).Inflate(Resource.Layout.listview, null);
Android.Widget.ListView listView = view.FindViewById<Android.Widget.ListView>(Resource.Id.listView1);
MyAdapter myAdapter = new MyAdapter(items, Element.SelectedIndex);
listView.Adapter = myAdapter;
listView.ItemClick += ListView_ItemClick;
builder.SetView(view);
listDialog = builder.Create();
listDialog.Window.DecorView.SetBackgroundColor(Android.Graphics.Color.Pink); // set the dialog background color
listDialog.Show();
//Android.Widget.Button button = listDialog.GetButton((int)DialogButtonType.Negative);
//button.Text = "Cancel";
//button.Click += Button_Click;
//button.SetTextColor(Android.Graphics.Color.Blue); // set the button bottom color
}
//private void Button_Click(object sender, EventArgs e)
//{
// listDialog.Dismiss();
// listDialog = null;
//}
private void ListView_ItemClick(object sender, AdapterView.ItemClickEventArgs e)
{
Control.Text = items[e.Position];
Element.SelectedIndex = e.Position;
Console.WriteLine(items[e.Position]);
listDialog.Dismiss();
listDialog = null;
}
class MyAdapter : BaseAdapter
{
private string[] items;
private int selectedIndex;
public MyAdapter(string[] items)
{
this.items = items;
}
public MyAdapter(string[] items, int selectedIndex) : this(items)
{
this.selectedIndex = selectedIndex;
}
public override int Count => items.Length;
public override Java.Lang.Object GetItem(int position)
{
return items[position];
}
public override long GetItemId(int position)
{
return position;
}
public override Android.Views.View GetView(int position, Android.Views.View convertView, ViewGroup parent)
{
if (convertView == null)
{
convertView = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.listview_item, null);
}
TextView textView = convertView.FindViewById<TextView>(Resource.Id.textView1);
textView.Text = items[position];
return convertView;
}
}
}
}
Xaml:
<Picker x:Name="picker" Title="Title" VerticalOptions="CenterAndExpand" >
<Picker.ItemsSource>
<x:Array Type="{x:Type x:String}">
<x:String>Option 1</x:String>
<x:String>Option 2</x:String>
<x:String>Option 3</x:String>
</x:Array>
</Picker.ItemsSource>
</Picker>
listview.xml: You could creat in your Resources/layout in android project.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="#+id/listView1"
android:divider="#android:color/holo_green_light"
android:dividerHeight="2dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
listview_item.xml : You could creat in your Resources/layout in android project.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
I implemented a tabbed application with Xamarin.Android using TabHost and MvxTabsFragmentActivity.
I want to refresh the current tab when clicking on it the second time.
Is there any method like OnTabReselected from Android?
That's how I am creating the tabs, using TabHost:
<TabHost android:id="#android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/white">
<LinearLayout android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="7dp"
android:background="#drawable/gradient_border_top"
android:orientation="horizontal" />
<TabWidget android:id="#android:id/tabs"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="56dp"
android:layout_weight="0"
android:background="#color/white" />
<FrameLayout android:id="#android:id/tabcontent"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="0" />
</LinearLayout>
</TabHost>
And MainView:
[Activity(Theme = "#style/MyTheme", ScreenOrientation = ScreenOrientation.Portrait, WindowSoftInputMode = SoftInput.AdjustPan)]
public class MainView : MvxTabsFragmentActivity
{
public MainView() : base(Resource.Layout.main_layout, Resource.Id.actualtabcontent)
{
}
private static TabHost TabHost { get; set; }
public override void OnTabChanged(string tag)
{
var pos = TabHost.CurrentTab;
var tabView = TabHost.TabWidget.GetChildTabViewAt(pos);
tabView.FindViewById<ImageView>(Resource.Id.tabImage)
.SetColorFilter(new Color(ContextCompat.GetColor(Application.Context, Resource.Color.tabColorSelected)));
tabView.FindViewById<TextView>(Resource.Id.tabTitle)
.SetTextColor(new Color(ContextCompat.GetColor(Application.Context, Resource.Color.tabColorSelected)));
for (var i = 0; i < TabHost.TabWidget.ChildCount; i++)
{
if (pos != i)
{
var tabViewUnselected = TabHost.TabWidget.GetChildTabViewAt(i);
tabViewUnselected.FindViewById<ImageView>(Resource.Id.tabImage)
.SetColorFilter(new Color(ContextCompat.GetColor(Application.Context, Resource.Color.tabColor)));
tabViewUnselected.FindViewById<TextView>(Resource.Id.tabTitle)
.SetTextColor(new Color(ContextCompat.GetColor(Application.Context, Resource.Color.tabColor)));
}
}
base.OnTabChanged(tag);
}
}
// This is where I add all 4 tabs
protected override void AddTabs(Bundle args)
{
AddTab<TrackHomeView>(
args,
Mvx.IoCProvider.IoCConstruct<TrackHomeViewModel>(),
CreateTabFor(((int)TabIdentifier.TrackTab).ToString(), Resource.Drawable.ic_track_icon, Strings.Track));
AddTab<SendView>(
args,
Mvx.IoCProvider.IoCConstruct<SendViewModel>(),
CreateTabFor(((int)TabIdentifier.SendTab).ToString(), Resource.Drawable.ic_send_icon, Strings.Send));
if (MainViewModel.IsUserLoggedIn())
{
AddTab<ProfileView>(
args,
Mvx.IoCProvider.IoCConstruct<ProfileViewModel>(),
CreateTabFor(((int)TabIdentifier.ProfileTab).ToString(), Resource.Drawable.ic_profile_icon, Strings.Profile));
}
else
{
AddTab<CreateAccountView>(
args,
Mvx.IoCProvider.IoCConstruct<CreateAccountViewModel>(),
CreateTabFor(((int)TabIdentifier.ProfileTab).ToString(), Resource.Drawable.ic_profile_icon, Strings.Profile));
}
AddTab<MoreView>(
args,
Mvx.IoCProvider.IoCConstruct<MoreViewModel>(),
CreateTabFor(((int)TabIdentifier.MoreTab).ToString(), Resource.Drawable.ic_more_icon, Strings.More));
}
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
TabHost = FindViewById<TabHost>(global::Android.Resource.Id.TabHost);
TabHost.TabWidget.SetDividerDrawable(null);
TabHost.Setup();
}
I added only relevant code.
The tabs are created using TabHost, and the Activity is inherited from MvxTabsFragmentActivity.
You can inherit the ActionBar.ITabListener interface in your TabHost's MvxTabsFragmentActivity and then you can get the events that you need.
public class MainActivity : MvxTabsFragmentActivity, ActionBar.ITabListener
{
public void OnTabReselected(ActionBar.Tab tab, FragmentTransaction ft)
{
// Optionally refresh/update the displayed tab.
Log.Debug(Tag, "The tab {0} was re-selected.", tab.Text);
}
public void OnTabSelected(ActionBar.Tab tab, FragmentTransaction ft)
{
// Display the fragment the user should see
Log.Debug(Tag, "The tab {0} has been selected.", tab.Text);
}
public void OnTabUnselected(ActionBar.Tab tab, FragmentTransaction ft)
{
// Save any state in the displayed fragment.
Log.Debug(Tag, "The tab {0} as been unselected.", tab.Text);
}
...
I'm trying to create a simple app that uses the Xamarin Geofence plugin. (https://github.com/domaven/xamarin-plugins/tree/master/Geofence).
I'm using MvvmCross for model binding and the App View is interested in events coming from the Geofence instance.
On My ViewModel i have implemented the IGeofenceListener interface so that when any of the events are fired i can directly change the value of the binding properties in my ViewModel that are being targeted in the View.
public class MainViewModel : MvxViewModel, IGeofenceListener
{
double _latitude;
public double Latitude
{
get
{
return _latitude;
}
set
{
_latitude = value;
RaisePropertyChanged(() => Latitude);
}
}
double _longitude;
public double Longitude
{
get
{
return _longitude;
}
set
{
_longitude = value;
RaisePropertyChanged(() => Longitude);
}
}
string _name;
public string Name
{
get
{
return _name;
}
set
{
_name = value;
RaisePropertyChanged(() => Name);
}
}
public void OnAppStarted()
{
Debug.WriteLine(string.Format("{0} - {1}", CrossGeofence.Id, "App started"));
}
public void OnError(string error)
{
Debug.WriteLine(string.Format("{0} - {1}: {2}", CrossGeofence.Id, "Error", error));
}
public void OnLocationChanged(GeofenceLocation location)
{
Longitude = location.Longitude;
Latitude = location.Latitude;
Name = CrossGeofence.Id;
Debug.WriteLine(string.Format("{0} - Long: {1} || Lat: {2}", CrossGeofence.Id, location.Longitude, location.Latitude));
}
public void OnMonitoringStarted(string identifier)
{
Debug.WriteLine(string.Format("{0} - Monitoring started in region: {1}", CrossGeofence.Id, identifier));
}
public void OnMonitoringStopped()
{
Debug.WriteLine(string.Format("{0} - {1}", CrossGeofence.Id, "Monitoring stopped for all regions"));
}
public void OnMonitoringStopped(string identifier)
{
Debug.WriteLine(string.Format("{0} - {1}: {2}", CrossGeofence.Id, "Monitoring stopped in region", identifier));
}
public void OnRegionStateChanged(GeofenceResult result)
{
Longitude = result.Longitude;
Latitude = result.Latitude;
Debug.WriteLine(string.Format("{0} - {1}", CrossGeofence.Id, result.ToString()));
}
}
As you can see, On certain events Im updating the properties of my ViewModel and then calling the RaisePropertyChanged event for the View.
I've added Debug tracing to ensure that these events are actually being fired.
I can see the events firing in my Output window.. and when i debug the application i can see the properties on the ViewModel been updated. It's just that the RaisePropertyChanged event in not actually updating the View.
Here is my View Code :-
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00007f"
android:layout_marginTop="10dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="20dp"
local:MvxBind="Text Longitude"
android:id="#+id/textViewLongitude"
android:textColor="#android:color/white" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="20dp"
local:MvxBind="Text Latitude"
android:id="#+id/textViewLatitude"
android:textColor="#android:color/white" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="20dp"
local:MvxBind="Text Name"
android:textColor="#android:color/white"
android:id="#+id/textViewName" />
</LinearLayout>
This is the App setup code in my Core Library :-
public class App : MvxApplication
{
public App()
{
Mvx.RegisterSingleton<IMvxAppStart>(new MvxAppStart<MainViewModel>());
}
}
Here is the Main Activity MvxClass :-
[Activity(Label = "Geofence.Android", MainLauncher = true)]
public class MainActivity : MvxActivity<MainViewModel>
{
protected override void OnViewModelSet()
{
SetContentView(Resource.Layout.Main);
}
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
CrossGeofence.Initialize<MainViewModel>();
CrossGeofence.Current.StopMonitoring("LHR");
CrossGeofence.Current.StartMonitoring(new Plugin.Abstractions.GeofenceCircularRegion("Location", 54.9672132, -1.5992939, 2000)
{
NotifyOnStay = true,
NotifyOnEntry = true,
NotifyOnExit = true,
ShowNotification = true,
ShowEntryNotification = false,
ShowExitNotification = false,
ShowStayNotification = true,
NotificationStayMessage = "stay message!",
NotificationEntryMessage = "entry message!",
NotificationExitMessage = "exit message!",
StayedInThresholdDuration = TimeSpan.FromSeconds(1),
});
}
}
This is because CrossGeofence.Initialize<MainViewModel>(); creates a new ViewModel, that is not that one that was created by MvvmCross. You can see that, when you inspect the ViewModel of the activity in the debugger.
Solution
Use the GeofenceListener property.
CrossGeofence.GeofenceListener = (IGeofenceListener)ViewModel;
CrossGeofence.Initialize<MainViewModel>();
A callback that notifies clients when the progress level has been changed. This includes changes that were initiated by the user through a touch gesture or arrow key/trackball as well as changes that were initiated programmatically.
Inside OnCreate
public class AudioPlayer : Activity,SeekBar.IOnSeekBarChangeListener
seekBar.SetOnSeekBarChangeListener (this);
seekBar.ProgressChanged+= (object sender, SeekBar.ProgressChangedEventArgs e) => {
int progress=(int)(utils.getProgressPercentage(player.CurrentPosition,player.Duration));
seekBar.Progress = progress;
};
public void OnStartTrackingTouch(SeekBar seekBar) {}
public void OnStopTrackingTouch(SeekBar seekBar) {}
public int getProgressPercentage(int currentDuration, int totalDuration)
{
int percentage;
int currentSeconds = (int)(currentDuration / 1000);
int totalSeconds = (int)(totalDuration / 1000);
//calculating percentage
percentage = (((int)currentSeconds) / totalSeconds) * 100;
return percentage;
}
While tracks are playing, seekBar still stops.
Think you want to do is create a timer which will update the seekBar like this:
Activity:
using System;
using Android.App;
using Android.Widget;
using Android.OS;
using Java.Lang;
using Android.Content;
using Android.Graphics.Drawables;
using Java.Util;
namespace PlayVideo
{
[Activity (Label = "PlayVideo", MainLauncher = true)]
public class Activity1 : Activity
{
VideoView videoView;
SeekBar seekBar;
System.Timers.Timer timer;
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
// Set our view from the "main" layout resource
SetContentView (Resource.Layout.Main);
videoView = FindViewById<VideoView> (Resource.Id.SampleVideoView);
videoView.SetMediaController(new MediaController(this));
videoView.SetVideoPath ($"android.resource://{PackageName}/{Resource.Raw.output2}");
videoView.Start ();
seekBar = FindViewById<SeekBar> (Resource.Id.seekBar);
seekBar.Max = videoView.Duration;
seekBar.StartTrackingTouch += (object sender, SeekBar.StartTrackingTouchEventArgs e) =>
{
timer.Enabled = false;
};
seekBar.StopTrackingTouch += (object sender, SeekBar.StopTrackingTouchEventArgs e) =>
{
videoView.SeekTo (e.SeekBar.Progress);
timer.Enabled = true;
};
UpdateProgressBar ();
}
private void UpdateProgressBar() {
timer = new System.Timers.Timer();
timer.Interval = 100;
timer.Elapsed += OnTimedEvent;
timer.Enabled = true;
}
private void OnTimedEvent(object sender, System.Timers.ElapsedEventArgs e)
{
seekBar.Progress = videoView.CurrentPosition;
seekBar.Max = videoView.Duration;
}
}
}
Layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<VideoView
android:id="#+id/SampleVideoView"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<SeekBar
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/seekBar" />
</LinearLayout>
it will look like this:
I am developing a chat application using socketIO library. Every thing seems to work fine except the UI updation. I am able to send message to the port and receive from it. But after reception, i cant update textview or any other UI. the code is given below
Any help is most appreciated
NB: the toast is coming, the **updated* message is also showing when next new message comes
chatRoomActivity.java
public class chatRoomActivity extends Activity implements OnClickListener{
int channelId = 0;
public final String SocketURL = "someURL";
String userName = "";
int connectioAttempt = 0;
SocketIOClient socketClient = null;
SocketIOClientOperations sioOps = null;
Button chatRoomSend = null;
EditText chatInput = null;
TextView msgcntr;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.chat_room);
chatRoomSend = (Button)findViewById(R.id.chatRoomSendBtn);
chatInput = (EditText)findViewById(R.id.chatRoomInput);
msgcntr=(TextView)findViewById(R.id.textView1);
chatRoomSend.setOnClickListener(this);
sioOps = new SocketIOClientOperations();
msgcntr = (TextView) findViewById(R.id.textView1);
socketClient = sioOps.connectToSocket(SocketURL);
System.out.println("**********Connected**********");
if(socketClient != null)
{
boolean joined = false;
joined = sioOps.joinChannel(socketClient, channelId);
System.out.println("*******Joined*********");
}
else
{
System.out.println("*******Null*********");
}
socketClient.on("incomingMessage", new EventCallback() {
public void onEvent(JSONArray argument, Acknowledge acknowledge) {
System.out.println("***************New Message*********");
System.out.println("***************"+argument.toString()+"*********");
msgcntr.setText("test");
updateClock();
}
});
}
#Override
public void onClick(View v) {
if(v == chatRoomSend)
{
boolean sent = sioOps.sendNewMessage(socketClient, userName, "empty");
if(sent)
System.out.println("************** Message Sent *********");
else
System.out.println("************** Message Failed *********");
}
}
protected void updateClock() {
runOnUiThread(new Runnable(){
public void run() {
Toast.makeText(getApplicationContext(), "end", Toast.LENGTH_SHORT).show();
msgcntr.setText("test");
System.out.print("************Updated*********");
}
});
}
}
socketIOClientOperations.java
public class SocketIOClientOperations {
public SocketIOClientOperations(){}
public SocketIOClient connectToSocket(String SocketURL)
{
SocketIORequest connectionRequest = new SocketIORequest(SocketURL);
SocketIOClient socketClient = null;
try {
socketClient = SocketIOClient.connect(AsyncHttpClient.getDefaultInstance(), connectionRequest, null).get();
} catch (InterruptedException e) {
e.printStackTrace();
return null;
} catch (ExecutionException e) {
e.printStackTrace();
return null;
}
return socketClient;
}
public boolean joinChannel(SocketIOClient client,int channelId)
{
JSONArray joinChannel = new JSONArray();
JSONObject values = new JSONObject();
try {
values.put("channelID", channelId);
joinChannel.put(values);
client.emit("joinChannel", joinChannel);
return true;
} catch (JSONException e) {
e.printStackTrace();
return false;
}
}
public boolean sendNewMessage(SocketIOClient client,String name,String txt)
{
JSONArray newMsg = new JSONArray();
JSONObject msgBody = new JSONObject();
try {
msgBody.put("From", name);
msgBody.put("Content", txt);
newMsg.put(msgBody);
client.emit("newMessage", newMsg);
System.out.println("***************SendMessage*********");
System.out.println("************** "+newMsg.toString()+" *********");
return true;
} catch (JSONException e) {
e.printStackTrace();
return false;
}
}
}
chat_room.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="40dp"
android:background="#000"
android:padding="10dp"
android:id="#+id/header">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Chat Room"
android:textColor="#fff"
android:textSize="14sp"/>
</RelativeLayout>
<ListView
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:stackFromBottom="true"
android:layout_above="#+id/footer"
android:layout_below="#+id/header"
android:id="#+id/chatRoomMsgs"
android:background="#cccccc"
android:visibility="gone" />
<TextView
android:id="#+id/msgConatainer"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_above="#+id/fooer"
android:layout_below="#+id/header"
android:background="#ccc"
android:textColor="#000" />
<RelativeLayout
android:id="#+id/fooer"
android:background="#000"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="5dp"
android:layout_alignParentBottom="true">
<EditText
android:id="#+id/chatRoomInput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Enter your message...."
android:layout_toLeftOf="#+id/chatRoomSendBtn"
android:layout_alignParentLeft="true"/>
<Button
android:id="#+id/chatRoomSendBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Send"
android:layout_alignParentRight="true" />
</RelativeLayout>
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/msgConatainer"
android:layout_centerHorizontal="true"
android:layout_marginBottom="48dp"
android:text="TextView"
android:textColor="#android:color/black" />
</RelativeLayout>
Try this way
private Handler mHandler = new Handler();
mHandler.post(new Runnable() {
public void run() {
msgcntr.setText("test");
}
});