Commit e6d72fa4 by 郑鹏

更改餐馆评论的图片选择方式

parent eb844dc5
/*apply plugin: 'com.android.application'*/
apply plugin: 'com.android.library'
apply plugin: 'maven'
apply plugin: 'com.android.application'
/*apply plugin: 'com.android.library'
apply plugin: 'maven'*/
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
......@@ -16,8 +16,8 @@ android {
compileSdkVersion 30
defaultConfig {
/* multiDexEnabled true
applicationId "com.mhq.smartorder"*/
multiDexEnabled true
applicationId "com.mhq.smartorder"
minSdkVersion 26
targetSdkVersion 30
......@@ -35,13 +35,13 @@ android {
abiFilters "armeabi-v7a", "armeabi", "x86"
}
manifestPlaceholders = [
MTA_APPKEY:"AIAF8SC17A3L",
MTA_CHANNEL:"GooglePay"
MTA_APPKEY : "AIAF8SC17A3L",
MTA_CHANNEL: "GooglePay"
//极光推送
/* JPUSH_PKGNAME: applicationId,
JPUSH_APPKEY : "xx", //JPush上注册的包名对应的appkey.
JPUSH_CHANNEL: "xx-default", //暂时填写默认值即可.*/
/* JPUSH_PKGNAME: applicationId,
JPUSH_APPKEY : "xx", //JPush上注册的包名对应的appkey.
JPUSH_CHANNEL: "xx-default", //暂时填写默认值即可.*/
]
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
......@@ -53,23 +53,23 @@ android {
timeOutInMs=5*1000
installOptions '-r','-s'
}
*/
/* signingConfigs {
/*signingConfigs {
def appStoreFilePath = System.getProperty('StoreFilePath')
def appStorePassword = System.getProperty('StorePassword')
def appKeyAlias = System.getProperty('KeyAlias')
def appKeyPassword = System.getProperty('KeyPassword')
Properties properties = new Properties()
if (rootProject.file("local.properties").exists()) {
properties.load(rootProject.file("local.properties").newDataInputStream())
storeFilePath= properties.get("STOREFILE")
storePassword= properties.get("STOREPASSWORD")
keyAlias= properties.get("KEYALIAS")
keyPassword= properties.get("KEYPASSWORD")
}
Properties properties = new Properties()
if (rootProject.file("local.properties").exists()) {
properties.load(rootProject.file("local.properties").newDataInputStream())
storeFilePath = properties.get("STOREFILE")
storePassword = properties.get("STOREPASSWORD")
keyAlias = properties.get("KEYALIAS")
keyPassword = properties.get("KEYPASSWORD")
}
if (!appStoreFilePath || !appStorePassword || !appKeyAlias || !appKeyPassword) {
//将.android下的debug.keystore放到app目录下
......@@ -90,7 +90,7 @@ android {
}*/
/* buildTypes {
/* buildTypes {
debug {
// buildConfigField 'String','NAME','value'
zipAlignEnabled true
......@@ -114,6 +114,8 @@ android {
}
}*/
sourceSets.main {
jniLibs.srcDirs = ['libs']
java.srcDirs += 'src/support/java'
......@@ -127,7 +129,7 @@ android {
targetCompatibility JavaVersion.VERSION_1_8
}
/* //DomainObjectCollection集合
//DomainObjectCollection集合
applicationVariants.all { variant ->
variant.outputs.each { output ->
if (output.outputFile != null && output.outputFile.name.endsWith('.apk')
......@@ -143,8 +145,9 @@ android {
// output.outputFile=apkFile
}
}
}*/
}
}
def buildTime() {
def date = new Date();
def formattedDate = date.format("yyyyMMdd");
......@@ -169,7 +172,9 @@ def getAppVersionCode() {
}
return stout.toString().split("\n").size()
}
ext {
/*ext {
GITHUB_REPO_PATH = "../../androidlibrary"
PUBLISH_GROUP_ID = 'com.mhq.smartorder'
PUBLISH_ARTIFACT_ID = 'smartorder'
......@@ -186,7 +191,11 @@ uploadArchives {
pom.version = project.PUBLISH_VERSION // 版本号
}
}
}
}*/
dependencies {
......@@ -212,9 +221,9 @@ dependencies {
api 'com.tbruyelle.rxpermissions2:rxpermissions:0.9.5@aar'
//api 'com.github.bumptech.glide:glide:4.7.1'
// api 'com.github.bumptech.glide:okhttp3-integration:4.7.1'
/* annotationProcessor 'com.github.bumptech.glide:compiler:4.7.1'
kapt 'com.github.bumptech.glide:compiler:4.7.1'*/
// api 'com.github.bumptech.glide:okhttp3-integration:4.7.1'
/* annotationProcessor 'com.github.bumptech.glide:compiler:4.7.1'
kapt 'com.github.bumptech.glide:compiler:4.7.1'*/
api 'com.github.chrisbanes.photoview:library:1.2.4'
//api 'com.jakewharton:butterknife:8.4.0'
......@@ -230,8 +239,8 @@ dependencies {
//kapt deps.butterknife.butterknife_compiler
kapt 'com.alibaba:arouter-compiler:1.1.4'
/* api 'com.qq.mta:mta:3.4.7-release'
api 'com.tencent.mid:mid:4.06-release'*/
/* api 'com.qq.mta:mta:3.4.7-release'
api 'com.tencent.mid:mid:4.06-release'*/
// api project(':component-easeui')
api 'com.tencent.mm.opensdk:wechat-sdk-android-without-mta:+'
implementation 'org.aspectj:aspectjrt:1.8.9'
......@@ -251,13 +260,13 @@ dependencies {
//api 'com.google.android.gms:play-services-wallet:16.0.1'
api 'com.tencent.qcloud:cosxml:5.4.25'
api 'com.sunfusheng:marqueeview:1.3.3'
/* api 'com.google.firebase:firebase-core:16.0.8'
api 'com.google.firebase:firebase-messaging:17.6.0'*/
/* api 'com.tencent.bugly:crashreport:latest.release'
api 'com.tencent.bugly:nativecrashreport:latest.release'*/
/* api 'com.google.firebase:firebase-core:16.0.8'
api 'com.google.firebase:firebase-messaging:17.6.0'*/
/* api 'com.tencent.bugly:crashreport:latest.release'
api 'com.tencent.bugly:nativecrashreport:latest.release'*/
//MTA主包
/* api 'com.qq.mta:mta:3.4.7-Release'
api 'com.tencent.mid:mid:4.06-Release'*/
/* api 'com.qq.mta:mta:3.4.7-Release'
api 'com.tencent.mid:mid:4.06-Release'*/
api 'com.github.liys666666:DoubleClick:V2.0.4'
api 'com.readystatesoftware.chuck:library:1.1.0'
......
......@@ -29,7 +29,10 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".ui.home.FoodAllEvaluateActivity"></activity>
<activity android:name=".ui.home.FoodAllEvaluateActivity"
android:screenOrientation="portrait" >
</activity>
<activity
android:name=".ui.home.HomeActivity"
android:configChanges="locale"
......@@ -132,7 +135,23 @@
android:screenOrientation="portrait" />
<activity
android:name=".ui.personal.order.food.FoodEvaluationActivity"
android:screenOrientation="portrait" />
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.genericFile.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
</provider>
<activity
android:name=".ui.shop.MallSearchActivity"
android:screenOrientation="portrait" />
......
......@@ -17,6 +17,7 @@ import org.litepal.LitePal;
import java.util.Locale;
import cn.dankal.basiclib.image.Utils;
import cn.dankal.basiclib.util.AppUtils;
import cn.dankal.basiclib.util.DensityAdaptationUtils;
import cn.dankal.basiclib.util.StringUtil;
......@@ -55,6 +56,8 @@ public class ModooApplication extends Application {
//데이터베이스 초기 화 스 캔
LitePal.initialize(this);
Utils.mAppContext=this.getApplicationContext();
//bugly
//CrashReport.initCrashReport(getApplicationContext(), "74a2fc949e", isDev);
......@@ -182,7 +185,6 @@ public class ModooApplication extends Application {
/**
* App 가 현재 암흑 모드 상태 에 있 는 지 판단
*
* @param context 문맥
* @return
*/
public static boolean isDarkMode() {
......
......@@ -25,8 +25,8 @@ public class BaseApi {
/*public static final String BASE_URL = isDev ? "https://api-koreadc.dankal.cn/v1/"
: "https://modoo-api.mhqglobal.com/v1/";*/
//public static final String BASE_URL = "https://api-koreadc.dankal.cn/v1/";
public static final String BASE_URL = "https://modoo-api.mhqglobal.com/v1/";
public static final String BASE_URL = "https://api-koreadc.dankal.cn/v1/";
//public static final String BASE_URL = "https://modoo-api.mhqglobal.com/v1/";
public static final String BASE_EXPRESS_URL = "https://info.sweettracker.co.kr/";
......
package cn.dankal.basiclib.image;
import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Parcelable;
import android.provider.Settings;
import com.facebook.stetho.common.LogUtil;
import java.util.ArrayList;
import java.util.List;
public final class AppUtil
{
private static final String TAG = "AppUtil";
private AppUtil()
{
}
public static String getCurrentProcessName()
{
int pid = android.os.Process.myPid();
ActivityManager mActivityManager = (ActivityManager) Utils.mAppContext.getSystemService(
Context.ACTIVITY_SERVICE);
if (mActivityManager != null)
{
for (ActivityManager.RunningAppProcessInfo appProcess : mActivityManager.getRunningAppProcesses())
{
if (appProcess.pid == pid)
{
return appProcess.processName;
}
}
}
return null;
}
public static Intent shareTextIntent(String text)
{
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
sendIntent.putExtra(Intent.EXTRA_TEXT, text);
sendIntent.setType("text/plain");
return sendIntent;
}
public static List<ResolveInfo> getTextReceivers(PackageManager pm)
{
final Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
intent.setType("text/plain");
final List<ResolveInfo> resolveInfos = pm.queryIntentActivities(intent,
PackageManager.MATCH_DEFAULT_ONLY);
return resolveInfos;
}
/**
* @return 获取所有的带启动图标的App
*/
public static List<ResolveInfo> getLaunchableResolveInfos()
{
final Intent intent = new Intent();
intent.setAction(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
return Utils.mAppContext.getPackageManager().queryIntentActivities(intent, 0);
}
/**
* 取得版本名称,对应 AndroidManifest.xml 文件 <manifest> 标签下的 versionName 属性
*
* @return 返回版本字符串,比如:1.0
*/
public static String getVersionName()
{
return getDefPackageInfo().versionName;
}
/**
* 取得版本号,对应 AndroidManifest.xml 文件 <manifest> 标签下的 versionCode 属性
*
* @return 返回版本,比如:1
*/
public static int getVersionCode()
{
return getDefPackageInfo().versionCode;
}
public static PackageInfo getDefPackageInfo()
{
PackageManager packageManager = Utils.mAppContext.getPackageManager();
// getPackageName()是你当前类的包名,0代表是获取版本信息
PackageInfo packInfo = null;
try
{
packInfo = packageManager.getPackageInfo(Utils.mAppContext.getPackageName(), 0);
}
catch (PackageManager.NameNotFoundException e)
{
e.printStackTrace();
}
return packInfo;
}
public static boolean isAppExist(String packageName)
{
final PackageManager packageManager = Utils.mAppContext.getPackageManager();
// 获取所有已安装程序的包信息
List<PackageInfo> pinfo = packageManager.getInstalledPackages(0);
for (int i = 0; i < pinfo.size(); i++)
{
if (pinfo.get(i).packageName.equalsIgnoreCase(packageName))
{
return true;
}
}
return false;
}
public static void gotoAppDetailsSettings(Context context, int requestCode)
{
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setData(Uri.fromParts("package", context.getPackageName(), null));
if (context instanceof Activity)
{
((Activity) context).startActivityForResult(intent, requestCode);
}
}
public static String getCurProcessName()
{
int pid = android.os.Process.myPid();
ActivityManager mActivityManager = (ActivityManager) Utils.mAppContext.getSystemService(
Context.ACTIVITY_SERVICE);
if (mActivityManager != null)
{
for (ActivityManager.RunningAppProcessInfo appProcess : mActivityManager.getRunningAppProcesses())
{
if (appProcess.pid == pid)
{
return appProcess.processName;
}
}
}
return null;
}
public static String getAppLabel()
{
PackageManager packageManager = Utils.mAppContext.getPackageManager();
try
{
return packageManager.getApplicationLabel(
packageManager.getApplicationInfo(Utils.mAppContext.getPackageName(),
0)).toString();
}
catch (PackageManager.NameNotFoundException e)
{
e.printStackTrace();
LogUtil.e(TAG, "getDefPackageInfo: " + e.getMessage());
}
return null;
}
public static boolean startActivityForPackage(Context context, String packageName)
{
final PackageManager pm = context.getPackageManager();
Intent intent = pm.getLaunchIntentForPackage(packageName);
if (null != intent)
{
context.startActivity(intent);
return true;
}
return false;
}
/**
* 打开其他的Activity
*
* @param cls 要打开的Activity
*/
public static void startActivity(Context context, Class<?> cls)
{
if (context == null)
{
return;
}
context.startActivity(new Intent(context, cls));
}
/**
* 打开其他的Activity,并附带Object
*
* @param cls 要打开的Activity
* @param value 要附带的Object
*/
// public static void startActivity(Context context, Class<?> cls, String name, Object value)
// {
// Intent intent = new Intent(context, cls);
// intent.putExtra(name, PG.convertParcelable(value));
// context.startActivity(intent);
// }
//
// public static void startActivity(Context context, Class<?> cls, Object value)
// {
// Intent intent = new Intent(context, cls);
// intent.putExtra(Constants.EXTRA_PARCELABLE, PG.convertParcelable(value));
// context.startActivity(intent);
// }
//
// public static void startActivity(Context context, Intent intent, String name, Object value)
// {
// intent.putExtra(name, PG.convertParcelable(value));
// context.startActivity(intent);
// }
public static void startActivity(Context context, Class<?> cls, String name, int value)
{
Intent intent = new Intent(context, cls);
intent.putExtra(name, value);
context.startActivity(intent);
}
public static void startActivity(Context context, Class<?> cls, String name, boolean value)
{
Intent intent = new Intent(context, cls);
intent.putExtra(name, value);
context.startActivity(intent);
}
/**
* 打开其他的Activity,并附带字符串
*
* @param cls 要打开的Activity
* @param name 字符串名称
* @param value 字符串值
*/
public static void startActivity(Context context, Class<?> cls, String name, String value)
{
Intent intent = new Intent(context, cls);
intent.putExtra(name, value);
context.startActivity(intent);
}
public static void startActivityForResult(Activity context, Class<?> cls, int requestCode,
String name, String value)
{
Intent intent = new Intent(context, cls);
intent.putExtra(name, value);
context.startActivityForResult(intent, requestCode);
}
/* public static <T extends BaseActivity> void startActivityWithParcelable(Context context, Class<T> cls,
Parcelable par)
{
Intent intent = new Intent(context, cls);
intent.putExtra(Constants.EXTRA_PARCELABLE, par);
context.startActivity(intent);
}
public static <T extends BaseActivity> void startActivityWithParcelableList(Context context, Class<T> cls,
ArrayList<? extends Parcelable> par)
{
Intent intent = new Intent(context, cls);
intent.putParcelableArrayListExtra(Constants.EXTRA_PARCELABLE_LIST, par);
context.startActivity(intent);
}*/
/**
* 检测 响应某个意图的Activity 是否存在
* @param context
* @param intent
* @return
*/
/* public static boolean isIntentAvailable(Context context, Intent intent)
{
final PackageManager packageManager = context.getPackageManager();
List<ResolveInfo> list = packageManager.queryIntentActivities(intent,
PackageManager.GET_ACTIVITIES);
return list.size() > 0;
}*/
}
package cn.dankal.basiclib.image;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.provider.MediaStore;
import android.support.v4.app.Fragment;
import android.support.v4.content.FileProvider;
import android.widget.Toast;
import com.yanzhenjie.permission.AndPermission;
import com.yanzhenjie.permission.Permission;
import java.io.File;
import cn.dankal.basiclib.ModooApplication;
import cn.dankal.client.R;
public final class CaptureAndCropManager
{
public static final int REQUEST_CODE_CAPTURE = 200;
public static final int REQUEST_CODE_CROP = 300;
public static final int REQUEST_CODE_ALBUM = 400;
public static final String AUTHORITY = ModooApplication.getContext().getPackageName() + ".genericFile.provider";
private static File mOutCameraCaptureImageFile;
private static File mOutCropImageFile;
private static Integer outputX;
private static Integer outputY;
private static Integer aspectX;
private static Integer aspectY;
public static Integer getOutputX()
{
return outputX;
}
public static void setOutputX(Integer outputX)
{
CaptureAndCropManager.outputX = outputX;
}
public static Integer getOutputY()
{
return outputY;
}
public static void setOutputY(Integer outputY)
{
CaptureAndCropManager.outputY = outputY;
}
public static Integer getAspectX()
{
return aspectX;
}
public static void setAspectX(Integer aspectX)
{
CaptureAndCropManager.aspectX = aspectX;
}
public static Integer getAspectY()
{
return aspectY;
}
public static void setAspectY(Integer aspectY)
{
CaptureAndCropManager.aspectY = aspectY;
}
// 获取最后一次拍照得到的照片
public static File getLastCameraCaptureImageFile()
{
return mOutCameraCaptureImageFile;
}
// 获取最后一次裁剪后的图片
public static File getLastCropImageFile()
{
return mOutCropImageFile;
}
// 从相册获取照片完毕,从uri中跳到裁剪
public static void cropPhotoFromUri(Activity activity, Uri uri, int requestCode)
{
cropPhotoFromUri(activity, null, uri, requestCode);
}
public static void cropPhotoFromUri(Fragment fragment, Uri uri, int requestCode)
{
cropPhotoFromUri(null, fragment, uri, requestCode);
}
private static void cropPhotoFromUri(Activity activity, Fragment fragment, Uri uri, int requestCode)
{
mOutCropImageFile = new File(FileUtil.getCacheDir(),
"crop_" + System.currentTimeMillis() + ".jpg");
Intent intent = new Intent("com.android.camera.action.CROP");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
{
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); //添加这一句表示对目标应用临时授权该Uri所代表的文件
intent.setDataAndType(uri, "image/*");
}
else
{
intent.setDataAndType(uri, "image/*");
}
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mOutCropImageFile));
// 设置裁剪
fillCropIntent(intent);
if (activity != null)
{
activity.startActivityForResult(intent, requestCode);
}
else if (fragment != null)
{
fragment.startActivityForResult(intent, requestCode);
}
}
// 拍照完毕,跳到裁剪
public static void cropPhotoAfterCapture(Fragment fragment, int requestCode)
{
cropPhotoAfterCapture(null, fragment, requestCode);
}
public static void cropPhotoAfterCapture(Activity activity, int requestCode)
{
cropPhotoAfterCapture(activity, null, requestCode);
}
private static void cropPhotoAfterCapture(Activity activity, Fragment fragment, int requestCode)
{
mOutCropImageFile = new File(FileUtil.getCacheDir(),
"crop_" + System.currentTimeMillis() + ".jpg");
Intent intent = new Intent("com.android.camera.action.CROP");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
{
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); //添加这一句表示对目标应用临时授权该Uri所代表的文件
intent.setDataAndType(
FileProvider.getUriForFile(activity == null ? fragment.getActivity() : activity, AUTHORITY, mOutCameraCaptureImageFile),
"image/*");
}
else
{
intent.setDataAndType(Uri.fromFile(mOutCameraCaptureImageFile), "image/*");
}
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mOutCropImageFile));
fillCropIntent(intent);
if (activity != null)
{
activity.startActivityForResult(intent, requestCode);
}
else if (fragment != null)
{
fragment.startActivityForResult(intent, requestCode);
}
}
// 填充裁剪的Intent
private static void fillCropIntent(Intent intent)
{
// 设置裁剪
intent.putExtra("crop", "true");
// aspectX aspectY 是宽高的比例
if (aspectX != null)
{
intent.putExtra("aspectX", aspectX);
}
if (aspectY != null)
{
intent.putExtra("aspectY", aspectY);
}
// outputX outputY 是裁剪图片宽高
if (outputX != null)
{
intent.putExtra("outputX", outputX);
}
if (outputY != null)
{
intent.putExtra("outputY", outputY);
}
intent.putExtra("scale ", true); //是否保留比例
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
}
// 从相册获取照片
public static void capturePhotoFromGallery(Activity context, int requestCode)
{
capturePhotoFromGallery(context, null, requestCode);
}
public static void capturePhotoFromGallery(Fragment fragment, int requestCode)
{
capturePhotoFromGallery(null, fragment, requestCode);
}
public static void capturePhotoFromGallery(Activity activity, Fragment fragment, int requestCode)
{
Intent intent = new Intent(Intent.ACTION_PICK,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
if (activity != null)
{
activity.startActivityForResult(intent, requestCode);
}
else if (fragment != null)
{
fragment.startActivityForResult(intent, requestCode);
}
}
// 从相机获取照片
public static void capturePhotoFromCamera(Activity context, int requestCode)
{
capturePhotoFromCamera(context, null, requestCode);
}
public static void capturePhotoFromCamera(Fragment fragment, int requestCode)
{
capturePhotoFromCamera(null, fragment, requestCode);
}
private static void capturePhotoFromCamera(Activity activity, Fragment fragment, int requestCode)
{
Context context = activity == null ? fragment.getActivity() : activity;
if (Utils.isNeedCheckPermission())
{
AndPermission.with(context).runtime().permission(Permission.CAMERA).onGranted(
permissions -> {
captureCameraPhotoWithPermission(activity, fragment, requestCode);
}).onDenied(permissions -> {
if (AndPermission.hasAlwaysDeniedPermission(context, permissions))
{
String[] s = new String[permissions.size()];
s = permissions.toArray(s);
if (AndPermission.hasPermissions(context, s))
{
captureCameraPhotoWithPermission(activity, fragment, requestCode);
}
else
{
AppUtil.gotoAppDetailsSettings(context, 0);
Toast.makeText(context, ModooApplication.getContext().getResources().getText(R.string.many_times_you_have_refused_authorization_has_been_detected_please_manually_open_the_camera_privileges_), Toast.LENGTH_SHORT).show();
}
}
else
{
Toast.makeText(context, ModooApplication.getContext().getResources().getText(R.string.authorization_failed_and_the_camera_was_unavailable), Toast.LENGTH_SHORT).show();
}
}).start();
}
else
{
captureCameraPhotoWithPermission(activity, fragment, requestCode);
}
}
// 必须有权限了,才可以拍照获取照片
private static void captureCameraPhotoWithPermission(Activity context, Fragment fragment, int requestCode)
{
mOutCameraCaptureImageFile = new File(FileUtil.getCacheDir(),
"capture_" + System.currentTimeMillis() + ".jpg");
Intent intentToTakePhoto = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
Uri imageUri;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
{
intentToTakePhoto.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
imageUri = FileProvider.getUriForFile(context == null ? fragment.getActivity() : context, AUTHORITY, mOutCameraCaptureImageFile);
}
else
{
imageUri = Uri.fromFile(mOutCameraCaptureImageFile);
}
//下面这句指定调用相机拍照后的照片存储的路径
intentToTakePhoto.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
// 格式
intentToTakePhoto.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
if (intentToTakePhoto.resolveActivity(Utils.mAppContext.getPackageManager()) != null)
{
if (context != null)
{
context.startActivityForResult(intentToTakePhoto, requestCode);
}
else
{
fragment.startActivityForResult(intentToTakePhoto, requestCode);
}
}
}
}
package cn.dankal.basiclib.image;
/**
* Created by imyyq on 2018/3/14.
*/
public final class Constants
{
public static final String EXTRA_PARCELABLE = "EXTRA_PARCELABLE";
public static final String EXTRA_PARCELABLE_LIST = "EXTRA_PARCELABLE_LIST";
public static final String RELEASE = "release";
}
package cn.dankal.basiclib.image;
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.facebook.stetho.common.LogUtil;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Locale;
public final class FileUtil
{
private FileUtil()
{
}
public static double getDirLengthForM(File dir)
{
return getDirLength(dir) * 1.0 / 1024 / 1024;
}
public static long getDirLength(File dir)
{
long length = 0;
// 删除文件夹中的所有文件包括子目录
File[] files = dir.listFiles();
if (files == null)
{
return length;
}
for (File file : files)
{
// 删除子文件
if (file.isFile())
{
length += file.length();
}
// 删除子目录
else if (file.isDirectory())
{
length += getDirLength(file);
}
}
return length;
}
public static File getCacheDir()
{
File f = Utils.mAppContext.getExternalCacheDir();
if (f == null)
{
return Utils.mAppContext.getCacheDir();
}
return f;
}
// 取得App的文件目录,在sd卡根目录下用包名为目录名,或者在内部的存储目录,用/结尾
public static String getAppDir()
{
return isSDCardMounted()
? getSDCardBaseDir() + "/" + AppUtil.getDefPackageInfo().packageName + "/"
: Utils.mAppContext.getFilesDir().getAbsolutePath() + "/";
}
// 取得App的文件目录,/sdcard/包名/File,没有sd卡则是/data/data/包名/files/File
public static String getAppFileDir()
{
String s = "/File/";
return isSDCardMounted()
? getSDCardBaseDir() + "/" + AppUtil.getDefPackageInfo().packageName + s
: Utils.mAppContext.getFilesDir().getAbsolutePath() + s;
}
// 取得App的log目录:/sdcard/包名/Log,没有sd卡则是/data/data/包名/files/Log
public static String getAppLogDir()
{
String s = "/Log/";
String path = isSDCardMounted()
? getSDCardBaseDir() + "/" + AppUtil.getDefPackageInfo().packageName + s
: Utils.mAppContext.getFilesDir().getAbsolutePath() + s;
File file = new File(path);
if (!file.exists())
{
file.mkdirs();
}
return path;
}
// 判断SD卡是否被挂载
public static boolean isSDCardMounted()
{
// return Environment.getExternalStorageState().equals("mounted");
return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
}
// 获取SD卡的根目录
public static String getSDCardBaseDir()
{
if (isSDCardMounted())
{
return Environment.getExternalStorageDirectory().getAbsolutePath();
}
return null;
}
public static boolean copyFile(String srcPath, String targetPath)
{
File file = new File(targetPath);
try (FileInputStream inputStream = new FileInputStream(srcPath); //
FileOutputStream outputStream = new FileOutputStream(file))
{
byte[] bs = new byte[1024 * 10];
int len;
while ((len = inputStream.read(bs)) != -1)
{
outputStream.write(bs, 0, len);
}
outputStream.flush();
file.setLastModified(System.currentTimeMillis());
return true;
}
catch (Exception e)
{
e.printStackTrace();
}
return false;
}
public static String readAssetsFileContent(String fileName)
{
try (InputStream stream = Utils.mAppContext.getAssets().open(fileName))
{
byte[] bs = new byte[stream.available()];
stream.read(bs);
return new String(bs);
}
catch (IOException e)
{
e.printStackTrace();
}
return null;
}
/**
* 拷贝 assets 目录下的文件到指定路径
*
* @param targetDir 目标目录
* @param assetsFileName 文件名称
*/
public static void copyAssetsFile(String targetDir, String assetsFileName)
{
File dir = new File(targetDir);
if (!dir.exists())
{
if (!dir.mkdirs()) // 创建失败,退出
{
return;
}
}
InputStream in;
OutputStream out;
try
{
in = FileUtil.class.getResourceAsStream("/assets/" + assetsFileName);
out = new FileOutputStream(new File(targetDir + File.separator + assetsFileName));
byte[] buffer = new byte[1024];
int len;
while ((len = in.read(buffer)) > 0)
{
out.write(buffer, 0, len);
}
out.flush();
in.close();
out.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
/**
* 将指定的实体对象转成JSON字符串后保存到指定文件
*
* @return 返回true,保存成功
*/
public static boolean saveJSONObjectToLocal(String filePath, Object object,
boolean isSave2SDCard)
{
return isSave2SDCard
? saveStr2External(filePath, JSON.toJSONString(object, true), false)
: saveStr2Internal(filePath, JSON.toJSONString(object, true), false);
}
/**
* 保存字符串到本地
*/
private static boolean saveStrToLocal(String filePath, String str, boolean append)
{
File file = new File(filePath);
if (!file.getParentFile().exists()) // 文件路径不存在则创建
{
if (!file.getParentFile().mkdirs()) // 创建失败直接返回
{
return false;
}
}
FileOutputStream fw = null;
try
{
fw = new FileOutputStream(filePath, append);
fw.write(str.getBytes("UTF-8"));
return true;
}
catch (IOException | JSONException ex)
{
ex.printStackTrace();
}
finally
{
try
{
if (fw != null)
{
fw.flush();
fw.close();
}
}
catch (IOException ex)
{
ex.printStackTrace();
}
}
return false;
}
/**
* 保存字符串到内部的存储
*/
public static boolean saveStr2Internal(String filePath, String str, boolean append)
{
return saveStrToLocal(filePath, str, append);
}
/**
* 保存字符串到外部存储
*/
public static boolean saveStr2External(String filePath, String str, boolean append)
{
return isSDCardExists() && saveStrToLocal(filePath, str, append);
}
/**
* @param rootDir 根目录,比如/sdcard
* @param dirName 子目录,可以多级,比如com.yyq,Log
* @return 比如/sdcard/com.yyq/Log/
*/
private static String getDir(String rootDir, Object... dirName)
{
StringBuilder format = new StringBuilder("/");
for (int i = 0; i < dirName.length; i++)
{
format.append("%s/");
}
return String.format(Locale.getDefault(), rootDir + format.toString(), dirName);
}
/**
* 获取外部存储文件夹路径,比如参数是:org.sxisa.ui,Log,那么返回的是
* /sdcard/org.sxisa.ui/Log/
*/
public static String getExternalDir(Object... dirName)
{
return getDir(Environment.getExternalStorageDirectory().getAbsolutePath(), dirName);
}
/**
* 获取内部存储files文件夹路径,比如输入的是Log
* /data/user/0/org.sxisa.ui/files/Log/
*/
public static String getInternalFilesDir(Object... dirName)
{
return getDir(Utils.mAppContext.getFilesDir().getAbsolutePath(), dirName);
}
/**
* 获取内部存储Log文件夹路径,比如
* /data/user/0/org.sxisa.ui/files/Log/
*/
public static String getInternalLogDir()
{
return getInternalFilesDir("Log");
}
private static boolean isSDCardExists()
{
return Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState());
}
public static String getFilePathFromUri(Context context, Uri uri)
{
if (null == uri)
{
return null;
}
final String scheme = uri.getScheme();
String data = null;
if (scheme == null)
{
data = uri.getPath();
}
else if (ContentResolver.SCHEME_FILE.equals(scheme))
{
data = uri.getPath();
}
else if (ContentResolver.SCHEME_CONTENT.equals(scheme))
{
Cursor cursor = context.getContentResolver().query(uri,
new String[]{MediaStore.Images.ImageColumns.DATA}, null, null, null);
if (null != cursor)
{
if (cursor.moveToFirst())
{
int index = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
if (index > -1)
{
data = cursor.getString(index);
}
}
cursor.close();
}
}
else
{
LogUtil.e("FileUtil", "getFilePathFromUri: " + uri);
}
return data;
}
/**
* 删除文件,可以是文件或文件夹
*
* @param fileName 要删除的文件名
* @return 删除成功返回true,否则返回false
*/
public static boolean delete(String fileName)
{
File file = new File(fileName);
if (!file.exists())
{
return false;
}
else
{
if (file.isFile())
{
return deleteFile(fileName);
}
else
{
return deleteDirectory(fileName, true);
}
}
}
/**
* 删除单个文件
*
* @param fileName 要删除的文件的文件名
* @return 单个文件删除成功返回true,否则返回false
*/
public static boolean deleteFile(String fileName)
{
File file = new File(fileName);
// 如果文件路径所对应的文件存在,并且是一个文件,则直接删除
if (file.exists() && file.isFile())
{
return file.delete();
}
else
{
return false;
}
}
/**
* 删除目录及目录下的文件
*
* @param dir 要删除的目录的文件路径
* @return 目录删除成功返回true,否则返回false
*/
public static boolean deleteDirectory(String dir, boolean isDeleteSelf)
{
File dirFile = new File(dir);
// 如果dir对应的文件不存在,或者不是一个目录,则退出
if ((!dirFile.exists()) || (!dirFile.isDirectory()))
{
return false;
}
// 删除文件夹中的所有文件包括子目录
File[] files = dirFile.listFiles();
for (File file : files)
{
// 删除子文件
if (file.isFile())
{
deleteFile(file.getAbsolutePath());
}
// 删除子目录
else if (file.isDirectory())
{
deleteDirectory(file.getAbsolutePath(), true);
}
}
// 删除当前目录
return isDeleteSelf && dirFile.delete();
}
}
package cn.dankal.basiclib.image;
import android.app.Activity;
import android.content.Intent;
import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
import android.support.v4.app.Fragment;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import com.yzq.zxinglibrary.decode.ImageUtil;
import com.zhy.adapter.recyclerview.CommonAdapter;
import com.zhy.adapter.recyclerview.MultiItemTypeAdapter;
import com.zhy.adapter.recyclerview.base.ViewHolder;
import java.io.File;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import cn.dankal.client.R;
public class PickPhotoForRvManager
implements MultiItemTypeAdapter.OnItemClickListener
{
private Activity mActivity;
private Fragment mFragment;
private RecyclerView rvList;
private TextView tvPhotoNum;
@StringRes
private int mPhotoNumTipsRes;
private MyAdapter mAdapter;
private int mMaxPhotoNum;
private int mSpanCount;
private boolean mIsNeedCrop = false;
private Integer outputX;
private Integer outputY;
private Integer aspectX;
private Integer aspectY;
/*
* 可能一个界面有多个rv,当点击某个rv的添加按钮,记录下该rv的id
* 当onActivityResult的时候,可以判断当前的rv和点击的rv是否是同一个
*/
private static int mCurClickRvId;
public PickPhotoForRvManager(Activity mActivity, RecyclerView rvList, TextView tvPhotoNum,
int mPhotoNumTipsRes, int mMaxPhotoNum,
int mSpanCount)
{
this(mActivity, null, rvList, tvPhotoNum, mPhotoNumTipsRes, mMaxPhotoNum, mSpanCount);
}
public PickPhotoForRvManager(Fragment fragment, RecyclerView rvList, TextView tvPhotoNum,
int mPhotoNumTipsRes, int mMaxPhotoNum,
int mSpanCount)
{
this(null, fragment, rvList, tvPhotoNum, mPhotoNumTipsRes, mMaxPhotoNum, mSpanCount);
}
private PickPhotoForRvManager(Activity mActivity, Fragment fragment, RecyclerView rvList, TextView tvPhotoNum,
int mPhotoNumTipsRes, int mMaxPhotoNum,
int mSpanCount)
{
this.mActivity = mActivity;
this.mFragment = fragment;
this.rvList = rvList;
this.tvPhotoNum = tvPhotoNum;
this.mPhotoNumTipsRes = mPhotoNumTipsRes;
this.mMaxPhotoNum = mMaxPhotoNum;
this.mSpanCount = mSpanCount;
initRv();
/* tvPhotoNum.setText(AppActivityManager.topContext().getString(mPhotoNumTipsRes, mAdapter.getItemCount() - 1,
mMaxPhotoNum));*/
}
public void setIsNeedCrop(boolean isNeedCrop)
{
this.mIsNeedCrop = isNeedCrop;
}
public void setOutputX(Integer outputX)
{
this.outputX = outputX;
}
public void setOutputY(Integer outputY)
{
this.outputY = outputY;
}
public void setAspectX(Integer aspectX)
{
this.aspectX = aspectX;
}
public void setAspectY(Integer aspectY)
{
this.aspectY = aspectY;
}
private void initRv()
{
mAdapter = new MyAdapter();
mAdapter.getDatas().add(null);
rvList.setHasFixedSize(true);
rvList.setNestedScrollingEnabled(false);
rvList.setLayoutManager(new GridLayoutManager(Utils.mAppContext, mSpanCount));
rvList.setAdapter(mAdapter);
mAdapter.setOnItemClickListener(this);
}
public List<PickPhotoItem> getPic()
{
List<PickPhotoItem> list = new ArrayList<>();
for (PickPhotoItem data : mAdapter.getDatas())
{
if (data != null)
{
list.add(data);
}
}
return list;
}
public List<File> getPicFileList()
{
List<File> list = new ArrayList<>();
for (PickPhotoItem data : mAdapter.getDatas())
{
if (data != null && data.getFile() != null)
{
list.add(data.getFile());
}
}
return list;
}
public List<String> getPicUrlList()
{
List<String> list = new ArrayList<>();
for (PickPhotoItem data : mAdapter.getDatas())
{
if (data != null && data.getUrl() != null)
{
list.add(data.getUrl());
}
}
return list;
}
public void setPic(List<PickPhotoItem> list)
{
mAdapter.getDatas().clear();
mAdapter.getDatas().addAll(list);
mAdapter.notifyData();
}
@Override
public void onItemClick(View view, RecyclerView.ViewHolder holder, int position)
{
/* PickPhotoItem item = mAdapter.getDatas().get(position);
if (item == null)
{
new XPopup.Builder(Utils.mAppContext).asCustom(new BottomPopupView(mActivity == null
? mFragment.getActivity()
: mActivity)
{
@Override
protected int getImplLayoutId()
{
return R.layout.dlg_pic_choose;
}
@Override
protected void initPopupContent()
{
super.initPopupContent();
findViewById(R.id.tv_cancel).setOnClickListener(view1 -> dismiss());
findViewById(R.id.tv_shooting).setOnClickListener(v -> {
dismiss();
if (mActivity == null)
{
CaptureAndCropManager.capturePhotoFromCamera(mFragment,
CaptureAndCropManager.REQUEST_CODE_CAPTURE);
}
else
{
CaptureAndCropManager.capturePhotoFromCamera(mActivity,
CaptureAndCropManager.REQUEST_CODE_CAPTURE);
}
});
findViewById(R.id.tv_from_galley).setOnClickListener(v -> {
dismiss();
if (mActivity == null)
{
CaptureAndCropManager.capturePhotoFromGallery(mFragment,
CaptureAndCropManager.REQUEST_CODE_ALBUM);
}
else
{
CaptureAndCropManager.capturePhotoFromGallery(mActivity,
CaptureAndCropManager.REQUEST_CODE_ALBUM);
}
});
}
}).show();
mCurClickRvId = rvList.getId();
}*/
}
@Override
public boolean onItemLongClick(View view, RecyclerView.ViewHolder holder, int position)
{
return false;
}
public void onActivityResult(int requestCode, int resultCode,
@Nullable
Intent data)
{
if (mCurClickRvId != rvList.getId())
{
return;
}
if (resultCode == Activity.RESULT_OK)
{
if (mIsNeedCrop)
{
CaptureAndCropManager.setAspectX(aspectX);
CaptureAndCropManager.setAspectY(aspectY);
CaptureAndCropManager.setOutputX(outputX);
CaptureAndCropManager.setOutputY(outputY);
switch (requestCode)
{
case CaptureAndCropManager.REQUEST_CODE_CAPTURE:
if (mActivity == null)
{
CaptureAndCropManager.cropPhotoAfterCapture(mFragment,
CaptureAndCropManager.REQUEST_CODE_CROP);
}
else
{
CaptureAndCropManager.cropPhotoAfterCapture(mActivity,
CaptureAndCropManager.REQUEST_CODE_CROP);
}
break;
case CaptureAndCropManager.REQUEST_CODE_ALBUM:
if (data != null && data.getData() != null)
{
if (mActivity == null)
{
CaptureAndCropManager.cropPhotoFromUri(mFragment, data.getData(),
CaptureAndCropManager.REQUEST_CODE_CROP);
}
else
{
CaptureAndCropManager.cropPhotoFromUri(mActivity, data.getData(),
CaptureAndCropManager.REQUEST_CODE_CROP);
}
}
break;
case CaptureAndCropManager.REQUEST_CODE_CROP:
if (data != null)
{
File file = CaptureAndCropManager.getLastCropImageFile();
addItem(file);
}
mCurClickRvId = -1;
break;
}
}
else
{
switch (requestCode)
{
case CaptureAndCropManager.REQUEST_CODE_CAPTURE:
{
addItem(CaptureAndCropManager.getLastCameraCaptureImageFile());
}
break;
case CaptureAndCropManager.REQUEST_CODE_ALBUM:
if (data != null && data.getData() != null)
{
String filePath = FileUtil.getFilePathFromUri(Utils.mAppContext, data.getData());
addItem(new File(filePath));
}
break;
}
mCurClickRvId = -1;
}
}
}
private void addItem(File file)
{
/* if (!MerchantUtil.isPhotoValid(file))
{
return;
}*/
PickPhotoItem item = new PickPhotoItem();
item.setFile(file);
mAdapter.getDatas().add(item);
mAdapter.notifyData();
}
private class MyAdapter
extends CommonAdapter<PickPhotoItem>
{
MyAdapter()
{
super(Utils.mAppContext, R.layout.gv_filter_image, new LinkedList<>());
}
void notifyData()
{
if (getItemCount() > mMaxPhotoNum)
{
getDatas().remove(null);
/* tvPhotoNum.setText(
AppActivityManager.topContext().getString(mPhotoNumTipsRes, mMaxPhotoNum, mMaxPhotoNum));*/
}
else
{
getDatas().remove(null);
getDatas().add(null);
/* tvPhotoNum.setText(
AppActivityManager.topContext().getString(mPhotoNumTipsRes, getItemCount() - 1,
mMaxPhotoNum));*/
}
notifyDataSetChanged();
}
@Override
protected void convert(ViewHolder holder, PickPhotoItem s, int position)
{
View del = holder.getView(R.id.iv_del);
ImageView iv = holder.getView(R.id.fiv);
if (s == null)
{
//iv.setImageResource(R.mipmap.pic_mine_add);
del.setVisibility(View.INVISIBLE);
}
else
{
del.setVisibility(View.VISIBLE);
if (TextUtils.isEmpty(s.getUrl()))
{
//ImageUtil.loadImg(Utils.mAppContext, s.getFile(), iv);
}
else
{
//ImageUtil.loadImg(Utils.mAppContext, TencentCosUtil.getUrl(s.getUrl()), iv);
}
}
del.setTag(position);
del.setOnClickListener(this::onDel);
}
private void onDel(View view)
{
int position = (int) view.getTag();
mAdapter.getDatas().remove(position);
mAdapter.notifyData();
}
}
}
package cn.dankal.basiclib.image;
import java.io.File;
// file和url是互斥的
public class PickPhotoItem
{
private File file;
private String url; // url优先
public PickPhotoItem()
{
}
public PickPhotoItem(String url)
{
this.url = url;
}
public String getUrl()
{
return url;
}
public void setUrl(String url)
{
this.url = url;
file = null;
}
public File getFile()
{
return file;
}
public void setFile(File file)
{
this.file = file;
url = null;
}
}
package cn.dankal.basiclib.image;
import android.app.ActivityManager;
import android.content.Context;
import android.os.Build;
import android.view.View;
import com.alibaba.fastjson.JSON;
import com.facebook.stetho.common.LogUtil;
import java.util.Collection;
import java.util.List;
import cn.dankal.client.BuildConfig;
public final class Utils
{
private static final String TAG = "Utils";
public static Context mAppContext;
public static final boolean isRelease;
static
{
isRelease = Constants.RELEASE.equals(BuildConfig.BUILD_TYPE);
}
public static <E> boolean isEmpty(Collection<E> e)
{
return e == null || e.isEmpty();
}
public static String getStackTrace()
{
StackTraceElement[] stackTraceElements = (new Throwable()).getStackTrace();
if (stackTraceElements != null && stackTraceElements.length != 0)
{
StringBuilder builder = new StringBuilder();
for (int i = stackTraceElements.length - 1; i >= 0; i--)
{
StackTraceElement stackTraceElement = stackTraceElements[i];
builder.append("fileName=").append(stackTraceElement.getFileName());
builder.append("\n");
builder.append("info=").append(stackTraceElement.getClassName()).append(
" - ").append(stackTraceElement.getMethodName());
builder.append("\n");
builder.append("\n");
}
return builder.toString();
}
return "getStackTrace";
}
/**
* 取得Json解析的结果
*
* @param jsonString Json格式的字符串
* @param classT 相应的JavaBean类
* @return 返回相应的JavaBean类实例,解析失败,返回null,是控制台上输出出错结果,不是Log
*/
public static <T> T getJsonParseResult(String jsonString, Class<T> classT)
{
T t = null;
try
{
t = JSON.parseObject(jsonString, classT);
}
catch (Exception e)
{
LogUtil.e(TAG, "###JSON解析出错,类名:" + classT.getName() + "###,字符串是:" + jsonString);
e.printStackTrace();
}
return t;
}
/**
* @return JSON数组解析
*/
public static <T> List<T> getJsonParseArrayResult(String jsonString, Class<T> classT)
{
List<T> t = null;
try
{
t = JSON.parseArray(jsonString, classT);
}
catch (Exception e)
{
LogUtil.e(TAG, "###JSON数组解析出错,类名:" + classT.getName() + "###,字符串是:" + jsonString);
e.printStackTrace();
}
return t;
}
public static boolean isNeedCheckPermission()
{
return Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1;
}
// 头部补0
public static String headReplenishZero(String src, int targetLen)
{
if (src.length() >= targetLen)
{
return src;
}
StringBuilder builder = new StringBuilder();
for (int i = 0; i < targetLen - src.length(); i++)
{
builder.append("0");
}
builder.append(src);
return builder.toString();
}
// 尾部补0
public static String tailReplenishZero(String src, int targetLen)
{
int len = src.length();
if (len == targetLen)
{
return src;
}
for (int i = 0; i < targetLen - len; i++)
{
src = src.concat("0");
}
return src;
}
/**
* 根据手机的分辨率从 dp 的单位 转成为 px(像素)
*/
public static int dip2px(float dpValue)
{
return (int) (dpValue * Utils.mAppContext.getResources().getDisplayMetrics().density + 0.5f);
}
/**
* 根据手机的分辨率从 px(像素) 的单位 转成为 dp
*/
public static int px2dip(float pxValue)
{
return (int) (pxValue / Utils.mAppContext.getResources().getDisplayMetrics().density + 0.5f);
}
public static int[] measureView(View view)
{
int[] arr = new int[2];
int spec = View.MeasureSpec.makeMeasureSpec(View.MeasureSpec.UNSPECIFIED,
View.MeasureSpec.UNSPECIFIED);
view.measure(spec, spec);
arr[0] = view.getMeasuredWidth();
arr[1] = view.getMeasuredHeight();
return arr;
}
/**
* 判断服务是否启动, 注意只要名称相同, 会检测任何服务.
*
* @param context 上下文
* @param serviceClass 服务类
* @return 是否启动服务
*/
public static boolean isServiceRunning(Context context, Class<?> serviceClass)
{
if (context == null)
{
return false;
}
Context appContext = context.getApplicationContext();
ActivityManager manager = (ActivityManager) appContext.getSystemService(
Context.ACTIVITY_SERVICE);
if (manager != null)
{
List<ActivityManager.RunningServiceInfo> infos = manager.getRunningServices(
Integer.MAX_VALUE);
if (infos != null && !infos.isEmpty())
{
for (ActivityManager.RunningServiceInfo service : infos)
{
// 添加Uid验证, 防止服务重名, 当前服务无法启动
if (getUid(context) == service.uid)
{
if (serviceClass.getName().equals(service.service.getClassName()))
{
return true;
}
}
}
}
}
return false;
}
/**
* 获取应用的Uid, 用于验证服务是否启动
*
* @param context 上下文
* @return uid
*/
public static int getUid(Context context)
{
if (context == null)
{
return -1;
}
int pid = android.os.Process.myPid();
ActivityManager manager = (ActivityManager) context.getSystemService(
Context.ACTIVITY_SERVICE);
if (manager != null)
{
List<ActivityManager.RunningAppProcessInfo> infos = manager.getRunningAppProcesses();
if (infos != null && !infos.isEmpty())
{
for (ActivityManager.RunningAppProcessInfo processInfo : infos)
{
if (processInfo.pid == pid)
{
return processInfo.uid;
}
}
}
}
return -1;
}
}
package cn.dankal.client.adapter.shop;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.sdk.glide.Glide;
import com.sdk.glide.load.engine.DiskCacheStrategy;
import com.sdk.glide.request.RequestOptions;
import java.util.ArrayList;
import java.util.List;
import cn.dankal.basiclib.ModooApplication;
import cn.dankal.client.R;
/**
* Created by zhengpeng on 2019/5/13.
*/
public class GridImageNewAdapter extends
RecyclerView.Adapter<GridImageNewAdapter.ViewHolder> {
public static final int TYPE_CAMERA = 1;
public static final int TYPE_PICTURE = 2;
private LayoutInflater mInflater;
private List<String> list = new ArrayList<>();
private int selectMax = 9;
private Context context;
/**
* 클릭 하여 이미지 전송 추가
*/
private onAddPicClickListener mOnAddPicClickListener;
public interface onAddPicClickListener {
void onAddPicClick();
void onDelete();
}
public GridImageNewAdapter(Context context, onAddPicClickListener mOnAddPicClickListener) {
this.context = context;
mInflater = LayoutInflater.from(context);
this.mOnAddPicClickListener = mOnAddPicClickListener;
}
public void setSelectMax(int selectMax) {
this.selectMax = selectMax;
}
public void setList(List<String> list) {
this.list = list;
}
public class ViewHolder extends RecyclerView.ViewHolder {
ImageView mImg;
LinearLayout ll_del;
TextView tv_duration;
TextView tvTip;
public ViewHolder(View view) {
super(view);
mImg = (ImageView) view.findViewById(R.id.fiv);
ll_del = (LinearLayout) view.findViewById(R.id.ll_del);
tv_duration = (TextView) view.findViewById(R.id.tv_duration);
tvTip = view.findViewById(R.id.tv_tip_text);
}
}
@Override
public int getItemCount() {
if (list.size() < selectMax) {
return list.size() + 1;
} else {
return list.size();
}
}
@Override
public int getItemViewType(int position) {
if (isShowAddItem(position)) {
return TYPE_CAMERA;
} else {
return TYPE_PICTURE;
}
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View view = mInflater.inflate(R.layout.gv_filter_image,
viewGroup, false);
final ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
private boolean isShowAddItem(int position) {
int size = list.size() == 0 ? 0 : list.size();
return position == size;
}
/**
* 설정 값
*/
@Override
public void onBindViewHolder(final ViewHolder viewHolder, final int position) {
//8 장 미 만, 추가 아이콘 보이 기
if (getItemViewType(position) == TYPE_CAMERA) {
if (ModooApplication.isDarkMode()){
viewHolder.mImg.setImageResource(R.mipmap.ic_evaluation_increase);
}else {
viewHolder.mImg.setImageResource(R.mipmap.ic_evaluation_increase_s);
}
viewHolder.mImg.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mOnAddPicClickListener.onAddPicClick();
}
});
viewHolder.ll_del.setVisibility(View.INVISIBLE);
viewHolder.tvTip.setVisibility(View.VISIBLE);
} else {
viewHolder.tvTip.setVisibility(View.GONE);
viewHolder.ll_del.setVisibility(View.VISIBLE);
viewHolder.ll_del.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int index = viewHolder.getAdapterPosition();
//여 기 는 가끔 - 1 로 데이터 가 아래로 넘 어 갈 수 있 습 니 다. 구체 적 으로 getAdapterPosition () 소스 코드 를 참고 하 십시오.
if (index != RecyclerView.NO_POSITION) {
list.remove(index);
mOnAddPicClickListener.onDelete();
notifyItemRemoved(index);
notifyItemRangeChanged(index, list.size());
}
}
});
RequestOptions options = new RequestOptions()
.centerCrop()
.placeholder(R.color.white)
.diskCacheStrategy(DiskCacheStrategy.ALL);
Glide.with(viewHolder.itemView.getContext())
.load(list.get(position))
.apply(options)
.into(viewHolder.mImg);
// }
if (mItemClickListener != null) {
viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int adapterPosition = viewHolder.getAdapterPosition();
mItemClickListener.onItemClick(adapterPosition, v);
}
});
}
}
}
protected OnItemClickListener mItemClickListener;
public interface OnItemClickListener {
void onItemClick(int position, View v);
}
public void setOnItemClickListener(OnItemClickListener listener) {
this.mItemClickListener = listener;
}
}
......@@ -2,57 +2,46 @@ package cn.dankal.client.ui.personal.order.food
import android.app.Activity
import android.content.Intent
import android.graphics.Paint
import android.os.Bundle
import android.support.v4.app.Fragment
import android.support.design.widget.BottomSheetDialog
import android.support.v4.content.ContextCompat
import android.support.v7.widget.AppCompatButton
import android.support.v7.widget.GridLayoutManager
import android.text.Editable
import android.text.TextUtils
import android.text.TextWatcher
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import cn.dankal.basiclib.api.RestaurantServiceFactory
import cn.dankal.basiclib.api.UserServiceFactory
import cn.dankal.basiclib.base.activity.BaseActivity
import cn.dankal.basiclib.base.activity.BigPhotoActivity
import cn.dankal.basiclib.base.callback.DKCallBackBoolean
import cn.dankal.basiclib.base.fragmentactivity.FragmentAdapter
import cn.dankal.basiclib.cos.CosUploadUtil
import cn.dankal.basiclib.image.CaptureAndCropManager
import cn.dankal.basiclib.rx.AbstractDialogSubscriber
import cn.dankal.basiclib.util.ButtonUtil
import cn.dankal.basiclib.util.ToastUtils
import cn.dankal.basiclib.util.WebViewUtil
import cn.dankal.basiclib.util.image.PicUtils
import cn.dankal.basiclib.widget.FullyGridLayoutManager
import cn.dankal.entities.home.EvaluationCommitEntity
import cn.dankal.entities.personal.OrderHotelDetail
import cn.dankal.client.R
import cn.dankal.client.adapter.shop.GridImageAdapter
import cn.dankal.client.constants.ConstantsShopType
import cn.dankal.client.ui.shop.DetailsMerchantFragment
import cn.dankal.client.ui.shop.MerchantInfoFragment
import cn.dankal.client.util.UIUtile
import cn.dankal.client.adapter.shop.GridImageNewAdapter
import cn.dankal.entities.home.EvaluationCommitEntity
import cn.dankal.entities.home.RestaurantDetailEntity
import cn.dankal.entities.shop.MerchantHomeEntity
import cn.dankal.entities.shop.ShopDetailEntity
import com.luck.picture.lib.PictureSelector
import com.luck.picture.lib.config.PictureConfig
import com.luck.picture.lib.config.PictureMimeType
import cn.dankal.entities.personal.OrderHotelDetail
import com.luck.picture.lib.entity.LocalMedia
import io.reactivex.rxjava3.disposables.Disposable
import kotlinx.android.synthetic.main.activity_food_evaluation.*
import kotlinx.android.synthetic.main.activity_merchant_home.*
import okhttp3.ResponseBody
import java.io.Serializable
/**
* 식당 평가
*/
class FoodEvaluationActivity : BaseActivity(), GridImageAdapter.onAddPicClickListener, View.OnClickListener {
class FoodEvaluationActivity : BaseActivity(), GridImageNewAdapter.onAddPicClickListener, View.OnClickListener {
private var listImage = mutableListOf<String>()//제출 해 야 할 댓 글 사진, 텐 센트 클 라 우 드 에 올 려 주세요.
private var commitListImage = mutableListOf<String>()//매개 변수 로 올 린 이미지
private lateinit var mBottomDialog: BottomSheetDialog
override fun onClick(v: View?) {
var content = et_feedback.text.toString().trim()
......@@ -110,32 +99,16 @@ class FoodEvaluationActivity : BaseActivity(), GridImageAdapter.onAddPicClickLis
})
}
private var adapter: GridImageAdapter? = null
private var adapter: GridImageNewAdapter? = null
private var selectList: List<LocalMedia> = ArrayList<LocalMedia>()
private var themeId = R.style.picture_default_style
private var orderId: String? = ""
override fun onDelete() {
tv_img_count.text = "(${listImage.size}/6)"
}
override fun onAddPicClick() {
PictureSelector.create(this@FoodEvaluationActivity)
.openGallery(PictureMimeType.ofImage())
.theme(themeId)
.maxSelectNum(6)
.minSelectNum(1)
.imageSpanCount(4)
.selectionMode(PictureConfig.MULTIPLE)
.previewImage(true)
.isCamera(true)
.isZoomAnim(true)
//.imageFormat(PictureMimeType.PNG)
//.setOutputCameraPath("/CustomPath")
.enableCrop(false)
.compress(true)
.synOrAsy(true)
.glideOverride(160, 160)
.freeStyleCropEnabled(true)
.selectionMedia(selectList)
.minimumCompressSize(100)
.forResult(PictureConfig.CHOOSE_REQUEST)
mBottomDialog.show()
}
override fun getLayoutId(): Int {
......@@ -171,10 +144,29 @@ class FoodEvaluationActivity : BaseActivity(), GridImageAdapter.onAddPicClickLis
tv_btn_commit.setOnClickListener(this)
mBottomDialog = BottomSheetDialog(this)
val bottomView = LayoutInflater.from(this).inflate(R.layout.dialog_photo_picker, null)
bottomView.findViewById<AppCompatButton>(R.id.photodialog_btn_take).setOnClickListener {
CaptureAndCropManager.capturePhotoFromCamera(this,
CaptureAndCropManager.REQUEST_CODE_CAPTURE)
mBottomDialog.dismiss()
}
bottomView.findViewById<AppCompatButton>(R.id.photodialog_btn_native).setOnClickListener {
CaptureAndCropManager.capturePhotoFromGallery(this,
CaptureAndCropManager.REQUEST_CODE_ALBUM)
mBottomDialog.dismiss()
}
bottomView.findViewById<AppCompatButton>(R.id.photodialog_btn_cancel).setOnClickListener {
mBottomDialog.dismiss()
}
mBottomDialog.setContentView(bottomView)
val manager = FullyGridLayoutManager(this@FoodEvaluationActivity, 4, GridLayoutManager.VERTICAL, false)
rv_add_picture.layoutManager = manager
adapter = GridImageAdapter(this, this)
adapter = GridImageNewAdapter(this, this)
rv_add_picture.adapter = adapter
}
/**
......@@ -202,53 +194,36 @@ class FoodEvaluationActivity : BaseActivity(), GridImageAdapter.onAddPicClickLis
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == Activity.RESULT_OK) {
when (requestCode) {
PictureConfig.CHOOSE_REQUEST -> {
if (data == null) {
return
}
// 이미지 선택 결과 반전
selectList = PictureSelector.obtainMultipleResult(data)
if (selectList != null) {
tv_img_count.text = "上传图片(${selectList.size}/6)"
listImage.clear()
commitListImage.clear()
for (i in 0 until selectList.size) {
val media = selectList.get(i)
var path = ""
path = if (media.isCut && !media.isCompressed) {
// 재단 한 적 이 있다
media.cutPath
} else if (media.isCompressed || media.isCut && media.isCompressed) {
// 압축 한 적 이 있 거나, 재단 과 동시에 압축 한 적 이 있 으 며, 최종 적 으로 그림 을 압축 한 적 이 있 는 것 을 기준 으로 한다.
media.compressPath
} else {
// 원 도
media.path
}
if (path == "") {
return
}
listImage.add(path)
val avatar = path.substring(path.lastIndexOf("/") + 1)
commitListImage.add(avatar)
CaptureAndCropManager.REQUEST_CODE_CAPTURE -> {
CaptureAndCropManager.cropPhotoAfterCapture(this,
CaptureAndCropManager.REQUEST_CODE_CROP)
}
CaptureAndCropManager.REQUEST_CODE_ALBUM -> if (data != null && data.data != null) {
CaptureAndCropManager.cropPhotoFromUri(this, data.data,
CaptureAndCropManager.REQUEST_CODE_CROP)
}
CaptureAndCropManager.REQUEST_CODE_CROP -> {
if (data != null) {
val file = CaptureAndCropManager.getLastCropImageFile()
var path = file.path
listImage.add(path)
val avatar = path.substring(path.lastIndexOf("/") + 1)
commitListImage.add(avatar)
tv_img_count.text = "(${listImage.size}/6)"
adapter?.let {
it.setList(listImage)
it.notifyDataSetChanged()
}
}
adapter?.let {
it.setList(selectList)
it.notifyDataSetChanged()
}
}
}
}
}
}
package com.zhy.adapter.recyclerview;
import android.content.Context;
import android.view.LayoutInflater;
import com.zhy.adapter.recyclerview.base.ItemViewDelegate;
import com.zhy.adapter.recyclerview.base.ViewHolder;
import java.util.List;
/**
* Created by zhy on 16/4/9.
*/
public abstract class CommonAdapter<T> extends MultiItemTypeAdapter<T>
{
protected Context mContext;
protected int mLayoutId;
protected List<T> mDatas;
protected LayoutInflater mInflater;
public CommonAdapter(final Context context, final int layoutId, List<T> datas)
{
super(context, datas);
mContext = context;
mInflater = LayoutInflater.from(context);
mLayoutId = layoutId;
mDatas = datas;
addItemViewDelegate(new ItemViewDelegate<T>()
{
@Override
public int getItemViewLayoutId()
{
return layoutId;
}
@Override
public boolean isForViewType( T item, int position)
{
return true;
}
@Override
public void convert(ViewHolder holder, T t, int position)
{
CommonAdapter.this.convert(holder, t, position);
}
});
}
protected abstract void convert(ViewHolder holder, T t, int position);
}
package com.zhy.adapter.recyclerview;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import com.zhy.adapter.recyclerview.base.ItemViewDelegate;
import com.zhy.adapter.recyclerview.base.ItemViewDelegateManager;
import com.zhy.adapter.recyclerview.base.ViewHolder;
import java.util.List;
import cn.dankal.client.R;
/**
* Created by zhy on 16/4/9.
*/
public class MultiItemTypeAdapter<T> extends RecyclerView.Adapter<ViewHolder> {
protected Context mContext;
protected List<T> mDatas;
protected ItemViewDelegateManager mItemViewDelegateManager;
protected OnItemClickListener mOnItemClickListener;
private View.OnClickListener mOnClickListener;
private View.OnLongClickListener mOnLongClickListener;
public MultiItemTypeAdapter(Context context, List<T> datas) {
mContext = context;
mDatas = datas;
mItemViewDelegateManager = new ItemViewDelegateManager();
mOnClickListener = new View.OnClickListener()
{
@Override
public void onClick(View v)
{
if (mOnItemClickListener != null) {
int position = (int) v.getTag(R.id.tag_for_position);
RecyclerView.ViewHolder viewHolder = (RecyclerView.ViewHolder) v.getTag(
R.id.tag_for_view_holder);
mOnItemClickListener.onItemClick(v, viewHolder, position);
}
}
};
mOnLongClickListener = new View.OnLongClickListener()
{
@Override
public boolean onLongClick(View v)
{
if (mOnItemClickListener != null) {
int position = (int) v.getTag(R.id.tag_for_position);
RecyclerView.ViewHolder viewHolder = (RecyclerView.ViewHolder) v.getTag(
R.id.tag_for_view_holder);
return mOnItemClickListener.onItemLongClick(v, viewHolder, position);
}
return false;
}
};
}
@Override
public int getItemViewType(int position) {
if (!useItemViewDelegateManager()) return super.getItemViewType(position);
return mItemViewDelegateManager.getItemViewType(mDatas.get(position), position);
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(
@NonNull
ViewGroup parent, int viewType) {
ItemViewDelegate itemViewDelegate = mItemViewDelegateManager.getItemViewDelegate(viewType);
int layoutId = itemViewDelegate.getItemViewLayoutId();
ViewHolder holder = ViewHolder.createViewHolder(mContext, parent, layoutId);
onViewHolderCreated(holder,holder.getConvertView());
holder.getConvertView().setTag(R.id.tag_for_view_type, viewType);
return holder;
}
public void onViewHolderCreated(ViewHolder holder, View itemView){
}
public void convert(ViewHolder holder, T t) {
mItemViewDelegateManager.convert(holder, t, holder.getAdapterPosition());
}
protected boolean isEnabled(int viewType) {
return true;
}
@Override
public void onBindViewHolder(
@NonNull
ViewHolder holder, int position) {
View convertView = holder.getConvertView();
int viewType = (int) convertView.getTag(R.id.tag_for_view_type);
if (isEnabled(viewType))
{
convertView.setTag(R.id.tag_for_position, position);
convertView.setTag(R.id.tag_for_view_holder, holder);
convertView.setOnClickListener(mOnClickListener);
convertView.setOnLongClickListener(mOnLongClickListener);
}
else
{
convertView.setOnClickListener(null);
convertView.setOnLongClickListener(null);
}
convert(holder, mDatas.get(position));
}
@Override
public int getItemCount() {
int itemCount = mDatas.size();
return itemCount;
}
public List<T> getDatas() {
return mDatas;
}
public MultiItemTypeAdapter addItemViewDelegate(ItemViewDelegate<T> itemViewDelegate) {
mItemViewDelegateManager.addDelegate(itemViewDelegate);
return this;
}
public MultiItemTypeAdapter addItemViewDelegate(int viewType, ItemViewDelegate<T> itemViewDelegate) {
mItemViewDelegateManager.addDelegate(viewType, itemViewDelegate);
return this;
}
protected boolean useItemViewDelegateManager() {
return mItemViewDelegateManager.getItemViewDelegateCount() > 0;
}
public interface OnItemClickListener {
void onItemClick(View view, RecyclerView.ViewHolder holder, int position);
boolean onItemLongClick(View view, RecyclerView.ViewHolder holder, int position);
}
public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
this.mOnItemClickListener = onItemClickListener;
}
}
package com.zhy.adapter.recyclerview.base;
/**
* Created by zhy on 16/6/22.
*/
public interface ItemViewDelegate<T>
{
int getItemViewLayoutId();
boolean isForViewType(T item, int position);
void convert(ViewHolder holder, T t, int position);
}
package com.zhy.adapter.recyclerview.base;
import android.support.v4.util.SparseArrayCompat;
/**
* Created by zhy on 16/6/22.
*/
public class ItemViewDelegateManager<T>
{
SparseArrayCompat<ItemViewDelegate<T>> delegates = new SparseArrayCompat<>();
public int getItemViewDelegateCount()
{
return delegates.size();
}
public ItemViewDelegateManager<T> addDelegate(ItemViewDelegate<T> delegate)
{
int viewType = delegates.size();
if (delegate != null)
{
delegates.put(viewType, delegate);
viewType++;
}
return this;
}
public ItemViewDelegateManager<T> addDelegate(int viewType, ItemViewDelegate<T> delegate)
{
if (delegates.get(viewType) != null)
{
throw new IllegalArgumentException(
"An ItemViewDelegate is already registered for the viewType = "
+ viewType
+ ". Already registered ItemViewDelegate is "
+ delegates.get(viewType));
}
delegates.put(viewType, delegate);
return this;
}
public ItemViewDelegateManager<T> removeDelegate(ItemViewDelegate<T> delegate)
{
if (delegate == null)
{
throw new NullPointerException("ItemViewDelegate is null");
}
int indexToRemove = delegates.indexOfValue(delegate);
if (indexToRemove >= 0)
{
delegates.removeAt(indexToRemove);
}
return this;
}
public ItemViewDelegateManager<T> removeDelegate(int itemType)
{
int indexToRemove = delegates.indexOfKey(itemType);
if (indexToRemove >= 0)
{
delegates.removeAt(indexToRemove);
}
return this;
}
public int getItemViewType(T item, int position)
{
int delegatesCount = delegates.size();
for (int i = delegatesCount - 1; i >= 0; i--)
{
ItemViewDelegate<T> delegate = delegates.valueAt(i);
if (delegate.isForViewType( item, position))
{
return delegates.keyAt(i);
}
}
throw new IllegalArgumentException(
"No ItemViewDelegate added that matches position=" + position + " in data source");
}
public void convert(ViewHolder holder, T item, int position)
{
int delegatesCount = delegates.size();
for (int i = 0; i < delegatesCount; i++)
{
ItemViewDelegate<T> delegate = delegates.valueAt(i);
if (delegate.isForViewType( item, position))
{
delegate.convert(holder, item, position);
return;
}
}
throw new IllegalArgumentException(
"No ItemViewDelegateManager added that matches position=" + position + " in data source");
}
public ItemViewDelegate getItemViewDelegate(int viewType)
{
return delegates.get(viewType);
}
public int getItemViewLayoutId(int viewType)
{
return getItemViewDelegate(viewType).getItemViewLayoutId();
}
public int getItemViewType(ItemViewDelegate itemViewDelegate)
{
return delegates.indexOfValue(itemViewDelegate);
}
}
package com.zhy.adapter.recyclerview.base;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.support.v7.widget.RecyclerView;
import android.text.util.Linkify;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AlphaAnimation;
import android.widget.Checkable;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.RatingBar;
import android.widget.TextView;
public class ViewHolder extends RecyclerView.ViewHolder
{
private SparseArray<View> mViews;
private View mConvertView;
private Context mContext;
public ViewHolder(Context context, View itemView)
{
super(itemView);
mContext = context;
mConvertView = itemView;
mViews = new SparseArray<View>();
}
public static ViewHolder createViewHolder(Context context, View itemView)
{
ViewHolder holder = new ViewHolder(context, itemView);
return holder;
}
public static ViewHolder createViewHolder(Context context,
ViewGroup parent, int layoutId)
{
View itemView = LayoutInflater.from(context).inflate(layoutId, parent,
false);
ViewHolder holder = new ViewHolder(context, itemView);
return holder;
}
/**
* 通过viewId获取控件
*
* @param viewId
* @return
*/
public <T extends View> T getView(int viewId)
{
View view = mViews.get(viewId);
if (view == null)
{
view = mConvertView.findViewById(viewId);
mViews.put(viewId, view);
}
return (T) view;
}
public View getConvertView()
{
return mConvertView;
}
/****以下为辅助方法*****/
/**
* 设置TextView的值
*
* @param viewId
* @param text
* @return
*/
public ViewHolder setText(int viewId, String text)
{
TextView tv = getView(viewId);
tv.setText(text);
return this;
}
public ViewHolder setImageResource(int viewId, int resId)
{
ImageView view = getView(viewId);
view.setImageResource(resId);
return this;
}
public ViewHolder setImageBitmap(int viewId, Bitmap bitmap)
{
ImageView view = getView(viewId);
view.setImageBitmap(bitmap);
return this;
}
public ViewHolder setImageDrawable(int viewId, Drawable drawable)
{
ImageView view = getView(viewId);
view.setImageDrawable(drawable);
return this;
}
public ViewHolder setBackgroundColor(int viewId, int color)
{
View view = getView(viewId);
view.setBackgroundColor(color);
return this;
}
public ViewHolder setBackgroundRes(int viewId, int backgroundRes)
{
View view = getView(viewId);
view.setBackgroundResource(backgroundRes);
return this;
}
public ViewHolder setTextColor(int viewId, int textColor)
{
TextView view = getView(viewId);
view.setTextColor(textColor);
return this;
}
public ViewHolder setTextColorRes(int viewId, int textColorRes)
{
TextView view = getView(viewId);
view.setTextColor(mContext.getResources().getColor(textColorRes));
return this;
}
@SuppressLint("NewApi")
public ViewHolder setAlpha(int viewId, float value)
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
{
getView(viewId).setAlpha(value);
} else
{
// Pre-honeycomb hack to set Alpha value
AlphaAnimation alpha = new AlphaAnimation(value, value);
alpha.setDuration(0);
alpha.setFillAfter(true);
getView(viewId).startAnimation(alpha);
}
return this;
}
public ViewHolder setVisible(int viewId, boolean visible)
{
View view = getView(viewId);
view.setVisibility(visible ? View.VISIBLE : View.GONE);
return this;
}
public ViewHolder linkify(int viewId)
{
TextView view = getView(viewId);
Linkify.addLinks(view, Linkify.ALL);
return this;
}
public ViewHolder setTypeface(Typeface typeface, int... viewIds)
{
for (int viewId : viewIds)
{
TextView view = getView(viewId);
view.setTypeface(typeface);
view.setPaintFlags(view.getPaintFlags() | Paint.SUBPIXEL_TEXT_FLAG);
}
return this;
}
public ViewHolder setProgress(int viewId, int progress)
{
ProgressBar view = getView(viewId);
view.setProgress(progress);
return this;
}
public ViewHolder setProgress(int viewId, int progress, int max)
{
ProgressBar view = getView(viewId);
view.setMax(max);
view.setProgress(progress);
return this;
}
public ViewHolder setMax(int viewId, int max)
{
ProgressBar view = getView(viewId);
view.setMax(max);
return this;
}
public ViewHolder setRating(int viewId, float rating)
{
RatingBar view = getView(viewId);
view.setRating(rating);
return this;
}
public ViewHolder setRating(int viewId, float rating, int max)
{
RatingBar view = getView(viewId);
view.setMax(max);
view.setRating(rating);
return this;
}
public ViewHolder setTag(int viewId, Object tag)
{
View view = getView(viewId);
view.setTag(tag);
return this;
}
public ViewHolder setTag(int viewId, int key, Object tag)
{
View view = getView(viewId);
view.setTag(key, tag);
return this;
}
public ViewHolder setChecked(int viewId, boolean checked)
{
Checkable view = (Checkable) getView(viewId);
view.setChecked(checked);
return this;
}
/**
* 关于事件的
*/
public ViewHolder setOnClickListener(int viewId,
View.OnClickListener listener)
{
View view = getView(viewId);
view.setOnClickListener(listener);
return this;
}
public ViewHolder setOnTouchListener(int viewId,
View.OnTouchListener listener)
{
View view = getView(viewId);
view.setOnTouchListener(listener);
return this;
}
public ViewHolder setOnLongClickListener(int viewId,
View.OnLongClickListener listener)
{
View view = getView(viewId);
view.setOnLongClickListener(listener);
return this;
}
}
package com.zhy.adapter.recyclerview.utils;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.view.ViewGroup;
/**
* Created by zhy on 16/6/28.
*/
public class WrapperUtils
{
public interface SpanSizeCallback
{
int getSpanSize(GridLayoutManager layoutManager , GridLayoutManager.SpanSizeLookup oldLookup, int position);
}
public static void onAttachedToRecyclerView(RecyclerView.Adapter innerAdapter, RecyclerView recyclerView, final SpanSizeCallback callback)
{
innerAdapter.onAttachedToRecyclerView(recyclerView);
RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
if (layoutManager instanceof GridLayoutManager)
{
final GridLayoutManager gridLayoutManager = (GridLayoutManager) layoutManager;
final GridLayoutManager.SpanSizeLookup spanSizeLookup = gridLayoutManager.getSpanSizeLookup();
gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup()
{
@Override
public int getSpanSize(int position)
{
return callback.getSpanSize(gridLayoutManager, spanSizeLookup, position);
}
});
gridLayoutManager.setSpanCount(gridLayoutManager.getSpanCount());
}
}
public static void setFullSpan(RecyclerView.ViewHolder holder)
{
ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams();
if (lp != null
&& lp instanceof StaggeredGridLayoutManager.LayoutParams)
{
StaggeredGridLayoutManager.LayoutParams p = (StaggeredGridLayoutManager.LayoutParams) lp;
p.setFullSpan(true);
}
}
}
package com.zhy.adapter.recyclerview.wrapper;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import com.zhy.adapter.recyclerview.base.ViewHolder;
import com.zhy.adapter.recyclerview.utils.WrapperUtils;
/**
* Created by zhy on 16/6/23.
*/
public class EmptyWrapper<T> extends RecyclerView.Adapter<RecyclerView.ViewHolder>
{
public static final int ITEM_TYPE_EMPTY = Integer.MAX_VALUE - 1;
private RecyclerView.Adapter mInnerAdapter;
private View mEmptyView;
private int mEmptyLayoutId;
public EmptyWrapper(RecyclerView.Adapter adapter)
{
mInnerAdapter = adapter;
}
private boolean isEmpty()
{
return (mEmptyView != null || mEmptyLayoutId != 0) && mInnerAdapter.getItemCount() == 0;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
if (isEmpty())
{
ViewHolder holder;
if (mEmptyView != null)
{
holder = ViewHolder.createViewHolder(parent.getContext(), mEmptyView);
} else
{
holder = ViewHolder.createViewHolder(parent.getContext(), parent, mEmptyLayoutId);
}
return holder;
}
return mInnerAdapter.onCreateViewHolder(parent, viewType);
}
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView)
{
WrapperUtils.onAttachedToRecyclerView(mInnerAdapter, recyclerView, new WrapperUtils.SpanSizeCallback()
{
@Override
public int getSpanSize(GridLayoutManager gridLayoutManager, GridLayoutManager.SpanSizeLookup oldLookup, int position)
{
if (isEmpty())
{
return gridLayoutManager.getSpanCount();
}
if (oldLookup != null)
{
return oldLookup.getSpanSize(position);
}
return 1;
}
});
}
@Override
public void onViewAttachedToWindow(RecyclerView.ViewHolder holder)
{
mInnerAdapter.onViewAttachedToWindow(holder);
if (isEmpty())
{
WrapperUtils.setFullSpan(holder);
}
}
@Override
public int getItemViewType(int position)
{
if (isEmpty())
{
return ITEM_TYPE_EMPTY;
}
return mInnerAdapter.getItemViewType(position);
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
if (isEmpty())
{
return;
}
mInnerAdapter.onBindViewHolder(holder, position);
}
@Override
public int getItemCount()
{
if (isEmpty()) return 1;
return mInnerAdapter.getItemCount();
}
public void setEmptyView(View emptyView)
{
mEmptyView = emptyView;
}
public void setEmptyView(int layoutId)
{
mEmptyLayoutId = layoutId;
}
}
package com.zhy.adapter.recyclerview.wrapper;
import android.support.v4.util.SparseArrayCompat;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import com.zhy.adapter.recyclerview.base.ViewHolder;
import com.zhy.adapter.recyclerview.utils.WrapperUtils;
/**
* Created by zhy on 16/6/23.
*/
public class HeaderAndFooterWrapper<T> extends RecyclerView.Adapter<RecyclerView.ViewHolder>
{
private static final int BASE_ITEM_TYPE_HEADER = 100000;
private static final int BASE_ITEM_TYPE_FOOTER = 200000;
private SparseArrayCompat<View> mHeaderViews = new SparseArrayCompat<>();
private SparseArrayCompat<View> mFootViews = new SparseArrayCompat<>();
private RecyclerView.Adapter mInnerAdapter;
public HeaderAndFooterWrapper(RecyclerView.Adapter adapter)
{
mInnerAdapter = adapter;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
if (mHeaderViews.get(viewType) != null)
{
ViewHolder holder = ViewHolder.createViewHolder(parent.getContext(), mHeaderViews.get(viewType));
return holder;
} else if (mFootViews.get(viewType) != null)
{
ViewHolder holder = ViewHolder.createViewHolder(parent.getContext(), mFootViews.get(viewType));
return holder;
}
return mInnerAdapter.onCreateViewHolder(parent, viewType);
}
@Override
public int getItemViewType(int position)
{
if (isHeaderViewPos(position))
{
return mHeaderViews.keyAt(position);
} else if (isFooterViewPos(position))
{
return mFootViews.keyAt(position - getHeadersCount() - getRealItemCount());
}
return mInnerAdapter.getItemViewType(position - getHeadersCount());
}
private int getRealItemCount()
{
return mInnerAdapter.getItemCount();
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
if (isHeaderViewPos(position))
{
return;
}
if (isFooterViewPos(position))
{
return;
}
mInnerAdapter.onBindViewHolder(holder, position - getHeadersCount());
}
@Override
public int getItemCount()
{
return getHeadersCount() + getFootersCount() + getRealItemCount();
}
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView)
{
WrapperUtils.onAttachedToRecyclerView(mInnerAdapter, recyclerView, new WrapperUtils.SpanSizeCallback()
{
@Override
public int getSpanSize(GridLayoutManager layoutManager, GridLayoutManager.SpanSizeLookup oldLookup, int position)
{
int viewType = getItemViewType(position);
if (mHeaderViews.get(viewType) != null)
{
return layoutManager.getSpanCount();
} else if (mFootViews.get(viewType) != null)
{
return layoutManager.getSpanCount();
}
if (oldLookup != null)
return oldLookup.getSpanSize(position);
return 1;
}
});
}
@Override
public void onViewAttachedToWindow(RecyclerView.ViewHolder holder)
{
mInnerAdapter.onViewAttachedToWindow(holder);
int position = holder.getLayoutPosition();
if (isHeaderViewPos(position) || isFooterViewPos(position))
{
WrapperUtils.setFullSpan(holder);
}
}
private boolean isHeaderViewPos(int position)
{
return position < getHeadersCount();
}
private boolean isFooterViewPos(int position)
{
return position >= getHeadersCount() + getRealItemCount();
}
public void addHeaderView(View view)
{
mHeaderViews.put(mHeaderViews.size() + BASE_ITEM_TYPE_HEADER, view);
}
public void addFootView(View view)
{
mFootViews.put(mFootViews.size() + BASE_ITEM_TYPE_FOOTER, view);
}
public int getHeadersCount()
{
return mHeaderViews.size();
}
public int getFootersCount()
{
return mFootViews.size();
}
}
package com.zhy.adapter.recyclerview.wrapper;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.view.View;
import android.view.ViewGroup;
import com.zhy.adapter.recyclerview.base.ViewHolder;
import com.zhy.adapter.recyclerview.utils.WrapperUtils;
/**
* Created by zhy on 16/6/23.
*/
public class LoadMoreWrapper<T> extends RecyclerView.Adapter<RecyclerView.ViewHolder>
{
public static final int ITEM_TYPE_LOAD_MORE = Integer.MAX_VALUE - 2;
private RecyclerView.Adapter mInnerAdapter;
private View mLoadMoreView;
private int mLoadMoreLayoutId;
public LoadMoreWrapper(RecyclerView.Adapter adapter)
{
mInnerAdapter = adapter;
}
private boolean hasLoadMore()
{
return mLoadMoreView != null || mLoadMoreLayoutId != 0;
}
private boolean isShowLoadMore(int position)
{
return hasLoadMore() && (position >= mInnerAdapter.getItemCount());
}
@Override
public int getItemViewType(int position)
{
if (isShowLoadMore(position))
{
return ITEM_TYPE_LOAD_MORE;
}
return mInnerAdapter.getItemViewType(position);
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
if (viewType == ITEM_TYPE_LOAD_MORE)
{
ViewHolder holder;
if (mLoadMoreView != null)
{
holder = ViewHolder.createViewHolder(parent.getContext(), mLoadMoreView);
} else
{
holder = ViewHolder.createViewHolder(parent.getContext(), parent, mLoadMoreLayoutId);
}
return holder;
}
return mInnerAdapter.onCreateViewHolder(parent, viewType);
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
if (isShowLoadMore(position))
{
if (mOnLoadMoreListener != null)
{
mOnLoadMoreListener.onLoadMoreRequested();
}
return;
}
mInnerAdapter.onBindViewHolder(holder, position);
}
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView)
{
WrapperUtils.onAttachedToRecyclerView(mInnerAdapter, recyclerView, new WrapperUtils.SpanSizeCallback()
{
@Override
public int getSpanSize(GridLayoutManager layoutManager, GridLayoutManager.SpanSizeLookup oldLookup, int position)
{
if (isShowLoadMore(position))
{
return layoutManager.getSpanCount();
}
if (oldLookup != null)
{
return oldLookup.getSpanSize(position);
}
return 1;
}
});
}
@Override
public void onViewAttachedToWindow(RecyclerView.ViewHolder holder)
{
mInnerAdapter.onViewAttachedToWindow(holder);
if (isShowLoadMore(holder.getLayoutPosition()))
{
setFullSpan(holder);
}
}
private void setFullSpan(RecyclerView.ViewHolder holder)
{
ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams();
if (lp != null
&& lp instanceof StaggeredGridLayoutManager.LayoutParams)
{
StaggeredGridLayoutManager.LayoutParams p = (StaggeredGridLayoutManager.LayoutParams) lp;
p.setFullSpan(true);
}
}
@Override
public int getItemCount()
{
return mInnerAdapter.getItemCount() + (hasLoadMore() ? 1 : 0);
}
public interface OnLoadMoreListener
{
void onLoadMoreRequested();
}
private OnLoadMoreListener mOnLoadMoreListener;
public LoadMoreWrapper setOnLoadMoreListener(OnLoadMoreListener loadMoreListener)
{
if (loadMoreListener != null)
{
mOnLoadMoreListener = loadMoreListener;
}
return this;
}
public LoadMoreWrapper setLoadMoreView(View loadMoreView)
{
mLoadMoreView = loadMoreView;
return this;
}
public LoadMoreWrapper setLoadMoreView(int layoutId)
{
mLoadMoreLayoutId = layoutId;
return this;
}
}
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
>
<ImageView
android:id="@+id/iv_photo"
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="centerCrop"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="@id/view"
app:layout_constraintTop_toTopOf="@id/view"
tools:src="@mipmap/ic_launcher"
/>
<ImageView
android:id="@+id/iv_del"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="@dimen/dp_5"
android:src="@mipmap/ic_successful"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
<View
android:id="@+id/view"
android:layout_width="1px"
android:layout_height="1px"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="@id/iv_del"
app:layout_constraintLeft_toLeftOf="@id/iv_del"
app:layout_constraintRight_toRightOf="@id/iv_del"
app:layout_constraintTop_toTopOf="@id/iv_del"
/>
</FrameLayout>
\ No newline at end of file
......@@ -6,16 +6,15 @@
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:background="@android:color/transparent"
android:orientation="vertical"
android:paddingBottom="10dp">
android:orientation="vertical">
<android.support.v7.widget.AppCompatButton
android:id="@+id/photodialog_btn_take"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@drawable/rect_white_l4t4"
android:background="@null"
android:gravity="center"
android:text="拍照"
android:text="@string/sdk_photograph"
android:textColor="#323232" />
<View
......@@ -28,26 +27,24 @@
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_gravity="center"
android:background="@drawable/rect_white_b4r4"
android:background="@null"
android:gravity="center"
android:text="相册"
android:text="@string/sdk_album"
android:textColor="#323232" />
<View
android:layout_width="match_parent"
android:layout_height="10dp"
android:layout_gravity="center"
android:background="@android:color/transparent"
android:gravity="center" />
android:layout_height="0.5dp"
android:background="@color/colorEF" />
<android.support.v7.widget.AppCompatButton
android:id="@+id/photodialog_btn_cancel"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_gravity="center"
android:background="@drawable/rect_white_4dc"
android:background="@null"
android:gravity="center"
android:text="取消"
android:text="@string/cancel"
android:textColor="@color/colorAccent" />
</android.support.v7.widget.LinearLayoutCompat>
\ No newline at end of file
......@@ -570,4 +570,11 @@
<string name="picture_audio_error">The audio is corrupted</string>
<string name="picture_confirm">Cancel</string>
<string name="picture_message_video_max_num">You can choose%1$s videos at most</string>
<string name="many_times_you_have_refused_authorization_has_been_detected_please_manually_open_the_camera_privileges_">It has been detected that you have refused authorization for many times. Please open the camera permission manually</string>
<string name="authorization_failed_and_the_camera_was_unavailable">Authorization failed, unable to use camera</string>
<string name="sdk_photograph">photograph</string>
<string name="sdk_album">album</string>
</resources>
\ No newline at end of file
......@@ -566,4 +566,11 @@
<string name="picture_video_error">ビデオが破</string>
<string name="picture_audio_error">オーディオ</string>
<string name="picture_confirm">決定</string>
<string name="many_times_you_have_refused_authorization_has_been_detected_please_manually_open_the_camera_privileges_">何度も認証を拒否していることが検出されました。手動でカメラの権限を開いてください。</string>
<string name="authorization_failed_and_the_camera_was_unavailable">認証に失敗しました。カメラを使えませんでした。</string>
<string name="sdk_photograph">写真を撮る</string>
<string name="sdk_album">アルバム</string>
</resources>
\ No newline at end of file
......@@ -581,4 +581,11 @@
<string name="picture_video_error">동영상 에러</string>
<string name="picture_audio_error">오디오 에러</string>
<string name="picture_confirm">확인</string>
<string name="many_times_you_have_refused_authorization_has_been_detected_please_manually_open_the_camera_privileges_">인증 을 여러 번 거부 한 것 이 검출 되 었 습 니 다. 수 동 으로 카메라 권한 을 열 어 주 십시오.</string>
<string name="authorization_failed_and_the_camera_was_unavailable">인증 실패, 카메라 사용 불가</string>
<string name="sdk_photograph">사진 을 찍다.</string>
<string name="sdk_album">앨범
</string>
</resources>
......@@ -583,4 +583,10 @@
<string name="picture_video_error">동영상 에러</string>
<string name="picture_audio_error">오디오 에러</string>
<string name="picture_confirm">확인</string>
<string name="many_times_you_have_refused_authorization_has_been_detected_please_manually_open_the_camera_privileges_">인증 을 여러 번 거부 한 것 이 검출 되 었 습 니 다. 수 동 으로 카메라 권한 을 열 어 주 십시오.</string>
<string name="authorization_failed_and_the_camera_was_unavailable">인증 실패, 카메라 사용 불가</string>
<string name="sdk_photograph">사진 을 찍다.</string>
<string name="sdk_album">앨범</string>
</resources>
......@@ -578,4 +578,10 @@
<string name="picture_video_error">视频已损坏</string>
<string name="picture_audio_error">音频已损坏</string>
<string name="picture_confirm">确定</string>
<string name="many_times_you_have_refused_authorization_has_been_detected_please_manually_open_the_camera_privileges_">检测到您多次拒绝授权,请手动打开相机权限</string>
<string name="authorization_failed_and_the_camera_was_unavailable">授权失败,无法使用相机</string>
<string name="sdk_photograph">拍照</string>
<string name="sdk_album">相册</string>
</resources>
......@@ -21,4 +21,8 @@
<item name="swipe_refresh_header" type="id" />
<item name="swipe_load_more_footer" type="id" />
<item name="swipe_toload_layout" type="id" />
<item name="tag_for_position" type="id"/>
<item name="tag_for_view_holder" type="id"/>
<item name="tag_for_view_type" type="id"/>
</resources>
\ No newline at end of file
......@@ -574,8 +574,14 @@
<string name="picture_audio_error">音频已损坏</string>
<string name="picture_confirm">确定</string>
<string name="many_times_you_have_refused_authorization_has_been_detected_please_manually_open_the_camera_privileges_">检测到您多次拒绝授权,请手动打开相机权限</string>
<string name="authorization_failed_and_the_camera_was_unavailable">授权失败,无法使用相机</string>
<!-- TODO: Remove or change this placeholder text -->
<string name="hello_blank_fragment">Hello blank fragment</string>
<string name="title_activity_maps">Map</string>
<string name="title_activity_google_maps">Map</string>
<string name="sdk_photograph">拍照</string>
<string name="sdk_album">相册</string>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path
name="external_files"
path="."/>
</paths>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment