Use FileProvider to prevent exception when cliking on image + fixed image preview orientation + improved bitmap memory management
This commit is contained in:
parent
c6379dab59
commit
04887af28e
5 changed files with 81 additions and 9 deletions
|
@ -287,6 +287,16 @@
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</service>
|
</service>
|
||||||
|
|
||||||
|
<provider
|
||||||
|
android:name="android.support.v4.content.FileProvider"
|
||||||
|
android:authorities="org.linphone.provider"
|
||||||
|
android:exported="false"
|
||||||
|
android:grantUriPermissions="true">
|
||||||
|
<meta-data
|
||||||
|
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||||
|
android:resource="@xml/provider_paths"/>
|
||||||
|
</provider>
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".tutorials.TutorialLauncherActivity"
|
android:name=".tutorials.TutorialLauncherActivity"
|
||||||
android:theme="@style/NoTitle">
|
android:theme="@style/NoTitle">
|
||||||
|
|
|
@ -18,7 +18,7 @@ buildscript {
|
||||||
mavenLocal()
|
mavenLocal()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:2.3.0'
|
classpath 'com.android.tools.build:gradle:2.3.3'
|
||||||
if (googleFile.exists()) {
|
if (googleFile.exists()) {
|
||||||
classpath 'com.google.gms:google-services:3.0.0'
|
classpath 'com.google.gms:google-services:3.0.0'
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ buildscript {
|
||||||
mavenLocal()
|
mavenLocal()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:2.3.0'
|
classpath 'com.android.tools.build:gradle:2.3.3'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
4
res/xml/provider_paths.xml
Normal file
4
res/xml/provider_paths.xml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<paths xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<external-path name="external_files" path="."/>
|
||||||
|
</paths>
|
|
@ -47,6 +47,7 @@ import android.os.Bundle;
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
import android.provider.MediaStore;
|
import android.provider.MediaStore;
|
||||||
|
import android.support.v4.content.FileProvider;
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
import android.text.Spanned;
|
import android.text.Spanned;
|
||||||
import android.text.TextWatcher;
|
import android.text.TextWatcher;
|
||||||
|
@ -97,6 +98,8 @@ import java.util.Calendar;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import static android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION;
|
||||||
|
|
||||||
|
|
||||||
public class ChatFragment extends Fragment implements OnClickListener, LinphoneChatMessage.LinphoneChatMessageListener {
|
public class ChatFragment extends Fragment implements OnClickListener, LinphoneChatMessage.LinphoneChatMessageListener {
|
||||||
private static final int ADD_PHOTO = 1337;
|
private static final int ADD_PHOTO = 1337;
|
||||||
|
@ -876,11 +879,18 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
||||||
@Override
|
@Override
|
||||||
protected byte[] doInBackground(Bitmap... params) {
|
protected byte[] doInBackground(Bitmap... params) {
|
||||||
Bitmap bm = params[0];
|
Bitmap bm = params[0];
|
||||||
|
Bitmap bm_tmp = null;
|
||||||
|
|
||||||
if (bm.getWidth() >= bm.getHeight() && bm.getWidth() > SIZE_MAX) {
|
if (bm.getWidth() >= bm.getHeight() && bm.getWidth() > SIZE_MAX) {
|
||||||
bm = Bitmap.createScaledBitmap(bm, SIZE_MAX, (SIZE_MAX * bm.getHeight()) / bm.getWidth(), false);
|
bm_tmp = Bitmap.createScaledBitmap(bm, SIZE_MAX, (SIZE_MAX * bm.getHeight()) / bm.getWidth(), false);
|
||||||
|
|
||||||
} else if (bm.getHeight() >= bm.getWidth() && bm.getHeight() > SIZE_MAX) {
|
} else if (bm.getHeight() >= bm.getWidth() && bm.getHeight() > SIZE_MAX) {
|
||||||
bm = Bitmap.createScaledBitmap(bm, (SIZE_MAX * bm.getWidth()) / bm.getHeight(), SIZE_MAX, false);
|
bm_tmp = Bitmap.createScaledBitmap(bm, (SIZE_MAX * bm.getWidth()) / bm.getHeight(), SIZE_MAX, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bm_tmp != null) {
|
||||||
|
bm.recycle();
|
||||||
|
bm = bm_tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rotate the bitmap if possible/needed, using EXIF data
|
// Rotate the bitmap if possible/needed, using EXIF data
|
||||||
|
@ -896,12 +906,17 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
||||||
} else if (pictureOrientation == 8) {
|
} else if (pictureOrientation == 8) {
|
||||||
matrix.postRotate(270);
|
matrix.postRotate(270);
|
||||||
}
|
}
|
||||||
bm = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true);
|
bm_tmp = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e(e);
|
Log.e(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bm_tmp != null) {
|
||||||
|
bm.recycle();
|
||||||
|
bm = bm_tmp;
|
||||||
|
}
|
||||||
|
|
||||||
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||||
String extension = LinphoneUtils.getExtensionFromFileName(path);
|
String extension = LinphoneUtils.getExtensionFromFileName(path);
|
||||||
if (extension != null && extension.toLowerCase(Locale.getDefault()).equals("png")) {
|
if (extension != null && extension.toLowerCase(Locale.getDefault()).equals("png")) {
|
||||||
|
@ -909,6 +924,14 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
||||||
} else {
|
} else {
|
||||||
bm.compress(Bitmap.CompressFormat.JPEG, 100, stream);
|
bm.compress(Bitmap.CompressFormat.JPEG, 100, stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bm_tmp != null) {
|
||||||
|
bm_tmp.recycle();
|
||||||
|
bm_tmp = null;
|
||||||
|
}
|
||||||
|
bm.recycle();
|
||||||
|
bm = null;
|
||||||
|
|
||||||
byte[] byteArray = stream.toByteArray();
|
byte[] byteArray = stream.toByteArray();
|
||||||
return byteArray;
|
return byteArray;
|
||||||
}
|
}
|
||||||
|
@ -1494,6 +1517,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
||||||
protected Bitmap doInBackground(String... params) {
|
protected Bitmap doInBackground(String... params) {
|
||||||
path = params[0];
|
path = params[0];
|
||||||
Bitmap bm = null;
|
Bitmap bm = null;
|
||||||
|
Bitmap thumbnail = null;
|
||||||
|
|
||||||
if (path.startsWith("content")) {
|
if (path.startsWith("content")) {
|
||||||
try {
|
try {
|
||||||
|
@ -1505,13 +1529,33 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
bm = BitmapFactory.decodeFile(path);
|
bm = BitmapFactory.decodeFile(path);
|
||||||
path = "file://" + path;
|
}
|
||||||
|
|
||||||
|
// Rotate the bitmap if possible/needed, using EXIF data
|
||||||
|
try {
|
||||||
|
Bitmap bm_tmp;
|
||||||
|
ExifInterface exif = new ExifInterface(path);
|
||||||
|
int pictureOrientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0);
|
||||||
|
Matrix matrix = new Matrix();
|
||||||
|
if (pictureOrientation == 6) {
|
||||||
|
matrix.postRotate(90);
|
||||||
|
} else if (pictureOrientation == 3) {
|
||||||
|
matrix.postRotate(180);
|
||||||
|
} else if (pictureOrientation == 8) {
|
||||||
|
matrix.postRotate(270);
|
||||||
|
}
|
||||||
|
bm_tmp = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true);
|
||||||
|
bm.recycle();
|
||||||
|
bm = bm_tmp;
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bm != null) {
|
if (bm != null) {
|
||||||
bm = ThumbnailUtils.extractThumbnail(bm, SIZE_MAX, SIZE_MAX);
|
thumbnail = ThumbnailUtils.extractThumbnail(bm, SIZE_SMALL, SIZE_SMALL);
|
||||||
|
bm.recycle();
|
||||||
}
|
}
|
||||||
return bm;
|
return thumbnail;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Once complete, see if ImageView is still around and set bitmap.
|
// Once complete, see if ImageView is still around and set bitmap.
|
||||||
|
@ -1531,7 +1575,21 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||||
intent.setDataAndType(Uri.parse((String)v.getTag()), "image/*");
|
|
||||||
|
Uri contentUri = null;
|
||||||
|
String imageUri = (String)v.getTag();
|
||||||
|
if (imageUri.startsWith("file://")) {
|
||||||
|
imageUri = imageUri.substring("file://".length());
|
||||||
|
File file = new File(imageUri);
|
||||||
|
contentUri = FileProvider.getUriForFile(getActivity(), "org.linphone.provider", file);
|
||||||
|
} else if (imageUri.startsWith("content://")) {
|
||||||
|
contentUri = Uri.parse(imageUri);
|
||||||
|
} else {
|
||||||
|
File file = new File(imageUri);
|
||||||
|
contentUri = FileProvider.getUriForFile(getActivity(), "org.linphone.provider", file);
|
||||||
|
}
|
||||||
|
intent.setDataAndType(contentUri, "image/*");
|
||||||
|
intent.addFlags(FLAG_GRANT_READ_URI_PERMISSION);
|
||||||
context.startActivity(intent);
|
context.startActivity(intent);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue