Merge remote-tracking branch 'origin/master' into dev_codec_downloader
This commit is contained in:
commit
e3f6137c5d
40 changed files with 1130 additions and 1003 deletions
6
.gitmodules
vendored
6
.gitmodules
vendored
|
@ -38,9 +38,6 @@
|
|||
[submodule "submodules/mssilk"]
|
||||
path = submodules/mssilk
|
||||
url = git://git.linphone.org/mssilk.git
|
||||
[submodule "submodules/externals/vo-amrwbenc"]
|
||||
path = submodules/externals/vo-amrwbenc
|
||||
url = git://git.linphone.org/vo-amrwbenc.git
|
||||
[submodule "submodules/bcg729"]
|
||||
path = submodules/bcg729
|
||||
url = git://git.linphone.org/bcg729.git
|
||||
|
@ -104,3 +101,6 @@
|
|||
[submodule "submodules/bcunit"]
|
||||
path = submodules/bcunit
|
||||
url = git://git.linphone.org/bcunit.git
|
||||
[submodule "submodules/externals/vo-amrwbenc"]
|
||||
path = submodules/externals/vo-amrwbenc
|
||||
url = git://git.linphone.org/vo-amrwbenc.git
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
<uses-feature android:name="android.hardware.camera" android:required="false" />
|
||||
<uses-permission android:name="android.permission.READ_LOGS" />
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||
<!-- Needed to store received images if the user wants to -->
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
<!-- Needed to use our own Contact editor -->
|
||||
|
@ -43,6 +44,8 @@
|
|||
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS"/>
|
||||
<!-- Needed for in-app purchase -->
|
||||
<uses-permission android:name="com.android.vending.BILLING" />
|
||||
<!-- Needed for overlay widget -->
|
||||
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
|
||||
|
||||
<supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:xlargeScreens="true" android:anyDensity="true"/>
|
||||
|
||||
|
@ -75,7 +78,7 @@
|
|||
</intent-filter>
|
||||
|
||||
<intent-filter>
|
||||
<data android:mimeType="vnd.android.cursor.item/org.linphone.profile" /> <!-- Change package ! -->
|
||||
<data android:mimeType="@string/sync_mimetype" /> <!-- Change package in res/values/non_localizable_custom.xml ! -->
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
|
@ -94,7 +97,6 @@
|
|||
|
||||
<activity android:name=".CallIncomingActivity"
|
||||
android:theme="@style/NoTitle"
|
||||
android:noHistory="true"
|
||||
android:launchMode="singleTop"
|
||||
android:screenOrientation="behind">
|
||||
<intent-filter>
|
||||
|
@ -104,7 +106,6 @@
|
|||
|
||||
<activity android:name=".CallOutgoingActivity"
|
||||
android:theme="@style/NoTitle"
|
||||
android:noHistory="true"
|
||||
android:launchMode="singleTop"
|
||||
android:screenOrientation="behind">
|
||||
<intent-filter>
|
||||
|
|
|
@ -8,50 +8,6 @@
|
|||
failonerror="false" />
|
||||
</target>
|
||||
|
||||
<target name="javah" depends="-set-debug-mode,-compile">
|
||||
<echo level="info">Generate JNI header</echo>
|
||||
<javah outputfile="gen/linphonecore_jni.h">
|
||||
<classpath>
|
||||
<pathelement location="${out.classes.absolute.dir}" />
|
||||
</classpath>
|
||||
<class name="org.linphone.core.LinphoneAddressImpl" />
|
||||
<class name="org.linphone.core.LinphoneAuthInfoImpl" />
|
||||
<class name="org.linphone.core.LinphoneCallImpl" />
|
||||
<class name="org.linphone.core.LinphoneCallLogImpl" />
|
||||
<class name="org.linphone.core.LinphoneCallParamsImpl" />
|
||||
<class name="org.linphone.core.LinphoneCallStatsImpl" />
|
||||
<class name="org.linphone.core.LinphoneChatMessageImpl" />
|
||||
<class name="org.linphone.core.LinphoneChatRoomImpl" />
|
||||
<class name="org.linphone.core.LinphoneCoreFactoryImpl" />
|
||||
<class name="org.linphone.core.LinphoneCoreImpl" />
|
||||
<class name="org.linphone.core.LinphoneFriendImpl" />
|
||||
<class name="org.linphone.core.LinphoneProxyConfigImpl" />
|
||||
<class name="org.linphone.core.PayloadTypeImpl" />
|
||||
<class name="org.linphone.core.LpConfigImpl" />
|
||||
<class name="org.linphone.core.LinphoneInfoMessageImpl" />
|
||||
<class name="org.linphone.core.LinphoneEventImpl" />
|
||||
<class name="org.linphone.core.PresenceActivityImpl" />
|
||||
<class name="org.linphone.core.PresenceModelImpl" />
|
||||
<class name="org.linphone.core.PresenceNoteImpl" />
|
||||
<class name="org.linphone.core.PresencePersonImpl" />
|
||||
<class name="org.linphone.core.PresenceServiceImpl" />
|
||||
<class name="org.linphone.core.ErrorInfoImpl" />
|
||||
<class name="org.linphone.core.TunnelConfigImpl" />
|
||||
</javah>
|
||||
<javah outputfile="gen/xml2lpc_jni.h">
|
||||
<classpath>
|
||||
<pathelement location="${out.classes.absolute.dir}" />
|
||||
</classpath>
|
||||
<class name="org.linphone.tools.Xml2Lpc" />
|
||||
</javah>
|
||||
<javah outputfile="gen/lpc2xml_jni.h">
|
||||
<classpath>
|
||||
<pathelement location="${out.classes.absolute.dir}" />
|
||||
</classpath>
|
||||
<class name="org.linphone.tools.Lpc2Xml" />
|
||||
</javah>
|
||||
</target>
|
||||
|
||||
<target name="partial-clean">
|
||||
<delete file="bin/${ant.project.name}.ap_" />
|
||||
</target>
|
||||
|
|
|
@ -287,6 +287,12 @@ generate-mediastreamer2-apk: java-clean build copy-libs update-mediastreamer2-pr
|
|||
\techo "version.name=$(LINPHONE_ANDROID_VERSION)" > default.properties && \\
|
||||
\tant debug
|
||||
|
||||
quick:
|
||||
\tant clean
|
||||
\tant debug
|
||||
\tant installd
|
||||
\tant run
|
||||
|
||||
install-apk:
|
||||
\tant installd
|
||||
|
||||
|
@ -328,7 +334,6 @@ run-all-tests: update-project
|
|||
\tant partial-clean
|
||||
\t$(MAKE) -C tests run-all-tests ANT_SILENT=$(ANT_SILENT)
|
||||
|
||||
|
||||
pull-transifex:
|
||||
\ttx pull -af
|
||||
|
||||
|
|
|
@ -78,6 +78,13 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="40dp"
|
||||
android:singleLine="true"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/forgot_password"
|
||||
android:layout_gravity="right"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"/>
|
||||
</LinearLayout>
|
||||
</TableRow>
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<string name="default_stun">stun.linphone.org</string>
|
||||
|
||||
<string name="sync_account_type">org.linphone</string> <!-- Change package ! -->
|
||||
<string name="sync_mimetype">vnd.android.cursor.item/org.linphone.profile</string> <!-- Change package, leave .profile at the end ! -->
|
||||
<string name="sync_mimetype">vnd.android.cursor.item/org.linphone.profile</string> <!-- Change package, leave .profile at the end. Also change res/xml/contacts.xml ! -->
|
||||
|
||||
<bool name="assistant_use_linphone_login_as_first_fragment">false</bool>
|
||||
<bool name="hide_in_call_stats">false</bool>
|
||||
|
@ -68,10 +68,8 @@
|
|||
<string name="about_bugreport_email">linphone-android@belledonne-communications.com</string>
|
||||
<bool name="use_linphonecore_ringing">false</bool>
|
||||
|
||||
|
||||
<string name="temp_photo_name">linphone-android-photo-temp.jpg</string>
|
||||
<string name="temp_photo_name_with_date">linphone-android-photo-%s.jpg</string>
|
||||
|
||||
<string name="temp_photo_name">linphone-android-photo-temp</string>
|
||||
<string name="temp_photo_name_with_date">linphone-android-photo-%s</string>
|
||||
|
||||
<bool name="hide_phone_numbers_in_editor">false</bool>
|
||||
<bool name="hide_sip_addresses_in_editor">false</bool>
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
|
||||
<string name="pref_wifi_only_key">pref_wifi_only_key</string>
|
||||
|
||||
<string name="pref_overlay_key">pref_overlay_key</string>
|
||||
<string name="pref_video_use_front_camera_key">pref_video_use_front_camera_key</string>
|
||||
<string name="pref_video_codec_h263_key">pref_video_codec_h263_key</string>
|
||||
<string name="pref_video_codec_mpeg4_key">pref_video_codec_mpeg4_key</string>
|
||||
|
@ -71,6 +72,7 @@
|
|||
<string name="pref_preferred_video_fps_key">pref_preferred_video_fps_key</string>
|
||||
<string name="pref_bandwidth_limit_key">pref_bandwidth_limit_key</string>
|
||||
<string name="pref_animation_enable_key">pref_animation_enable_key</string>
|
||||
<string name="pref_service_notification_key">pref_service_notification_key</string>
|
||||
<string name="pref_escape_plus_key">pref_escape_plus_key</string>
|
||||
<string name="pref_friendlist_subscribe_key">pref_friendlist_subscribe_key</string>
|
||||
<string name="pref_echo_cancellation_key">pref_echo_cancellation_key</string>
|
||||
|
@ -197,4 +199,6 @@
|
|||
<item>Send logs</item>
|
||||
<item>Cancel</item>
|
||||
</string-array>
|
||||
|
||||
<string name="pref_use_lime_encryption_key">pref_use_lime_encryption_key</string>
|
||||
</resources>
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
<string name="messages_date_format">dd/MM, HH:mm</string>
|
||||
<string name="messages_list_date_format">dd/MM</string>
|
||||
<string name="today_date_format">HH:mm</string>
|
||||
<string name="picture_name_format">linphone-mms-%s.jpg</string>
|
||||
|
||||
<!-- Common -->
|
||||
<string name="username">Username</string>
|
||||
|
@ -255,6 +254,8 @@
|
|||
|
||||
<!-- Video settings -->
|
||||
<string name="pref_video_title">Video</string>
|
||||
<string name="pref_overlay">Video overlay</string>
|
||||
<string name="pref_overlay_summary">Display call video in overlay when outside the application</string>
|
||||
<string name="pref_video_use_front_camera_title">Use front camera</string>
|
||||
<string name="pref_video_initiate_call_with_video_title">Initiate video calls</string>
|
||||
<string name="pref_video_initiate_call_with_video">Always send video requests</string>
|
||||
|
@ -272,6 +273,15 @@
|
|||
<string name="pref_rfc2833_dtmf">Send RFC2833 DTMFs</string>
|
||||
<string name="pref_sipinfo_dtmf">Send SIP INFO DTMFs</string>
|
||||
<string name="pref_voice_mail">Voice mail URI</string>
|
||||
|
||||
<!-- Chat settings -->
|
||||
<string name="pref_chat_title">Chat</string>
|
||||
<string name="pref_image_sharing_server_title">Sharing server</string>
|
||||
<string name="pref_image_sharing_server_desc">Do not edit unless you know what you are doing!</string>
|
||||
<string name="pref_use_lime_encryption">Use LIME encryption</string>
|
||||
<string name="lime_encryption_entry_disabled">Disabled</string>
|
||||
<string name="lime_encryption_entry_mandatory">Mandatory</string>
|
||||
<string name="lime_encryption_entry_preferred">Preferred</string>
|
||||
|
||||
<!-- Network settings -->
|
||||
<string name="pref_network_title">Network</string>
|
||||
|
@ -294,9 +304,9 @@
|
|||
<string name="pref_debug">Debug</string>
|
||||
<string name="pref_background_mode">Background mode</string>
|
||||
<string name="pref_animation_enable_title">Enable Animations</string>
|
||||
<string name="pref_service_notification">Enable service notification</string>
|
||||
<string name="pref_autostart">Start at boot time</string>
|
||||
<string name="pref_incoming_call_timeout_title">Incoming call hangup (in seconds)</string>
|
||||
<string name="pref_image_sharing_server_title">Sharing server</string>
|
||||
<string name="pref_remote_provisioning_title">Remote provisioning</string>
|
||||
<string name="pref_primary_account_title">Primary account</string>
|
||||
<string name="pref_display_name_title">Display name</string>
|
||||
|
|
|
@ -111,12 +111,17 @@
|
|||
android:title="@string/pref_bandwidth_limit"
|
||||
android:key="@string/pref_bandwidth_limit_key"
|
||||
android:numeric="integer" />
|
||||
|
||||
<CheckBoxPreference
|
||||
android:title="@string/pref_overlay"
|
||||
android:key="@string/pref_overlay_key"
|
||||
android:summary="@string/pref_overlay_summary"/>
|
||||
|
||||
<PreferenceCategory
|
||||
android:title="@string/pref_video_codecs_title"
|
||||
android:key="@string/pref_video_codecs_key"
|
||||
android:dependency="@string/pref_video_enable_key"
|
||||
android:shouldDisableView="true"/>
|
||||
<PreferenceCategory
|
||||
android:title="@string/pref_video_codecs_title"
|
||||
android:key="@string/pref_video_codecs_key"
|
||||
android:dependency="@string/pref_video_enable_key"
|
||||
android:shouldDisableView="true"/>
|
||||
|
||||
</PreferenceScreen>
|
||||
|
||||
|
@ -136,6 +141,20 @@
|
|||
android:key="@string/pref_voice_mail_key"/>
|
||||
|
||||
</PreferenceScreen>
|
||||
|
||||
<PreferenceScreen
|
||||
android:title="@string/pref_chat_title">
|
||||
|
||||
<EditTextPreference
|
||||
android:title="@string/pref_image_sharing_server_title"
|
||||
android:key="@string/pref_image_sharing_server_key"
|
||||
android:summary="@string/pref_image_sharing_server_desc"/>
|
||||
|
||||
<ListPreference
|
||||
android:title="@string/pref_use_lime_encryption"
|
||||
android:key="@string/pref_use_lime_encryption_key"/>
|
||||
|
||||
</PreferenceScreen>
|
||||
|
||||
<PreferenceScreen
|
||||
android:title="@string/pref_network_title">
|
||||
|
@ -202,6 +221,10 @@
|
|||
android:title="@string/pref_background_mode"
|
||||
android:key="@string/pref_background_mode_key"/>
|
||||
|
||||
<CheckBoxPreference
|
||||
android:title="@string/pref_service_notification"
|
||||
android:key="@string/pref_service_notification_key"/>
|
||||
|
||||
<CheckBoxPreference
|
||||
android:title="@string/pref_animation_enable_title"
|
||||
android:key="@string/pref_animation_enable_key"/>
|
||||
|
@ -215,10 +238,6 @@
|
|||
android:key="@string/pref_incoming_call_timeout_key"
|
||||
android:layout="@layout/hidden"/>
|
||||
|
||||
<EditTextPreference
|
||||
android:title="@string/pref_image_sharing_server_title"
|
||||
android:key="@string/pref_image_sharing_server_key"/>
|
||||
|
||||
<EditTextPreference
|
||||
android:title="@string/pref_remote_provisioning_title"
|
||||
android:key="@string/pref_remote_provisioning_key"/>
|
||||
|
|
|
@ -37,6 +37,7 @@ import org.linphone.ui.Numpad;
|
|||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.app.Dialog;
|
||||
import android.app.Fragment;
|
||||
import android.app.FragmentTransaction;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
@ -55,7 +56,6 @@ import android.os.CountDownTimer;
|
|||
import android.os.Handler;
|
||||
import android.os.PowerManager;
|
||||
import android.os.SystemClock;
|
||||
import android.app.Fragment;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.support.v4.widget.DrawerLayout;
|
||||
import android.view.Gravity;
|
||||
|
@ -87,6 +87,7 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve
|
|||
private final static int SECONDS_BEFORE_DENYING_CALL_UPDATE = 30000;
|
||||
private static final int PERMISSIONS_REQUEST_CAMERA = 202;
|
||||
private static final int PERMISSIONS_ENABLED_CAMERA = 203;
|
||||
private static final int PERMISSIONS_ENABLED_MIC = 204;
|
||||
|
||||
private static CallActivity instance;
|
||||
|
||||
|
@ -180,18 +181,14 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve
|
|||
if (state == State.IncomingReceived) {
|
||||
startIncomingCallActivity();
|
||||
return;
|
||||
}
|
||||
|
||||
if (state == State.Paused || state == State.PausedByRemote || state == State.Pausing) {
|
||||
} else if (state == State.Paused || state == State.PausedByRemote || state == State.Pausing) {
|
||||
if(LinphoneManager.getLc().getCurrentCall() != null) {
|
||||
enabledVideoButton(false);
|
||||
}
|
||||
if(isVideoEnabled(call)){
|
||||
showAudioView();
|
||||
}
|
||||
}
|
||||
|
||||
if (state == State.Resuming) {
|
||||
} else if (state == State.Resuming) {
|
||||
if(LinphonePreferences.instance().isVideoEnabled()){
|
||||
status.refreshStatusItems(call, isVideoEnabled(call));
|
||||
if(call.getCurrentParamsCopy().getVideoEnabled()){
|
||||
|
@ -201,9 +198,7 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve
|
|||
if(LinphoneManager.getLc().getCurrentCall() != null) {
|
||||
enabledVideoButton(true);
|
||||
}
|
||||
}
|
||||
|
||||
if (state == State.StreamsRunning) {
|
||||
} else if (state == State.StreamsRunning) {
|
||||
switchVideo(isVideoEnabled(call));
|
||||
enableAndRefreshInCallActions();
|
||||
|
||||
|
@ -211,9 +206,7 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve
|
|||
videoProgress.setVisibility(View.GONE);
|
||||
status.refreshStatusItems(call, isVideoEnabled(call));
|
||||
}
|
||||
}
|
||||
|
||||
if (state == State.CallUpdatedByRemote) {
|
||||
} else if (state == State.CallUpdatedByRemote) {
|
||||
// If the correspondent proposes video while audio call
|
||||
boolean videoEnabled = LinphonePreferences.instance().isVideoEnabled();
|
||||
if (!videoEnabled) {
|
||||
|
@ -454,21 +447,29 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve
|
|||
}
|
||||
|
||||
public void checkAndRequestPermission(String permission, int result) {
|
||||
if (getPackageManager().checkPermission(permission, getPackageName()) != PackageManager.PERMISSION_GRANTED) {
|
||||
if (!ActivityCompat.shouldShowRequestPermissionRationale(this,permission)){
|
||||
ActivityCompat.requestPermissions(this, new String[]{permission}, result);
|
||||
int permissionGranted = getPackageManager().checkPermission(permission, getPackageName());
|
||||
Log.i("[Permission] " + permission + " is " + (permissionGranted == PackageManager.PERMISSION_GRANTED ? "granted" : "denied"));
|
||||
|
||||
if (permissionGranted != PackageManager.PERMISSION_GRANTED) {
|
||||
if (LinphonePreferences.instance().firstTimeAskingForPermission(permission) || ActivityCompat.shouldShowRequestPermissionRationale(this, permission)) {
|
||||
Log.i("[Permission] Asking for " + permission);
|
||||
ActivityCompat.requestPermissions(this, new String[] { permission }, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
|
||||
public void onRequestPermissionsResult(int requestCode, String[] permissions, final int[] grantResults) {
|
||||
for (int i = 0; i < permissions.length; i++) {
|
||||
Log.i("[Permission] " + permissions[i] + " is " + (grantResults[i] == PackageManager.PERMISSION_GRANTED ? "granted" : "denied"));
|
||||
}
|
||||
|
||||
switch (requestCode) {
|
||||
case PERMISSIONS_REQUEST_CAMERA:
|
||||
UIThreadDispatcher.dispatch(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
acceptCallUpdate(true);
|
||||
acceptCallUpdate(grantResults[0] == PackageManager.PERMISSION_GRANTED);
|
||||
}
|
||||
});
|
||||
break;
|
||||
|
@ -476,12 +477,21 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve
|
|||
UIThreadDispatcher.dispatch(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
enabledOrDisabledVideo(false);
|
||||
disableVideo(grantResults[0] != PackageManager.PERMISSION_GRANTED);
|
||||
}
|
||||
});
|
||||
break;
|
||||
case PERMISSIONS_ENABLED_MIC:
|
||||
UIThreadDispatcher.dispatch(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
toggleMicro();
|
||||
}
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
LinphonePreferences.instance().neverAskCameraPerm();
|
||||
}
|
||||
|
||||
public void createInCallStats() {
|
||||
|
@ -527,6 +537,9 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve
|
|||
video.setImageResource(R.drawable.camera_button);
|
||||
}
|
||||
}
|
||||
if (getPackageManager().checkPermission(Manifest.permission.CAMERA, getPackageName()) != PackageManager.PERMISSION_GRANTED) {
|
||||
video.setImageResource(R.drawable.camera_button);
|
||||
}
|
||||
|
||||
if (isSpeakerEnabled) {
|
||||
speaker.setImageResource(R.drawable.speaker_selected);
|
||||
|
@ -534,6 +547,9 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve
|
|||
speaker.setImageResource(R.drawable.speaker_default);
|
||||
}
|
||||
|
||||
if (getPackageManager().checkPermission(Manifest.permission.RECORD_AUDIO, getPackageName()) != PackageManager.PERMISSION_GRANTED) {
|
||||
isMicMuted = true;
|
||||
}
|
||||
if (isMicMuted) {
|
||||
micro.setImageResource(R.drawable.micro_selected);
|
||||
} else {
|
||||
|
@ -613,14 +629,28 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve
|
|||
}
|
||||
|
||||
if (id == R.id.video) {
|
||||
if (getPackageManager().checkPermission(Manifest.permission.CAMERA, getPackageName()) == PackageManager.PERMISSION_GRANTED) {
|
||||
enabledOrDisabledVideo(isVideoEnabled(LinphoneManager.getLc().getCurrentCall()));
|
||||
int camera = getPackageManager().checkPermission(Manifest.permission.CAMERA, getPackageName());
|
||||
Log.i("[Permission] Camera permission is " + (camera == PackageManager.PERMISSION_GRANTED ? "granted" : "denied"));
|
||||
|
||||
if (camera == PackageManager.PERMISSION_GRANTED) {
|
||||
disableVideo(isVideoEnabled(LinphoneManager.getLc().getCurrentCall()));
|
||||
} else {
|
||||
checkAndRequestPermission(Manifest.permission.CAMERA, PERMISSIONS_ENABLED_CAMERA);
|
||||
if (LinphonePreferences.instance().firstTimeAskingForPermission(Manifest.permission.CAMERA) || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {
|
||||
checkAndRequestPermission(Manifest.permission.CAMERA, PERMISSIONS_ENABLED_CAMERA);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (id == R.id.micro) {
|
||||
toggleMicro();
|
||||
int recordAudio = getPackageManager().checkPermission(Manifest.permission.RECORD_AUDIO, getPackageName());
|
||||
Log.i("[Permission] Record audio permission is " + (recordAudio == PackageManager.PERMISSION_GRANTED ? "granted" : "denied"));
|
||||
|
||||
if (recordAudio == PackageManager.PERMISSION_GRANTED) {
|
||||
toggleMicro();
|
||||
} else {
|
||||
if (LinphonePreferences.instance().firstTimeAskingForPermission(Manifest.permission.RECORD_AUDIO) || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.RECORD_AUDIO)) {
|
||||
checkAndRequestPermission(Manifest.permission.RECORD_AUDIO, PERMISSIONS_ENABLED_MIC);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (id == R.id.speaker) {
|
||||
toggleSpeaker();
|
||||
|
@ -727,13 +757,13 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve
|
|||
}
|
||||
}
|
||||
|
||||
private void enabledOrDisabledVideo(final boolean isVideoEnabled) {
|
||||
private void disableVideo(final boolean videoDisabled) {
|
||||
final LinphoneCall call = LinphoneManager.getLc().getCurrentCall();
|
||||
if (call == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isVideoEnabled) {
|
||||
if (videoDisabled) {
|
||||
LinphoneCallParams params = LinphoneManager.getLc().createCallParams(call);
|
||||
params.setVideoEnabled(false);
|
||||
LinphoneManager.getLc().updateCall(call, params);
|
||||
|
@ -1387,19 +1417,24 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve
|
|||
delete.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (getPackageManager().checkPermission(Manifest.permission.CAMERA, getPackageName()) == PackageManager.PERMISSION_GRANTED || LinphonePreferences.instance().cameraPermAsked()) {
|
||||
int camera = getPackageManager().checkPermission(Manifest.permission.CAMERA, getPackageName());
|
||||
Log.i("[Permission] Camera permission is " + (camera == PackageManager.PERMISSION_GRANTED ? "granted" : "denied"));
|
||||
|
||||
if (camera == PackageManager.PERMISSION_GRANTED) {
|
||||
CallActivity.instance().acceptCallUpdate(true);
|
||||
} else {
|
||||
checkAndRequestPermission(Manifest.permission.CAMERA, PERMISSIONS_REQUEST_CAMERA);
|
||||
if (LinphonePreferences.instance().firstTimeAskingForPermission(Manifest.permission.CAMERA) || ActivityCompat.shouldShowRequestPermissionRationale(CallActivity.this, Manifest.permission.CAMERA)) {
|
||||
checkAndRequestPermission(Manifest.permission.CAMERA, PERMISSIONS_REQUEST_CAMERA);
|
||||
} else {
|
||||
CallActivity.instance().acceptCallUpdate(false);
|
||||
}
|
||||
}
|
||||
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
|
||||
cancel.setOnClickListener(new
|
||||
|
||||
OnClickListener() {
|
||||
cancel.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick (View view){
|
||||
if (CallActivity.isInstanciated()) {
|
||||
|
|
|
@ -18,6 +18,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
*/
|
||||
package org.linphone;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.linphone.core.LinphoneAddress;
|
||||
|
@ -29,12 +30,15 @@ import org.linphone.core.LinphoneCoreListenerBase;
|
|||
import org.linphone.mediastream.Log;
|
||||
import org.linphone.ui.LinphoneSliders.LinphoneSliderTriggered;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.PowerManager;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
|
@ -45,7 +49,6 @@ import android.widget.TextView;
|
|||
import android.widget.Toast;
|
||||
|
||||
public class CallIncomingActivity extends Activity implements LinphoneSliderTriggered {
|
||||
|
||||
private static CallIncomingActivity instance;
|
||||
|
||||
private TextView name, number;
|
||||
|
@ -186,9 +189,6 @@ public class CallIncomingActivity extends Activity implements LinphoneSliderTrig
|
|||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
mListener = new LinphoneCoreListenerBase(){
|
||||
@Override
|
||||
public void callState(LinphoneCore lc, LinphoneCall call, State state, String message) {
|
||||
|
@ -202,7 +202,6 @@ public class CallIncomingActivity extends Activity implements LinphoneSliderTrig
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
instance = this;
|
||||
}
|
||||
|
@ -234,6 +233,8 @@ public class CallIncomingActivity extends Activity implements LinphoneSliderTrig
|
|||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
LinphoneAddress address = mCall.getRemoteAddress();
|
||||
LinphoneContact contact = ContactsManager.getInstance().findContactFromAddress(address);
|
||||
if (contact != null) {
|
||||
|
@ -244,6 +245,12 @@ public class CallIncomingActivity extends Activity implements LinphoneSliderTrig
|
|||
}
|
||||
number.setText(address.asStringUriOnly());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
checkAndRequestCallPermissions();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
|
@ -320,4 +327,41 @@ public class CallIncomingActivity extends Activity implements LinphoneSliderTrig
|
|||
public void onRightHandleTriggered() {
|
||||
|
||||
}
|
||||
|
||||
private void checkAndRequestCallPermissions() {
|
||||
ArrayList<String> permissionsList = new ArrayList<String>();
|
||||
|
||||
int recordAudio = getPackageManager().checkPermission(Manifest.permission.RECORD_AUDIO, getPackageName());
|
||||
Log.i("[Permission] Record audio permission is " + (recordAudio == PackageManager.PERMISSION_GRANTED ? "granted" : "denied"));
|
||||
int camera = getPackageManager().checkPermission(Manifest.permission.CAMERA, getPackageName());
|
||||
Log.i("[Permission] Camera permission is " + (camera == PackageManager.PERMISSION_GRANTED ? "granted" : "denied"));
|
||||
|
||||
if (recordAudio != PackageManager.PERMISSION_GRANTED) {
|
||||
if (LinphonePreferences.instance().firstTimeAskingForPermission(Manifest.permission.RECORD_AUDIO) || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.RECORD_AUDIO)) {
|
||||
Log.i("[Permission] Asking for record audio");
|
||||
permissionsList.add(Manifest.permission.RECORD_AUDIO);
|
||||
}
|
||||
}
|
||||
if (LinphonePreferences.instance().shouldInitiateVideoCall() || LinphonePreferences.instance().shouldAutomaticallyAcceptVideoRequests()) {
|
||||
if (camera != PackageManager.PERMISSION_GRANTED) {
|
||||
if (LinphonePreferences.instance().firstTimeAskingForPermission(Manifest.permission.CAMERA) || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {
|
||||
Log.i("[Permission] Asking for camera");
|
||||
permissionsList.add(Manifest.permission.CAMERA);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (permissionsList.size() > 0) {
|
||||
String[] permissions = new String[permissionsList.size()];
|
||||
permissions = permissionsList.toArray(permissions);
|
||||
ActivityCompat.requestPermissions(this, permissions, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
|
||||
for (int i = 0; i < permissions.length; i++) {
|
||||
Log.i("[Permission] " + permissions[i] + " is " + (grantResults[i] == PackageManager.PERMISSION_GRANTED ? "granted" : "denied"));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -18,6 +18,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
*/
|
||||
package org.linphone;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.linphone.core.LinphoneAddress;
|
||||
|
@ -26,20 +27,27 @@ import org.linphone.core.LinphoneCall.State;
|
|||
import org.linphone.core.LinphoneCallParams;
|
||||
import org.linphone.core.LinphoneCore;
|
||||
import org.linphone.core.LinphoneCoreListenerBase;
|
||||
import org.linphone.core.Reason;
|
||||
import org.linphone.mediastream.Log;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.view.Gravity;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
public class CallOutgoingActivity extends Activity implements OnClickListener{
|
||||
|
||||
private static CallOutgoingActivity instance;
|
||||
|
||||
private TextView name, number;
|
||||
|
@ -88,16 +96,8 @@ public class CallOutgoingActivity extends Activity implements OnClickListener{
|
|||
|
||||
mListener = new LinphoneCoreListenerBase(){
|
||||
@Override
|
||||
public void callState(LinphoneCore lc, LinphoneCall call, LinphoneCall.State state, String message) {
|
||||
if (LinphoneManager.getLc().getCallsNb() == 0) {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
if (call == mCall && State.CallEnd == state) {
|
||||
finish();
|
||||
}
|
||||
|
||||
if (call == mCall && (State.Connected == state)){
|
||||
public void callState(LinphoneCore lc, LinphoneCall call, LinphoneCall.State state, String message) {
|
||||
if (call == mCall && State.Connected == state) {
|
||||
if (!LinphoneActivity.isInstanciated()) {
|
||||
return;
|
||||
}
|
||||
|
@ -109,6 +109,22 @@ public class CallOutgoingActivity extends Activity implements OnClickListener{
|
|||
}
|
||||
finish();
|
||||
return;
|
||||
} else if (state == State.Error) {
|
||||
// Convert LinphoneCore message for internalization
|
||||
if (message != null && call.getErrorInfo().getReason() == Reason.Declined) {
|
||||
displayCustomToast(getString(R.string.error_call_declined), Toast.LENGTH_SHORT);
|
||||
} else if (message != null && call.getErrorInfo().getReason() == Reason.NotFound) {
|
||||
displayCustomToast(getString(R.string.error_user_not_found), Toast.LENGTH_SHORT);
|
||||
} else if (message != null && call.getErrorInfo().getReason() == Reason.Media) {
|
||||
displayCustomToast(getString(R.string.error_incompatible_media), Toast.LENGTH_SHORT);
|
||||
} else if (message != null) {
|
||||
displayCustomToast(getString(R.string.error_unknown) + " - " + message, Toast.LENGTH_SHORT);
|
||||
}
|
||||
}
|
||||
|
||||
if (LinphoneManager.getLc().getCallsNb() == 0) {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -152,6 +168,12 @@ public class CallOutgoingActivity extends Activity implements OnClickListener{
|
|||
}
|
||||
number.setText(address.asStringUriOnly());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
checkAndRequestCallPermissions();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
|
@ -204,7 +226,58 @@ public class CallOutgoingActivity extends Activity implements OnClickListener{
|
|||
return super.onKeyDown(keyCode, event);
|
||||
}
|
||||
|
||||
public void displayCustomToast(final String message, final int duration) {
|
||||
LayoutInflater inflater = getLayoutInflater();
|
||||
View layout = inflater.inflate(R.layout.toast, (ViewGroup) findViewById(R.id.toastRoot));
|
||||
|
||||
TextView toastText = (TextView) layout.findViewById(R.id.toastMessage);
|
||||
toastText.setText(message);
|
||||
|
||||
final Toast toast = new Toast(getApplicationContext());
|
||||
toast.setGravity(Gravity.CENTER, 0, 0);
|
||||
toast.setDuration(duration);
|
||||
toast.setView(layout);
|
||||
toast.show();
|
||||
}
|
||||
|
||||
private void decline() {
|
||||
LinphoneManager.getLc().terminateCall(mCall);
|
||||
}
|
||||
|
||||
private void checkAndRequestCallPermissions() {
|
||||
ArrayList<String> permissionsList = new ArrayList<String>();
|
||||
|
||||
int recordAudio = getPackageManager().checkPermission(Manifest.permission.RECORD_AUDIO, getPackageName());
|
||||
Log.i("[Permission] Record audio permission is " + (recordAudio == PackageManager.PERMISSION_GRANTED ? "granted" : "denied"));
|
||||
int camera = getPackageManager().checkPermission(Manifest.permission.CAMERA, getPackageName());
|
||||
Log.i("[Permission] Camera permission is " + (camera == PackageManager.PERMISSION_GRANTED ? "granted" : "denied"));
|
||||
|
||||
if (recordAudio != PackageManager.PERMISSION_GRANTED) {
|
||||
if (LinphonePreferences.instance().firstTimeAskingForPermission(Manifest.permission.RECORD_AUDIO) || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.RECORD_AUDIO)) {
|
||||
Log.i("[Permission] Asking for record audio");
|
||||
permissionsList.add(Manifest.permission.RECORD_AUDIO);
|
||||
}
|
||||
}
|
||||
if (LinphonePreferences.instance().shouldInitiateVideoCall() || LinphonePreferences.instance().shouldAutomaticallyAcceptVideoRequests()) {
|
||||
if (camera != PackageManager.PERMISSION_GRANTED) {
|
||||
if (LinphonePreferences.instance().firstTimeAskingForPermission(Manifest.permission.CAMERA) || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {
|
||||
Log.i("[Permission] Asking for camera");
|
||||
permissionsList.add(Manifest.permission.CAMERA);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (permissionsList.size() > 0) {
|
||||
String[] permissions = new String[permissionsList.size()];
|
||||
permissions = permissionsList.toArray(permissions);
|
||||
ActivityCompat.requestPermissions(this, permissions, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
|
||||
for (int i = 0; i < permissions.length; i++) {
|
||||
Log.i("[Permission] " + permissions[i] + " is " + (grantResults[i] == PackageManager.PERMISSION_GRANTED ? "granted" : "denied"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ import android.view.SurfaceView;
|
|||
import android.view.View;
|
||||
import android.view.View.OnTouchListener;
|
||||
import android.view.ViewGroup;
|
||||
//import android.opengl.GLSurfaceView;
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
/**
|
||||
* @author Sylvain Berfini
|
||||
|
@ -52,6 +52,7 @@ public class CallVideoFragment extends Fragment implements OnGestureListener, On
|
|||
private float mZoomCenterX, mZoomCenterY;
|
||||
private CompatibilityScaleGestureDetector mScaleDetector;
|
||||
private CallActivity inCallActivity;
|
||||
private int previewX, previewY;
|
||||
|
||||
@SuppressWarnings("deprecation") // Warning useless because value is ignored and automatically set by new APIs.
|
||||
@Override
|
||||
|
@ -61,7 +62,7 @@ public class CallVideoFragment extends Fragment implements OnGestureListener, On
|
|||
if (LinphoneManager.getLc().hasCrappyOpenGL()) {
|
||||
view = inflater.inflate(R.layout.video_no_opengl, container, false);
|
||||
} else {
|
||||
view = inflater.inflate(R.layout.video, container, false);
|
||||
view = inflater.inflate(R.layout.video, container, false);
|
||||
}
|
||||
|
||||
mVideoView = (SurfaceView) view.findViewById(R.id.videoSurface);
|
||||
|
@ -104,6 +105,30 @@ public class CallVideoFragment extends Fragment implements OnGestureListener, On
|
|||
}
|
||||
});
|
||||
|
||||
mCaptureView.setOnTouchListener(new OnTouchListener() {
|
||||
@Override
|
||||
public boolean onTouch(View view, MotionEvent motionEvent) {
|
||||
switch (motionEvent.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
previewX = (int) motionEvent.getX();
|
||||
previewY = (int) motionEvent.getY();
|
||||
break;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
int x = (int) motionEvent.getX();
|
||||
int y = (int) motionEvent.getY();
|
||||
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams)mCaptureView.getLayoutParams();
|
||||
lp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, 0); // Clears the rule, as there is no removeRule until API 17.
|
||||
lp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, 0);
|
||||
int left = lp.leftMargin + (x - previewX);
|
||||
int top = lp.topMargin + (y - previewY);
|
||||
lp.leftMargin = left;
|
||||
lp.topMargin = top;
|
||||
view.setLayoutParams(lp);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
return view;
|
||||
}
|
||||
|
||||
|
@ -134,6 +159,9 @@ public class CallVideoFragment extends Fragment implements OnGestureListener, On
|
|||
public void onResume() {
|
||||
super.onResume();
|
||||
|
||||
if (LinphonePreferences.instance().isOverlayEnabled()) {
|
||||
LinphoneService.instance().destroyOverlay();
|
||||
}
|
||||
if (androidVideoWindowImpl != null) {
|
||||
synchronized (androidVideoWindowImpl) {
|
||||
LinphoneManager.getLc().setVideoWindow(androidVideoWindowImpl);
|
||||
|
@ -155,6 +183,9 @@ public class CallVideoFragment extends Fragment implements OnGestureListener, On
|
|||
LinphoneManager.getLc().setVideoWindow(null);
|
||||
}
|
||||
}
|
||||
if (LinphonePreferences.instance().isOverlayEnabled()) {
|
||||
LinphoneService.instance().createOverlay();
|
||||
}
|
||||
|
||||
super.onPause();
|
||||
}
|
||||
|
|
|
@ -192,7 +192,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
@Override
|
||||
public void onClick(View v) {
|
||||
pickImage();
|
||||
LinphoneActivity.instance().checkAndRequestCameraPermission();
|
||||
LinphoneActivity.instance().checkAndRequestPermissionsToSendImage();
|
||||
}
|
||||
});
|
||||
//registerForContextMenu(sendImage);
|
||||
|
@ -482,7 +482,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
if (adapter != null) {
|
||||
adapter.refreshHistory();
|
||||
} else {
|
||||
adapter = new ChatMessageAdapter(getActivity().getApplicationContext());
|
||||
adapter = new ChatMessageAdapter(getActivity());
|
||||
}
|
||||
}
|
||||
messagesList.setAdapter(adapter);
|
||||
|
@ -710,7 +710,6 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
editList.setVisibility(View.VISIBLE);
|
||||
isEditMode = true;
|
||||
redrawMessageList();
|
||||
//TODO refaire la liste
|
||||
}
|
||||
if(id == R.id.start_call){
|
||||
LinphoneActivity.instance().setAddresGoToDialerAndCall(sipUri, LinphoneUtils.getUsernameFromAddress(sipUri), null);
|
||||
|
@ -742,10 +741,6 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
chatRoom.sendChatMessage(message);
|
||||
lAddress = chatRoom.getPeerAddress();
|
||||
|
||||
if (LinphoneActivity.isInstanciated()) {
|
||||
LinphoneActivity.instance().onMessageSent(sipUri, messageToSend);
|
||||
}
|
||||
|
||||
message.setListener(LinphoneManager.getInstance());
|
||||
if (newChatConversation) {
|
||||
exitNewConversationMode(lAddress.asStringUriOnly());
|
||||
|
@ -819,9 +814,21 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
}
|
||||
|
||||
private void copyTextMessageToClipboard(int id) {
|
||||
String msg = LinphoneActivity.instance().getChatStorage().getTextMessageForId(chatRoom, id);
|
||||
if (msg != null) {
|
||||
Compatibility.copyTextToClipboard(getActivity(), msg);
|
||||
LinphoneChatMessage message = null;
|
||||
for (int i = 0; i < adapter.getCount(); i++) {
|
||||
LinphoneChatMessage msg = adapter.getItem(i);
|
||||
if (msg.getStorageId() == id) {
|
||||
message = msg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
String txt = null;
|
||||
if (message != null) {
|
||||
txt = message.getText();
|
||||
}
|
||||
if (txt != null) {
|
||||
Compatibility.copyTextToClipboard(getActivity(), txt);
|
||||
LinphoneActivity.instance().displayCustomToast(getString(R.string.text_copied_to_clipboard), Toast.LENGTH_SHORT);
|
||||
}
|
||||
}
|
||||
|
@ -901,7 +908,12 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
}
|
||||
|
||||
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||
bm.compress(Bitmap.CompressFormat.PNG, 100, stream);
|
||||
String extension = LinphoneUtils.getExtensionFromFileName(path);
|
||||
if (extension != null && extension.toLowerCase(Locale.getDefault()).equals("png")) {
|
||||
bm.compress(Bitmap.CompressFormat.PNG, 100, stream);
|
||||
} else {
|
||||
bm.compress(Bitmap.CompressFormat.JPEG, 100, stream);
|
||||
}
|
||||
byte[] byteArray = stream.toByteArray();
|
||||
return byteArray;
|
||||
}
|
||||
|
@ -913,8 +925,9 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
}
|
||||
mUploadingImageStream = new ByteArrayInputStream(result);
|
||||
|
||||
LinphoneContent content = LinphoneCoreFactory.instance().createLinphoneContent("image", "jpeg", result, null);
|
||||
String fileName = path.substring(path.lastIndexOf("/") + 1);
|
||||
String extension = LinphoneUtils.getExtensionFromFileName(fileName);
|
||||
LinphoneContent content = LinphoneCoreFactory.instance().createLinphoneContent("image", extension, result, null);
|
||||
content.setName(fileName);
|
||||
|
||||
LinphoneChatMessage message = chatRoom.createFileTransferMessage(content);
|
||||
|
|
|
@ -57,7 +57,7 @@ import android.widget.TextView;
|
|||
*/
|
||||
public class ChatListFragment extends Fragment implements OnClickListener, OnItemClickListener {
|
||||
private LayoutInflater mInflater;
|
||||
private List<String> mConversations, mDrafts;
|
||||
private List<String> mConversations;
|
||||
private ListView chatList;
|
||||
private TextView noChatHistory;
|
||||
private ImageView edit, selectAll, deselectAll, delete, newDiscussion, cancel, backInCall;
|
||||
|
@ -164,7 +164,7 @@ public class ChatListFragment extends Fragment implements OnClickListener, OnIte
|
|||
}
|
||||
|
||||
private void hideAndDisplayMessageIfNoChat() {
|
||||
if (mConversations.size() == 0 && mDrafts.size() == 0) {
|
||||
if (mConversations.size() == 0) {
|
||||
noChatHistory.setVisibility(View.VISIBLE);
|
||||
chatList.setVisibility(View.GONE);
|
||||
edit.setEnabled(false);
|
||||
|
@ -179,8 +179,6 @@ public class ChatListFragment extends Fragment implements OnClickListener, OnIte
|
|||
|
||||
public void refresh() {
|
||||
mConversations = LinphoneActivity.instance().getChatList();
|
||||
mDrafts = LinphoneActivity.instance().getDraftChatList();
|
||||
mConversations.removeAll(mDrafts);
|
||||
hideAndDisplayMessageIfNoChat();
|
||||
}
|
||||
|
||||
|
@ -240,8 +238,6 @@ public class ChatListFragment extends Fragment implements OnClickListener, OnIte
|
|||
|
||||
LinphoneActivity.instance().removeFromChatList(sipUri);
|
||||
mConversations = LinphoneActivity.instance().getChatList();
|
||||
mDrafts = LinphoneActivity.instance().getDraftChatList();
|
||||
mConversations.removeAll(mDrafts);
|
||||
hideAndDisplayMessageIfNoChat();
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1,409 +0,0 @@
|
|||
package org.linphone;
|
||||
/*
|
||||
ChatStorage.java
|
||||
Copyright (C) 2012 Belledonne Communications, Grenoble, France
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import org.linphone.core.LinphoneChatMessage;
|
||||
import org.linphone.core.LinphoneChatRoom;
|
||||
import org.linphone.mediastream.Log;
|
||||
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Bitmap.CompressFormat;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.preference.PreferenceManager;
|
||||
|
||||
/**
|
||||
* @author Sylvain Berfini
|
||||
*/
|
||||
public class ChatStorage {
|
||||
private static final int INCOMING = 1;
|
||||
private static final int OUTGOING = 0;
|
||||
private static final int READ = 1;
|
||||
private static final int NOT_READ = 0;
|
||||
|
||||
private static ChatStorage instance;
|
||||
private Context context;
|
||||
private SQLiteDatabase db;
|
||||
private boolean useNativeAPI;
|
||||
private static final String TABLE_NAME = "chat";
|
||||
private static final String DRAFT_TABLE_NAME = "chat_draft";
|
||||
|
||||
public synchronized static final ChatStorage getInstance() {
|
||||
if (instance == null)
|
||||
instance = new ChatStorage(LinphoneService.instance().getApplicationContext());
|
||||
return instance;
|
||||
}
|
||||
|
||||
public void restartChatStorage() {
|
||||
if (instance != null)
|
||||
instance.close();
|
||||
instance = new ChatStorage(LinphoneService.instance().getApplicationContext());
|
||||
}
|
||||
|
||||
private boolean isVersionUsingNewChatStorage() {
|
||||
try {
|
||||
return context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionCode >= 2200;
|
||||
} catch (NameNotFoundException e) {
|
||||
Log.e(e);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private ChatStorage(Context c) {
|
||||
context = c;
|
||||
boolean useLinphoneStorage = true;
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(LinphoneService.instance());
|
||||
boolean updateNeeded = prefs.getBoolean(c.getString(R.string.pref_first_time_linphone_chat_storage), !LinphonePreferences.instance().isFirstLaunch());
|
||||
updateNeeded = updateNeeded && !isVersionUsingNewChatStorage();
|
||||
useNativeAPI = useLinphoneStorage && !updateNeeded;
|
||||
Log.d("Using native API: " + useNativeAPI);
|
||||
|
||||
if (!useNativeAPI) {
|
||||
ChatHelper chatHelper = new ChatHelper(context);
|
||||
db = chatHelper.getWritableDatabase();
|
||||
}
|
||||
}
|
||||
|
||||
public void close() {
|
||||
if (!useNativeAPI) {
|
||||
db.close();
|
||||
}
|
||||
}
|
||||
|
||||
public void updateMessageStatus(String to, String message, int status) {
|
||||
if (useNativeAPI) {
|
||||
return;
|
||||
}
|
||||
|
||||
String[] whereArgs = { String.valueOf(OUTGOING), to, message };
|
||||
Cursor c = db.query(TABLE_NAME, null, "direction LIKE ? AND remoteContact LIKE ? AND message LIKE ?", whereArgs, null, null, "id DESC");
|
||||
|
||||
String id = null;
|
||||
if (c.moveToFirst()) {
|
||||
try {
|
||||
id = c.getString(c.getColumnIndex("id"));
|
||||
} catch (Exception e) {
|
||||
Log.e(e);
|
||||
}
|
||||
}
|
||||
c.close();
|
||||
|
||||
if (id != null && id.length() > 0) {
|
||||
int intID = Integer.parseInt(id);
|
||||
updateMessageStatus(to, intID, status);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateMessageStatus(String to, int id, int status) {
|
||||
if (useNativeAPI) {
|
||||
return;
|
||||
}
|
||||
|
||||
ContentValues values = new ContentValues();
|
||||
values.put("status", status);
|
||||
|
||||
db.update(TABLE_NAME, values, "id LIKE " + id, null);
|
||||
}
|
||||
|
||||
public int saveTextMessage(String from, String to, String message, long time) {
|
||||
if (useNativeAPI) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ContentValues values = new ContentValues();
|
||||
if (from.equals("")) {
|
||||
values.put("localContact", from);
|
||||
values.put("remoteContact", to);
|
||||
values.put("direction", OUTGOING);
|
||||
values.put("read", READ);
|
||||
values.put("status", LinphoneChatMessage.State.InProgress.toInt());
|
||||
} else if (to.equals("")) {
|
||||
values.put("localContact", to);
|
||||
values.put("remoteContact", from);
|
||||
values.put("direction", INCOMING);
|
||||
values.put("read", NOT_READ);
|
||||
values.put("status", LinphoneChatMessage.State.Idle.toInt());
|
||||
}
|
||||
values.put("message", message);
|
||||
values.put("time", time);
|
||||
return (int) db.insert(TABLE_NAME, null, values);
|
||||
}
|
||||
|
||||
public int saveImageMessage(String from, String to, Bitmap image, String url, long time) {
|
||||
if (useNativeAPI) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ContentValues values = new ContentValues();
|
||||
if (from.equals("")) {
|
||||
values.put("localContact", from);
|
||||
values.put("remoteContact", to);
|
||||
values.put("direction", OUTGOING);
|
||||
values.put("read", READ);
|
||||
values.put("status", LinphoneChatMessage.State.InProgress.toInt());
|
||||
} else if (to.equals("")) {
|
||||
values.put("localContact", to);
|
||||
values.put("remoteContact", from);
|
||||
values.put("direction", INCOMING);
|
||||
values.put("read", NOT_READ);
|
||||
values.put("status", LinphoneChatMessage.State.Idle.toInt());
|
||||
}
|
||||
values.put("url", url);
|
||||
|
||||
if (image != null) {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
image.compress(CompressFormat.JPEG, 100, baos);
|
||||
values.put("image", baos.toByteArray());
|
||||
}
|
||||
|
||||
values.put("time", time);
|
||||
return (int) db.insert(TABLE_NAME, null, values);
|
||||
}
|
||||
|
||||
public void saveImage(int id, Bitmap image) {
|
||||
if (useNativeAPI) {
|
||||
//Handled before this point
|
||||
return;
|
||||
}
|
||||
|
||||
if (image == null)
|
||||
return;
|
||||
|
||||
ContentValues values = new ContentValues();
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
image.compress(CompressFormat.JPEG, 100, baos);
|
||||
values.put("image", baos.toByteArray());
|
||||
|
||||
db.update(TABLE_NAME, values, "id LIKE " + id, null);
|
||||
}
|
||||
|
||||
public int saveDraft(String to, String message) {
|
||||
if (useNativeAPI) {
|
||||
//TODO
|
||||
return -1;
|
||||
}
|
||||
|
||||
ContentValues values = new ContentValues();
|
||||
values.put("remoteContact", to);
|
||||
values.put("message", message);
|
||||
return (int) db.insert(DRAFT_TABLE_NAME, null, values);
|
||||
}
|
||||
|
||||
public void updateDraft(String to, String message) {
|
||||
if (useNativeAPI) {
|
||||
//TODO
|
||||
return;
|
||||
}
|
||||
|
||||
ContentValues values = new ContentValues();
|
||||
values.put("message", message);
|
||||
|
||||
db.update(DRAFT_TABLE_NAME, values, "remoteContact LIKE \"" + to + "\"", null);
|
||||
}
|
||||
|
||||
public void deleteDraft(String to) {
|
||||
if (useNativeAPI) {
|
||||
//TODO
|
||||
return;
|
||||
}
|
||||
|
||||
db.delete(DRAFT_TABLE_NAME, "remoteContact LIKE \"" + to + "\"", null);
|
||||
}
|
||||
|
||||
public String getDraft(String to) {
|
||||
if (useNativeAPI) {
|
||||
//TODO
|
||||
return "";
|
||||
}
|
||||
|
||||
Cursor c = db.query(DRAFT_TABLE_NAME, null, "remoteContact LIKE \"" + to + "\"", null, null, null, "id ASC");
|
||||
|
||||
String message = null;
|
||||
while (c.moveToNext()) {
|
||||
try {
|
||||
message = c.getString(c.getColumnIndex("message"));
|
||||
} catch (Exception e) {
|
||||
Log.e(e);
|
||||
}
|
||||
}
|
||||
c.close();
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
public List<String> getDrafts() {
|
||||
List<String> drafts = new ArrayList<String>();
|
||||
|
||||
if (useNativeAPI) {
|
||||
//TODO
|
||||
} else {
|
||||
Cursor c = db.query(DRAFT_TABLE_NAME, null, null, null, null, null, "id ASC");
|
||||
|
||||
while (c.moveToNext()) {
|
||||
try {
|
||||
String to = c.getString(c.getColumnIndex("remoteContact"));
|
||||
drafts.add(to);
|
||||
} catch (Exception e) {
|
||||
Log.e(e);
|
||||
}
|
||||
}
|
||||
c.close();
|
||||
}
|
||||
|
||||
return drafts;
|
||||
}
|
||||
|
||||
public String getTextMessageForId(LinphoneChatRoom chatroom, int id) {
|
||||
String message = null;
|
||||
|
||||
if (useNativeAPI) {
|
||||
LinphoneChatMessage msg = getMessage(chatroom, id);
|
||||
|
||||
if (msg != null) {
|
||||
message = msg.getText();
|
||||
}
|
||||
} else {
|
||||
Cursor c = db.query(TABLE_NAME, null, "id LIKE " + id, null, null, null, null);
|
||||
|
||||
if (c.moveToFirst()) {
|
||||
try {
|
||||
message = c.getString(c.getColumnIndex("message"));
|
||||
} catch (Exception e) {
|
||||
Log.e(e);
|
||||
}
|
||||
}
|
||||
c.close();
|
||||
}
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
public LinphoneChatMessage getMessage(LinphoneChatRoom chatroom, int id) {
|
||||
LinphoneChatMessage[] history = chatroom.getHistory();
|
||||
for (LinphoneChatMessage msg : history) {
|
||||
if (msg.getStorageId() == id) {
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void removeDiscussion(String correspondent) {
|
||||
LinphoneChatRoom chatroom = LinphoneManager.getLc().getOrCreateChatRoom(correspondent);
|
||||
chatroom.deleteHistory();
|
||||
}
|
||||
|
||||
public ArrayList<String> getChatList() {
|
||||
ArrayList<String> chatList = new ArrayList<String>();
|
||||
|
||||
LinphoneChatRoom[] chats = LinphoneManager.getLc().getChatRooms();
|
||||
List<LinphoneChatRoom> rooms = new ArrayList<LinphoneChatRoom>();
|
||||
|
||||
for (LinphoneChatRoom chatroom : chats) {
|
||||
if (chatroom.getHistorySize() > 0) {
|
||||
rooms.add(chatroom);
|
||||
}
|
||||
}
|
||||
|
||||
if (rooms.size() > 1) {
|
||||
Collections.sort(rooms, new Comparator<LinphoneChatRoom>() {
|
||||
@Override
|
||||
public int compare(LinphoneChatRoom a, LinphoneChatRoom b) {
|
||||
LinphoneChatMessage[] messagesA = a.getHistory(1);
|
||||
LinphoneChatMessage[] messagesB = b.getHistory(1);
|
||||
long atime = messagesA[0].getTime();
|
||||
long btime = messagesB[0].getTime();
|
||||
|
||||
if (atime > btime)
|
||||
return -1;
|
||||
else if (btime > atime)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
for (LinphoneChatRoom chatroom : rooms) {
|
||||
chatList.add(chatroom.getPeerAddress().asStringUriOnly());
|
||||
}
|
||||
|
||||
return chatList;
|
||||
}
|
||||
|
||||
public void deleteMessage(LinphoneChatRoom chatroom, int id) {
|
||||
if (useNativeAPI) {
|
||||
LinphoneChatMessage msg = getMessage(chatroom, id);
|
||||
if (msg != null){
|
||||
chatroom.deleteMessage(msg);
|
||||
}
|
||||
} else {
|
||||
db.delete(TABLE_NAME, "id LIKE " + id, null);
|
||||
}
|
||||
}
|
||||
|
||||
public void markMessageAsRead(int id) {
|
||||
if (!useNativeAPI) {
|
||||
ContentValues values = new ContentValues();
|
||||
values.put("read", READ);
|
||||
db.update(TABLE_NAME, values, "id LIKE " + id, null);
|
||||
}
|
||||
}
|
||||
|
||||
public void markConversationAsRead(LinphoneChatRoom chatroom) {
|
||||
if (useNativeAPI) {
|
||||
chatroom.markAsRead();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class ChatHelper extends SQLiteOpenHelper {
|
||||
|
||||
private static final int DATABASE_VERSION = 15;
|
||||
private static final String DATABASE_NAME = "linphone-android";
|
||||
|
||||
ChatHelper(Context context) {
|
||||
super(context, DATABASE_NAME, null, DATABASE_VERSION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(SQLiteDatabase db) {
|
||||
db.execSQL("CREATE TABLE " + TABLE_NAME + " (id INTEGER PRIMARY KEY AUTOINCREMENT, localContact TEXT NOT NULL, remoteContact TEXT NOT NULL, direction INTEGER, message TEXT, image BLOB, url TEXT, time NUMERIC, read INTEGER, status INTEGER);");
|
||||
db.execSQL("CREATE TABLE " + DRAFT_TABLE_NAME + " (id INTEGER PRIMARY KEY AUTOINCREMENT, remoteContact TEXT NOT NULL, message TEXT);");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
||||
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME + ";");
|
||||
db.execSQL("DROP TABLE IF EXISTS " + DRAFT_TABLE_NAME + ";");
|
||||
onCreate(db);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -129,6 +129,9 @@ public class ContactDetailsFragment extends Fragment implements OnClickListener
|
|||
if (displayednumberOrAddress.startsWith("sip:")) {
|
||||
displayednumberOrAddress = displayednumberOrAddress.replace("sip:", "");
|
||||
}
|
||||
if (displayednumberOrAddress.contains("@")) {
|
||||
displayednumberOrAddress = displayednumberOrAddress.split("@")[0];
|
||||
}
|
||||
|
||||
TextView label = (TextView) v.findViewById(R.id.address_label);
|
||||
if (noa.isSIPAddress()) {
|
||||
|
|
|
@ -25,6 +25,8 @@ import java.io.Serializable;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.linphone.core.LinphoneCore;
|
||||
import org.linphone.core.LinphoneProxyConfig;
|
||||
import org.linphone.mediastream.Log;
|
||||
import org.linphone.mediastream.Version;
|
||||
|
||||
|
@ -34,12 +36,14 @@ import android.app.Dialog;
|
|||
import android.app.Fragment;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.os.Parcelable;
|
||||
import android.provider.ContactsContract.DisplayPhoto;
|
||||
import android.provider.MediaStore;
|
||||
import android.text.Editable;
|
||||
import android.text.InputType;
|
||||
|
@ -122,6 +126,10 @@ public class ContactEditorFragment extends Fragment {
|
|||
ok.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
|
||||
LinphoneProxyConfig lpc = lc != null ? lc.getDefaultProxyConfig() : null;
|
||||
String defaultDomain = lpc != null ? lpc.getDomain() : null;
|
||||
|
||||
if (isNewContact) {
|
||||
boolean areAllFielsEmpty = true;
|
||||
for (LinphoneNumberOrAddress nounoa : numbersAndAddresses) {
|
||||
|
@ -140,8 +148,16 @@ public class ContactEditorFragment extends Fragment {
|
|||
if (photoToAdd != null) {
|
||||
contact.setPhoto(photoToAdd);
|
||||
}
|
||||
for (LinphoneNumberOrAddress numberOrAddress : numbersAndAddresses) {
|
||||
contact.addOrUpdateNumberOrAddress(numberOrAddress);
|
||||
for (LinphoneNumberOrAddress noa : numbersAndAddresses) {
|
||||
if (noa.isSIPAddress() && noa.getValue() != null) {
|
||||
if (!noa.getValue().contains("@") && defaultDomain != null) {
|
||||
noa.setValue(noa.getValue() + "@" + defaultDomain);
|
||||
}
|
||||
if (!noa.getValue().startsWith("sip:")) {
|
||||
noa.setValue("sip:" + noa.getValue());
|
||||
}
|
||||
}
|
||||
contact.addOrUpdateNumberOrAddress(noa);
|
||||
}
|
||||
contact.save();
|
||||
getFragmentManager().popBackStackImmediate();
|
||||
|
@ -372,10 +388,31 @@ public class ContactEditorFragment extends Fragment {
|
|||
image = BitmapFactory.decodeFile(filePath);
|
||||
}
|
||||
|
||||
Bitmap scaledPhoto;
|
||||
int size = getThumbnailSize();
|
||||
if (size > 0) {
|
||||
scaledPhoto = Bitmap.createScaledBitmap(image, size, size, false);
|
||||
} else {
|
||||
scaledPhoto = Bitmap.createBitmap(image);
|
||||
}
|
||||
image.recycle();
|
||||
|
||||
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||
image.compress(Bitmap.CompressFormat.PNG , 75, stream);
|
||||
photoToAdd = stream.toByteArray();
|
||||
contactPicture.setImageBitmap(image);
|
||||
scaledPhoto.compress(Bitmap.CompressFormat.PNG , 0, stream);
|
||||
contactPicture.setImageBitmap(scaledPhoto);
|
||||
photoToAdd = stream.toByteArray();
|
||||
}
|
||||
|
||||
private int getThumbnailSize() {
|
||||
int value = -1;
|
||||
Cursor c = LinphoneActivity.instance().getContentResolver().query(DisplayPhoto.CONTENT_MAX_DIMENSIONS_URI, new String[] { DisplayPhoto.THUMBNAIL_MAX_DIM }, null, null, null);
|
||||
try {
|
||||
c.moveToFirst();
|
||||
value = c.getInt(0);
|
||||
} catch (Exception e) {
|
||||
Log.e(e);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
private LinearLayout initNumbersFields(final LinphoneContact contact) {
|
||||
|
@ -449,6 +486,9 @@ public class ContactEditorFragment extends Fragment {
|
|||
firstSipAddressIndex = controls.getChildCount();
|
||||
}
|
||||
numberOrAddress = numberOrAddress.replace("sip:", "");
|
||||
if (numberOrAddress.contains("@")) {
|
||||
numberOrAddress = numberOrAddress.split("@")[0];
|
||||
}
|
||||
}
|
||||
if ((getResources().getBoolean(R.bool.hide_phone_numbers_in_editor) && !isSIP) || (getResources().getBoolean(R.bool.hide_sip_addresses_in_editor) && isSIP)) {
|
||||
if (forceAddNumber)
|
||||
|
|
|
@ -174,7 +174,7 @@ public class ContactsManager extends ContentObserver {
|
|||
}
|
||||
|
||||
public void initializeSyncAccount(Context context, ContentResolver contentResolver) {
|
||||
initializeContactManager(context,contentResolver);
|
||||
initializeContactManager(context, contentResolver);
|
||||
AccountManager accountManager = (AccountManager) context.getSystemService(Context.ACCOUNT_SERVICE);
|
||||
|
||||
Account[] accounts = accountManager.getAccountsByType(context.getPackageName());
|
||||
|
@ -236,7 +236,7 @@ public class ContactsManager extends ContentObserver {
|
|||
public List<LinphoneContact> fetchContactsAsync() {
|
||||
List<LinphoneContact> contacts = new ArrayList<LinphoneContact>();
|
||||
|
||||
if (mAccount != null && hasContactsAccess()) {
|
||||
if (hasContactsAccess()) {
|
||||
Cursor c = Compatibility.getContactsCursor(contentResolver, null);
|
||||
if (c != null) {
|
||||
while (c.moveToNext()) {
|
||||
|
@ -330,6 +330,7 @@ public class ContactsManager extends ContentObserver {
|
|||
Log.e(e);
|
||||
}
|
||||
}
|
||||
|
||||
public String getString(int resourceID) {
|
||||
return context.getString(resourceID);
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ along with this program; if not, write to the Free Software
|
|||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
import org.linphone.core.LinphoneCoreFactory;
|
||||
import org.linphone.mediastream.Log;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
|
@ -25,10 +26,13 @@ import android.content.Context;
|
|||
import android.content.Intent;
|
||||
|
||||
public class KeepAliveHandler extends BroadcastReceiver {
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
//Log.i("Keep alive handler invoked"); //TODO FIXME Crash since the log rework
|
||||
boolean isDebugEnabled = LinphonePreferences.instance().isDebugEnabled();
|
||||
LinphoneCoreFactory.instance().enableLogCollection(isDebugEnabled);
|
||||
LinphoneCoreFactory.instance().setDebugMode(isDebugEnabled, context.getString(R.string.app_name));
|
||||
|
||||
Log.i("Keep alive handler invoked");
|
||||
if (LinphoneManager.getLcIfManagerNotDestroyedOrNull() != null) {
|
||||
//first refresh registers
|
||||
LinphoneManager.getLc().refreshRegisters();
|
||||
|
@ -38,9 +42,6 @@ public class KeepAliveHandler extends BroadcastReceiver {
|
|||
} catch (InterruptedException e) {
|
||||
//Log.e("Cannot sleep for 2s", e); //TODO FIXME Crash since the log rework
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -29,10 +29,8 @@ import android.content.Intent;
|
|||
* Purpose of this receiver is to disable keep alives when screen is off
|
||||
* */
|
||||
public class KeepAliveReceiver extends BroadcastReceiver {
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
|
||||
if (!LinphoneService.isReady()) {
|
||||
Log.i("Keep alive broadcast received while Linphone service not ready");
|
||||
return;
|
||||
|
@ -43,7 +41,5 @@ public class KeepAliveReceiver extends BroadcastReceiver {
|
|||
LinphoneManager.getLc().enableKeepAlive(false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,11 +23,14 @@ import java.text.SimpleDateFormat;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import org.linphone.LinphoneManager.AddressType;
|
||||
import org.linphone.assistant.AssistantActivity;
|
||||
import org.linphone.assistant.RemoteProvisioningLoginActivity;
|
||||
import org.linphone.compatibility.Compatibility;
|
||||
import org.linphone.core.CallDirection;
|
||||
import org.linphone.core.LinphoneAddress;
|
||||
import org.linphone.core.LinphoneAuthInfo;
|
||||
|
@ -61,11 +64,11 @@ import android.content.Intent;
|
|||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Settings;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.support.v4.widget.DrawerLayout;
|
||||
import android.view.Gravity;
|
||||
|
@ -97,14 +100,10 @@ import android.widget.Toast;
|
|||
public class LinphoneActivity extends Activity implements OnClickListener, ContactPicked, ActivityCompat.OnRequestPermissionsResultCallback {
|
||||
public static final String PREF_FIRST_LAUNCH = "pref_first_launch";
|
||||
private static final int SETTINGS_ACTIVITY = 123;
|
||||
private static final int FIRST_LOGIN_ACTIVITY = 101;
|
||||
private static final int REMOTE_PROVISIONING_LOGIN_ACTIVITY = 102;
|
||||
private static final int CALL_ACTIVITY = 19;
|
||||
private static final int PERMISSIONS_REQUEST_CONTACTS = 200;
|
||||
private static final int PERMISSIONS_REQUEST_RECORD_AUDIO = 201;
|
||||
private static final int PERMISSIONS_REQUEST_RECORD_AUDIO_INCOMING_CALL = 203;
|
||||
private static final int PERMISSIONS_REQUEST_EXTERNAL_FILE_STORAGE = 204;
|
||||
private static final int PERMISSIONS_REQUEST_CAMERA = 205;
|
||||
private static final int PERMISSIONS_REQUEST_OVERLAY = 206;
|
||||
private static final int PERMISSIONS_REQUEST_SYNC = 207;
|
||||
private static final int PERMISSIONS_REQUEST_CONTACTS = 208;
|
||||
|
||||
private static LinphoneActivity instance;
|
||||
|
||||
|
@ -140,17 +139,6 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
|
|||
return instance;
|
||||
throw new RuntimeException("LinphoneActivity not instantiated yet");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
outState.putSerializable("CurrentFragment", currentFragment);
|
||||
super.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRestoreInstanceState(Bundle savedInstanceState) {
|
||||
super.onRestoreInstanceState(savedInstanceState);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
|
@ -171,18 +159,29 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
|
|||
Intent wizard = new Intent();
|
||||
wizard.setClass(this, RemoteProvisioningLoginActivity.class);
|
||||
wizard.putExtra("Domain", LinphoneManager.getInstance().wizardLoginViewDomain);
|
||||
startActivityForResult(wizard, REMOTE_PROVISIONING_LOGIN_ACTIVITY);
|
||||
} else if (savedInstanceState == null && (useFirstLoginActivity && LinphonePreferences.instance().isFirstLaunch() || LinphoneManager.getLc().getProxyConfigList().length == 0)) {
|
||||
startActivity(wizard);
|
||||
finish();
|
||||
return;
|
||||
} else if (savedInstanceState == null && (useFirstLoginActivity && LinphonePreferences.instance().isFirstLaunch())) {
|
||||
if (LinphonePreferences.instance().getAccountCount() > 0) {
|
||||
LinphonePreferences.instance().firstLaunchSuccessful();
|
||||
} else {
|
||||
startActivityForResult(new Intent().setClass(this, AssistantActivity.class), FIRST_LOGIN_ACTIVITY);
|
||||
startActivity(new Intent().setClass(this, AssistantActivity.class));
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (getIntent() != null && getIntent().getExtras() != null) {
|
||||
newProxyConfig = getIntent().getExtras().getBoolean("isNewProxyConfig");
|
||||
}
|
||||
|
||||
//TODO rework
|
||||
if (getResources().getBoolean(R.bool.use_linphone_tag) && getPackageManager().checkPermission(Manifest.permission.WRITE_SYNC_SETTINGS, getPackageName()) == PackageManager.PERMISSION_GRANTED) {
|
||||
ContactsManager.getInstance().initializeSyncAccount(getApplicationContext(), getContentResolver());
|
||||
if (getResources().getBoolean(R.bool.use_linphone_tag)) {
|
||||
if (getPackageManager().checkPermission(Manifest.permission.WRITE_SYNC_SETTINGS, getPackageName()) != PackageManager.PERMISSION_GRANTED) {
|
||||
checkSyncPermission();
|
||||
} else {
|
||||
ContactsManager.getInstance().initializeSyncAccount(getApplicationContext(), getContentResolver());
|
||||
}
|
||||
} else {
|
||||
ContactsManager.getInstance().initializeContactManager(getApplicationContext(), getContentResolver());
|
||||
}
|
||||
|
@ -198,8 +197,6 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
|
|||
currentFragment = nextFragment = FragmentsAvailable.EMPTY;
|
||||
if (savedInstanceState == null) {
|
||||
changeCurrentFragment(FragmentsAvailable.DIALER, getIntent().getExtras());
|
||||
} else {
|
||||
changeCurrentFragment(((FragmentsAvailable)savedInstanceState.getSerializable("CurrentFragment")), getIntent().getExtras());
|
||||
}
|
||||
|
||||
mListener = new LinphoneCoreListenerBase(){
|
||||
|
@ -243,28 +240,10 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
|
|||
@Override
|
||||
public void callState(LinphoneCore lc, LinphoneCall call, LinphoneCall.State state, String message) {
|
||||
if (state == State.IncomingReceived) {
|
||||
if (getPackageManager().checkPermission(Manifest.permission.RECORD_AUDIO, getPackageName()) == PackageManager.PERMISSION_GRANTED || LinphonePreferences.instance().audioPermAsked()) {
|
||||
startActivity(new Intent(LinphoneActivity.instance(), CallIncomingActivity.class));
|
||||
} else {
|
||||
checkAndRequestAudioPermission(true);
|
||||
}
|
||||
startActivity(new Intent(LinphoneActivity.instance(), CallIncomingActivity.class));
|
||||
} else if (state == State.OutgoingInit || state == State.OutgoingProgress) {
|
||||
if (getPackageManager().checkPermission(Manifest.permission.RECORD_AUDIO, getPackageName()) == PackageManager.PERMISSION_GRANTED || LinphonePreferences.instance().audioPermAsked()) {
|
||||
startActivity(new Intent(LinphoneActivity.instance(), CallOutgoingActivity.class));
|
||||
} else {
|
||||
checkAndRequestAudioPermission(false);
|
||||
}
|
||||
startActivity(new Intent(LinphoneActivity.instance(), CallOutgoingActivity.class));
|
||||
} else if (state == State.CallEnd || state == State.Error || state == State.CallReleased) {
|
||||
// Convert LinphoneCore message for internalization
|
||||
if (message != null && call.getErrorInfo().getReason() == Reason.Declined) {
|
||||
displayCustomToast(getString(R.string.error_call_declined), Toast.LENGTH_SHORT);
|
||||
} else if (message != null && call.getErrorInfo().getReason() == Reason.NotFound) {
|
||||
displayCustomToast(getString(R.string.error_user_not_found), Toast.LENGTH_SHORT);
|
||||
} else if (message != null && call.getErrorInfo().getReason() == Reason.Media) {
|
||||
displayCustomToast(getString(R.string.error_incompatible_media), Toast.LENGTH_SHORT);
|
||||
} else if (message != null && state == State.Error) {
|
||||
displayCustomToast(getString(R.string.error_unknown) + " - " + message, Toast.LENGTH_SHORT);
|
||||
}
|
||||
resetClassicMenuLayoutAndGoBackToCallIfStillRunning();
|
||||
}
|
||||
|
||||
|
@ -381,6 +360,7 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
|
|||
newFragment = new HistoryDetailFragment();
|
||||
break;
|
||||
case CONTACTS_LIST:
|
||||
checkAndRequestReadContactsPermission();
|
||||
newFragment = new ContactsListFragment();
|
||||
if (isTablet()) {
|
||||
((ContactsListFragment) newFragment).displayFirstContact();
|
||||
|
@ -826,43 +806,52 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
|
|||
}
|
||||
|
||||
public List<String> getChatList() {
|
||||
return getChatStorage().getChatList();
|
||||
}
|
||||
ArrayList<String> chatList = new ArrayList<String>();
|
||||
|
||||
public List<String> getDraftChatList() {
|
||||
return getChatStorage().getDrafts();
|
||||
LinphoneChatRoom[] chats = LinphoneManager.getLc().getChatRooms();
|
||||
List<LinphoneChatRoom> rooms = new ArrayList<LinphoneChatRoom>();
|
||||
|
||||
for (LinphoneChatRoom chatroom : chats) {
|
||||
if (chatroom.getHistorySize() > 0) {
|
||||
rooms.add(chatroom);
|
||||
}
|
||||
}
|
||||
|
||||
if (rooms.size() > 1) {
|
||||
Collections.sort(rooms, new Comparator<LinphoneChatRoom>() {
|
||||
@Override
|
||||
public int compare(LinphoneChatRoom a, LinphoneChatRoom b) {
|
||||
LinphoneChatMessage[] messagesA = a.getHistory(1);
|
||||
LinphoneChatMessage[] messagesB = b.getHistory(1);
|
||||
long atime = messagesA[0].getTime();
|
||||
long btime = messagesB[0].getTime();
|
||||
|
||||
if (atime > btime)
|
||||
return -1;
|
||||
else if (btime > atime)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
for (LinphoneChatRoom chatroom : rooms) {
|
||||
chatList.add(chatroom.getPeerAddress().asStringUriOnly());
|
||||
}
|
||||
|
||||
return chatList;
|
||||
}
|
||||
|
||||
public void removeFromChatList(String sipUri) {
|
||||
getChatStorage().removeDiscussion(sipUri);
|
||||
}
|
||||
|
||||
public void removeFromDrafts(String sipUri) {
|
||||
getChatStorage().deleteDraft(sipUri);
|
||||
LinphoneChatRoom chatroom = LinphoneManager.getLc().getOrCreateChatRoom(sipUri);
|
||||
chatroom.deleteHistory();
|
||||
}
|
||||
|
||||
public void updateMissedChatCount() {
|
||||
displayMissedChats(getUnreadMessageCount());
|
||||
}
|
||||
|
||||
public int onMessageSent(String to, String message) {
|
||||
getChatStorage().deleteDraft(to);
|
||||
return getChatStorage().saveTextMessage("", to, message, System.currentTimeMillis());
|
||||
}
|
||||
|
||||
public int onMessageSent(String to, Bitmap image, String imageURL) {
|
||||
getChatStorage().deleteDraft(to);
|
||||
return getChatStorage().saveImageMessage("", to, image, imageURL, System.currentTimeMillis());
|
||||
}
|
||||
|
||||
public void onMessageStateChanged(String to, String message, int newState) {
|
||||
getChatStorage().updateMessageStatus(to, message, newState);
|
||||
}
|
||||
|
||||
public void onImageMessageStateChanged(String to, int id, int newState) {
|
||||
getChatStorage().updateMessageStatus(to, id, newState);
|
||||
}
|
||||
|
||||
public void displayMissedCalls(final int missedCallsCount) {
|
||||
if (missedCallsCount > 0) {
|
||||
missedCalls.setText(missedCallsCount + "");
|
||||
|
@ -893,8 +882,6 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void displayCustomToast(final String message, final int duration) {
|
||||
LayoutInflater inflater = getLayoutInflater();
|
||||
View layout = inflater.inflate(R.layout.toast, (ViewGroup) findViewById(R.id.toastRoot));
|
||||
|
@ -1066,10 +1053,6 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
|
|||
return currentFragment;
|
||||
}
|
||||
|
||||
public ChatStorage getChatStorage() {
|
||||
return ChatStorage.getInstance();
|
||||
}
|
||||
|
||||
public void addContact(String displayName, String sipUri)
|
||||
{
|
||||
Bundle extras = new Bundle();
|
||||
|
@ -1079,19 +1062,17 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
|
|||
|
||||
public void editContact(LinphoneContact contact)
|
||||
{
|
||||
Bundle extras = new Bundle();
|
||||
extras.putSerializable("Contact", contact);
|
||||
changeCurrentFragment(FragmentsAvailable.CONTACT_EDITOR, extras);
|
||||
|
||||
Bundle extras = new Bundle();
|
||||
extras.putSerializable("Contact", contact);
|
||||
changeCurrentFragment(FragmentsAvailable.CONTACT_EDITOR, extras);
|
||||
}
|
||||
|
||||
public void editContact(LinphoneContact contact, String sipAddress)
|
||||
{
|
||||
|
||||
Bundle extras = new Bundle();
|
||||
extras.putSerializable("Contact", contact);
|
||||
extras.putSerializable("NewSipAdress", sipAddress);
|
||||
changeCurrentFragment(FragmentsAvailable.CONTACT_EDITOR, extras);
|
||||
Bundle extras = new Bundle();
|
||||
extras.putSerializable("Contact", contact);
|
||||
extras.putSerializable("NewSipAdress", sipAddress);
|
||||
changeCurrentFragment(FragmentsAvailable.CONTACT_EDITOR, extras);
|
||||
}
|
||||
|
||||
public void quit() {
|
||||
|
@ -1129,6 +1110,10 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
|
|||
} else {
|
||||
resetClassicMenuLayoutAndGoBackToCallIfStillRunning();
|
||||
}
|
||||
} else if (requestCode == PERMISSIONS_REQUEST_OVERLAY) {
|
||||
if (Compatibility.canDrawOverlays(this)) {
|
||||
LinphonePreferences.instance().enableOverlay(true);
|
||||
}
|
||||
} else {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
}
|
||||
|
@ -1169,101 +1154,125 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean checkAndRequestOverlayPermission() {
|
||||
Log.i("[Permission] Draw overlays permission is " + (Compatibility.canDrawOverlays(this) ? "granted" : "denied"));
|
||||
if (!Compatibility.canDrawOverlays(this)) {
|
||||
Log.i("[Permission] Asking for overlay");
|
||||
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName()));
|
||||
startActivityForResult(intent, PERMISSIONS_REQUEST_OVERLAY);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void checkAndRequestReadExternalStoragePermission() {
|
||||
checkAndRequestPermission(Manifest.permission.READ_EXTERNAL_STORAGE, 0);
|
||||
}
|
||||
|
||||
public void checkAndRequestExternalStoragePermission() {
|
||||
if (LinphonePreferences.instance().writeExternalStoragePermAsked()) {
|
||||
return;
|
||||
}
|
||||
checkAndRequestPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE, PERMISSIONS_REQUEST_EXTERNAL_FILE_STORAGE);
|
||||
checkAndRequestPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE, 0);
|
||||
}
|
||||
|
||||
public void checkAndRequestCameraPermission() {
|
||||
if (LinphonePreferences.instance().cameraPermAsked()) {
|
||||
return;
|
||||
}
|
||||
checkAndRequestPermission(Manifest.permission.CAMERA, PERMISSIONS_REQUEST_CAMERA);
|
||||
checkAndRequestPermission(Manifest.permission.CAMERA, 0);
|
||||
}
|
||||
|
||||
public void checkAndRequestReadContactsPermission() {
|
||||
if (LinphonePreferences.instance().readContactsPermAsked()) {
|
||||
return;
|
||||
}
|
||||
checkAndRequestPermission(Manifest.permission.READ_CONTACTS, PERMISSIONS_REQUEST_CONTACTS);
|
||||
}
|
||||
|
||||
public void checkAndRequestWriteContactsPermission() {
|
||||
if (LinphonePreferences.instance().writeContactsPermAsked()) {
|
||||
return;
|
||||
}
|
||||
checkAndRequestPermission(Manifest.permission.WRITE_CONTACTS, PERMISSIONS_REQUEST_CONTACTS);
|
||||
checkAndRequestPermission(Manifest.permission.WRITE_CONTACTS, 0);
|
||||
}
|
||||
|
||||
public void checkAndRequestAudioPermission(boolean isIncomingCall) {
|
||||
if (LinphonePreferences.instance().audioPermAsked()) {
|
||||
return;
|
||||
public void checkAndRequestPermissionsToSendImage() {
|
||||
ArrayList<String> permissionsList = new ArrayList<String>();
|
||||
|
||||
int readExternalStorage = getPackageManager().checkPermission(Manifest.permission.READ_EXTERNAL_STORAGE, getPackageName());
|
||||
Log.i("[Permission] Read external storage permission is " + (readExternalStorage == PackageManager.PERMISSION_GRANTED ? "granted" : "denied"));
|
||||
int camera = getPackageManager().checkPermission(Manifest.permission.CAMERA, getPackageName());
|
||||
Log.i("[Permission] Camera permission is " + (camera == PackageManager.PERMISSION_GRANTED ? "granted" : "denied"));
|
||||
|
||||
if (readExternalStorage != PackageManager.PERMISSION_GRANTED) {
|
||||
if (LinphonePreferences.instance().firstTimeAskingForPermission(Manifest.permission.READ_EXTERNAL_STORAGE) || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_EXTERNAL_STORAGE)) {
|
||||
Log.i("[Permission] Asking for read external storage");
|
||||
permissionsList.add(Manifest.permission.READ_EXTERNAL_STORAGE);
|
||||
}
|
||||
}
|
||||
checkAndRequestPermission(Manifest.permission.RECORD_AUDIO, isIncomingCall ? PERMISSIONS_REQUEST_RECORD_AUDIO_INCOMING_CALL : PERMISSIONS_REQUEST_RECORD_AUDIO);
|
||||
if (LinphonePreferences.instance().shouldInitiateVideoCall() ||
|
||||
LinphonePreferences.instance().shouldAutomaticallyAcceptVideoRequests()) {
|
||||
checkAndRequestCameraPermission();
|
||||
if (camera != PackageManager.PERMISSION_GRANTED) {
|
||||
if (LinphonePreferences.instance().firstTimeAskingForPermission(Manifest.permission.CAMERA) || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {
|
||||
Log.i("[Permission] Asking for camera");
|
||||
permissionsList.add(Manifest.permission.CAMERA);
|
||||
}
|
||||
}
|
||||
if (permissionsList.size() > 0) {
|
||||
String[] permissions = new String[permissionsList.size()];
|
||||
permissions = permissionsList.toArray(permissions);
|
||||
ActivityCompat.requestPermissions(this, permissions, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkSyncPermission() {
|
||||
checkAndRequestPermission(Manifest.permission.WRITE_SYNC_SETTINGS, PERMISSIONS_REQUEST_SYNC);
|
||||
}
|
||||
|
||||
public void checkAndRequestPermission(String permission, int result) {
|
||||
if (getPackageManager().checkPermission(permission, getPackageName()) != PackageManager.PERMISSION_GRANTED) {
|
||||
ActivityCompat.requestPermissions(this, new String[]{permission}, result);
|
||||
int permissionGranted = getPackageManager().checkPermission(permission, getPackageName());
|
||||
Log.i("[Permission] " + permission + " is " + (permissionGranted == PackageManager.PERMISSION_GRANTED ? "granted" : "denied"));
|
||||
|
||||
if (permissionGranted != PackageManager.PERMISSION_GRANTED) {
|
||||
if (LinphonePreferences.instance().firstTimeAskingForPermission(permission) || ActivityCompat.shouldShowRequestPermissionRationale(this, permission)) {
|
||||
Log.i("[Permission] Asking for " + permission);
|
||||
ActivityCompat.requestPermissions(this, new String[] { permission }, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
|
||||
if (grantResults.length > 0) {
|
||||
for (int i = 0; i < grantResults.length; i++) {
|
||||
if (grantResults[i] == PackageManager.PERMISSION_DENIED) {
|
||||
if (!ActivityCompat.shouldShowRequestPermissionRationale(this, permissions[i])) {
|
||||
if (permissions[i].equals(Manifest.permission.RECORD_AUDIO)) {
|
||||
LinphonePreferences.instance().neverAskAudioPerm();
|
||||
} else if (permissions[i].equals(Manifest.permission.CAMERA)) {
|
||||
LinphonePreferences.instance().neverAskCameraPerm();
|
||||
} else if (permissions[i].equals(Manifest.permission.READ_CONTACTS)) {
|
||||
LinphonePreferences.instance().neverAskReadContactsPerm();
|
||||
} else if (permissions[i].equals(Manifest.permission.WRITE_CONTACTS)) {
|
||||
LinphonePreferences.instance().neverAskWriteContactsPerm();
|
||||
} else if (permissions[i].equals(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
|
||||
LinphonePreferences.instance().neverAskWriteExternalStoragePerm();
|
||||
}
|
||||
} else {
|
||||
//TODO: show dialog explaining what we need the permission for
|
||||
}
|
||||
} else {
|
||||
if (permissions[i].equals(Manifest.permission.RECORD_AUDIO)) {
|
||||
LinphonePreferences.instance().neverAskAudioPerm();
|
||||
} else if (permissions[i].equals(Manifest.permission.CAMERA)) {
|
||||
LinphonePreferences.instance().neverAskCameraPerm();
|
||||
} else if (permissions[i].equals(Manifest.permission.READ_CONTACTS)) {
|
||||
LinphonePreferences.instance().neverAskReadContactsPerm();
|
||||
} else if (permissions[i].equals(Manifest.permission.WRITE_CONTACTS)) {
|
||||
LinphonePreferences.instance().neverAskWriteContactsPerm();
|
||||
} else if (permissions[i].equals(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
|
||||
LinphonePreferences.instance().neverAskWriteExternalStoragePerm();
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < permissions.length; i++) {
|
||||
Log.i("[Permission] " + permissions[i] + " is " + (grantResults[i] == PackageManager.PERMISSION_GRANTED ? "granted" : "denied"));
|
||||
}
|
||||
|
||||
switch (requestCode) {
|
||||
case PERMISSIONS_REQUEST_RECORD_AUDIO:
|
||||
startActivity(new Intent(this, CallOutgoingActivity.class));
|
||||
case PERMISSIONS_REQUEST_SYNC:
|
||||
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
ContactsManager.getInstance().initializeSyncAccount(getApplicationContext(), getContentResolver());
|
||||
} else {
|
||||
ContactsManager.getInstance().initializeContactManager(getApplicationContext(), getContentResolver());
|
||||
}
|
||||
break;
|
||||
case PERMISSIONS_REQUEST_RECORD_AUDIO_INCOMING_CALL:
|
||||
startActivity(new Intent(this, CallIncomingActivity.class));
|
||||
case PERMISSIONS_REQUEST_CONTACTS:
|
||||
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
ContactsManager.getInstance().enableContactsAccess();
|
||||
ContactsManager.getInstance().fetchContacts();
|
||||
fetchedContactsOnce = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
|
||||
int contacts = getPackageManager().checkPermission(Manifest.permission.READ_CONTACTS, getPackageName());
|
||||
Log.i("[Permission] Contacts permission is " + (contacts == PackageManager.PERMISSION_GRANTED ? "granted" : "denied"));
|
||||
|
||||
if (contacts == PackageManager.PERMISSION_GRANTED && !fetchedContactsOnce) {
|
||||
ContactsManager.getInstance().enableContactsAccess();
|
||||
ContactsManager.getInstance().fetchContacts();
|
||||
fetchedContactsOnce = true;
|
||||
} else {
|
||||
checkAndRequestReadContactsPermission();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
|
||||
|
||||
if (!LinphoneService.isReady()) {
|
||||
startService(new Intent(Intent.ACTION_MAIN).setClass(this, LinphoneService.class));
|
||||
}
|
||||
|
@ -1273,14 +1282,6 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
|
|||
lc.addListener(mListener);
|
||||
}
|
||||
|
||||
if (getPackageManager().checkPermission(Manifest.permission.READ_CONTACTS, getPackageName()) == PackageManager.PERMISSION_GRANTED && !fetchedContactsOnce) {
|
||||
ContactsManager.getInstance().enableContactsAccess();
|
||||
ContactsManager.getInstance().fetchContacts();
|
||||
fetchedContactsOnce = true;
|
||||
} else {
|
||||
checkAndRequestReadContactsPermission();
|
||||
}
|
||||
|
||||
refreshAccounts();
|
||||
|
||||
updateMissedChatCount();
|
||||
|
@ -1296,18 +1297,11 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
|
|||
if (LinphoneManager.getLc().getCalls().length > 0) {
|
||||
LinphoneCall call = LinphoneManager.getLc().getCalls()[0];
|
||||
LinphoneCall.State callState = call.getState();
|
||||
|
||||
if (callState == State.IncomingReceived) {
|
||||
if (getPackageManager().checkPermission(Manifest.permission.RECORD_AUDIO, getPackageName()) == PackageManager.PERMISSION_GRANTED || LinphonePreferences.instance().audioPermAsked()) {
|
||||
startActivity(new Intent(this, CallIncomingActivity.class));
|
||||
} else {
|
||||
checkAndRequestAudioPermission(true);
|
||||
}
|
||||
startActivity(new Intent(this, CallIncomingActivity.class));
|
||||
} else if (callState == State.OutgoingInit || callState == State.OutgoingProgress || callState == State.OutgoingRinging) {
|
||||
if (getPackageManager().checkPermission(Manifest.permission.RECORD_AUDIO, getPackageName()) == PackageManager.PERMISSION_GRANTED || LinphonePreferences.instance().audioPermAsked()) {
|
||||
startActivity(new Intent(this, CallOutgoingActivity.class));
|
||||
} else {
|
||||
checkAndRequestAudioPermission(false);
|
||||
}
|
||||
startActivity(new Intent(this, CallOutgoingActivity.class));
|
||||
} else {
|
||||
if (call.getCurrentParamsCopy().getVideoEnabled()) {
|
||||
startVideoActivity(call);
|
||||
|
@ -1349,7 +1343,7 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
|
|||
@Override
|
||||
protected void onNewIntent(Intent intent) {
|
||||
super.onNewIntent(intent);
|
||||
|
||||
|
||||
Bundle extras = intent.getExtras();
|
||||
if (extras != null && extras.getBoolean("GoToChat", false)) {
|
||||
LinphoneService.instance().removeMessageNotification();
|
||||
|
@ -1386,11 +1380,7 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
|
|||
if (CallActivity.isInstanciated()) {
|
||||
CallActivity.instance().startIncomingCallActivity();
|
||||
} else {
|
||||
if (getPackageManager().checkPermission(Manifest.permission.RECORD_AUDIO, getPackageName()) == PackageManager.PERMISSION_GRANTED || LinphonePreferences.instance().audioPermAsked()) {
|
||||
startActivity(new Intent(this, CallIncomingActivity.class));
|
||||
} else {
|
||||
checkAndRequestAudioPermission(true);
|
||||
}
|
||||
startActivity(new Intent(this, CallIncomingActivity.class));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,10 +48,11 @@ public class LinphoneContact implements Serializable, Comparable<LinphoneContact
|
|||
private static final long serialVersionUID = 9015568163905205244L;
|
||||
|
||||
private transient LinphoneFriend friend;
|
||||
private String fullName, firstName, lastName, androidId;
|
||||
private String fullName, firstName, lastName, androidId, androidRawId, androidTagId;
|
||||
private transient Uri photoUri, thumbnailUri;
|
||||
private List<LinphoneNumberOrAddress> addresses;
|
||||
private transient ArrayList<ContentProviderOperation> changesToCommit;
|
||||
private transient ArrayList<ContentProviderOperation> changesToCommit2;
|
||||
private boolean hasSipAddress;
|
||||
|
||||
public LinphoneContact() {
|
||||
|
@ -60,6 +61,7 @@ public class LinphoneContact implements Serializable, Comparable<LinphoneContact
|
|||
thumbnailUri = null;
|
||||
photoUri = null;
|
||||
changesToCommit = new ArrayList<ContentProviderOperation>();
|
||||
changesToCommit2 = new ArrayList<ContentProviderOperation>();
|
||||
hasSipAddress = false;
|
||||
}
|
||||
|
||||
|
@ -138,12 +140,12 @@ public class LinphoneContact implements Serializable, Comparable<LinphoneContact
|
|||
public void setPhoto(byte[] photo) {
|
||||
if (photo != null) {
|
||||
if (isAndroidContact()) {
|
||||
String rawContactId = findRawContactID(getAndroidId());
|
||||
if (rawContactId != null) {
|
||||
if (androidRawId != null) {
|
||||
changesToCommit.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
|
||||
.withValue(ContactsContract.Data.RAW_CONTACT_ID, rawContactId)
|
||||
.withValue(ContactsContract.Data.RAW_CONTACT_ID, androidRawId)
|
||||
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE)
|
||||
.withValue(ContactsContract.CommonDataKinds.Photo.PHOTO, photo)
|
||||
.withValue(ContactsContract.Data.IS_PRIMARY, 1)
|
||||
.withValue(ContactsContract.Data.IS_SUPER_PRIMARY, 1)
|
||||
.build());
|
||||
} else {
|
||||
|
@ -153,8 +155,6 @@ public class LinphoneContact implements Serializable, Comparable<LinphoneContact
|
|||
.withValue(ContactsContract.CommonDataKinds.Photo.PHOTO, photo)
|
||||
.build());
|
||||
}
|
||||
} else if (isLinphoneFriend()) {
|
||||
//TODO: prepare photo changes in friend
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -201,6 +201,15 @@ public class LinphoneContact implements Serializable, Comparable<LinphoneContact
|
|||
changesToCommit.add(ContentProviderOperation.newDelete(ContactsContract.Data.CONTENT_URI)
|
||||
.withSelection(select, args)
|
||||
.build());
|
||||
|
||||
if (androidTagId != null && noa.isSIPAddress()) {
|
||||
select = ContactsContract.Data.RAW_CONTACT_ID + "=? AND " + ContactsContract.Data.DATA1 + "=?";
|
||||
args = new String[] { androidTagId, noa.getOldValue() };
|
||||
|
||||
changesToCommit.add(ContentProviderOperation.newDelete(ContactsContract.Data.CONTENT_URI)
|
||||
.withSelection(select, args)
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
||||
if (isLinphoneFriend()) {
|
||||
|
@ -239,19 +248,37 @@ public class LinphoneContact implements Serializable, Comparable<LinphoneContact
|
|||
values.put(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_CUSTOM);
|
||||
values.put(ContactsContract.CommonDataKinds.Phone.LABEL, ContactsManager.getInstance().getString(R.string.addressbook_label));
|
||||
}
|
||||
|
||||
String rawContactId = findRawContactID(getAndroidId());
|
||||
if (rawContactId != null) {
|
||||
if (androidRawId != null) {
|
||||
changesToCommit.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
|
||||
.withValue(ContactsContract.Data.RAW_CONTACT_ID, rawContactId)
|
||||
.withValues(values)
|
||||
.build());
|
||||
.withValue(ContactsContract.Data.RAW_CONTACT_ID, androidRawId)
|
||||
.withValues(values)
|
||||
.build());
|
||||
} else {
|
||||
changesToCommit.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
|
||||
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
|
||||
.withValues(values)
|
||||
.build());
|
||||
}
|
||||
|
||||
if (noa.isSIPAddress() && LinphoneManager.getInstance().getContext().getResources().getBoolean(R.bool.use_linphone_tag)) {
|
||||
if (androidTagId != null) {
|
||||
changesToCommit.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
|
||||
.withValue(ContactsContract.Data.RAW_CONTACT_ID, androidTagId)
|
||||
.withValue(ContactsContract.Data.MIMETYPE, ContactsManager.getInstance().getString(R.string.sync_mimetype))
|
||||
.withValue(ContactsContract.Data.DATA1, noa.getValue())
|
||||
.withValue(ContactsContract.Data.DATA2, ContactsManager.getInstance().getString(R.string.app_name))
|
||||
.withValue(ContactsContract.Data.DATA3, noa.getValue())
|
||||
.build());
|
||||
} else {
|
||||
changesToCommit2.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
|
||||
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
|
||||
.withValue(ContactsContract.Data.MIMETYPE, ContactsManager.getInstance().getString(R.string.sync_mimetype))
|
||||
.withValue(ContactsContract.Data.DATA1, noa.getValue())
|
||||
.withValue(ContactsContract.Data.DATA2, ContactsManager.getInstance().getString(R.string.app_name))
|
||||
.withValue(ContactsContract.Data.DATA3, noa.getValue())
|
||||
.build());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ContentValues values = new ContentValues();
|
||||
String select;
|
||||
|
@ -266,13 +293,28 @@ public class LinphoneContact implements Serializable, Comparable<LinphoneContact
|
|||
values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
|
||||
values.put(ContactsContract.CommonDataKinds.Phone.NUMBER, noa.getValue());
|
||||
}
|
||||
changesToCommit.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
|
||||
.withSelection(select, args)
|
||||
.withValues(values)
|
||||
.build());
|
||||
|
||||
String rawContactId = findRawContactID(getAndroidId());
|
||||
if (rawContactId != null) {
|
||||
changesToCommit.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
|
||||
.withSelection(select, args)
|
||||
.withValues(values)
|
||||
.build());
|
||||
if (noa.isSIPAddress() && LinphoneManager.getInstance().getContext().getResources().getBoolean(R.bool.use_linphone_tag)) {
|
||||
if (androidTagId != null) {
|
||||
changesToCommit.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
|
||||
.withSelection(ContactsContract.Data.RAW_CONTACT_ID + "=? AND " + ContactsContract.Data.DATA1 + "=? ", new String[] { androidTagId, noa.getOldValue() })
|
||||
.withValue(ContactsContract.Data.DATA1, noa.getValue())
|
||||
.withValue(ContactsContract.Data.DATA2, ContactsManager.getInstance().getString(R.string.app_name))
|
||||
.withValue(ContactsContract.Data.DATA3, noa.getValue())
|
||||
.build());
|
||||
} else {
|
||||
changesToCommit2.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
|
||||
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
|
||||
.withValue(ContactsContract.Data.MIMETYPE, ContactsManager.getInstance().getString(R.string.sync_mimetype))
|
||||
.withValue(ContactsContract.Data.DATA1, noa.getValue())
|
||||
.withValue(ContactsContract.Data.DATA2, ContactsManager.getInstance().getString(R.string.app_name))
|
||||
.withValue(ContactsContract.Data.DATA3, noa.getValue())
|
||||
.build());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -309,16 +351,19 @@ public class LinphoneContact implements Serializable, Comparable<LinphoneContact
|
|||
return androidId;
|
||||
}
|
||||
|
||||
public void save() {
|
||||
if (isAndroidContact() && ContactsManager.getInstance().hasContactsAccess() && changesToCommit.size() > 0) {
|
||||
public void save() {
|
||||
if (isAndroidContact() && ContactsManager.getInstance().hasContactsAccess() && changesToCommit.size() > 0) {
|
||||
try {
|
||||
ContactsManager.getInstance().getContentResolver().applyBatch(ContactsContract.AUTHORITY, changesToCommit);
|
||||
createLinphoneTagIfNeeded();
|
||||
} catch (Exception e) {
|
||||
Log.e(e);
|
||||
} finally {
|
||||
changesToCommit = new ArrayList<ContentProviderOperation>();
|
||||
changesToCommit2 = new ArrayList<ContentProviderOperation>();
|
||||
}
|
||||
}
|
||||
|
||||
if (isLinphoneFriend()) {
|
||||
boolean hasAddr = false;
|
||||
LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
|
||||
|
@ -387,17 +432,22 @@ public class LinphoneContact implements Serializable, Comparable<LinphoneContact
|
|||
hasSipAddress = false;
|
||||
|
||||
if (isAndroidContact()) {
|
||||
String id = getAndroidId();
|
||||
getContactNames(id);
|
||||
setThumbnailUri(getContactPictureUri(id));
|
||||
setPhotoUri(getContactPhotoUri(id));
|
||||
for (LinphoneNumberOrAddress noa : getAddressesAndNumbersForAndroidContact(id)) {
|
||||
getContactNames();
|
||||
setThumbnailUri(getContactPictureUri());
|
||||
setPhotoUri(getContactPhotoUri());
|
||||
androidRawId = findRawContactID();
|
||||
|
||||
if (LinphoneManager.getInstance().getContext().getResources().getBoolean(R.bool.use_linphone_tag)) {
|
||||
androidTagId = findLinphoneRawContactId();
|
||||
}
|
||||
|
||||
for (LinphoneNumberOrAddress noa : getAddressesAndNumbersForAndroidContact()) {
|
||||
addNumberOrAddress(noa);
|
||||
}
|
||||
|
||||
if (friend == null) {
|
||||
friend = LinphoneCoreFactory.instance().createLinphoneFriend();
|
||||
friend.setRefKey(id);
|
||||
friend.setRefKey(getAndroidId());
|
||||
// Disable subscribes for now
|
||||
friend.enableSubscribes(false);
|
||||
friend.setIncSubscribePolicy(SubscribePolicy.SPDeny);
|
||||
|
@ -471,21 +521,21 @@ public class LinphoneContact implements Serializable, Comparable<LinphoneContact
|
|||
return firstLetter.compareTo(contactfirstLetter);
|
||||
}
|
||||
|
||||
private Uri getContactPictureUri(String id) {
|
||||
Uri person = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, Long.parseLong(id));
|
||||
private Uri getContactPictureUri() {
|
||||
Uri person = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, Long.parseLong(getAndroidId()));
|
||||
return Uri.withAppendedPath(person, ContactsContract.Contacts.Photo.CONTENT_DIRECTORY);
|
||||
}
|
||||
|
||||
private Uri getContactPhotoUri(String id) {
|
||||
Uri person = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, Long.parseLong(id));
|
||||
private Uri getContactPhotoUri() {
|
||||
Uri person = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, Long.parseLong(getAndroidId()));
|
||||
return Uri.withAppendedPath(person, ContactsContract.Contacts.Photo.DISPLAY_PHOTO);
|
||||
}
|
||||
|
||||
private void getContactNames(String id) {
|
||||
private void getContactNames() {
|
||||
ContentResolver resolver = ContactsManager.getInstance().getContentResolver();
|
||||
String[] proj = new String[]{ ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME, ContactsContract.Contacts.DISPLAY_NAME };
|
||||
String select = ContactsContract.Data.CONTACT_ID + "=? AND " + ContactsContract.Data.MIMETYPE + "=?";
|
||||
String[] args = new String[]{ id, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE };
|
||||
String[] args = new String[]{ getAndroidId(), ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE };
|
||||
Cursor c = resolver.query(ContactsContract.Data.CONTENT_URI, proj, select, args, null);
|
||||
if (c != null) {
|
||||
if (c.moveToFirst()) {
|
||||
|
@ -497,13 +547,13 @@ public class LinphoneContact implements Serializable, Comparable<LinphoneContact
|
|||
}
|
||||
}
|
||||
|
||||
private String findRawContactID(String id) {
|
||||
private String findRawContactID() {
|
||||
ContentResolver resolver = ContactsManager.getInstance().getContentResolver();
|
||||
String result = null;
|
||||
String[] projection = { ContactsContract.RawContacts._ID };
|
||||
|
||||
String selection = ContactsContract.RawContacts.CONTACT_ID + "=?";
|
||||
Cursor c = resolver.query(ContactsContract.RawContacts.CONTENT_URI, projection, selection, new String[]{ id }, null);
|
||||
Cursor c = resolver.query(ContactsContract.RawContacts.CONTENT_URI, projection, selection, new String[]{ getAndroidId() }, null);
|
||||
if (c != null) {
|
||||
if (c.moveToFirst()) {
|
||||
result = c.getString(c.getColumnIndex(ContactsContract.RawContacts._ID));
|
||||
|
@ -513,13 +563,13 @@ public class LinphoneContact implements Serializable, Comparable<LinphoneContact
|
|||
return result;
|
||||
}
|
||||
|
||||
private List<LinphoneNumberOrAddress> getAddressesAndNumbersForAndroidContact(String id) {
|
||||
private List<LinphoneNumberOrAddress> getAddressesAndNumbersForAndroidContact() {
|
||||
List<LinphoneNumberOrAddress> result = new ArrayList<LinphoneNumberOrAddress>();
|
||||
ContentResolver resolver = ContactsManager.getInstance().getContentResolver();
|
||||
|
||||
String select = ContactsContract.Data.CONTACT_ID + " =? AND (" + ContactsContract.Data.MIMETYPE + "=? OR " + ContactsContract.Data.MIMETYPE + "=?)";
|
||||
String[] projection = new String[] { ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS, ContactsContract.Data.MIMETYPE }; // PHONE_NUMBER == SIP_ADDRESS == "data1"...
|
||||
Cursor c = resolver.query(ContactsContract.Data.CONTENT_URI, projection, select, new String[]{ id, ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE }, null);
|
||||
Cursor c = resolver.query(ContactsContract.Data.CONTENT_URI, projection, select, new String[]{ getAndroidId(), ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE }, null);
|
||||
if (c != null) {
|
||||
while (c.moveToNext()) {
|
||||
String mime = c.getString(c.getColumnIndex(ContactsContract.Data.MIMETYPE));
|
||||
|
@ -552,12 +602,14 @@ public class LinphoneContact implements Serializable, Comparable<LinphoneContact
|
|||
|
||||
private static LinphoneContact createAndroidContact() {
|
||||
LinphoneContact contact = new LinphoneContact();
|
||||
|
||||
contact.changesToCommit.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
|
||||
.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, null)
|
||||
.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null)
|
||||
.withValue(ContactsContract.RawContacts.AGGREGATION_MODE, ContactsContract.RawContacts.AGGREGATION_MODE_DEFAULT)
|
||||
.build());
|
||||
contact.setAndroidId("0");
|
||||
|
||||
return contact;
|
||||
}
|
||||
|
||||
|
@ -570,4 +622,63 @@ public class LinphoneContact implements Serializable, Comparable<LinphoneContact
|
|||
contact.friend = friend;
|
||||
return contact;
|
||||
}
|
||||
|
||||
private String findLinphoneRawContactId() {
|
||||
ContentResolver resolver = ContactsManager.getInstance().getContentResolver();
|
||||
String result = null;
|
||||
String[] projection = { ContactsContract.RawContacts._ID };
|
||||
|
||||
String selection = ContactsContract.RawContacts.CONTACT_ID + "=? AND " + ContactsContract.RawContacts.ACCOUNT_TYPE + "=?";
|
||||
Cursor c = resolver.query(ContactsContract.RawContacts.CONTENT_URI, projection, selection, new String[] { getAndroidId(), ContactsManager.getInstance().getString(R.string.sync_account_type) }, null);
|
||||
if (c != null) {
|
||||
if (c.moveToFirst()) {
|
||||
result = c.getString(c.getColumnIndex(ContactsContract.RawContacts._ID));
|
||||
}
|
||||
c.close();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void createLinphoneTagIfNeeded() {
|
||||
if (LinphoneManager.getInstance().getContext().getResources().getBoolean(R.bool.use_linphone_tag)) {
|
||||
if (androidTagId == null && findLinphoneRawContactId() == null) {
|
||||
createLinphoneContactTag();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void createLinphoneContactTag() {
|
||||
ArrayList<ContentProviderOperation> batch = new ArrayList<ContentProviderOperation>();
|
||||
|
||||
batch.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
|
||||
.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, ContactsManager.getInstance().getString(R.string.sync_account_type))
|
||||
.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, ContactsManager.getInstance().getString(R.string.sync_account_name))
|
||||
.withValue(ContactsContract.RawContacts.AGGREGATION_MODE, ContactsContract.RawContacts.AGGREGATION_MODE_DEFAULT)
|
||||
.build());
|
||||
|
||||
batch.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
|
||||
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
|
||||
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
|
||||
.withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, getFullName())
|
||||
.build());
|
||||
|
||||
batch.add(ContentProviderOperation.newUpdate(ContactsContract.AggregationExceptions.CONTENT_URI)
|
||||
.withValue(ContactsContract.AggregationExceptions.TYPE, ContactsContract.AggregationExceptions.TYPE_KEEP_TOGETHER)
|
||||
.withValue(ContactsContract.AggregationExceptions.RAW_CONTACT_ID1, androidRawId)
|
||||
.withValueBackReference(ContactsContract.AggregationExceptions.RAW_CONTACT_ID2, 0)
|
||||
.build());
|
||||
|
||||
if (changesToCommit2.size() > 0) {
|
||||
for(ContentProviderOperation cpo : changesToCommit2) {
|
||||
batch.add(cpo);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
ContactsManager.getInstance().getContentResolver().applyBatch(ContactsContract.AUTHORITY, batch);
|
||||
androidTagId = findLinphoneRawContactId();
|
||||
} catch (Exception e) {
|
||||
Log.e(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@ package org.linphone;
|
|||
|
||||
import static android.content.Intent.ACTION_MAIN;
|
||||
|
||||
import org.linphone.mediastream.Log;
|
||||
import org.linphone.assistant.RemoteProvisioningActivity;
|
||||
import org.linphone.tutorials.TutorialLauncherActivity;
|
||||
|
||||
|
@ -83,7 +82,6 @@ public class LinphoneLauncherActivity extends Activity {
|
|||
}, 1000);
|
||||
}
|
||||
|
||||
|
||||
private class ServiceWaitThread extends Thread {
|
||||
public void run() {
|
||||
while (!LinphoneService.isReady()) {
|
||||
|
|
|
@ -29,10 +29,12 @@ import java.io.FileNotFoundException;
|
|||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
@ -85,6 +87,7 @@ import android.app.AlertDialog;
|
|||
import android.app.ProgressDialog;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
|
@ -110,6 +113,7 @@ import android.os.PowerManager.WakeLock;
|
|||
import android.os.Vibrator;
|
||||
import android.preference.CheckBoxPreference;
|
||||
import android.provider.MediaStore;
|
||||
import android.provider.MediaStore.Images;
|
||||
import android.provider.Settings;
|
||||
import android.provider.Settings.SettingNotFoundException;
|
||||
import android.telephony.TelephonyManager;
|
||||
|
@ -354,6 +358,40 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag
|
|||
public void setUploadingImageStream(ByteArrayInputStream array){
|
||||
this.mUploadingImageStream = array;
|
||||
}
|
||||
|
||||
private void storeImage(LinphoneChatMessage msg) {
|
||||
if (msg == null || msg.getFileTransferInformation() == null || msg.getAppData() == null) return;
|
||||
File file = new File(Environment.getExternalStorageDirectory(), msg.getAppData());
|
||||
Bitmap bm = BitmapFactory.decodeFile(file.getPath());
|
||||
if (bm == null) return;
|
||||
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(Images.Media.TITLE, file.getName());
|
||||
String extension = msg.getFileTransferInformation().getSubtype();
|
||||
values.put(Images.Media.MIME_TYPE, "image/" + extension);
|
||||
ContentResolver cr = getContext().getContentResolver();
|
||||
Uri path = cr.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
|
||||
|
||||
OutputStream stream;
|
||||
try {
|
||||
stream = cr.openOutputStream(path);
|
||||
if (extension != null && extension.toLowerCase(Locale.getDefault()).equals("png")) {
|
||||
bm.compress(Bitmap.CompressFormat.PNG, 100, stream);
|
||||
} else {
|
||||
bm.compress(Bitmap.CompressFormat.JPEG, 100, stream);
|
||||
}
|
||||
|
||||
stream.close();
|
||||
file.delete();
|
||||
bm.recycle();
|
||||
|
||||
msg.setAppData(path.toString());
|
||||
} catch (FileNotFoundException e) {
|
||||
Log.e(e);
|
||||
} catch (IOException e) {
|
||||
Log.e(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLinphoneChatMessageStateChanged(LinphoneChatMessage msg, LinphoneChatMessage.State state) {
|
||||
|
@ -362,17 +400,7 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag
|
|||
mUploadPendingFileMessage = null;
|
||||
mUploadingImageStream = null;
|
||||
} else {
|
||||
File file = new File(Environment.getExternalStorageDirectory(), msg.getAppData());
|
||||
try {
|
||||
Bitmap bm = BitmapFactory.decodeFile(file.getPath());
|
||||
if (bm != null) {
|
||||
String url = MediaStore.Images.Media.insertImage(getContext().getContentResolver(), file.getPath(), file.getName(), null);
|
||||
msg.setAppData(url);
|
||||
file.delete();
|
||||
}
|
||||
} catch (FileNotFoundException e) {
|
||||
Log.e(e);
|
||||
}
|
||||
storeImage(msg);
|
||||
removePendingMessage(msg);
|
||||
}
|
||||
}
|
||||
|
@ -862,13 +890,16 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag
|
|||
mLastNetworkType=curtype;
|
||||
}
|
||||
}
|
||||
|
||||
if (mLc.isNetworkReachable()) {
|
||||
// When network isn't available, push informations might not be set. This should fix the issue.
|
||||
LinphonePreferences prefs = LinphonePreferences.instance();
|
||||
prefs.setPushNotificationEnabled(prefs.isPushNotificationEnabled());
|
||||
}
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
|
||||
private void doDestroy() {
|
||||
if (LinphoneService.isReady()) // indeed, no need to crash
|
||||
ChatStorage.getInstance().close();
|
||||
|
||||
BluetoothManager.getInstance().destroy();
|
||||
try {
|
||||
mTimer.cancel();
|
||||
|
@ -943,13 +974,6 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag
|
|||
LinphoneAddress from = message.getFrom();
|
||||
|
||||
String textMessage = message.getText();
|
||||
String url = message.getExternalBodyUrl();
|
||||
if (textMessage != null && textMessage.length() > 0) {
|
||||
ChatStorage.getInstance().saveTextMessage(from.asStringUriOnly(), "", textMessage, message.getTime());
|
||||
} else if (url != null && url.length() > 0) {
|
||||
ChatStorage.getInstance().saveImageMessage(from.asStringUriOnly(), "", null, message.getExternalBodyUrl(), message.getTime());
|
||||
}
|
||||
|
||||
try {
|
||||
LinphoneContact contact = ContactsManager.getInstance().findContactFromAddress(from);
|
||||
if (!mServiceContext.getResources().getBoolean(R.bool.disable_chat_message_notification)) {
|
||||
|
|
|
@ -19,12 +19,12 @@ along with this program; if not, write to the Free Software
|
|||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.linphone.core.LinphoneAddress;
|
||||
import org.linphone.core.LinphoneAddress.TransportType;
|
||||
|
@ -32,6 +32,7 @@ import org.linphone.core.LinphoneAuthInfo;
|
|||
import org.linphone.core.LinphoneCore;
|
||||
import org.linphone.core.LinphoneCore.AdaptiveRateAlgorithm;
|
||||
import org.linphone.core.LinphoneCore.FirewallPolicy;
|
||||
import org.linphone.core.LinphoneCore.LinphoneLimeState;
|
||||
import org.linphone.core.LinphoneCore.MediaEncryption;
|
||||
import org.linphone.core.LinphoneCore.Transports;
|
||||
import org.linphone.core.LinphoneCoreException;
|
||||
|
@ -1017,7 +1018,7 @@ public class LinphonePreferences {
|
|||
lpc.edit();
|
||||
lpc.setContactUriParameters(contactInfos);
|
||||
lpc.done();
|
||||
Log.d("Push notif infos added to proxy config");
|
||||
Log.d("Push notif infos added to proxy config " + lpc.getAddress().asStringUriOnly());
|
||||
}
|
||||
lc.refreshRegisters();
|
||||
}
|
||||
|
@ -1027,7 +1028,7 @@ public class LinphonePreferences {
|
|||
lpc.edit();
|
||||
lpc.setContactUriParameters(null);
|
||||
lpc.done();
|
||||
Log.d("Push notif infos removed from proxy config");
|
||||
Log.d("Push notif infos removed from proxy config " + lpc.getAddress().asStringUriOnly());
|
||||
}
|
||||
lc.refreshRegisters();
|
||||
}
|
||||
|
@ -1287,46 +1288,6 @@ public class LinphonePreferences {
|
|||
return getConfig().getString("app", "debug_popup_magic", null);
|
||||
}
|
||||
|
||||
public Boolean audioPermAsked(){
|
||||
return getConfig().getBool("app", "audio_perm", false);
|
||||
}
|
||||
|
||||
public void neverAskAudioPerm(){
|
||||
getConfig().setBool("app", "audio_perm", true);
|
||||
}
|
||||
|
||||
public Boolean cameraPermAsked(){
|
||||
return getConfig().getBool("app", "camera_perm", false);
|
||||
}
|
||||
|
||||
public void neverAskCameraPerm(){
|
||||
getConfig().setBool("app", "camera_perm", true);
|
||||
}
|
||||
|
||||
public Boolean readContactsPermAsked(){
|
||||
return getConfig().getBool("app", "read_contacts_perm", false);
|
||||
}
|
||||
|
||||
public void neverAskReadContactsPerm(){
|
||||
getConfig().setBool("app", "read_contacts_perm", true);
|
||||
}
|
||||
|
||||
public Boolean writeContactsPermAsked(){
|
||||
return getConfig().getBool("app", "write_contacts_perm", false);
|
||||
}
|
||||
|
||||
public void neverAskWriteContactsPerm(){
|
||||
getConfig().setBool("app", "write_contacts_perm", true);
|
||||
}
|
||||
|
||||
public Boolean writeExternalStoragePermAsked(){
|
||||
return getConfig().getBool("app", "write_external_storage_perm", false);
|
||||
}
|
||||
|
||||
public void neverAskWriteExternalStoragePerm(){
|
||||
getConfig().setBool("app", "write_external_storage_perm", true);
|
||||
}
|
||||
|
||||
public String getActivityToLaunchOnIncomingReceived() {
|
||||
return getConfig().getString("app", "incoming_call_activity", "org.linphone.LinphoneActivity");
|
||||
}
|
||||
|
@ -1334,4 +1295,36 @@ public class LinphonePreferences {
|
|||
public void setActivityToLaunchOnIncomingReceived(String name) {
|
||||
getConfig().setString("app", "incoming_call_activity", name);
|
||||
}
|
||||
|
||||
public boolean getServiceNotificationVisibility() {
|
||||
return getConfig().getBool("app", "show_service_notification", true);
|
||||
}
|
||||
|
||||
public void setServiceNotificationVisibility(boolean enable) {
|
||||
getConfig().setBool("app", "show_service_notification", enable);
|
||||
}
|
||||
|
||||
public boolean isOverlayEnabled() {
|
||||
return getConfig().getBool("app", "display_overlay", false);
|
||||
}
|
||||
|
||||
public void enableOverlay(boolean enable) {
|
||||
getConfig().setBool("app", "display_overlay", enable);
|
||||
}
|
||||
|
||||
public LinphoneLimeState getLimeEncryption() {
|
||||
return getLc().getLimeEncryption();
|
||||
}
|
||||
|
||||
public void setLimeEncryption(LinphoneLimeState lime) {
|
||||
getLc().setLimeEncryption(lime);
|
||||
}
|
||||
|
||||
public boolean firstTimeAskingForPermission(String permission) {
|
||||
boolean firstTime = getConfig().getBool("app", permission, true);
|
||||
if (firstTime) {
|
||||
getConfig().setBool("app", permission, false);
|
||||
}
|
||||
return firstTime;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ import org.linphone.core.LinphoneCoreListenerBase;
|
|||
import org.linphone.core.LinphoneProxyConfig;
|
||||
import org.linphone.mediastream.Log;
|
||||
import org.linphone.mediastream.Version;
|
||||
import org.linphone.ui.LinphoneOverlay;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Activity;
|
||||
|
@ -46,7 +47,6 @@ import android.content.Context;
|
|||
import android.content.Intent;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.database.ContentObserver;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.net.Uri;
|
||||
|
@ -56,6 +56,7 @@ import android.os.IBinder;
|
|||
import android.os.SystemClock;
|
||||
import android.provider.ContactsContract;
|
||||
import android.provider.MediaStore;
|
||||
import android.view.WindowManager;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -118,6 +119,8 @@ public final class LinphoneService extends Service {
|
|||
private boolean mDisableRegistrationStatus;
|
||||
private LinphoneCoreListenerBase mListener;
|
||||
public static int notifcationsPriority = (Version.sdkAboveOrEqual(Version.API16_JELLY_BEAN_41) ? Notification.PRIORITY_MIN : 0);
|
||||
private WindowManager mWindowManager;
|
||||
private LinphoneOverlay mOverlay;
|
||||
|
||||
public int getMessageNotifCount() {
|
||||
return mMsgNotifCount;
|
||||
|
@ -126,6 +129,31 @@ public final class LinphoneService extends Service {
|
|||
public void resetMessageNotifCount() {
|
||||
mMsgNotifCount = 0;
|
||||
}
|
||||
|
||||
private boolean displayServiceNotification() {
|
||||
return LinphonePreferences.instance().getServiceNotificationVisibility();
|
||||
}
|
||||
|
||||
public void showServiceNotification() {
|
||||
startForegroundCompat(NOTIF_ID, mNotif);
|
||||
|
||||
LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
|
||||
if (lc == null) return;
|
||||
LinphoneProxyConfig lpc = lc.getDefaultProxyConfig();
|
||||
if (lpc != null) {
|
||||
if (lpc.isRegistered()) {
|
||||
sendNotification(IC_LEVEL_ORANGE, R.string.notification_registered);
|
||||
} else {
|
||||
sendNotification(IC_LEVEL_ORANGE, R.string.notification_register_failure);
|
||||
}
|
||||
} else {
|
||||
sendNotification(IC_LEVEL_ORANGE, R.string.notification_started);
|
||||
}
|
||||
}
|
||||
|
||||
public void hideServiceNotification() {
|
||||
stopForegroundCompat(NOTIF_ID);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
|
@ -182,6 +210,10 @@ public final class LinphoneService extends Service {
|
|||
if (state == LinphoneCall.State.IncomingReceived) {
|
||||
onIncomingReceived();
|
||||
}
|
||||
|
||||
if (state == State.CallEnd || state == State.CallReleased || state == State.Error) {
|
||||
destroyOverlay();
|
||||
}
|
||||
|
||||
if (state == State.StreamsRunning) {
|
||||
// Workaround bug current call seems to be updated after state changed to streams running
|
||||
|
@ -195,7 +227,7 @@ public final class LinphoneService extends Service {
|
|||
|
||||
@Override
|
||||
public void globalState(LinphoneCore lc,LinphoneCore.GlobalState state, String message) {
|
||||
if (state == GlobalState.GlobalOn) {
|
||||
if (state == GlobalState.GlobalOn && displayServiceNotification()) {
|
||||
sendNotification(IC_LEVEL_ORANGE, R.string.notification_started);
|
||||
}
|
||||
}
|
||||
|
@ -207,15 +239,15 @@ public final class LinphoneService extends Service {
|
|||
// return;
|
||||
// }
|
||||
if (!mDisableRegistrationStatus) {
|
||||
if (state == RegistrationState.RegistrationOk && LinphoneManager.getLc().getDefaultProxyConfig() != null && LinphoneManager.getLc().getDefaultProxyConfig().isRegistered()) {
|
||||
if (displayServiceNotification() && state == RegistrationState.RegistrationOk && LinphoneManager.getLc().getDefaultProxyConfig() != null && LinphoneManager.getLc().getDefaultProxyConfig().isRegistered()) {
|
||||
sendNotification(IC_LEVEL_ORANGE, R.string.notification_registered);
|
||||
}
|
||||
|
||||
if ((state == RegistrationState.RegistrationFailed || state == RegistrationState.RegistrationCleared) && (LinphoneManager.getLc().getDefaultProxyConfig() == null || !LinphoneManager.getLc().getDefaultProxyConfig().isRegistered())) {
|
||||
if (displayServiceNotification() && (state == RegistrationState.RegistrationFailed || state == RegistrationState.RegistrationCleared) && (LinphoneManager.getLc().getDefaultProxyConfig() == null || !LinphoneManager.getLc().getDefaultProxyConfig().isRegistered())) {
|
||||
sendNotification(IC_LEVEL_ORANGE, R.string.notification_register_failure);
|
||||
}
|
||||
|
||||
if (state == RegistrationState.RegistrationNone) {
|
||||
if (displayServiceNotification() && state == RegistrationState.RegistrationNone) {
|
||||
sendNotification(IC_LEVEL_ORANGE, R.string.notification_started);
|
||||
}
|
||||
}
|
||||
|
@ -241,7 +273,9 @@ public final class LinphoneService extends Service {
|
|||
|
||||
getContentResolver().registerContentObserver(ContactsContract.Contacts.CONTENT_URI, true, ContactsManager.getInstance());
|
||||
|
||||
startForegroundCompat(NOTIF_ID, mNotif);
|
||||
if (displayServiceNotification()) {
|
||||
startForegroundCompat(NOTIF_ID, mNotif);
|
||||
}
|
||||
|
||||
if (!mTestDelayElapsed) {
|
||||
// Only used when testing. Simulates a 5 seconds delay for launching service
|
||||
|
@ -259,8 +293,30 @@ public final class LinphoneService extends Service {
|
|||
, SystemClock.elapsedRealtime()+600000
|
||||
, 600000
|
||||
, mkeepAlivePendingIntent);
|
||||
}
|
||||
|
||||
mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
|
||||
}
|
||||
|
||||
public void createOverlay() {
|
||||
if (mOverlay != null) destroyOverlay();
|
||||
|
||||
LinphoneCall call = LinphoneManager.getLc().getCurrentCall();
|
||||
if (call == null || !call.getCurrentParamsCopy().getVideoEnabled()) return;
|
||||
|
||||
mOverlay = new LinphoneOverlay(this);
|
||||
WindowManager.LayoutParams params = mOverlay.getWindowManagerLayoutParams();
|
||||
params.x = 0;
|
||||
params.y = 0;
|
||||
mWindowManager.addView(mOverlay, params);
|
||||
}
|
||||
|
||||
public void destroyOverlay() {
|
||||
if (mOverlay != null) {
|
||||
mWindowManager.removeViewImmediate(mOverlay);
|
||||
mOverlay.destroy();
|
||||
}
|
||||
mOverlay = null;
|
||||
}
|
||||
|
||||
private enum IncallIconState {INCALL, PAUSE, VIDEO, IDLE}
|
||||
private IncallIconState mCurrentIncallIconState = IncallIconState.IDLE;
|
||||
|
@ -505,7 +561,7 @@ public final class LinphoneService extends Service {
|
|||
mDisableRegistrationStatus = true;
|
||||
}
|
||||
|
||||
public synchronized void sendNotification(int level, int textId) {
|
||||
private synchronized void sendNotification(int level, int textId) {
|
||||
String text = getString(textId);
|
||||
if (text.contains("%s") && LinphoneManager.getLc() != null) {
|
||||
// Test for null lc is to avoid a NPE when Android mess up badly with the String resources.
|
||||
|
@ -559,6 +615,7 @@ public final class LinphoneService extends Service {
|
|||
|
||||
@Override
|
||||
public synchronized void onDestroy() {
|
||||
destroyOverlay();
|
||||
LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
|
||||
if (lc != null) {
|
||||
lc.removeListener(mListener);
|
||||
|
@ -593,10 +650,10 @@ public final class LinphoneService extends Service {
|
|||
Intent notifIntent = new Intent(this, incomingReceivedActivity);
|
||||
mNotifContentIntent = PendingIntent.getActivity(this, 0, notifIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
|
||||
if (mNotif != null) {
|
||||
/*if (mNotif != null) {
|
||||
mNotif.contentIntent = mNotifContentIntent;
|
||||
}
|
||||
notifyWrapper(NOTIF_ID, mNotif);
|
||||
notifyWrapper(NOTIF_ID, mNotif);*/
|
||||
}
|
||||
|
||||
protected void onIncomingReceived() {
|
||||
|
|
|
@ -455,5 +455,14 @@ public final class LinphoneUtils {
|
|||
Log.e(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static String getExtensionFromFileName(String fileName) {
|
||||
String extension = null;
|
||||
int i = fileName.lastIndexOf('.');
|
||||
if (i > 0) {
|
||||
extension = fileName.substring(i+1);
|
||||
}
|
||||
return extension;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,8 +18,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
*/
|
||||
package org.linphone;
|
||||
|
||||
import org.linphone.mediastream.Log;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
@ -32,26 +30,18 @@ import android.telephony.TelephonyManager;
|
|||
*
|
||||
*/
|
||||
public class PhoneStateChangedReceiver extends BroadcastReceiver {
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
|
||||
|
||||
final String extraState = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
|
||||
|
||||
if (TelephonyManager.EXTRA_STATE_RINGING.equals(extraState) || TelephonyManager.EXTRA_STATE_OFFHOOK.equals(extraState)) {
|
||||
LinphoneManager.setGsmIdle(false);
|
||||
if (!LinphoneManager.isInstanciated()) {
|
||||
Log.i("GSM call state changed but manager not instantiated");
|
||||
return;
|
||||
}
|
||||
LinphoneManager.getLc().pauseAllCalls();
|
||||
} else if (TelephonyManager.EXTRA_STATE_IDLE.equals(extraState)) {
|
||||
LinphoneManager.setGsmIdle(true);
|
||||
}
|
||||
|
||||
|
||||
// do nothing
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,12 +19,14 @@ along with this program; if not, write to the Free Software
|
|||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.linphone.core.LinphoneAddress;
|
||||
import org.linphone.core.LinphoneCore;
|
||||
import org.linphone.core.LinphoneCore.EcCalibratorStatus;
|
||||
import org.linphone.core.LinphoneCore.LinphoneLimeState;
|
||||
import org.linphone.core.LinphoneCore.MediaEncryption;
|
||||
import org.linphone.core.LinphoneCoreException;
|
||||
import org.linphone.core.LinphoneCoreListenerBase;
|
||||
|
@ -37,10 +39,10 @@ import org.linphone.tools.OpenH264DownloadHelper;
|
|||
import org.linphone.purchase.InAppPurchaseActivity;
|
||||
import org.linphone.ui.LedPreference;
|
||||
import org.linphone.ui.PreferencesListFragment;
|
||||
import android.content.Intent;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.preference.CheckBoxPreference;
|
||||
|
@ -56,21 +58,19 @@ import android.preference.PreferenceScreen;
|
|||
* @author Sylvain Berfini
|
||||
*/
|
||||
public class SettingsFragment extends PreferencesListFragment {
|
||||
private static final int WIZARD_INTENT = 1;
|
||||
private static final int STORE_INTENT = 2;
|
||||
private LinphonePreferences mPrefs;
|
||||
private Handler mHandler = new Handler();
|
||||
private LinphoneCoreListenerBase mListener;
|
||||
|
||||
public SettingsFragment() {
|
||||
super(R.xml.preferences);
|
||||
mPrefs = LinphonePreferences.instance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle bundle) {
|
||||
super.onCreate(bundle);
|
||||
|
||||
mPrefs = LinphonePreferences.instance();
|
||||
removePreviousPreferencesFile(); // Required when updating the preferences order
|
||||
addPreferencesFromResource(R.xml.preferences);
|
||||
|
||||
// Init the settings page interface
|
||||
initSettings();
|
||||
setListeners();
|
||||
|
@ -100,6 +100,11 @@ public class SettingsFragment extends PreferencesListFragment {
|
|||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void removePreviousPreferencesFile() {
|
||||
File dir = new File(LinphoneActivity.instance().getFilesDir().getAbsolutePath() + "shared_prefs");
|
||||
dir.delete();
|
||||
}
|
||||
|
||||
// Inits the values or the listener on some settings
|
||||
private void initSettings() {
|
||||
|
@ -107,6 +112,7 @@ public class SettingsFragment extends PreferencesListFragment {
|
|||
initAudioSettings();
|
||||
initVideoSettings();
|
||||
initCallSettings();
|
||||
initChatSettings();
|
||||
initNetworkSettings();
|
||||
initAdvancedSettings();
|
||||
|
||||
|
@ -134,6 +140,7 @@ public class SettingsFragment extends PreferencesListFragment {
|
|||
setAudioPreferencesListener();
|
||||
setVideoPreferencesListener();
|
||||
setCallPreferencesListener();
|
||||
setChatPreferencesListener();
|
||||
setNetworkPreferencesListener();
|
||||
setAdvancedPreferencesListener();
|
||||
}
|
||||
|
@ -436,6 +443,30 @@ public class SettingsFragment extends PreferencesListFragment {
|
|||
pref.setSummary(value);
|
||||
pref.setValue(value);
|
||||
}
|
||||
|
||||
private void initLimeEncryptionPreference(ListPreference pref) {
|
||||
List<CharSequence> entries = new ArrayList<CharSequence>();
|
||||
List<CharSequence> values = new ArrayList<CharSequence>();
|
||||
entries.add(getString(R.string.lime_encryption_entry_disabled));
|
||||
values.add(LinphoneLimeState.Disabled.toString());
|
||||
|
||||
LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
|
||||
if (lc == null || !lc.isLimeEncryptionAvailable()) {
|
||||
setListPreferenceValues(pref, entries, values);
|
||||
pref.setEnabled(false);
|
||||
return;
|
||||
}
|
||||
|
||||
entries.add(getString(R.string.lime_encryption_entry_mandatory));
|
||||
values.add(LinphoneLimeState.Mandatory.toString());
|
||||
entries.add(getString(R.string.lime_encryption_entry_preferred));
|
||||
values.add(LinphoneLimeState.Preferred.toString());
|
||||
setListPreferenceValues(pref, entries, values);
|
||||
|
||||
LinphoneLimeState lime = mPrefs.getLimeEncryption();
|
||||
pref.setSummary(lime.toString());
|
||||
pref.setValue(lime.toString());
|
||||
}
|
||||
|
||||
private static void setListPreferenceValues(ListPreference pref, List<CharSequence> entries, List<CharSequence> values) {
|
||||
CharSequence[] contents = new CharSequence[entries.size()];
|
||||
|
@ -639,6 +670,7 @@ public class SettingsFragment extends PreferencesListFragment {
|
|||
((CheckBoxPreference) findPreference(getString(R.string.pref_video_use_front_camera_key))).setChecked(mPrefs.useFrontCam());
|
||||
((CheckBoxPreference) findPreference(getString(R.string.pref_video_initiate_call_with_video_key))).setChecked(mPrefs.shouldInitiateVideoCall());
|
||||
((CheckBoxPreference) findPreference(getString(R.string.pref_video_automatically_accept_video_key))).setChecked(mPrefs.shouldAutomaticallyAcceptVideoRequests());
|
||||
((CheckBoxPreference) findPreference(getString(R.string.pref_overlay_key))).setChecked(mPrefs.isOverlayEnabled());
|
||||
}
|
||||
|
||||
private void updateVideoPreferencesAccordingToPreset() {
|
||||
|
@ -732,6 +764,21 @@ public class SettingsFragment extends PreferencesListFragment {
|
|||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
findPreference(getString(R.string.pref_overlay_key)).setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
boolean enable = (Boolean) newValue;
|
||||
if (enable) {
|
||||
if (LinphoneActivity.instance().checkAndRequestOverlayPermission()) {
|
||||
mPrefs.enableOverlay(true);
|
||||
}
|
||||
} else {
|
||||
mPrefs.enableOverlay(false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void initCallSettings() {
|
||||
|
@ -788,6 +835,47 @@ public class SettingsFragment extends PreferencesListFragment {
|
|||
});
|
||||
}
|
||||
|
||||
private void initChatSettings() {
|
||||
setPreferenceDefaultValueAndSummary(R.string.pref_image_sharing_server_key, mPrefs.getSharingPictureServerUrl());
|
||||
initLimeEncryptionPreference((ListPreference) findPreference(getString(R.string.pref_use_lime_encryption_key)));
|
||||
}
|
||||
|
||||
private void setChatPreferencesListener() {
|
||||
findPreference(getString(R.string.pref_image_sharing_server_key)).setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
String value = (String) newValue;
|
||||
mPrefs.setSharingPictureServerUrl(value);
|
||||
preference.setSummary(value);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
findPreference(getString(R.string.pref_use_lime_encryption_key)).setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
String value = newValue.toString();
|
||||
LinphoneLimeState lime = LinphoneLimeState.Disabled;
|
||||
if (value.equals(LinphoneLimeState.Mandatory.toString()))
|
||||
lime = LinphoneLimeState.Mandatory;
|
||||
else if (value.equals(LinphoneLimeState.Preferred.toString()))
|
||||
lime = LinphoneLimeState.Preferred;
|
||||
mPrefs.setLimeEncryption(lime);
|
||||
|
||||
lime = mPrefs.getLimeEncryption();
|
||||
if (lime == LinphoneLimeState.Disabled) {
|
||||
preference.setSummary(getString(R.string.lime_encryption_entry_disabled));
|
||||
} else if (lime == LinphoneLimeState.Mandatory) {
|
||||
preference.setSummary(getString(R.string.lime_encryption_entry_mandatory));
|
||||
} else if (lime == LinphoneLimeState.Preferred) {
|
||||
preference.setSummary(getString(R.string.lime_encryption_entry_preferred));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void initNetworkSettings() {
|
||||
initMediaEncryptionPreference((ListPreference) findPreference(getString(R.string.pref_media_encryption_key)));
|
||||
|
||||
|
@ -929,8 +1017,8 @@ public class SettingsFragment extends PreferencesListFragment {
|
|||
((CheckBoxPreference)findPreference(getString(R.string.pref_debug_key))).setChecked(mPrefs.isDebugEnabled());
|
||||
((CheckBoxPreference)findPreference(getString(R.string.pref_background_mode_key))).setChecked(mPrefs.isBackgroundModeEnabled());
|
||||
((CheckBoxPreference)findPreference(getString(R.string.pref_animation_enable_key))).setChecked(mPrefs.areAnimationsEnabled());
|
||||
((CheckBoxPreference)findPreference(getString(R.string.pref_service_notification_key))).setChecked(mPrefs.getServiceNotificationVisibility());
|
||||
((CheckBoxPreference)findPreference(getString(R.string.pref_autostart_key))).setChecked(mPrefs.isAutoStartEnabled());
|
||||
setPreferenceDefaultValueAndSummary(R.string.pref_image_sharing_server_key, mPrefs.getSharingPictureServerUrl());
|
||||
setPreferenceDefaultValueAndSummary(R.string.pref_remote_provisioning_key, mPrefs.getRemoteProvisioningUrl());
|
||||
setPreferenceDefaultValueAndSummary(R.string.pref_display_name_key, mPrefs.getDefaultDisplayName());
|
||||
setPreferenceDefaultValueAndSummary(R.string.pref_user_name_key, mPrefs.getDefaultUsername());
|
||||
|
@ -964,6 +1052,20 @@ public class SettingsFragment extends PreferencesListFragment {
|
|||
}
|
||||
});
|
||||
|
||||
findPreference(getString(R.string.pref_service_notification_key)).setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
boolean value = (Boolean) newValue;
|
||||
mPrefs.setServiceNotificationVisibility(value);
|
||||
if (value) {
|
||||
LinphoneService.instance().showServiceNotification();
|
||||
} else {
|
||||
LinphoneService.instance().hideServiceNotification();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
findPreference(getString(R.string.pref_autostart_key)).setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
|
@ -973,16 +1075,6 @@ public class SettingsFragment extends PreferencesListFragment {
|
|||
}
|
||||
});
|
||||
|
||||
findPreference(getString(R.string.pref_image_sharing_server_key)).setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
String value = (String) newValue;
|
||||
mPrefs.setSharingPictureServerUrl(value);
|
||||
preference.setSummary(value);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
findPreference(getString(R.string.pref_remote_provisioning_key)).setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
|
|
|
@ -44,6 +44,7 @@ import android.app.FragmentTransaction;
|
|||
import android.app.ProgressDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
|
@ -200,7 +201,8 @@ private static AssistantActivity instance;
|
|||
if (getResources().getBoolean(R.bool.setup_cancel_move_to_back)) {
|
||||
moveTaskToBack(true);
|
||||
} else {
|
||||
setResult(Activity.RESULT_CANCELED);
|
||||
LinphonePreferences.instance().firstLaunchSuccessful();
|
||||
startActivity(new Intent().setClass(this, LinphoneActivity.class));
|
||||
finish();
|
||||
}
|
||||
} else if (id == R.id.back) {
|
||||
|
@ -216,7 +218,8 @@ private static AssistantActivity instance;
|
|||
if (getResources().getBoolean(R.bool.setup_cancel_move_to_back)) {
|
||||
moveTaskToBack(true);
|
||||
} else {
|
||||
setResult(Activity.RESULT_CANCELED);
|
||||
LinphonePreferences.instance().firstLaunchSuccessful();
|
||||
startActivity(new Intent().setClass(this, LinphoneActivity.class));
|
||||
finish();
|
||||
}
|
||||
} else if (currentFragment == AssistantFragmentsEnum.LOGIN
|
||||
|
@ -241,8 +244,12 @@ private static AssistantActivity instance;
|
|||
}
|
||||
|
||||
public void checkAndRequestAudioPermission() {
|
||||
if (getPackageManager().checkPermission(Manifest.permission.RECORD_AUDIO, getPackageName()) != PackageManager.PERMISSION_GRANTED) {
|
||||
if (!ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.RECORD_AUDIO)) {
|
||||
int recordAudio = getPackageManager().checkPermission(Manifest.permission.RECORD_AUDIO, getPackageName());
|
||||
Log.i("[Permission] Record audio permission is " + (recordAudio == PackageManager.PERMISSION_GRANTED ? "granted" : "denied"));
|
||||
|
||||
if (recordAudio != PackageManager.PERMISSION_GRANTED) {
|
||||
if (LinphonePreferences.instance().firstTimeAskingForPermission(Manifest.permission.RECORD_AUDIO) || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.RECORD_AUDIO)) {
|
||||
Log.i("[Permission] Asking for record audio");
|
||||
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO}, PERMISSIONS_REQUEST_RECORD_AUDIO);
|
||||
}
|
||||
}
|
||||
|
@ -250,8 +257,12 @@ private static AssistantActivity instance;
|
|||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
|
||||
for (int i = 0; i < permissions.length; i++) {
|
||||
Log.i("[Permission] " + permissions[i] + " is " + (grantResults[i] == PackageManager.PERMISSION_GRANTED ? "granted" : "denied"));
|
||||
}
|
||||
|
||||
if (requestCode == PERMISSIONS_REQUEST_RECORD_AUDIO) {
|
||||
if (getPackageManager().checkPermission(Manifest.permission.RECORD_AUDIO, getPackageName()) == PackageManager.PERMISSION_GRANTED) {
|
||||
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
launchEchoCancellerCalibration(true);
|
||||
} else {
|
||||
isEchoCalibrationFinished();
|
||||
|
@ -541,10 +552,7 @@ private static AssistantActivity instance;
|
|||
|
||||
public void success() {
|
||||
mPrefs.firstLaunchSuccessful();
|
||||
if(LinphoneActivity.instance() != null) {
|
||||
LinphoneActivity.instance().isNewProxyConfig();
|
||||
setResult(Activity.RESULT_OK);
|
||||
}
|
||||
startActivity(new Intent().setClass(this, LinphoneActivity.class).putExtra("isNewProxyConfig", true));
|
||||
finish();
|
||||
}
|
||||
|
||||
|
|
|
@ -69,6 +69,7 @@ public class ApiElevenPlus {
|
|||
| Notification.DEFAULT_SOUND
|
||||
| Notification.DEFAULT_VIBRATE)
|
||||
.setWhen(System.currentTimeMillis())
|
||||
.setNumber(msgCount)
|
||||
.setLargeIcon(contactIcon).getNotification();
|
||||
|
||||
return notif;
|
||||
|
|
|
@ -3,12 +3,9 @@ package org.linphone.compatibility;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.linphone.Contact;
|
||||
import org.linphone.LinphoneContact;
|
||||
import org.linphone.LinphoneUtils;
|
||||
import org.linphone.R;
|
||||
import org.linphone.core.LinphoneAddress;
|
||||
import org.linphone.mediastream.Log;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.ContentProviderOperation;
|
||||
|
@ -195,89 +192,4 @@ public class ApiNinePlus {
|
|||
cursor.close();
|
||||
return null;
|
||||
}
|
||||
|
||||
//Linphone Contacts Tag
|
||||
public static void addLinphoneContactTag(Context context, ArrayList<ContentProviderOperation> ops, String newAddress, String rawContactId){
|
||||
if(rawContactId != null) {
|
||||
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
|
||||
.withValue(ContactsContract.Data.RAW_CONTACT_ID, rawContactId)
|
||||
.withValue(ContactsContract.Data.MIMETYPE, context.getString(R.string.sync_mimetype))
|
||||
.withValue(ContactsContract.Data.DATA1, newAddress)
|
||||
.withValue(ContactsContract.Data.DATA2, context.getString(R.string.app_name))
|
||||
.withValue(ContactsContract.Data.DATA3, newAddress)
|
||||
.build()
|
||||
);
|
||||
}
|
||||
}
|
||||
public static void updateLinphoneContactTag(Context context, ArrayList<ContentProviderOperation> ops, String newAddress, String oldAddress, String rawContactId){
|
||||
if(rawContactId != null) {
|
||||
ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
|
||||
.withSelection(ContactsContract.Data.RAW_CONTACT_ID + "=? AND " + ContactsContract.Data.DATA1 + "=? ", new String[]{rawContactId, oldAddress})
|
||||
.withValue(ContactsContract.Data.DATA1, newAddress)
|
||||
.withValue(ContactsContract.Data.DATA2, context.getString(R.string.app_name))
|
||||
.withValue(ContactsContract.Data.DATA3, newAddress)
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
||||
public static void deleteLinphoneContactTag(ArrayList<ContentProviderOperation> ops , String oldAddress, String rawContactId){
|
||||
if(rawContactId != null) {
|
||||
String select = ContactsContract.Data.RAW_CONTACT_ID + "=? AND "
|
||||
+ ContactsContract.Data.DATA1 + "= ?";
|
||||
String[] args = new String[]{rawContactId, oldAddress};
|
||||
|
||||
ops.add(ContentProviderOperation.newDelete(ContactsContract.Data.CONTENT_URI)
|
||||
.withSelection(select, args)
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
||||
public static void createLinphoneContactTag(Context context, ContentResolver contentResolver, Contact contact, String rawContactId){
|
||||
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
|
||||
|
||||
if (contact != null) {
|
||||
ops.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
|
||||
.withValue(ContactsContract.RawContacts.AGGREGATION_MODE, ContactsContract.RawContacts.AGGREGATION_MODE_DEFAULT)
|
||||
.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, context.getString(R.string.sync_account_type))
|
||||
.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, context.getString(R.string.sync_account_name))
|
||||
.build()
|
||||
);
|
||||
|
||||
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
|
||||
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
|
||||
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
|
||||
.withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, contact.getName())
|
||||
.build()
|
||||
);
|
||||
|
||||
List<String> numbersOrAddresses = contact.getNumbersOrAddresses();
|
||||
for (String numberOrAddress : numbersOrAddresses) {
|
||||
if (LinphoneUtils.isSipAddress(numberOrAddress)) {
|
||||
if (numberOrAddress.startsWith("sip:")){
|
||||
numberOrAddress = numberOrAddress.substring(4);
|
||||
}
|
||||
|
||||
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
|
||||
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
|
||||
.withValue(ContactsContract.Data.MIMETYPE, context.getString(R.string.sync_mimetype))
|
||||
.withValue(ContactsContract.Data.DATA1, numberOrAddress)
|
||||
.withValue(ContactsContract.Data.DATA2, context.getString(R.string.app_name))
|
||||
.withValue(ContactsContract.Data.DATA3, numberOrAddress)
|
||||
.build()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ops.add(ContentProviderOperation.newUpdate(ContactsContract.AggregationExceptions.CONTENT_URI)
|
||||
.withValue(ContactsContract.AggregationExceptions.TYPE, ContactsContract.AggregationExceptions.TYPE_KEEP_TOGETHER)
|
||||
.withValue(ContactsContract.AggregationExceptions.RAW_CONTACT_ID1, rawContactId)
|
||||
.withValueBackReference(ContactsContract.AggregationExceptions.RAW_CONTACT_ID2, 0).build());
|
||||
|
||||
try {
|
||||
contentResolver.applyBatch(ContactsContract.AUTHORITY, ops);
|
||||
} catch (Exception e) {
|
||||
Log.e(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,6 +56,7 @@ public class ApiSixteenPlus {
|
|||
| Notification.DEFAULT_VIBRATE)
|
||||
.setWhen(System.currentTimeMillis())
|
||||
.setLargeIcon(contactIcon)
|
||||
.setNumber(msgCount)
|
||||
.build();
|
||||
|
||||
return notif;
|
||||
|
|
|
@ -54,6 +54,7 @@ public class ApiTwentyOnePlus {
|
|||
.setCategory(Notification.CATEGORY_MESSAGE)
|
||||
.setVisibility(Notification.VISIBILITY_PRIVATE)
|
||||
.setPriority(Notification.PRIORITY_HIGH)
|
||||
.setNumber(msgCount)
|
||||
.build();
|
||||
|
||||
return notif;
|
||||
|
|
|
@ -21,7 +21,6 @@ import java.io.InputStream;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.linphone.Contact;
|
||||
import org.linphone.LinphoneContact;
|
||||
import org.linphone.core.LinphoneAddress;
|
||||
import org.linphone.mediastream.Version;
|
||||
|
@ -38,6 +37,7 @@ import android.graphics.Bitmap;
|
|||
import android.media.AudioManager;
|
||||
import android.net.Uri;
|
||||
import android.preference.Preference;
|
||||
import android.provider.Settings;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
|
||||
/**
|
||||
|
@ -300,32 +300,6 @@ public class Compatibility {
|
|||
ApiFivePlus.deleteSipAddressFromContact(ops, oldSipAddress, contactID);
|
||||
}
|
||||
|
||||
//Linphone Contacts Tag
|
||||
public static void addLinphoneContactTag(Context context, ArrayList<ContentProviderOperation> ops, String newSipAddress, String rawContactId) {
|
||||
if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) {
|
||||
ApiNinePlus.addLinphoneContactTag(context, ops, newSipAddress, rawContactId);
|
||||
}
|
||||
}
|
||||
|
||||
public static void updateLinphoneContactTag(Context context, ArrayList<ContentProviderOperation> ops, String newSipAddress, String oldSipAddress, String rawContactId) {
|
||||
if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) {
|
||||
ApiNinePlus.updateLinphoneContactTag(context, ops, newSipAddress, oldSipAddress, rawContactId);
|
||||
}
|
||||
}
|
||||
|
||||
public static void deleteLinphoneContactTag(ArrayList<ContentProviderOperation> ops, String oldSipAddress, String rawContactId) {
|
||||
if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) {
|
||||
ApiNinePlus.deleteLinphoneContactTag(ops, oldSipAddress, rawContactId);
|
||||
}
|
||||
}
|
||||
|
||||
public static void createLinphoneContactTag(Context context, ContentResolver contentResolver, Contact contact, String rawContactId) {
|
||||
if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) {
|
||||
ApiNinePlus.createLinphoneContactTag(context, contentResolver, contact, rawContactId);
|
||||
}
|
||||
}
|
||||
//End of Linphone Contact Tag
|
||||
|
||||
public static void removeGlobalLayoutListener(ViewTreeObserver viewTreeObserver, OnGlobalLayoutListener keyboardListener) {
|
||||
if (Version.sdkAboveOrEqual(Version.API16_JELLY_BEAN_41)) {
|
||||
ApiSixteenPlus.removeGlobalLayoutListener(viewTreeObserver, keyboardListener);
|
||||
|
@ -363,4 +337,11 @@ public class Compatibility {
|
|||
return ApiEightPlus.getAudioManagerEventForBluetoothConnectionStateChangedEvent();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean canDrawOverlays(Context context) {
|
||||
if (Version.sdkAboveOrEqual(Version.API23_MARSHMALLOW_60)) {
|
||||
return Settings.canDrawOverlays(context);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ import org.linphone.LinphonePreferences;
|
|||
import org.linphone.LinphoneService;
|
||||
import org.linphone.R;
|
||||
import org.linphone.UIThreadDispatcher;
|
||||
import org.linphone.core.LinphoneCoreFactory;
|
||||
import org.linphone.mediastream.Log;
|
||||
|
||||
import android.content.Context;
|
||||
|
@ -44,12 +45,19 @@ public class GCMService extends GCMBaseIntentService {
|
|||
|
||||
@Override
|
||||
protected void onError(Context context, String errorId) {
|
||||
boolean isDebugEnabled = LinphonePreferences.instance().isDebugEnabled();
|
||||
LinphoneCoreFactory.instance().enableLogCollection(isDebugEnabled);
|
||||
LinphoneCoreFactory.instance().setDebugMode(isDebugEnabled, context.getString(R.string.app_name));
|
||||
Log.e("Error while registering push notification : " + errorId);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMessage(Context context, Intent intent) {
|
||||
boolean isDebugEnabled = LinphonePreferences.instance().isDebugEnabled();
|
||||
LinphoneCoreFactory.instance().enableLogCollection(isDebugEnabled);
|
||||
LinphoneCoreFactory.instance().setDebugMode(isDebugEnabled, context.getString(R.string.app_name));
|
||||
Log.d("Push notification received");
|
||||
|
||||
if (!LinphoneService.isReady()) {
|
||||
startService(new Intent(ACTION_MAIN).setClass(this, LinphoneService.class));
|
||||
} else if (LinphoneManager.isInstanciated() && LinphoneManager.getLc().getCallsNb() == 0) {
|
||||
|
@ -68,13 +76,21 @@ public class GCMService extends GCMBaseIntentService {
|
|||
|
||||
@Override
|
||||
protected void onRegistered(Context context, String regId) {
|
||||
boolean isDebugEnabled = LinphonePreferences.instance().isDebugEnabled();
|
||||
LinphoneCoreFactory.instance().enableLogCollection(isDebugEnabled);
|
||||
LinphoneCoreFactory.instance().setDebugMode(isDebugEnabled, context.getString(R.string.app_name));
|
||||
Log.d("Registered push notification : " + regId);
|
||||
|
||||
LinphonePreferences.instance().setPushNotificationRegistrationID(regId);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onUnregistered(Context context, String regId) {
|
||||
boolean isDebugEnabled = LinphonePreferences.instance().isDebugEnabled();
|
||||
LinphoneCoreFactory.instance().enableLogCollection(isDebugEnabled);
|
||||
LinphoneCoreFactory.instance().setDebugMode(isDebugEnabled, context.getString(R.string.app_name));
|
||||
Log.w("Unregistered push notification : " + regId);
|
||||
|
||||
LinphonePreferences.instance().setPushNotificationRegistrationID(null);
|
||||
}
|
||||
|
||||
|
|
|
@ -173,7 +173,8 @@ public class BubbleChat implements LinphoneChatMessage.LinphoneChatMessageListen
|
|||
public void onClick(View v) {
|
||||
if (mContext.getPackageManager().checkPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE, mContext.getPackageName()) == PackageManager.PERMISSION_GRANTED) {
|
||||
v.setEnabled(false);
|
||||
String filename = context.getString(R.string.temp_photo_name_with_date).replace("%s", String.valueOf(System.currentTimeMillis()));
|
||||
String extension = nativeMessage.getFileTransferInformation().getSubtype();
|
||||
String filename = context.getString(R.string.temp_photo_name_with_date).replace("%s", String.valueOf(System.currentTimeMillis())) + "." + extension;
|
||||
File file = new File(Environment.getExternalStorageDirectory(), filename);
|
||||
nativeMessage.setAppData(filename);
|
||||
LinphoneManager.getInstance().addDownloadMessagePending(nativeMessage);
|
||||
|
|
119
src/org/linphone/ui/LinphoneOverlay.java
Normal file
119
src/org/linphone/ui/LinphoneOverlay.java
Normal file
|
@ -0,0 +1,119 @@
|
|||
package org.linphone.ui;
|
||||
|
||||
import org.linphone.LinphoneActivity;
|
||||
import org.linphone.LinphoneManager;
|
||||
import org.linphone.LinphoneService;
|
||||
import org.linphone.core.LinphoneCall;
|
||||
import org.linphone.core.LinphoneCallParams;
|
||||
import org.linphone.mediastream.video.AndroidVideoWindowImpl;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.Gravity;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.SurfaceView;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
|
||||
public class LinphoneOverlay extends org.linphone.mediastream.video.display.GL2JNIView {
|
||||
private WindowManager wm;
|
||||
private WindowManager.LayoutParams params;
|
||||
private DisplayMetrics metrics;
|
||||
private float x;
|
||||
private float y;
|
||||
private float touchX;
|
||||
private float touchY;
|
||||
private AndroidVideoWindowImpl androidVideoWindowImpl;
|
||||
|
||||
public LinphoneOverlay(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs);
|
||||
wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
|
||||
params = new WindowManager.LayoutParams(
|
||||
WindowManager.LayoutParams.WRAP_CONTENT,
|
||||
WindowManager.LayoutParams.WRAP_CONTENT,
|
||||
WindowManager.LayoutParams.TYPE_PHONE,
|
||||
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
|
||||
PixelFormat.TRANSLUCENT);
|
||||
params.gravity = Gravity.TOP | Gravity.LEFT;
|
||||
metrics = new DisplayMetrics();
|
||||
wm.getDefaultDisplay().getMetrics(metrics);
|
||||
|
||||
androidVideoWindowImpl = new AndroidVideoWindowImpl(this, null, new AndroidVideoWindowImpl.VideoWindowListener() {
|
||||
public void onVideoRenderingSurfaceReady(AndroidVideoWindowImpl vw, SurfaceView surface) {
|
||||
LinphoneManager.getLc().setVideoWindow(vw);
|
||||
}
|
||||
|
||||
public void onVideoRenderingSurfaceDestroyed(AndroidVideoWindowImpl vw) {
|
||||
|
||||
}
|
||||
|
||||
public void onVideoPreviewSurfaceReady(AndroidVideoWindowImpl vw, SurfaceView surface) {
|
||||
}
|
||||
|
||||
public void onVideoPreviewSurfaceDestroyed(AndroidVideoWindowImpl vw) {
|
||||
}
|
||||
});
|
||||
|
||||
LinphoneCall call = LinphoneManager.getLc().getCurrentCall();
|
||||
LinphoneCallParams callParams = call.getCurrentParamsCopy();
|
||||
params.width = callParams.getReceivedVideoSize().width;
|
||||
params.height = callParams.getReceivedVideoSize().height;
|
||||
LinphoneManager.getLc().setVideoWindow(androidVideoWindowImpl);
|
||||
|
||||
setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Context context = LinphoneService.instance();
|
||||
Intent intent = new Intent(context, LinphoneActivity.class).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
context.startActivity(intent);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public LinphoneOverlay(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public LinphoneOverlay(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
androidVideoWindowImpl.release();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
x = event.getRawX();
|
||||
y = event.getRawY();
|
||||
switch (event.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
touchX = event.getX();
|
||||
touchY = event.getY();
|
||||
break;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
updateViewPostion();
|
||||
break;
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
case MotionEvent.ACTION_UP:
|
||||
touchX = touchY = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return super.onTouchEvent(event);
|
||||
}
|
||||
|
||||
private void updateViewPostion() {
|
||||
params.x = Math.min(Math.max(0, (int) (x - touchX)), metrics.widthPixels - getMeasuredWidth());
|
||||
params.y = Math.min(Math.max(0, (int) (y - touchY)), metrics.heightPixels - getMeasuredHeight());
|
||||
wm.updateViewLayout(this, params);
|
||||
}
|
||||
|
||||
public WindowManager.LayoutParams getWindowManagerLayoutParams() {
|
||||
return params;
|
||||
}
|
||||
}
|
|
@ -2,7 +2,6 @@ package org.linphone.test;
|
|||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.linphone.ChatStorage;
|
||||
import org.linphone.LinphoneActivity;
|
||||
import org.linphone.core.LinphoneChatMessage;
|
||||
import org.linphone.core.LinphoneChatMessage.State;
|
||||
|
@ -29,9 +28,9 @@ public class Chat extends SampleTest {
|
|||
public void testAEmptyChatHistory() {
|
||||
goToChat();
|
||||
|
||||
ChatStorage chatStorage = ChatStorage.getInstance();
|
||||
for (String conversation : chatStorage.getChatList()) {
|
||||
chatStorage.removeDiscussion(conversation);
|
||||
LinphoneChatRoom[] chats = LinphoneTestManager.getInstance().getLc().getChatRooms();
|
||||
for (LinphoneChatRoom chatroom : chats) {
|
||||
chatroom.deleteHistory();
|
||||
}
|
||||
|
||||
Assert.assertEquals(0, LinphoneActivity.instance().getUnreadMessageCount());
|
||||
|
|
Loading…
Reference in a new issue