diff --git a/res/layout/chat.xml b/res/layout/chat.xml index 7d8a36867..f08594b00 100644 --- a/res/layout/chat.xml +++ b/res/layout/chat.xml @@ -181,13 +181,13 @@ android:choiceMode="multipleChoice" android:stackFromBottom="true" android:transcriptMode="normal" - android:dividerHeight="10dp" android:cacheColorHint="@color/transparent" - android:listSelector="@color/transparent" + android:listSelector="@color/transparent" android:layout_above="@id/remote_composing" android:layout_width="match_parent" android:layout_height="match_parent" - android:layout_margin="10dp" + android:layout_marginRight="10dp" + android:layout_marginLeft="10dp" android:layout_below="@+id/top"/> diff --git a/res/layout/chat_bubble.xml b/res/layout/chat_bubble.xml index 0942f2127..5323345db 100644 --- a/res/layout/chat_bubble.xml +++ b/res/layout/chat_bubble.xml @@ -20,6 +20,8 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_toLeftOf="@id/delete_message" + android:layout_marginTop="5dp" + android:layout_marginBottom="5dp" android:gravity="center_vertical"> + + OK Yes Link your account + An update is available the libre SIP client diff --git a/src/android/org/linphone/LinphoneManager.java b/src/android/org/linphone/LinphoneManager.java index b157eb9e6..4046e3ecb 100644 --- a/src/android/org/linphone/LinphoneManager.java +++ b/src/android/org/linphone/LinphoneManager.java @@ -27,6 +27,7 @@ import android.app.ProgressDialog; import android.content.BroadcastReceiver; import android.content.ContentResolver; import android.content.Context; +import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager.NameNotFoundException; @@ -691,6 +692,9 @@ public class LinphoneManager implements CoreListener, SensorEventListener, Accou String versionName = mServiceContext.getPackageManager().getPackageInfo(mServiceContext.getPackageName(), 0).versionName; if (versionName == null) { versionName = String.valueOf(mServiceContext.getPackageManager().getPackageInfo(mServiceContext.getPackageName(), 0).versionCode); + } else { + //Api to check version can't use version code + mLc.checkForUpdate(versionName); } mLc.setUserAgent("LinphoneAndroid", versionName); } catch (NameNotFoundException e) { @@ -1618,7 +1622,29 @@ public class LinphoneManager implements CoreListener, SensorEventListener, Accou @Override public void onVersionUpdateCheckResultReceived(Core lc, VersionUpdateCheckResult result, String version, String url) { - + if (result == VersionUpdateCheckResult.NewVersionAvailable) { + final String urlToUse = url; + final String versionAv = version; + mHandler.postDelayed(new Runnable() { + @Override + public void run() { + AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); + builder.setMessage(getString(R.string.update_available) + ": " + versionAv); + builder.setCancelable(false); + builder.setNeutralButton(getString(R.string.ok), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + if (urlToUse != null) { + Intent urlIntent = new Intent(Intent.ACTION_VIEW); + urlIntent.setData(Uri.parse(urlToUse)); + getContext().startActivity(urlIntent); + } + } + }); + builder.show(); + } + }, 1000); + } } @Override diff --git a/src/android/org/linphone/LinphoneService.java b/src/android/org/linphone/LinphoneService.java index 3f0a4bdaa..fc5bf8f5f 100644 --- a/src/android/org/linphone/LinphoneService.java +++ b/src/android/org/linphone/LinphoneService.java @@ -310,59 +310,13 @@ public final class LinphoneService extends Service { stopForegroundCompat(NOTIF_ID); } - @SuppressWarnings("unchecked") @Override - public void onCreate() { - super.onCreate(); - mLastNotificationId = 8; // To not interfere with other notifs ids - mChatNotifMap = new HashMap(); - - setupActivityMonitor(); - // In case restart after a crash. Main in LinphoneActivity - mNotificationTitle = getString(R.string.service_name); - - // Needed in order for the two next calls to succeed, libraries must have been loaded first - LinphonePreferences.instance().setContext(getBaseContext()); - Factory.instance().setLogCollectionPath(getFilesDir().getAbsolutePath()); - boolean isDebugEnabled = LinphonePreferences.instance().isDebugEnabled(); - LinphoneUtils.initLoggingService(isDebugEnabled, getString(R.string.app_name)); - - // Dump some debugging information to the logs - Log.i(START_LINPHONE_LOGS); - dumpDeviceInformation(); - dumpInstalledLinphoneInformation(); - - //Disable service notification for Android O - if ((Version.sdkAboveOrEqual(Version.API26_O_80))) { - LinphonePreferences.instance().setServiceNotificationVisibility(false); - mDisableRegistrationStatus = true; - } - - mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); - mNM.cancel(INCALL_NOTIF_ID); // in case of crash the icon is not removed - Compatibility.CreateChannel(this); - - Intent notifIntent = new Intent(this, incomingReceivedActivity); - notifIntent.putExtra("Notification", true); - mNotifContentIntent = PendingIntent.getActivity(this, 0, notifIntent, PendingIntent.FLAG_UPDATE_CURRENT); - - Bitmap bm = null; - try { - bm = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher); - } catch (Exception e) { - } - mNotif = Compatibility.createNotification(this, mNotificationTitle, "", R.drawable.linphone_notification_icon, R.mipmap.ic_launcher, bm, mNotifContentIntent, true,notifcationsPriority); + public int onStartCommand(Intent intent, int flags, int startId) { + super.onStartCommand(intent, flags, startId); LinphoneManager.createAndStart(LinphoneService.this); instance = this; // instance is ready once linphone manager has been created - incomingReceivedActivityName = LinphonePreferences.instance().getActivityToLaunchOnIncomingReceived(); - try { - incomingReceivedActivity = (Class) Class.forName(incomingReceivedActivityName); - } catch (ClassNotFoundException e) { - Log.e(e); - } - LinphoneManager.getLc().addListener(mListener = new CoreListenerStub() { @Override public void onCallStateChanged(Core lc, Call call, Call.State state, String message) { @@ -451,12 +405,8 @@ public final class LinphoneService extends Service { } }); - - try { - mStartForeground = getClass().getMethod("startForeground", mStartFgSign); - mStopForeground = getClass().getMethod("stopForeground", mStopFgSign); - } catch (NoSuchMethodException e) { - Log.e(e, "Couldn't find startForeground or stopForeground"); + if (displayServiceNotification() || (Version.sdkAboveOrEqual(Version.API26_O_80) && intent.getBooleanExtra("ForceStartForeground", false))) { + startForegroundCompat(NOTIF_ID, mNotif); } if (!Version.sdkAboveOrEqual(Version.API26_O_80) @@ -464,10 +414,6 @@ public final class LinphoneService extends Service { getContentResolver().registerContentObserver(ContactsContract.Contacts.CONTENT_URI, true, ContactsManager.getInstance()); } - if (displayServiceNotification()) { - startForegroundCompat(NOTIF_ID, mNotif); - } - if (!mTestDelayElapsed) { // Only used when testing. Simulates a 5 seconds delay for launching service mHandler.postDelayed(new Runnable() { @@ -478,11 +424,71 @@ public final class LinphoneService extends Service { } //make sure the application will at least wakes up every 10 mn - Intent intent = new Intent(this, KeepAliveReceiver.class); - PendingIntent keepAlivePendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_ONE_SHOT); + Intent keepAliveIntent = new Intent(this, KeepAliveReceiver.class); + PendingIntent keepAlivePendingIntent = PendingIntent.getBroadcast(this, 0, keepAliveIntent, PendingIntent.FLAG_ONE_SHOT); AlarmManager alarmManager = ((AlarmManager) this.getSystemService(Context.ALARM_SERVICE)); Compatibility.scheduleAlarm(alarmManager, AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 600000, keepAlivePendingIntent); + return START_STICKY; + } + + @SuppressWarnings("unchecked") + @Override + public void onCreate() { + super.onCreate(); + mLastNotificationId = 8; // To not interfere with other notifs ids + mChatNotifMap = new HashMap(); + + setupActivityMonitor(); + // In case restart after a crash. Main in LinphoneActivity + mNotificationTitle = getString(R.string.service_name); + + // Needed in order for the two next calls to succeed, libraries must have been loaded first + LinphonePreferences.instance().setContext(getBaseContext()); + Factory.instance().setLogCollectionPath(getFilesDir().getAbsolutePath()); + boolean isDebugEnabled = LinphonePreferences.instance().isDebugEnabled(); + LinphoneUtils.initLoggingService(isDebugEnabled, getString(R.string.app_name)); + + // Dump some debugging information to the logs + Log.i(START_LINPHONE_LOGS); + dumpDeviceInformation(); + dumpInstalledLinphoneInformation(); + + //Disable service notification for Android O + if ((Version.sdkAboveOrEqual(Version.API26_O_80))) { + LinphonePreferences.instance().setServiceNotificationVisibility(false); + mDisableRegistrationStatus = true; + } + + mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); + mNM.cancel(INCALL_NOTIF_ID); // in case of crash the icon is not removed + Compatibility.CreateChannel(this); + + Intent notifIntent = new Intent(this, incomingReceivedActivity); + notifIntent.putExtra("Notification", true); + mNotifContentIntent = PendingIntent.getActivity(this, 0, notifIntent, PendingIntent.FLAG_UPDATE_CURRENT); + + Bitmap bm = null; + try { + bm = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher); + } catch (Exception e) { + } + mNotif = Compatibility.createNotification(this, mNotificationTitle, "", R.drawable.linphone_notification_icon, R.mipmap.ic_launcher, bm, mNotifContentIntent, true,notifcationsPriority); + + incomingReceivedActivityName = LinphonePreferences.instance().getActivityToLaunchOnIncomingReceived(); + try { + incomingReceivedActivity = (Class) Class.forName(incomingReceivedActivityName); + } catch (ClassNotFoundException e) { + Log.e(e); + } + + try { + mStartForeground = getClass().getMethod("startForeground", mStartFgSign); + mStopForeground = getClass().getMethod("stopForeground", mStopFgSign); + } catch (NoSuchMethodException e) { + Log.e(e, "Couldn't find startForeground or stopForeground"); + } + mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE); } diff --git a/src/android/org/linphone/chat/ChatBubbleViewHolder.java b/src/android/org/linphone/chat/ChatBubbleViewHolder.java index 1606d127e..671b06ea8 100644 --- a/src/android/org/linphone/chat/ChatBubbleViewHolder.java +++ b/src/android/org/linphone/chat/ChatBubbleViewHolder.java @@ -47,6 +47,7 @@ public class ChatBubbleViewHolder extends RecyclerView.ViewHolder implements Vie public TextView eventMessage; public RelativeLayout bubbleLayout; + public LinearLayout separatorLayout; public LinearLayout background; public ImageView contactPicture; public ImageView contactPictureMask; @@ -93,6 +94,7 @@ public class ChatBubbleViewHolder extends RecyclerView.ViewHolder implements Vie this.messageText = view.findViewById(R.id.message); this.messageImage = view.findViewById(R.id.image); + this.separatorLayout = view.findViewById(R.id.separator); this.fileTransferLayout = view.findViewById(R.id.file_transfer_layout); this.fileTransferProgressBar = view.findViewById(R.id.progress_bar); @@ -128,6 +130,7 @@ public class ChatBubbleViewHolder extends RecyclerView.ViewHolder implements Vie this.messageText = view.findViewById(R.id.message); this.messageImage = view.findViewById(R.id.image); + this.separatorLayout = view.findViewById(R.id.separator); this.fileTransferLayout = view.findViewById(R.id.file_transfer_layout); this.fileTransferProgressBar = view.findViewById(R.id.progress_bar); diff --git a/src/android/org/linphone/chat/ChatEventsAdapter.java b/src/android/org/linphone/chat/ChatEventsAdapter.java index d444c0195..25ab1eb28 100644 --- a/src/android/org/linphone/chat/ChatEventsAdapter.java +++ b/src/android/org/linphone/chat/ChatEventsAdapter.java @@ -59,6 +59,7 @@ import org.linphone.core.ChatMessage; import org.linphone.core.ChatMessageListenerStub; import org.linphone.core.ChatRoom; import org.linphone.core.Content; +import org.linphone.core.Event; import org.linphone.core.EventLog; import org.linphone.core.LimeState; import org.linphone.mediastream.Log; @@ -77,12 +78,14 @@ import java.util.List; import static android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION; + public class ChatEventsAdapter extends SelectableAdapter { -//public class ChatEventsAdapter extends RecyclerView.Adapter { + + private static int MARGIN_BETWEEN_MESSAGES = 10; + private static int SIDE_MARGIN = 100; private Context mContext; private List mHistory; private List mParticipants; -// private LayoutInflater mLayoutInflater; private int itemResource; private Bitmap mDefaultBitmap; private GroupChatFragment mFragment; @@ -90,16 +93,12 @@ public class ChatEventsAdapter extends SelectableAdapter { private ChatBubbleViewHolder.ClickListener clickListener; -// public ChatEventsAdapter(GroupChatFragment fragment, ListSelectionHelper helper, LayoutInflater inflater, EventLog[] history, ArrayList participants) { public ChatEventsAdapter(GroupChatFragment fragment, SelectableHelper helper, int itemResource, EventLog[] history, ArrayList participants, ChatBubbleViewHolder.ClickListener clickListener) { -// public ChatEventsAdapter(GroupChatFragment fragment, SelectableHelper helper, LayoutInflater inflater, ArrayList mHistory, ArrayList participants, ChatBubbleViewHolder.ClickListener clickListener) { super(helper); this.mFragment=fragment; this.mContext = mFragment.getActivity(); this.itemResource = itemResource; -// this.mLayoutInflater = inflater; -// this.mHistory = mHistory; mHistory = new ArrayList<>(Arrays.asList(history)); this.mParticipants = participants; this.clickListener = clickListener; @@ -224,13 +223,14 @@ public class ChatEventsAdapter extends SelectableAdapter { holder.imdmLabel.setTextColor(mContext.getResources().getColor(R.color.colorI)); } - if (isEditionEnabled()) { - layoutParams.addRule(RelativeLayout.LEFT_OF, holder.delete.getId()); - layoutParams.setMargins(100, 10, 10, 10); - } else { - layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); - layoutParams.setMargins(100, 10, 10, 10); - } + + if (isEditionEnabled()) { + layoutParams.addRule(RelativeLayout.LEFT_OF, holder.delete.getId()); + layoutParams.setMargins(SIDE_MARGIN, MARGIN_BETWEEN_MESSAGES/2, 0, MARGIN_BETWEEN_MESSAGES/2); + } else { + layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); + layoutParams.setMargins(SIDE_MARGIN, MARGIN_BETWEEN_MESSAGES/2, 0, MARGIN_BETWEEN_MESSAGES/2); + } holder.background.setBackgroundResource(R.drawable.resizable_chat_bubble_outgoing); Compatibility.setTextAppearance(holder.contactName, mContext, R.style.font3); @@ -245,13 +245,14 @@ public class ChatEventsAdapter extends SelectableAdapter { } } - if (isEditionEnabled()) { - layoutParams.addRule(RelativeLayout.LEFT_OF, holder.delete.getId()); - layoutParams.setMargins(100, 10, 10, 10); - } else { - layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT); - layoutParams.setMargins(10, 10, 100, 10); - } + + if (isEditionEnabled()) { + layoutParams.addRule(RelativeLayout.LEFT_OF, holder.delete.getId()); + layoutParams.setMargins(SIDE_MARGIN, MARGIN_BETWEEN_MESSAGES/2, 0, MARGIN_BETWEEN_MESSAGES/2); + } else { + layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT); + layoutParams.setMargins(0, MARGIN_BETWEEN_MESSAGES/2, SIDE_MARGIN, MARGIN_BETWEEN_MESSAGES/2); + } holder.background.setBackgroundResource(R.drawable.resizable_chat_bubble_incoming); Compatibility.setTextAppearance(holder.contactName, mContext, R.style.font9); @@ -644,7 +645,6 @@ public class ChatEventsAdapter extends SelectableAdapter { } private BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) { -// private BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) { if (imageView != null) { final Drawable drawable = imageView.getDrawable(); if (drawable instanceof AsyncBitmap) { diff --git a/src/android/org/linphone/chat/GroupChatFragment.java b/src/android/org/linphone/chat/GroupChatFragment.java index 18e550e94..e001c6168 100644 --- a/src/android/org/linphone/chat/GroupChatFragment.java +++ b/src/android/org/linphone/chat/GroupChatFragment.java @@ -530,7 +530,7 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener, Con getContactsForParticipants(); - mRemoteComposing.setVisibility(View.INVISIBLE); + mRemoteComposing.setVisibility(View.GONE); } private void displayChatRoomHeader() { diff --git a/src/android/org/linphone/receivers/BootReceiver.java b/src/android/org/linphone/receivers/BootReceiver.java index 360382a8d..340206aec 100644 --- a/src/android/org/linphone/receivers/BootReceiver.java +++ b/src/android/org/linphone/receivers/BootReceiver.java @@ -42,6 +42,7 @@ public class BootReceiver extends BroadcastReceiver { if (autostart) { Intent lLinphoneServiceIntent = new Intent(Intent.ACTION_MAIN); lLinphoneServiceIntent.setClass(context, LinphoneService.class); + lLinphoneServiceIntent.putExtra("ForceStartForeground", true); Compatibility.startService(context, lLinphoneServiceIntent); } }