This commit is contained in:
zhongchao
2021-01-27 19:29:06 +08:00
14 changed files with 162 additions and 103 deletions

View File

@@ -28,6 +28,9 @@ import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable; import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers; import io.reactivex.schedulers.Schedulers;
import static com.mogo.cloud.commons.network.NetConstants.GEOFENCE_HOST;
import static com.mogo.cloud.commons.network.NetConstants.REALTIME_LOCATION_HOST;
/** /**
* created by wujifei on 2021/1/21 12:26 * created by wujifei on 2021/1/21 12:26
* describe: * describe:
@@ -45,18 +48,17 @@ public class NetworkActivity extends AppCompatActivity {
setContentView(R.layout.activity_network); setContentView(R.layout.activity_network);
btn = (Button) findViewById(R.id.btn); btn = (Button) findViewById(R.id.btn);
tvResult = (TextView) findViewById(R.id.tv_result); tvResult = (TextView) findViewById(R.id.tv_result);
apiService = RetrofitFactory.INSTANCE.getInstance("http://dzt-test.zhidaozhixing.com")
.create(ApiService.class);
btn.setOnClickListener(new View.OnClickListener() { btn.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View view) { public void onClick(View view) {
tvResult.setText("结果显示"); tvResult.setText("结果显示");
// queryRoadData("ZD802C1938L10797"); queryRoadData("ZD802C1938L10797");
// queryHelpSignal("ZD802C1938L10797"); // queryHelpSignal("F803EB2046PZD00006");
//上报路况到服务端 //上报路况到服务端
// uploadRoadInfo(); // uploadRoadInfo();
//查询路况 //查询路况
// queryRoad(); // queryRoad();
} }
@@ -126,10 +128,11 @@ public class NetworkActivity extends AppCompatActivity {
Log.d(TAG, "NetworkActivity uploadRoadInfo onError e = " + e); Log.d(TAG, "NetworkActivity uploadRoadInfo onError e = " + e);
} }
}); });
} }
public void queryRoadData(String sn) { public void queryRoadData(String sn) {
apiService = RetrofitFactory.INSTANCE.getInstance(GEOFENCE_HOST)
.create(ApiService.class);
if (apiService != null) { if (apiService != null) {
Map<String, Object> map = new HashMap<>(); Map<String, Object> map = new HashMap<>();
map.put("sn", sn); map.put("sn", sn);
@@ -163,6 +166,8 @@ public class NetworkActivity extends AppCompatActivity {
} }
public void queryHelpSignal(String sn) { public void queryHelpSignal(String sn) {
apiService = RetrofitFactory.INSTANCE.getInstance("http://dzt-realtimeLocation.zhidaozhixing.com")
.create(ApiService.class);
if (apiService != null) { if (apiService != null) {
Map<String, Object> map = new HashMap<>(); Map<String, Object> map = new HashMap<>();
map.put("sn", sn); map.put("sn", sn);

View File

@@ -50,7 +50,6 @@ android {
dependencies { dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"]) implementation fileTree(dir: "libs", include: ["*.jar"])
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation rootProject.ext.dependencies.okhttpinterceptor
if (Boolean.valueOf(RELEASE)) { if (Boolean.valueOf(RELEASE)) {
api "com.mogo.cloud:passport:${MOGO_PASSPORT_VERSION}" api "com.mogo.cloud:passport:${MOGO_PASSPORT_VERSION}"

View File

@@ -1,20 +0,0 @@
package com.mogo.cloud.commons.network
import android.text.TextUtils
import com.mogo.cloud.commons.utils.getInetAddressByHost
import okhttp3.Dns
import java.net.InetAddress
/**
* created by wujifei on 2021/1/26 12:51
* describe:
*/
class HttpDns : Dns {
override fun lookup(hostname: String): List<InetAddress> {
val addresses: List<InetAddress> = getInetAddressByHost(hostname)
if (!addresses.isEmpty()) {
return addresses
}
return Dns.SYSTEM.lookup(hostname)
}
}

View File

@@ -6,13 +6,26 @@ package com.mogo.cloud.commons.network
*/ */
class NetConstants { class NetConstants {
companion object { companion object {
const val TAG = "LogInterceptor"
const val READ_TIMEOUT = 20000L const val READ_TIMEOUT = 20000L
const val WRITE_TIMEOUT = 20000L const val WRITE_TIMEOUT = 20000L
const val CONNECT_TIMEOUT = 15000L const val CONNECT_TIMEOUT = 15000L
const val HTTP_DNS_ADDRESS_TYPE_HTTP = 0 const val DEVA_HOST = "http://dzt-deva.zhidaozhixing.com"
const val HTTP_DNS_ADDRESS_TYPE_WS = 1 const val IM_HOST = "http://dzt-im.zhidaozhixing.com"
const val HTTP_DNS_ADDRESS_TYPE_IM = 2 const val LAUNCHER_SNAPSHOT_HOST = "http://dzt-launcherSnapshot.zhidaozhixing.com"
const val CHANNEL_MANAGER_HOST = "http://dzt-channelManager.zhidaozhixing.com"
const val DATA_SERVICE_HOST = "http://dzt-dataService.zhidaozhixing.com"
const val REALTIME_LOCATION_HOST = "http://dzt-realtimeLocation.zhidaozhixing.com"
const val INSTANT_HOST = "http://dzt-Instant.zhidaozhixing.com"
const val GEOFENCE_HOST = "http://dzt-geoFenceCarService.zhidaozhixing.com"
const val CARLIFE_HOST = "http://dzt-carlife.zhidaozhixing.com"
const val STRATEGY_PUSH_HOST = "http://dzt-strategyPush.zhidaozhixing.com"
const val TRAVEL_CONDITION_HOST = "http://dzt-travelCondition.zhidaozhixing.com"
const val TMC_HOST = "http://dzt-tmcServer.zhidaozhixing.com"
const val IM_SOCKET_DOMAIN = "dzt-im.zhidaozhixing.com"
const val WEBSOCKET_DOMAIN = "dzt-Instant.zhidaozhixing.com"
} }
} }

View File

@@ -5,12 +5,10 @@ import com.mogo.cloud.commons.network.NetConstants.Companion.READ_TIMEOUT
import com.mogo.cloud.commons.network.NetConstants.Companion.WRITE_TIMEOUT import com.mogo.cloud.commons.network.NetConstants.Companion.WRITE_TIMEOUT
import com.mogo.cloud.commons.network.SSLSocketFactoryUtils.createSSLSocketFactory import com.mogo.cloud.commons.network.SSLSocketFactoryUtils.createSSLSocketFactory
import com.mogo.cloud.commons.network.SSLSocketFactoryUtils.createTrustAllManager import com.mogo.cloud.commons.network.SSLSocketFactoryUtils.createTrustAllManager
import com.mogo.cloud.commons.network.interceptor.HeaderNetworkInterceptor import com.mogo.cloud.commons.network.interceptor.HttpHeaderInterceptor
import com.mogo.cloud.commons.utils.lookup import com.mogo.cloud.commons.network.interceptor.HttpDnsInterceptor
import okhttp3.Dns import com.mogo.cloud.commons.network.interceptor.HttpLoggingInterceptor
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import java.net.InetAddress
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
@@ -22,16 +20,16 @@ import java.util.concurrent.TimeUnit
*/ */
class OkHttpFactory private constructor() { class OkHttpFactory private constructor() {
companion object { companion object {
val okHttpClient: OkHttpClient by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { val okHttpClient: OkHttpClient by lazy {
OkHttpClient.Builder() OkHttpClient.Builder()
.addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)) .addNetworkInterceptor(HttpHeaderInterceptor())
.addNetworkInterceptor(HeaderNetworkInterceptor()) .addInterceptor(HttpDnsInterceptor())
.addInterceptor(HttpLoggingInterceptor())
.sslSocketFactory(createSSLSocketFactory(), createTrustAllManager()) .sslSocketFactory(createSSLSocketFactory(), createTrustAllManager())
.hostnameVerifier(SSLSocketFactoryUtils.TrustAllHostnameVerifier()) .hostnameVerifier(SSLSocketFactoryUtils.TrustAllHostnameVerifier())
.connectTimeout(CONNECT_TIMEOUT, TimeUnit.MILLISECONDS) .connectTimeout(CONNECT_TIMEOUT, TimeUnit.MILLISECONDS)
.readTimeout(READ_TIMEOUT, TimeUnit.MILLISECONDS) .readTimeout(READ_TIMEOUT, TimeUnit.MILLISECONDS)
.writeTimeout(WRITE_TIMEOUT, TimeUnit.MILLISECONDS) .writeTimeout(WRITE_TIMEOUT, TimeUnit.MILLISECONDS)
.dns(HttpDns())
.build() .build()
} }

View File

@@ -0,0 +1,26 @@
package com.mogo.cloud.commons.network.interceptor
import com.mogo.cloud.httpdns.MogoHttpDnsClient
import com.mogo.utils.logger.Logger
import okhttp3.Interceptor
import okhttp3.Request
import okhttp3.Response
/**
* created by wujifei on 2021/1/27 15:57
* describe:
*/
class HttpDnsInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val request: Request = chain.request()
val path: String = request.url().encodedPath()
val query: String? = request.url().encodedQuery()
val host = "http://" + MogoHttpDnsClient.getHttpDnsAddressUseCacheIfNecessary(0, request.url().host().replace("http://", "").replace("https://", ""))
var url = host + path
query?.let {
url=url+"?"+query
}
Logger.d("DomainExchange", """oriHost: ${request.url().host().toString()} newHost: $host newUrl: $url""")
return chain.proceed(request.newBuilder().url(url).build())
}
}

View File

@@ -8,7 +8,7 @@ import okhttp3.Response
* created by wujifei on 2021/1/20 15:18 * created by wujifei on 2021/1/20 15:18
* describe:header携带信息 * describe:header携带信息
*/ */
class HeaderNetworkInterceptor : Interceptor { class HttpHeaderInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response { override fun intercept(chain: Interceptor.Chain): Response {
val original = chain.request() val original = chain.request()
val request = original.newBuilder() val request = original.newBuilder()

View File

@@ -0,0 +1,87 @@
package com.mogo.cloud.commons.network.interceptor
import com.mogo.cloud.commons.network.NetConstants.Companion.TAG
import com.mogo.utils.logger.Logger
import okhttp3.*
import okio.Buffer
import java.io.IOException
import java.nio.charset.Charset
import java.util.concurrent.TimeUnit
/**
* created by wujifei on 2021/1/27 14:33
* describe:
*/
class HttpLoggingInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request()
val requestBody = request.body()
val hasRequestBody = requestBody != null
var protocol = Protocol.HTTP_1_1.toString()
var body = ""
if (chain.connection() != null && chain.connection()!!.protocol() != null) {
protocol = chain.connection()!!.protocol().toString()
}
if (hasRequestBody) {
try {
val UTF8 = Charset.forName("UTF-8")
val buffer = Buffer()
requestBody?.writeTo(buffer)
var charset = UTF8
val contentType = requestBody?.contentType()
if (contentType != null) {
charset = contentType.charset(UTF8)
}
if (charset != null) {
body = buffer.readString(charset)
}
} catch (e: IOException) {
e.printStackTrace()
}
}
val logMsg = StringBuilder()
.append("------> http request start").append("\r\n")
.append(protocol).append(", ")
.append(request.method()).append(", ")
.append("Request Headers: ").append(request.headers().toString()).append("\r\n")
.append("Url: ").append(request.url()).append("\r\n")
.append("Content-Type: ").append(requestBody?.contentType()).append("\r\n")
.append("Content-Length: ").append(requestBody?.contentLength()).append("\r\n")
.append("Content-body: ").append(body).append("\r\n")
.append("------> http request end").append("\r\n").append("\r\n")
val startTime = System.nanoTime()
val response = chain.proceed(chain.request())
val endTime = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime)
val responseBody = response.body()
var responseContent: String? = null
var bodySize: String? = null
var contentType: MediaType? = null
var consumedResponse = false
if (responseBody != null) {
val contentLength = responseBody.contentLength()
bodySize = if (contentLength != -1L) "$contentLength-byte" else "unknown-length"
contentType = responseBody.contentType()
responseContent = responseBody.string()
consumedResponse = true
}
logMsg.append("------> http response start").append("\r\n")
.append(response.code()).append(" ")
.append(response.message()).append(" ")
.append(response.protocol()).append(" ").append("\r\n")
.append("Response Content: ").append(responseContent).append("\r\n")
.append("Content-Type: ").append(contentType).append("\r\n")
.append("Content-Length: ").append(bodySize).append("\r\n")
.append(" (").append(endTime).append("ms)").append("\r\n")
.append("------> http response end")
Logger.d(TAG, logMsg.toString())
return if (consumedResponse) response.newBuilder().body(ResponseBody.create(contentType, responseContent)).build() else response
}
}

View File

@@ -1,48 +0,0 @@
package com.mogo.cloud.commons.utils
import android.text.TextUtils
import com.mogo.cloud.commons.network.NetConstants.Companion.HTTP_DNS_ADDRESS_TYPE_HTTP
import com.mogo.cloud.httpdns.MogoHttpDnsClient
import java.net.InetAddress
import java.net.UnknownHostException
import java.util.*
/**
* created by wujifei on 2021/1/20 12:51
* describe:网络工具
*/
/**
* 根据host获取InetAddress
*/
@Throws(UnknownHostException::class)
fun lookup(hostname: String?): List<InetAddress?>? {
val cacheIp: String? = hostname?.let { MogoHttpDnsClient.getHttpDnsAddressUseCacheIfNecessary(HTTP_DNS_ADDRESS_TYPE_HTTP, it) }
if (cacheIp == null || TextUtils.isEmpty(cacheIp)) {
return emptyList<InetAddress>()
}
val info = cacheIp.split(":").toTypedArray()
return if (info.size > 1) {
Arrays.asList(*InetAddress.getAllByName(info[0]))
} else {
Arrays.asList(*InetAddress.getAllByName(cacheIp))
}
}
/**
* 根据host获取InetAddress
*/
@Throws(UnknownHostException::class)
fun getInetAddressByHost(hostname: String): List<InetAddress> {
val cacheIp: String? = hostname?.let { MogoHttpDnsClient.getHttpDnsAddressUseCacheIfNecessary(HTTP_DNS_ADDRESS_TYPE_HTTP, it) }
if (cacheIp == null || TextUtils.isEmpty(cacheIp)) {
return emptyList<InetAddress>()
}
val info = cacheIp.split(":").toTypedArray()
return if (info.size > 1) {
Arrays.asList(*InetAddress.getAllByName(info[0]))
} else {
Arrays.asList(*InetAddress.getAllByName(cacheIp))
}
}

View File

@@ -65,7 +65,6 @@ public class CosUpload implements CosStatusCallback {
public void uploadInfo(UploadInfo info, ITanluUploadCallback callback) { public void uploadInfo(UploadInfo info, ITanluUploadCallback callback) {
mCallback = callback; mCallback = callback;
mUploadInfo = info; mUploadInfo = info;
Log.d(HttpConstant.TANLU, "videoPath = " + info.getFilePath()); Log.d(HttpConstant.TANLU, "videoPath = " + info.getFilePath());
if (!TextUtils.isEmpty(info.getFilePath())) { //不传路径 if (!TextUtils.isEmpty(info.getFilePath())) { //不传路径
if (isVideo(info.getFilePath())) { if (isVideo(info.getFilePath())) {
@@ -100,10 +99,8 @@ public class CosUpload implements CosStatusCallback {
Log.d(HttpConstant.TANLU, "uploadCosCompleted ----> downloadUrl =" + downloadUrl + "--localPath =" + localPath); Log.d(HttpConstant.TANLU, "uploadCosCompleted ----> downloadUrl =" + downloadUrl + "--localPath =" + localPath);
if (filePath.size() == 2) { if (filePath.size() == 2) {
if (isVideo(localPath)) { //如果是视频 localPath if (isVideo(localPath)) { //如果是视频 localPath
Log.e(HttpConstant.TANLU, "1111111-------");
mCosVideoUrl = downloadUrl; mCosVideoUrl = downloadUrl;
} else { } else {
Log.e(HttpConstant.TANLU, "22222222------");
mCosPicUrl = downloadUrl; mCosPicUrl = downloadUrl;
} }
@@ -112,7 +109,6 @@ public class CosUpload implements CosStatusCallback {
sendInformation(); sendInformation();
} }
} else { } else {
Log.e(HttpConstant.TANLU, "333333------");
mCosPicUrl = downloadUrl; mCosPicUrl = downloadUrl;
sendInformation(); sendInformation();
} }
@@ -137,7 +133,7 @@ public class CosUpload implements CosStatusCallback {
//删除本地生成的图片封面 //删除本地生成的图片封面
if (videoCoverImage != null) { if (videoCoverImage != null) {
boolean isDeleteSuccess = deletePicFile(videoCoverImage); deletePicFile(videoCoverImage);
} }
UploadManager.getInstance(mContext.getApplicationContext()).loadUpload(getInformation(), new ITanluUploadCallback() { UploadManager.getInstance(mContext.getApplicationContext()).loadUpload(getInformation(), new ITanluUploadCallback() {

View File

@@ -47,8 +47,8 @@ public class MogoRoadSearchManager {
return sInstance; return sInstance;
} }
public void init () { //TODO public void init () {
apiService = RetrofitFactory.INSTANCE.getInstance("http://dzt-test.zhidaozhixing.com") apiService = RetrofitFactory.INSTANCE.getInstance(HttpConstant.DEV_HOTS)
.create(TanluApiService.class); .create(TanluApiService.class);
} }

View File

@@ -45,8 +45,8 @@ public class UploadManager {
return sInstance; return sInstance;
} }
public void init () { //TODO public void init () {
apiService = RetrofitFactory.INSTANCE.getInstance("http://dzt-test.zhidaozhixing.com") apiService = RetrofitFactory.INSTANCE.getInstance(HttpConstant.DEV_HOTS)
.create(TanluApiService.class); .create(TanluApiService.class);
} }
@@ -60,11 +60,10 @@ public class UploadManager {
public void loadUpload(InformationBody informationBody, ITanluUploadCallback callback) { public void loadUpload(InformationBody informationBody, ITanluUploadCallback callback) {
Gson gson = new Gson(); Gson gson = new Gson();
Map<String, String> map = new HashMap<>(); Map<String, String> map = new HashMap<>();
// map.put("sn", MoGoAiCloudClient.getInstance().getAiCloudClientConfig().getSn()); //TODO map.put("sn", MoGoAiCloudClient.getInstance().getAiCloudClientConfig().getSn());
map.put("sn", "F803EB2046PZD00228");
map.put("data", gson.toJson(informationBody)); map.put("data", gson.toJson(informationBody));
Log.d(HttpConstant.TANLU, "info = " + gson.toJson(informationBody)); Log.d(HttpConstant.TANLU, "info = " + gson.toJson(informationBody));
// map.put("sn", "ZD802C1938L10797"); // map.put("sn", "F803EB2046PZD00228");
// map.put("data", "{\"addr\":\"北京市东城区小黄庄北街2号靠近中国银行(北京安贞桥支行)\",\"areaCode\":\"110101\",\"areaName\":\"东城区\",\"cityCode\":\"010\",\"cityName\":\"北京市\",\"data\":\"[{\\\"thumbnail\\\":\\\"http://petchfile-1255510688.cos.ap-beijing.myqcloud.com/CarPad/com.zhidao.roadcondition/F803EB2046PZD00228/F803EB2046PZD00228_20210121165329/Thumbnail1611219200669.jpg\\\",\\\"url\\\":\\\"http://petchfile-1255510688.cos.ap-beijing.myqcloud.com/CarPad/com.zhidao.roadcondition/F803EB2046PZD00228/F803EB2046PZD00228_20210121165329/compress_video_20210121165307.mp4\\\"}]\",\"direction\":0.0,\"fromType\":\"2\",\"generateTime\":1611219213616,\"infoTimeout\":240,\"infoType\":1,\"isShare\":false,\"lat\":39.968317,\"lon\":116.410892,\"mainInfoId\":0,\"poiType\":\"10008\",\"provinceName\":\"北京市\",\"sn\":\"F803EB2046PZD00228\",\"speed\":0.0,\"street\":\"小黄庄北街\",\"trafficInfoType\":\"\",\"type\":1,\"uid\":0}"); // map.put("data", "{\"addr\":\"北京市东城区小黄庄北街2号靠近中国银行(北京安贞桥支行)\",\"areaCode\":\"110101\",\"areaName\":\"东城区\",\"cityCode\":\"010\",\"cityName\":\"北京市\",\"data\":\"[{\\\"thumbnail\\\":\\\"http://petchfile-1255510688.cos.ap-beijing.myqcloud.com/CarPad/com.zhidao.roadcondition/F803EB2046PZD00228/F803EB2046PZD00228_20210121165329/Thumbnail1611219200669.jpg\\\",\\\"url\\\":\\\"http://petchfile-1255510688.cos.ap-beijing.myqcloud.com/CarPad/com.zhidao.roadcondition/F803EB2046PZD00228/F803EB2046PZD00228_20210121165329/compress_video_20210121165307.mp4\\\"}]\",\"direction\":0.0,\"fromType\":\"2\",\"generateTime\":1611219213616,\"infoTimeout\":240,\"infoType\":1,\"isShare\":false,\"lat\":39.968317,\"lon\":116.410892,\"mainInfoId\":0,\"poiType\":\"10008\",\"provinceName\":\"北京市\",\"sn\":\"F803EB2046PZD00228\",\"speed\":0.0,\"street\":\"小黄庄北街\",\"trafficInfoType\":\"\",\"type\":1,\"uid\":0}");
Log.d(HttpConstant.TANLU, "sn = " + MoGoAiCloudClient.getInstance().getAiCloudClientConfig().getSn()); Log.d(HttpConstant.TANLU, "sn = " + MoGoAiCloudClient.getInstance().getAiCloudClientConfig().getSn());
@@ -74,11 +73,11 @@ public class UploadManager {
.subscribe(new Observer<BaseData<UploadResult>>() { .subscribe(new Observer<BaseData<UploadResult>>() {
@Override @Override
public void onSubscribe(Disposable d) { public void onSubscribe(Disposable d) {
Log.d(HttpConstant.TANLU, "onSubscribe -----> ");
} }
@Override @Override
public void onNext(BaseData<UploadResult> result) { public void onNext(BaseData<UploadResult> result) {
Log.d(HttpConstant.TANLU, "onNext -----> ");
callback.onSuccess(result); callback.onSuccess(result);
} }
@@ -90,7 +89,6 @@ public class UploadManager {
@Override @Override
public void onComplete() { public void onComplete() {
Log.d(HttpConstant.TANLU, "onComplete -----> ");
} }
}); });
} }

View File

@@ -10,6 +10,11 @@ public class HttpConstant {
public static final String DZT_HOTS = "http://dzt-deva.zhidaozhixing.com"; public static final String DZT_HOTS = "http://dzt-deva.zhidaozhixing.com";
public static final String LAUNCHER_HOTS = "http://dzt-launcherSnapshot.zhidaozhixing.com"; public static final String LAUNCHER_HOTS = "http://dzt-launcherSnapshot.zhidaozhixing.com";
public static final String DEV_HOTS = "http://dzt-test.zhidaozhixing.com";
public static final String RELEASE_HOTS = "http://dzt.zhidaozhixing.com";
public static final String TANLU = "TANLU_MODULE"; public static final String TANLU = "TANLU_MODULE";
} }

View File

@@ -100,7 +100,7 @@ fun bitmapToFile(bitmap: Bitmap?, filePath: String): Boolean {
return true return true
} }
//
fun getVideoPicPath(): String { fun getVideoPicPath(): String {
val moviesDir = Environment.getExternalStoragePublicDirectory( val moviesDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES Environment.DIRECTORY_PICTURES