I found a code in StackOverflow that is written for monitoring incoming and outgoing SMS, but this code is written in Java. I want to use it in Xamarin as a Android Service. This is the code:
public class SMSMonitor
{
private ServiceController mainActivity;
private ContentResolver contentResolver = null;
private Handler smshandler = null;
private ContentObserver smsObserver = null;
public string smsNumber;
public static bool thCountStatus = false;
public static int thIncreCount = 0;
public bool monitorStatus = false;
internal string code;
public static string activationCode;
internal int smsCount = 0;
public SMSMonitor(in ServiceController mainActivity, in Context mainContext)
{
this.mainActivity = mainActivity;
contentResolver = mainActivity.ContentResolver();
smshandler = new SMSHandler(this);
smsObserver = new SMSObserver(this, smshandler);
}
public virtual void startSMSMonitoring()
{
try
{
monitorStatus = false;
if (!monitorStatus)
{
contentResolver.RegisterContentObserver(Android.Net.Uri.Parse("content://sms"), true, smsObserver);
}
}
catch (Exception e)
{
Log.WriteLine(LogPriority.Error,"test", "SMSMonitor :: startSMSMonitoring Exception == " + e.Message);
}
}
public void stopSMSMonitoring()
{
try
{
monitorStatus = false;
if (!monitorStatus)
{
contentResolver.UnregisterContentObserver(smsObserver);
}
}
catch (Exception e)
{
Log.WriteLine(LogPriority.Error,"test", "SMSMonitor :: stopSMSMonitoring Exception == " + e.Message);
}
}
internal class SMSHandler : Handler
{
private readonly SMSMonitor outerInstance;
public SMSHandler(SMSMonitor outerInstance)
{
this.outerInstance = outerInstance;
}
}
internal class SMSObserver : ContentObserver
{
private readonly SMSMonitor outerInstance;
internal Handler sms_handle = null;
public SMSObserver(SMSMonitor outerInstance, in Handler smshandle) : base(smshandle)
{
this.outerInstance = outerInstance;
sms_handle = smshandle;
}
public virtual void onChange(in bool bSelfChange)
{
base.OnChange(bSelfChange);
Thread thread = new Thread(() =>
{
try
{
outerInstance.monitorStatus = true;
Message msg = new Message();
sms_handle.sendMessage(msg);
Uri uriSMSURI = new Uri("content://sms");
Cursor cur = outerInstance.mainActivity.ContentResolver.query(uriSMSURI, null, null, null, "_id");
if (cur.Count != outerInstance.smsCount)
{
outerInstance.smsCount = cur.Count;
if (cur != null && cur.Count > 0)
{
cur.moveToLast();
outerInstance.smsNumber = cur.getString(cur.getColumnIndex("address"));
if (string.ReferenceEquals(outerInstance.smsNumber, null) || outerInstance.smsNumber.Length <= 0)
{
outerInstance.smsNumber = "Unknown";
}
int type = int.Parse(cur.getString(cur.getColumnIndex("type")));
string message = cur.getString(cur.getColumnIndex("body"));
Log.WriteLine(LogPriority.Error, "test", "SMSMonitor :: SMS type == " + type);
Log.WriteLine(LogPriority.Error, "test", "SMSMonitor :: Message Txt == " + message);
Log.WriteLine(LogPriority.Error, "test", "SMSMonitor :: Phone Number == " + outerInstance.smsNumber);
cur.close();
if (type == 1)
{
onSMSReceive(message, outerInstance.smsNumber);
}
else
{
onSMSSend(message, outerInstance.smsNumber);
}
}
}
}
catch (Exception)
{
// Log("KidSafe","SMSMonitor :: onChange Exception == "+ e.getMessage());
}
});
thread.Start();
}
internal virtual void onSMSReceive(in string message, in string number)
{
lock (this)
{
Log.WriteLine(LogPriority.Error, "test", "In OnSmsReceive");
Log.WriteLine(LogPriority.Error, "test", "Message" + message);
Log.WriteLine(LogPriority.Error, "Sample", "Number" + number);
}
}
internal virtual void onSMSSend(in string message, in string number)
{
lock (this)
{
Log.WriteLine(LogPriority.Error, "test", "In OnSmsSend");
Log.WriteLine(LogPriority.Error, "test", "Message" + message);
Log.WriteLine(LogPriority.Error, "Sample", "Number" + number);
}
}
}
}
The problems:
How can I access to ContenetResolver in Xamarin , when I convert this code to C# , an error occur about ContentResolver.
As the same problem is occurred for Cursor class.
In this code (in SMSMonitor class) the ContentResolver is not a part of mainActivity!!!
You could define global static variable for MainActivity or pass it as a parameter in SMSMonitor constructor.
global static variable:
public class MainActivity : AppCompatActivity
{
public static MainActivity Instance;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
...
Instance = this;
}
}
then in your SMSMonitor use like:
ContentResolver contentResolver = MainActivity.Instance.ContentResolver;
for Cursor :
var cursor = contentResolver.Query(uriSMSURI, null, null, null, "_id");
Related
#RequestMapping("/api/v1")
public class RemoteActionHistoryController {
public Mono<ResponseEntityDTO<List<RemoteActionHistoryDTO>>> excaliburData(#PathVariable(name = "deviceId", required = true)
String deviceId) {
return service.getRemoteActionHistory(deviceId);
}
}
public class RemoteActionHistoryServiceImpl {
#Autowired
RemoteActionHistoryRepository arrowFlightRepository;
#Override
public Mono<ResponseEntityDTO<List<RemoteActionHistoryDTO>>> getRemoteActionHistory(String deviceId) throws Exception {
return (Mono<ResponseEntityDTO<List<RemoteActionHistoryDTO>>>) arrowFlightRepository.getRemoteActionDetailsByDeviceId(deviceId).collectList().flatMap(mapper);
}
Function<List<RemoteActionHistory>, Mono<ResponseEntityDTO<RemoteActionHistoryDTO>>> mapper = remoteActions -> {
var remoteActionDTO = new RemoteActionHistoryDTO();
if (CollectionUtils.isEmpty(remoteActions)) {
return Mono.justOrEmpty(new ResponseEntityDTO<>(RemoteActionHistoryConstants.CODE_RET_000, null, remoteActionDTO));
}
System.out.println("Printing remoteActions"+remoteActions);
for (RemoteActionHistory excaliburData : remoteActions) {
remoteActionDTO.setStartDateTime(excaliburData.getStartDateTime());
remoteActionDTO.setEndDateTime(excaliburData.getEndDateTime());
remoteActionDTO.setRemoteActionType(excaliburData.getCommand());
remoteActionDTO.setTaskStatus(excaliburData.getStatus());
}
return Mono.justOrEmpty(new ResponseEntityDTO<>(RemoteActionHistoryConstants.CODE_RET_000, null, remoteActionDTO));
};
}
public class RemoteActionHistoryServiceImpl {
#Autowired
RemoteActionHistoryRepository arrowFlightRepository;
#Override
public Mono<ResponseEntityDTO<List<RemoteActionHistoryDTO>>> getRemoteActionHistory(String deviceId) throws Exception {
return (Mono<ResponseEntityDTO<List<RemoteActionHistoryDTO>>>) arrowFlightRepository.getRemoteActionDetailsByDeviceId(deviceId).collectList().flatMap(mapper);
}
Function<List<RemoteActionHistory>, Mono<ResponseEntityDTO<RemoteActionHistoryDTO>>> mapper = remoteActions -> {
var remoteActionDTO = new RemoteActionHistoryDTO();
if (CollectionUtils.isEmpty(remoteActions)) {
return Mono.justOrEmpty(new ResponseEntityDTO<>(RemoteActionHistoryConstants.CODE_RET_000, null, remoteActionDTO));
}
System.out.println("Printing remoteActions"+remoteActions);
for (RemoteActionHistory excaliburData : remoteActions) {
remoteActionDTO.setStartDateTime(excaliburData.getStartDateTime());
remoteActionDTO.setEndDateTime(excaliburData.getEndDateTime());
remoteActionDTO.setRemoteActionType(excaliburData.getCommand());
remoteActionDTO.setTaskStatus(excaliburData.getStatus());
}
return Mono.justOrEmpty(new ResponseEntityDTO<>(RemoteActionHistoryConstants.CODE_RET_000, null, remoteActionDTO));
};
}
public class RemoteActionHistoryRepositoryImpl {
#Override
public Flux<RemoteActionHistory> getRemoteActionDetailsByDeviceId(String deviceId) throws Exception {
return Flux.fromIterable(getExcaliburData(String.format(query, tableName, deviceId), true));
}
private List<RemoteActionHistory> getExcaliburData(String query, boolean retry) throws Exception {
List<RemoteActionHistory> remoteActionData = new ArrayList<>();
try (final FlightStream flightStream = adhocFlightClientConfig.createAdhocFlightClient().runQuery(query);) {
while (flightStream.next()) {
if (!flightStream.hasRoot()) {
break;
}
VectorSchemaRoot vectorSchemaRoot = flightStream.getRoot();
TimeStampMilliVector createdDateVector = (TimeStampMilliVector) vectorSchemaRoot
.getVector(RemoteActionHistoryConstants.CREATED_DATE_TIME);
TimeStampMilliVector modifiedDateVector = (TimeStampMilliVector) vectorSchemaRoot
.getVector(RemoteActionHistoryConstants.MODIFIED_DATE_TIME);
RemoteActionHistory remoteAction = null;
for (int i = 0; i < vectorSchemaRoot.getRowCount(); i++) {
remoteAction = new RemoteActionHistory();
remoteAction.setStartDateTime(createdDateVector.isNull(i)? null : new Timestamp(createdDateVector.get(i)));
remoteAction.setEndDateTime(modifiedDateVector.isNull(i)? null : new Timestamp(modifiedDateVector.get(i)));
remoteActionData.add(remoteAction);
}
} catch (Exception ex) {
log.error(String.format("Exception string : %s with retryEnabled is %s", ex.toString(),retry));
if (retry && StringUtils.containsIgnoreCase(ex.toString(), RemoteActionHistoryConstants.UNAUTHENTICATED_ERROR)) {
adhocFlightClientConfig.removeToken();
getExcaliburData(query, false);
}
throw ex;
}
return remoteActionData;
}
}
I have attached the result which I'm currently getting single record. when i debugged the code in the object i have multiple records but it shows only one record in postman
I want to stop Device.StartTimer when my current page is re-initialize from the App.cs page, but every time when page is re-initialize Device.Starttimer create new instance and function is calling multiple times.
from the links and references i get to know that it will not stop until return statement not execute, but in my case how to execute return statement outside the method, that i can not understand.
Below is my cs page code.
public partial class MediaScreen : ContentPage
{
public static readonly List<string> ImageExtensions = new List<string>
{ ".JPG", ".JPE", ".BMP", ".GIF", ".PNG" };
public static readonly List<string> videoExtensions = new List<string> {
".WAV", ".MID", ".MIDI", ".WMA", ".OGG", ".RMA", //etc
".AVI", ".MP4", ".DIVX", ".WMV", //etc
};
int i = 0;
DisplayInfo mainDisplayInfo = DeviceDisplay.MainDisplayInfo;
public MediaScreen()
{
InitializeComponent();
try
{
StartPlaying();
}
catch (Exception e)
{
}
}
public bool StartPlaying()
{
CrossMediaManager.Current.Stop();
if (i == App.localStorage.Playlist.PlayListItems.Count)
{
i = 0;
StartPlaying();
return false;
}
var data = App.localStorage.Playlist.PlayListItems[i].MediaLibrary;
string fileName = App.path + "\\" + Path.GetFileName(data.Url);
if (ImageExtensions.Contains(Path.GetExtension(fileName).ToUpperInvariant()))
{
// process image
imgPlayer.IsVisible = true;
imgPlayer.Source = fileName;
videoPlayer.IsVisible = false;
}
else
{
try
{
CrossMediaManager.Current.Play(fileName);
CrossMediaManager.Current.MediaItemFinished += finishVideo;
videoPlayer.IsVisible = true;
imgPlayer.IsVisible = false;
}
catch (Exception e1)
{
}
}
i++;
Device.StartTimer(TimeSpan.FromSeconds
(data.Duration), StartPlaying);
return false;
}
}
}
You can use a stoppable timer instead. It has 2 goals: it can be stopped, it can be rescheduled (if it didn't start yet you can reschedule it):
Schedule example:
public StoppableTimer<object> timerScheduled; //object is param type you want
public void LaunchTimer()
{
if (timerScheduled == null)
{
timerScheduled = new StoppableTimer<object>(TimeSpan.FromSeconds(2), OnTimerStart);
timerScheduled.Start(null); //whatever param
}
else
{
//relaunch
timerScheduled.Stop();
timerScheduled.Start(control);
}
}
So when you need to cancel the timer just call timerScheduled.Stop();
Your callback:
private void OnTimerStart(object p)
{
//StartPlaying - do your stuff
}
Class:
public class StoppableTimer<T> // T is the parameter you want to pass to timer
{
private readonly TimeSpan timespan;
private readonly Action<T> callback;
private CancellationTokenSource cancellation;
public StoppableTimer(TimeSpan timespan, Action<T> callback)
{
this.timespan = timespan;
this.callback = callback;
this.cancellation = new CancellationTokenSource();
}
public void Start(T param)
{
CancellationTokenSource cts = this.cancellation; // safe copy
Device.StartTimer(this.timespan,
() => {
if (cts.IsCancellationRequested) return false;
this.callback.Invoke(param);
return false; // or true for periodic behavior
});
}
public void Stop()
{
Interlocked.Exchange(ref this.cancellation, new CancellationTokenSource()).Cancel();
}
public void Dispose()
{
}
}
i am using Sinch in my app for video, audio and messaging purpose. calling and messaging works fine when the app is running in foreground. when the app is closed and removed from stack, incoming messages and calls still works as i implemented push notification to look for incoming calls and messages (i checked in debug mode). My problem is that
1) when i start incoming call activity from firebaseMessaginService it does not show the caller name and picture i am sending in headers as i start it through relayRemotePushNotificationPayload(HashMap);
2) i am unable to get the message content data from incoming message and show notification accordingly.
My Code.
public class MyFirebaseMessagingService extends FirebaseMessagingService implements ServiceConnection {
Context context;
private SinchService.SinchServiceInterface mSinchServiceInterface;
HashMap dataHashMap;
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
context = this;
if (SinchHelpers.isSinchPushPayload(remoteMessage.getData())) {
Map data = remoteMessage.getData();
dataHashMap = (data instanceof HashMap) ? (HashMap) data : new HashMap<>(data);
if (SinchHelpers.isSinchPushPayload(dataHashMap)) {
getApplicationContext().bindService(new Intent(getApplicationContext(), SinchService.class), this, Context.BIND_AUTO_CREATE);
}
} else {
Intent intent;
PendingIntent pendingIntent = null;
if (remoteMessage.getData().size() > 0) {
String identifier = remoteMessage.getData().get("identifier");
if (identifier.equals("0")) {
intent = new Intent(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
} else if (identifier.equals("1")) {
intent = new Intent(this, Appointments.class);
pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
StaticInfo.saveData("HEALTH_TIP", "TIP", this);
}
}
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this);
notificationBuilder.setWhen(System.currentTimeMillis());
notificationBuilder.setContentTitle(remoteMessage.getNotification().getTitle());
notificationBuilder.setContentText(remoteMessage.getNotification().getBody());
notificationBuilder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
notificationBuilder.setDefaults(Notification.DEFAULT_ALL | Notification.DEFAULT_LIGHTS | Notification.FLAG_SHOW_LIGHTS | Notification.DEFAULT_SOUND);
notificationBuilder.setAutoCancel(true);
notificationBuilder.setSmallIcon(R.mipmap.ic_launcher);
notificationBuilder.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notificationBuilder.build());
}
}
public static boolean foregrounded() {
ActivityManager.RunningAppProcessInfo appProcessInfo = new ActivityManager.RunningAppProcessInfo();
ActivityManager.getMyMemoryState(appProcessInfo);
return (appProcessInfo.importance == IMPORTANCE_FOREGROUND || appProcessInfo.importance == IMPORTANCE_VISIBLE);
}
#Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
if (SinchService.class.getName().equals(componentName.getClassName())) {
mSinchServiceInterface = (SinchService.SinchServiceInterface) iBinder;
}
// it starts incoming call activity which does not show incoming caller name and picture
NotificationResult result = mSinchServiceInterface.relayRemotePushNotificationPayload(dataHashMap);
if (result.isValid() && result.isCall()) {
CallNotificationResult callResult = result.getCallResult();
if (callResult.isCallCanceled() || callResult.isTimedOut()) {
createNotification("Missed Call from : ", callResult.getRemoteUserId());
return;
} else {
if (callResult.isVideoOffered()) {
Intent intent = new Intent(this, IncomingVideoCall.class);
intent.putExtra(SinchService.CALL_ID, callResult.getRemoteUserId());
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(intent);
} else {
Intent intent = new Intent(this, IncomingAudioCall.class);
intent.putExtra(SinchService.CALL_ID, callResult.getRemoteUserId());
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(intent);
}
}
} else if (result.isValid() && result.isMessage()) {
//i want to get message content here
MessageNotificationResult notificationResult = result.getMessageResult();
createNotification("Received Message from : ", notificationResult.getSenderId());
}
}
#Override
public void onServiceDisconnected(ComponentName componentName) {
unbindService(this);
}
private void createNotification(String contentTitle, String userId) {
PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, new Intent(getApplicationContext(), MainActivity.class), 0);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(getApplicationContext()).setSmallIcon(R.mipmap.ic_launcher).setContentTitle(contentTitle).setContentText(userId);
mBuilder.setContentIntent(contentIntent);
mBuilder.setDefaults(Notification.DEFAULT_SOUND);
mBuilder.setAutoCancel(true);
NotificationManager mNotificationManager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(1, mBuilder.build());
}
}
Sinch service is
public class SinchService extends Service {
private static final String APP_KEY = "123abc";
private static final String APP_SECRET = "123abc";
private static final String ENVIRONMENT = "sandbox.sinch.com";
public static final String CALL_ID = "CALL_ID";
static final String TAG = SinchService.class.getSimpleName();
private SinchServiceInterface mSinchServiceInterface = new SinchServiceInterface();
private SinchClient mSinchClient;
private String mUserId;
private StartFailedListener mListener;
private PersistedSettings mSettings;
#Override
public void onCreate() {
super.onCreate();
mSettings = new PersistedSettings(getApplicationContext());
String userName = mSettings.getUsername();
if (!userName.isEmpty()) {
start(userName);
}
}
#Override
public void onDestroy() {
if (mSinchClient != null && mSinchClient.isStarted()) {
mSinchClient.terminate();
}
super.onDestroy();
}
private void start(String userName) {
if (mSinchClient == null) {
mSettings.setUsername(userName);
mUserId = userName;
mSinchClient = Sinch.getSinchClientBuilder().context(getApplicationContext()).userId(userName).applicationKey(APP_KEY).applicationSecret(APP_SECRET).environmentHost(ENVIRONMENT).build();
mSinchClient.setSupportCalling(true);
mSinchClient.setSupportMessaging(true);
mSinchClient.setSupportManagedPush(true);
mSinchClient.checkManifest();
mSinchClient.setSupportActiveConnectionInBackground(true);
mSinchClient.startListeningOnActiveConnection();
mSinchClient.addSinchClientListener(new MySinchClientListener());
mSinchClient.getCallClient().setRespectNativeCalls(false);
mSinchClient.getCallClient().addCallClientListener(new SinchCallClientListener());
mSinchClient.getVideoController().setResizeBehaviour(VideoScalingType.ASPECT_FILL);
mSinchClient.start();
}
}
private void stop() {
if (mSinchClient != null) {
mSinchClient.terminate();
mSinchClient = null;
}
mSettings.setUsername("");
}
private boolean isStarted() {
return (mSinchClient != null && mSinchClient.isStarted());
}
#Override
public IBinder onBind(Intent intent) {
return mSinchServiceInterface;
}
public class SinchServiceInterface extends Binder {
public NotificationResult relayRemotePushNotificationPayload(final Map payload) {
if (mSinchClient == null && !mSettings.getUsername().isEmpty()) {
start(mSettings.getUsername());
} else if (mSinchClient == null && mSettings.getUsername().isEmpty()) {
if (!StaticInfo.getSavedData("username", SinchService.this).equals("")) {
start(StaticInfo.getSavedData("username", SinchService.this));
}
return null;
}
return mSinchClient.relayRemotePushNotificationPayload(payload);
}
public void sendMessage(String recipientUserId, String Name, String textBody, String imageUrl) {
SinchService.this.sendMessage(recipientUserId, Name, textBody, imageUrl);
}
public void addMessageClientListener(MessageClientListener listener) {
SinchService.this.addMessageClientListener(listener);
}
public void removeMessageClientListener(MessageClientListener listener) {
SinchService.this.removeMessageClientListener(listener);
}
public Call callUser(String userId, HashMap<String, String> name) {
if (mSinchClient == null) {
return null;
}
return mSinchClient.getCallClient().callUser(userId, name);
}
public Call callUserVideo(String userId, HashMap<String, String> name) {
return mSinchClient.getCallClient().callUserVideo(userId, name);
}
public String getUserName() {
return mUserId;
}
public boolean isStarted() {
return SinchService.this.isStarted();
}
public void startClient(String userName) {
start(userName);
}
public void stopClient() {
stop();
}
public void setStartListener(StartFailedListener listener) {
mListener = listener;
}
public Call getCall(String callId) {
return mSinchClient.getCallClient().getCall(callId);
}
public VideoController getVideoController() {
if (!isStarted()) {
return null;
}
return mSinchClient.getVideoController();
}
public AudioController getAudioController() {
if (!isStarted()) {
return null;
}
return mSinchClient.getAudioController();
}
public void LogOut() {
if (mSinchClient != null) {
mSinchClient.stopListeningOnActiveConnection();
mSinchClient.unregisterPushNotificationData();
mSinchClient.unregisterManagedPush();
//mSinchClient.terminate();
}
}
}
public interface StartFailedListener {
void onStartFailed(SinchError error);
void onStarted();
}
private class MySinchClientListener implements SinchClientListener {
#Override
public void onClientFailed(SinchClient client, SinchError error) {
if (mListener != null) {
mListener.onStartFailed(error);
}
mSinchClient.terminate();
mSinchClient = null;
}
#Override
public void onClientStarted(SinchClient client) {
Log.d(TAG, "SinchClient started");
if (mListener != null) {
mListener.onStarted();
}
}
#Override
public void onClientStopped(SinchClient client) {
Log.d(TAG, "SinchClient stopped");
}
#Override
public void onLogMessage(int level, String area, String message) {
switch (level) {
case Log.DEBUG:
Log.d(area, message);
break;
case Log.ERROR:
Log.e(area, message);
break;
case Log.INFO:
Log.i(area, message);
break;
case Log.VERBOSE:
Log.v(area, message);
break;
case Log.WARN:
Log.w(area, message);
break;
}
}
#Override
public void onRegistrationCredentialsRequired(SinchClient client, ClientRegistration clientRegistration) {
}
}
private class SinchCallClientListener implements CallClientListener {
#Override
public void onIncomingCall(CallClient callClient, Call call) {
if (call.getDetails().isVideoOffered()) {
Intent intent = new Intent(SinchService.this, IncomingVideoCall.class);
intent.putExtra(CALL_ID, call.getCallId());
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_HISTORY);
SinchService.this.startActivity(intent);
} else {
Intent intent = new Intent(SinchService.this, IncomingAudioCall.class);
intent.putExtra(CALL_ID, call.getCallId());
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_HISTORY);
SinchService.this.startActivity(intent);
}
}
}
private class PersistedSettings {
private SharedPreferences mStore;
private static final String PREF_KEY = "Sinch";
public PersistedSettings(Context context) {
mStore = context.getSharedPreferences(PREF_KEY, MODE_PRIVATE);
}
public String getUsername() {
return mStore.getString("Username", "");
}
public void setUsername(String username) {
SharedPreferences.Editor editor = mStore.edit();
editor.putString("Username", username);
editor.commit();
}
}
public void sendMessage(String recipientUserId, String name, String textBody, String imageUrl) {
if (isStarted()) {
WritableMessage message = new WritableMessage();
message.addHeader("imageUrl", imageUrl);
message.addHeader("Name", name);
message.addRecipient(recipientUserId);
message.setTextBody(textBody);
mSinchClient.getMessageClient().send(message);
}
}
public void addMessageClientListener(MessageClientListener listener) {
if (mSinchClient != null) {
mSinchClient.getMessageClient().addMessageClientListener(listener);
}
}
public void removeMessageClientListener(MessageClientListener listener) {
if (mSinchClient != null) {
mSinchClient.getMessageClient().removeMessageClientListener(listener);
}
}
}
i am sending message like this.
private void sendMessage() {
String textBody = mTxtTextBody.getText().toString();
if (textBody.isEmpty()) {
Toast.makeText(this, "No text message", Toast.LENGTH_SHORT).show();
return;
}
getSinchServiceInterface().sendMessage(receiver_username, name, textBody, picture);
mTxtTextBody.setText("");
}
and the adapter where extracting message headers is
public class MessageAdapter extends BaseAdapter {
public static final int DIRECTION_INCOMING = 0;
public static final int DIRECTION_OUTGOING = 1;
private List<Pair<Message, Integer>> mMessages;
private SimpleDateFormat mFormatter;
private LayoutInflater mInflater;
Context context; // modification here
int res = 0;
String photo_url;
public MessageAdapter(Activity activity) {
mInflater = activity.getLayoutInflater();
context = activity;
mMessages = new ArrayList<>();
mFormatter = new SimpleDateFormat("hh:mm aa");
}
public void addMessage(Message message, int direction) {
mMessages.add(new Pair(message, direction));
notifyDataSetChanged();
}
#Override
public int getCount() {
return mMessages.size();
}
#Override
public Object getItem(int i) {
return mMessages.get(i);
}
#Override
public long getItemId(int i) {
return 0;
}
#Override
public int getViewTypeCount() {
return 2;
}
#Override
public int getItemViewType(int i) {
return mMessages.get(i).second;
}
#Override
public View getView(int i, View convertView, ViewGroup viewGroup) {
int direction = getItemViewType(i);
if (convertView == null) {
if (direction == DIRECTION_INCOMING) {
res = R.layout.message_right;
} else if (direction == DIRECTION_OUTGOING) {
res = R.layout.message_left;
}
convertView = mInflater.inflate(res, viewGroup, false);
}
Message message = mMessages.get(i).first;
String name = message.getHeaders().get("Name");
if (direction == DIRECTION_INCOMING) {
photo_url = message.getHeaders().get("imageUrl");
} else if (direction == DIRECTION_OUTGOING) {
photo_url = StaticInfo.getSavedData("photo", context);
}
CircleImageView photo = convertView.findViewById(R.id.pic);
Picasso.with(context).load(photo_url).into(photo);
TextView txtSender = convertView.findViewById(R.id.txtSender);
TextView txtMessage = convertView.findViewById(R.id.txtMessage);
TextView txtDate = convertView.findViewById(R.id.txtDate);
txtSender.setText(name);
txtMessage.setText(message.getTextBody());
txtDate.setText(mFormatter.format(message.getTimestamp()));
return convertView;
}
}
I have list of tasks. When I delete my one of the task my list still shows that task in the list but on server side i have updated list I am not able to refresh my list. I am getting new task array from server but not able to show it. When I launched my app again then it is showing the updated list. How can I get updated list without killing the app? Both the times I have updated array but not able to show it on the view.
public class ModelClass {
private String message;
private String statusCode;
private Response[] res = null;
protected transient PropertyChangeSupport _propertyChangeSupport = new PropertyChangeSupport(this);
public ModelClass() {
super();
clickEvent(new ActionEvent());
}
public static String taskId;
public void setTaskId(String taskId) {
System.out.print(taskId);
this.taskId = taskId;
}
public String getTaskId() {
return taskId;
}
public PropertyChangeSupport getPropertyChangeSupport() {
return _propertyChangeSupport;
}
public void setMessage(String message) {
String oldMessage = this.message;
this.message = message;
_propertyChangeSupport.firePropertyChange("message", oldMessage, message);
}
public String getMessage() {
return message;
}
public void setStatusCode(String statusCode) {
String oldStatusCode = this.statusCode;
this.statusCode = statusCode;
_propertyChangeSupport.firePropertyChange("statusCode", oldStatusCode, statusCode);
}
public String getStatusCode() {
return statusCode;
}
public void setRes(Response[] res) {
Response[] oldRes = this.res;
this.res = res;
System.out.println(res);
_propertyChangeSupport.firePropertyChange("res", oldRes, res);
System.out.println("refreshing here ");
}
public Response[] getRes() {
return res;
}
#Override
public String toString() {
return "ClassPojo [response = " + res + ", message = " + message + ", statusCode = " + statusCode + "]";
}
public void addPropertyChangeListener(PropertyChangeListener l) {
_propertyChangeSupport.addPropertyChangeListener(l);
}
public void removePropertyChangeListener(PropertyChangeListener l) {
_propertyChangeSupport.removePropertyChangeListener(l);
}
public class Response {
private String taskId;
private String taskType;
private Integer taskTime;
private String taskName;
private PropertyChangeSupport _propertyChangeSupport = new PropertyChangeSupport(this);
Response(String taskId, String taskType, String taskName) {
super();
this.taskId = taskId;
this.taskType = taskType;
this.taskName = taskName;
}
public void setTaskId(String taskId) {
String oldTaskId = this.taskId;
this.taskId = taskId;
_propertyChangeSupport.firePropertyChange("taskId", oldTaskId, taskId);
}
public String getTaskId() {
return taskId;
}
public void setTaskType(String taskType) {
String oldTaskType = this.taskType;
this.taskType = taskType;
_propertyChangeSupport.firePropertyChange("taskType", oldTaskType, taskType);
}
public String getTaskType() {
return taskType;
}
public void setTaskTime(Integer taskTime) {
Integer oldTaskTime = this.taskTime;
this.taskTime = taskTime;
_propertyChangeSupport.firePropertyChange("taskTime", oldTaskTime, taskTime);
}
public Integer getTaskTime() {
return taskTime;
}
public void setTaskName(String taskName) {
String oldTaskName = this.taskName;
this.taskName = taskName;
_propertyChangeSupport.firePropertyChange("taskName", oldTaskName, taskName);
}
public String getTaskName() {
return taskName;
}
#Override
public String toString() {
return "ClassPojo [taskId = " + taskId + ", taskType = " + taskType + ", taskTime = " + taskTime +
", taskName = " + taskName + "]";
}
public void addPropertyChangeListener(PropertyChangeListener l) {
_propertyChangeSupport.addPropertyChangeListener(l);
}
public void removePropertyChangeListener(PropertyChangeListener l) {
_propertyChangeSupport.removePropertyChangeListener(l);
}
}
protected transient ProviderChangeSupport providerChangeSupport = new ProviderChangeSupport(this);
public void addProviderChangeListener(ProviderChangeListener l) {
providerChangeSupport.addProviderChangeListener(l);
}
public void removeProviderChangeListener(ProviderChangeListener l) {
providerChangeSupport.removeProviderChangeListener(l);
}
public void clickEvent(ActionEvent actionEvent) {
try {
JSONObject paramsMap = new JSONObject();
paramsMap.put("userId", "1");
HttpURLConnection httpURLConnection = null;
try {
URL url = new URL("http://ec2-54-226-57-153.compute-1.amazonaws.com:8080/#########");
httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setReadTimeout(120000);
httpURLConnection.setConnectTimeout(120000);
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setRequestProperty("Content-Type", "application/json");
httpURLConnection.setDoInput(true);
httpURLConnection.setDoOutput(true);
httpURLConnection.connect();
OutputStream os = httpURLConnection.getOutputStream();
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
os.write(paramsMap.toString().getBytes());
bufferedWriter.flush();
bufferedWriter.close();
os.close();
if (httpURLConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
InputStream is = httpURLConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
StringBuilder builder = new StringBuilder();
String line = bufferedReader.readLine();
while (line != null) {
builder.append(line + "\n");
line = bufferedReader.readLine();
}
is.close();
if (httpURLConnection != null)
httpURLConnection.disconnect();
System.out.println(builder.toString());
JSONObject json = new JSONObject(builder.toString());
String status = json.optString("statusCode");
String message = json.optString("message");
String response = json.optString("response");
System.out.println(status);
System.out.println(message);
// System.out.println(response);
JSONArray objarr = json.optJSONArray("response");
Response[] temp_res = new Response[objarr.length()];
for (int i = 0; i < objarr.length(); i++) {
System.out.println(objarr.getJSONObject(i));
JSONObject obj = objarr.getJSONObject(i);
String task = obj.optString("taskName");
taskId = obj.optString("taskId");
String taskType = obj.optString("taskType");
System.out.println(task);
System.out.println(taskId);
System.out.println(taskType);
temp_res[i] = new Response(taskId, taskType, task);
}
setRes(temp_res);
} else {
if (httpURLConnection != null)
httpURLConnection.disconnect();
System.out.println("Invalid response from the server");
}
} catch (Exception e) {
e.printStackTrace();
if (httpURLConnection != null)
httpURLConnection.disconnect();
} finally {
if (httpURLConnection != null)
httpURLConnection.disconnect();
}
} catch (Exception e) {
e.printStackTrace();
}
}
I think you need to add providerChangeSupport.fireProviderRefresh("res");
and you have to make public method for providerChangeSupport.
Here is the link : https://community.oracle.com/message/13203364#13203364
Other than the fix suggested by Rashi Verma, there is one more change required.
The code snippet:
res = (Response[]) res_new.toArray(new Response[res_new.size()]);
setRes(res);
needs to be changed to:
Response[] temp_res;
temp_res = (Response[]) res_new.toArray(new
Response[res_new.size()]);
setRes(temp_res);
Currently, because the value of res is changed before invoking setRes, the propertyChangeEvent is not fired inside setRes. Both this propertyChangeEvent and the providerRefresh are needed for the changes you are making to start reflecting on the UI.
This code will check my link is broken or not and validateWebResourceUrl method will return 0 status .even if i get 200 status my link couldn't redirect to mozilla firefox when i call my api call.Below code will show u my api cal.
#RequestMapping(method = RequestMethod.POST, value = "/validate/fburl")
public ModelAndView validateFbLink(HttpServletRequest request,#RequestParam(value="key", required=true) String key ,#RequestParam(value = "link") String link, HttpServletResponse response) throws Exception {
ModelAndView jsonmodel = new ModelAndView("rest/model");
jsonmodel.addObject("model", httpFrameBreakChecker.validateHttpLink(link, key));
return jsonmodel;
}
This api call will go to check the link is broken or not ,if not it will go to redirect.I am trying to find the broken links and i am getting status 200 for that link but that link is not redirecting.Below is my code.
package org.ednovo.gooru.util;
import org.springframework.stereotype.Component;
import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.WebResponse;
#Component
public class HttpFrameBreakChecker extends LinkChecker {
#Override
public Integer validateHttpLink(String resourceUrl, String key) {
Integer status = null;
status = validateWebResourceUrl(resourceUrl, getPageTesterPath());
putResourceStatus(status, key);
return status;
}
public synchronized Integer validateWebResourceUrl(String webURL, String pageTesterURL) {
WebClient webClient = null;
WebResponse webResponse = null;
try {
webClient = new WebClient(BrowserVersion.FIREFOX_3_6);
webClient.setCssEnabled(false);
webClient.setThrowExceptionOnScriptError(false);
webResponse = webClient.getPage(webURL).getWebResponse();
int i = webResponse.getStatusCode();
logger.info(i+"");
if (webResponse.getStatusCode() != 200) {
return null;
}
String urlToCheck = webURL + pageTesterURL;
// Now check if the page has a frame breaker.
webResponse = webClient.getPage(urlToCheck).getWebResponse();
int status = webResponse.getStatusCode();
logger.info(status+""+"frame");
String pageURL = webResponse.getWebRequest().getUrl().toString();
int validationStatus = (urlToCheck.equals(pageURL) && status == 200) ? 0 : 1;
logger.info(validationStatus+ " return statement of validateWebResourceUrl ");
return validationStatus;
} catch (Exception exception) {
logger.error("ERROR : Unable to start web driver : " + exception.getMessage());
return null;
} finally {
try {
if (webClient != null) {
webClient.closeAllWindows();
}
} catch (Exception ex) {
}
}
}
#Override
public void commitPage() {
if (resources.size() > 0) {
String resourcesString = getxStream().toXML(resources);
postData(getApiPath(), "/resource/urls/update/frameBreaker/" + getGlobalJobKey(), resourcesString);
postData(getSearchApiPath(), "/search/resource/update/index/" + getGlobalJobKey(), resourcesString );
}
}
#Override
public String getType() {
return "FB";
}
}
And Below code will show you the LinkChecker class.
package org.ednovo.gooru.util;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.restlet.data.Form;
import org.restlet.representation.Representation;
import org.restlet.resource.ClientResource;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
public abstract class LinkChecker extends BaseComponent {
private int pageSize = 100;
private Map<String, String> configSettings;
private XStream xStream = new XStream(new DomDriver());
protected Map<Integer, List<String>> resources = new HashMap<Integer, List<String>>();
private String listResponse = null;
private Map<Long, String> resourceUrls = null;
public final synchronized void execute() {
reset();
ClientResource configResource = null;
Representation representation = null;
try {
configResource = createClientResource(getApiPath() + "/config-settings");
representation = configResource.get();
String settingsText = representation.getText();
configSettings = (Map<String, String>) xStream.fromXML(settingsText);
if (isLinkCheckerSchedulerEnabled()) {
run();
}
} catch (Exception exception) {
logger.error(exception.getMessage());
} finally {
releaseClientResources(configResource, representation);
}
}
public void run() throws Exception {
reset();
int page = 0;
while (true) {
++page;
listResponse = null;
resourceUrls = null;
final int currentPage = page;
ClientResourceExecuter clientResourceExecuter = new ClientResourceExecuter() {
#Override
public void run(ClientResource clientResource, Representation representation) throws Exception {
reset();
clientResource = createClientResource(getSearchApiPath() +"/search/resource-url-check?category="+getType()+"&pageSize="+pageSize+"&format=xml");
representation = clientResource.get();
listResponse = representation.getText();
if (listResponse != null || listResponse.length() > 1) {
try {
resourceUrls = (Map<Long, String>) xStream.fromXML(listResponse);
} catch (Exception ex) {
logger.error("Conversion of json to list failed in " + getType() + " validation");
}
logger.warn("Validating " + getType() + " Urls of Page : " + currentPage + " with size : " + (resourceUrls != null ? resourceUrls.size() : 0));
validateResourceUrls(resourceUrls);
}
}
};
clientResourceExecuter = null;
listResponse = null;
if (resourceUrls == null || resourceUrls.size() == 0) {
break;
}
if (getType().equals("HTTP") && page >= 5) {
break;
}else if (getType().equals("FB") && page >= 1) {
break;
}
}
}
public Integer validateHttpLink(String link, String key) {
URL url = null;
URLConnection connection = null;
HttpURLConnection httpConnection = null;
Integer responseCode = null;
try {
url = new URL(link);
connection = url.openConnection();
connection.connect();
httpConnection = (HttpURLConnection) connection;
httpConnection.setConnectTimeout(60000);
responseCode = httpConnection.getResponseCode();
if (responseCode != 200) {
logger.error("Url Checker validation fails for resource : " + link + " : " + responseCode);
}
} catch (MalformedURLException e) {
logger.error("Error in link checker : " + link + " Message : " + e.getMessage());
return 404;
} catch (IOException e) {
logger.error("Error in link checker : " + link + " Message : " + e.getMessage());
return 404;
} catch (Exception ex) {
logger.error("Error in link checker : " + link + " Message : " + ex.getMessage());
return null;
} finally {
try {
if (httpConnection != null) {
httpConnection.disconnect();
}
} catch (Exception ex) {
}
}
return responseCode;
}
protected void postData(String path, String url, String data) {
Form form = new Form();
form.add("data", data);
createAndRunClientResource(path, url, form);
}
public void validateResourceUrls(Map<Long, String> resourceUrls) throws Exception {
if (resourceUrls.size() > 0) {
Iterator<?> iterator = resourceUrls.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<Long, String> entry = (Map.Entry<Long, String>) iterator.next();
String resourceUrl = entry.getValue();
if (getType().equals("FB")) {
Thread.sleep(1000);
} else {
Thread.sleep(900);
}
logger.debug("Validating " + getType() + " url - " + resourceUrl);
Integer status = validateHttpLink(resourceUrl, entry.getKey()+"");
putResourceStatus(status, entry.getKey()+"");
}
commitPage();
}
}
public void commitPage() throws Exception {
if (resources.size() > 0) {
String resourcesString = getxStream().toXML(resources);
postData(getApiPath(), "/resource/urls/checker/update/" + getGlobalJobKey(), resourcesString);
//postData(getSearchApiPath(), "/search/resource/update/index/" + getGlobalJobKey(), resourcesString);
}
}
public void putResourceStatus(Integer status, String resourceId) {
if (status == null) {
status = -99;
}
List<String> resourceIds = null;
if (resources.containsKey(status)) {
resourceIds = resources.get(status);
} else {
resourceIds = new ArrayList<String>();
resources.put(status, resourceIds);
}
resourceIds.add(resourceId);
}
public void reset() {
resources.clear();
}
public boolean isLinkCheckerSchedulerEnabled() {
if (configSettings != null && configSettings.containsKey("urlChecker.scheduler.enabled")) {
return configSettings.get("urlChecker.scheduler.enabled").equals("true") ? true : false;
} else {
return false;
}
}
public abstract String getType();
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public XStream getxStream() {
return xStream;
}
public static void main(String args[]) {
}
}