diff --git a/app/build.gradle b/app/build.gradle index 8d16f02..c5972a8 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -37,4 +37,6 @@ dependencies { testImplementation 'junit:junit:4.+' androidTestImplementation 'androidx.test.ext:junit:1.1.2' androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' + implementation 'com.github.Justson.AgentWeb:agentweb-core:v4.1.9-androidx' // (必选) + implementation 'com.github.Justson.AgentWeb:agentweb-filechooser:v4.1.9-androidx' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index dab2056..a3e0b91 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,10 +2,16 @@ - - - - + + + + + + + + + + = Build.VERSION_CODES.N) { + intentCamera.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); //添加这一句表示对目标应用临时授权该Uri所代表的文件 + } + intentCamera.setAction(MediaStore.ACTION_IMAGE_CAPTURE); + //将拍照结果保存至photo_file的Uri中,不保留在相册中 + intentCamera.putExtra(MediaStore.EXTRA_OUTPUT, imageUri); + if (activity != null) { + activity.startActivityForResult(intentCamera, requestCode); + } + } + + /** + * @param activity 当前activity + * @param requestCode 打开相册的请求码 + */ + public static void openPic(Activity activity, int requestCode) { + Intent photoPickerIntent = new Intent(Intent.ACTION_GET_CONTENT); + photoPickerIntent.setType("image/*"); + activity.startActivityForResult(photoPickerIntent, requestCode); + } + + /** + * @param activity 当前activity + * @param orgUri 剪裁原图的Uri + * @param desUri 剪裁后的图片的Uri + * @param aspectX X方向的比例 + * @param aspectY Y方向的比例 + * @param width 剪裁图片的宽度 + * @param height 剪裁图片高度 + * @param requestCode 剪裁图片的请求码 + */ + public static void cropImageUri(Activity activity, Uri orgUri, Uri desUri, int aspectX, int aspectY, int width, int height, int requestCode) { + 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); + } + intent.setDataAndType(orgUri, "image/*"); + intent.putExtra("crop", "true"); + intent.putExtra("aspectX", aspectX); + intent.putExtra("aspectY", aspectY); + intent.putExtra("outputX", width); + intent.putExtra("outputY", height); + intent.putExtra("scale", true); + //将剪切的图片保存到目标Uri中 + intent.putExtra(MediaStore.EXTRA_OUTPUT, desUri); + intent.putExtra("return-data", false); + intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString()); + intent.putExtra("noFaceDetection", true); + activity.startActivityForResult(intent, requestCode); + } + + /** + * 读取uri所在的图片 + * + * @param uri 图片对应的Uri + * @param mContext 上下文对象 + * @return 获取图像的Bitmap + */ + public static Bitmap getBitmapFromUri(Uri uri, Context mContext) { + try { +// Bitmap bitmap = MediaStore.Images.Media.getBitmap(mContext.getContentResolver(), uri); + Bitmap bitmapFormUri = getBitmapFormUri(mContext, uri); + return bitmapFormUri; + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + /** + * 通过uri获取图片并进行压缩 + * + * @param uri + */ + public static Bitmap getBitmapFormUri(Context ac, Uri uri) throws FileNotFoundException, IOException { + InputStream input = ac.getContentResolver().openInputStream(uri); + BitmapFactory.Options onlyBoundsOptions = new BitmapFactory.Options(); + onlyBoundsOptions.inJustDecodeBounds = true; + onlyBoundsOptions.inDither = true;//optional + onlyBoundsOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;//optional + BitmapFactory.decodeStream(input, null, onlyBoundsOptions); + input.close(); + int originalWidth = onlyBoundsOptions.outWidth; + int originalHeight = onlyBoundsOptions.outHeight; + if ((originalWidth == -1) || (originalHeight == -1)) { + return null; + } + //图片分辨率以480x800为标准 + float hh = 800f;//这里设置高度为800f + float ww = 480f;//这里设置宽度为480f + //缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可 + int be = 1;//be=1表示不缩放 + if (originalWidth > originalHeight && originalWidth > ww) {//如果宽度大的话根据宽度固定大小缩放 + be = (int) (originalWidth / ww); + } else if (originalWidth < originalHeight && originalHeight > hh) {//如果高度高的话根据宽度固定大小缩放 + be = (int) (originalHeight / hh); + } + if (be <= 0) { + be = 1; + } + //比例压缩 + BitmapFactory.Options bitmapOptions = new BitmapFactory.Options(); + bitmapOptions.inSampleSize = be;//设置缩放比例 + bitmapOptions.inDither = true;//optional + bitmapOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;//optional + input = ac.getContentResolver().openInputStream(uri); + Bitmap bitmap = BitmapFactory.decodeStream(input, null, bitmapOptions); + input.close(); + return compressImage(bitmap);//再进行质量压缩 + } + + /** + * 质量压缩方法 + * + * @param image + * @return + */ + public static Bitmap compressImage(Bitmap image) { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + image.compress(Bitmap.CompressFormat.JPEG, 100, baos);//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中 + int options = 100; + while (baos.toByteArray().length / 1024 > 100) { //循环判断如果压缩后图片是否大于100kb,大于继续压缩 + baos.reset();//重置baos即清空baos + //第一个参数 :图片格式 ,第二个参数: 图片质量,100为最高,0为最差 ,第三个参数:保存压缩后的数据的流 + image.compress(Bitmap.CompressFormat.JPEG, options, baos);//这里压缩options%,把压缩后的数据存放到baos中 + options -= 10;//每次都减少10 + } + ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());//把压缩后的数据baos存放到ByteArrayInputStream中 + Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);//把ByteArrayInputStream数据生成图片 + return bitmap; + } + + + /** + * @param context 上下文对象 + * @param uri 当前相册照片的Uri + * @return 解析后的Uri对应的String + */ + @SuppressLint("NewApi") + public static String getPath(final Context context, final Uri uri) { + + final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; + String pathHead = "file:///"; + // DocumentProvider + if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) { + // ExternalStorageProvider + if (isExternalStorageDocument(uri)) { + final String docId = DocumentsContract.getDocumentId(uri); + final String[] split = docId.split(":"); + final String type = split[0]; + if ("primary".equalsIgnoreCase(type)) { + return pathHead + Environment.getExternalStorageDirectory() + "/" + split[1]; + } + } + // DownloadsProvider + else if (isDownloadsDocument(uri)) { + + final String id = DocumentsContract.getDocumentId(uri); + + final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); + + return pathHead + getDataColumn(context, contentUri, null, null); + } + // MediaProvider + else if (isMediaDocument(uri)) { + final String docId = DocumentsContract.getDocumentId(uri); + final String[] split = docId.split(":"); + final String type = split[0]; + + Uri contentUri = null; + if ("image".equals(type)) { + contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; + } else if ("video".equals(type)) { + contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; + } else if ("audio".equals(type)) { + contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; + } + + final String selection = "_id=?"; + final String[] selectionArgs = new String[]{split[1]}; + + return pathHead + getDataColumn(context, contentUri, selection, selectionArgs); + } + } + // MediaStore (and general) + else if ("content".equalsIgnoreCase(uri.getScheme())) { + return pathHead + getDataColumn(context, uri, null, null); + } + // File + else if ("file".equalsIgnoreCase(uri.getScheme())) { + return pathHead + uri.getPath(); + } + return null; + } + + /** + * Get the value of the data column for this Uri. This is useful for + * MediaStore Uris, and other file-based ContentProviders. + * + * @param context The context. + * @param uri The Uri to query. + * @param selection (Optional) Filter used in the query. + * @param selectionArgs (Optional) Selection arguments used in the query. + * @return The value of the _data column, which is typically a file path. + */ + private static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) { + + Cursor cursor = null; + final String column = "_data"; + final String[] projection = {column}; + try { + cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null); + if (cursor != null && cursor.moveToFirst()) { + final int column_index = cursor.getColumnIndexOrThrow(column); + return cursor.getString(column_index); + } + } finally { + if (cursor != null) { + cursor.close(); + } + } + return null; + } + + /** + * @param uri The Uri to check. + * @return Whether the Uri authority is ExternalStorageProvider. + */ + private static boolean isExternalStorageDocument(Uri uri) { + return "com.android.externalstorage.documents".equals(uri.getAuthority()); + } + + /** + * @param uri The Uri to check. + * @return Whether the Uri authority is DownloadsProvider. + */ + private static boolean isDownloadsDocument(Uri uri) { + return "com.android.providers.downloads.documents".equals(uri.getAuthority()); + } + + /** + * @param uri The Uri to check. + * @return Whether the Uri authority is MediaProvider. + */ + private static boolean isMediaDocument(Uri uri) { + return "com.android.providers.media.documents".equals(uri.getAuthority()); + } + +} diff --git a/app/src/main/res/layout/activity_fullscreen.xml b/app/src/main/res/layout/activity_fullscreen.xml index e8aef8f..4036046 100644 --- a/app/src/main/res/layout/activity_fullscreen.xml +++ b/app/src/main/res/layout/activity_fullscreen.xml @@ -5,12 +5,13 @@ android:layout_height="match_parent" android:background="?attr/fullscreenBackgroundColor" android:theme="@style/ThemeOverlay.Nsgk_rural_web.FullscreenContainer" - tools:context=".FullscreenActivity"> + tools:context=".FullscreenActivity" + android:id="@+id/ll"> - + + + + \ No newline at end of file