안 드 로 이 드 10 구덩이 매 립 적합 가이드(실제 경험 코드)

11886 단어 Android10어울리다
오늘 좋 은 글 한 편 을 보고 모두 에 게 나 누 어 큰 사람 을 경 배 하 였 다.
Android 10 구덩이 매 립 매 립 매 칭 안내,실제 경험 코드 포함,번역 문 서 를 그대로 옮 기지 않 습 니 다.
1.Region.Op 관련 이상:java.lang.IllegalArgument 예외:유효 하지 않 은 Region.Op-INTERSECT 및 DIFFERENCE 만 허 용 됩 니 다.
...해 야 한다 targetSdkVersion >= Build.VERSION_CODES.P 시 canvas.clipPath(path,Region.Op.XXX)를 호출 합 니 다.발생 하 는 이상 은 다음 과 같 습 니 다.

@Deprecated
public boolean clipPath(@NonNull Path path, @NonNull Region.Op op) {
  checkValidClipOp(op);
  return nClipPath(mNativeCanvasWrapper, path.readOnlyNI(), op.nativeInt);
}

private static void checkValidClipOp(@NonNull Region.Op op) {
  if (sCompatiblityVersion >= Build.VERSION_CODES.P
   && op != Region.Op.INTERSECT && op != Region.Op.DIFFERENCE) {
   throw new IllegalArgumentException(
     "Invalid Region.Op - only INTERSECT and DIFFERENCE are allowed");
  }
}

대상 버 전이 Android P 에서 시작 할 때 Canvas.clipPath(@NonNull Path path,@NonNull Region.Op op)를 볼 수 있 습 니 다.이미 폐기 되 었 고 이상 위험 을 포함 한 폐기 API 만 있 습 니 다. Region.Op.INTERSECT 와 Region.Op.DIFERENCE 가 호 환 되 고 거의 모든 블 로그 솔 루 션 은 다음 과 같이 간단 하고 난폭 합 니 다.

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
 canvas.clipPath(path);
} else {
 canvas.clipPath(path, Region.Op.XOR);// REPLACE、UNION  
}
그러나 우 리 는 반드시 고급 논리 연산 효과 가 필요 하 다.어떻게 해 야 합 니까?예 를 들 어 소설의 모방 페이지 읽 기 효과 에 대해 해결 방안 은 다음 과 같다.Path.op 으로 대체 하고 Path 를 먼저 연산 한 다음 에

 canvas.clipPath:
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.P){
 Path mPathXOR = new Path();
 mPathXOR.moveTo(0,0);
 mPathXOR.lineTo(getWidth(),0);
 mPathXOR.lineTo(getWidth(),getHeight());
 mPathXOR.lineTo(0,getHeight());
 mPathXOR.close();
 //       Canvas View   ,       Path  
 mPathXOR.op(mPath0, Path.Op.XOR);
 canvas.clipPath(mPathXOR);
}else {
 canvas.clipPath(mPath0, Region.Op.XOR);
}
2.명문 HTTP 제한
...해 야 한다 targetSdkVersion >= Build.VERSION_CODES.P 에 서 는 기본적으로 HTTP 요청 을 제한 하고 로그 가 나타 납 니 다.java.net.UnknownServiceException: CLEARTEXT communication to xxx not permitted by network security policy 첫 번 째 해결 방안:AndroidManifest.xml 에 응용 프로그램 에 다음 과 같은 노드 코드 를 추가 합 니 다.

<application android:usesCleartextTraffic="true">
두 번 째 솔 루 션:res 디 렉 터 리 에 xml 디 렉 터 리 를 새로 만 들 고 xml 디 렉 터 리 에 xml 파일 network 를 새로 만 듭 니 다.security_config.xml,그리고 AndroidManifest.xml 에 Application 에 다음 노드 코드 를 추가 합 니 다.

android:networkSecurityConfig="@xml/network_config"
이름 은 랜 덤 입 니 다.내용 은 다음 과 같 습 니 다.

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
 <base-config cleartextTrafficPermitted="true" />
</network-security-config>
3.Android Q 의 미디어 자원 읽 기 및 쓰기
1.스 캔 시스템 앨범,동 영상 등,이미지,동 영상 선택 기 는 모두 ContentResolver 를 통 해 제 공 됩 니 다.주요 코드 는 다음 과 같 습 니 다.

private static final String[] IMAGE_PROJECTION = {
   MediaStore.Images.Media.DATA,
   MediaStore.Images.Media.DISPLAY_NAME,
   MediaStore.Images.Media._ID,
   MediaStore.Images.Media.BUCKET_ID,
   MediaStore.Images.Media.BUCKET_DISPLAY_NAME};

 Cursor imageCursor = mContext.getContentResolver().query(
     MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
     IMAGE_PROJECTION, null, null, IMAGE_PROJECTION[0] + " DESC");

String path = imageCursor.getString(imageCursor.getColumnIndexOrThrow(IMAGE_PROJECTION[0]));
String name = imageCursor.getString(imageCursor.getColumnIndexOrThrow(IMAGE_PROJECTION[1]));
int id = imageCursor.getInt(imageCursor.getColumnIndexOrThrow(IMAGE_PROJECTION[2]));
String folderPath = imageCursor.getString(imageCursor.getColumnIndexOrThrow(IMAGE_PROJECTION[3]));
String folderName = imageCursor.getString(imageCursor.getColumnIndexOrThrow(IMAGE_PROJECTION[4]));

//Android Q         Content Uri + id     ,   File      ,   Video,    MediaStore.Videos
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q){
  path = MediaStore.Images.Media
      .EXTERNAL_CONTENT_URI
      .buildUpon()
      .appendPath(String.valueOf(id)).build().toString();
 }

2.공유 디 렉 터 리 파일 의 존재 여 부 를 판단 합 니 다.Android Q 부터 공유 디 렉 터 리 File API 가 모두 효력 을 상실 하고 new File(path).exists()를 직접 통과 할 수 없습니다.공유 디 렉 터 리 파일 이 존재 하 는 지 여 부 를 판단 합 니 다.정확 한 방법 은 다음 과 같 습 니 다.

public static boolean isAndroidQFileExists(Context context, String path){
  AssetFileDescriptor afd = null;
  ContentResolver cr = context.getContentResolver();
  try {
   Uri uri = Uri.parse(path);
   afd = cr.openAssetFileDescriptor(uri, "r");
   if (afd == null) {
    return false;
   } else {
    close(afd);
   }
  } catch (FileNotFoundException e) {
   return false;
  }finally {
   close(afd);
  }
  return true;
}
3.copy 또는 공유 디 렉 터 리 에 파일 을 다운로드 하고 Bitmap 를 저장 합 니 다.예 를 들 어 Download,MIMETYPE 형식 은 자체 적 으로 대응 하 는 파일 형식 을 참고 할 수 있 습 니 다.여 기 는 APK 에 대해 서 만 설명 할 수 있 습 니 다.개인 디 렉 터 리 copy 에서 공유 디 렉 터 리 demo 까지 다음 과 같 습 니 다.

public static void copyToDownloadAndroidQ(Context context, String sourcePath, String fileName, String saveDirName){
  ContentValues values = new ContentValues();
  values.put(MediaStore.Downloads.DISPLAY_NAME, fileName);
  values.put(MediaStore.Downloads.MIME_TYPE, "application/vnd.android.package-archive");
  values.put(MediaStore.Downloads.RELATIVE_PATH, "Download/" + saveDirName.replaceAll("/","") + "/");

  Uri external = MediaStore.Downloads.EXTERNAL_CONTENT_URI;
  ContentResolver resolver = context.getContentResolver();

  Uri insertUri = resolver.insert(external, values);
  if(insertUri == null) {
   return;
  }

  String mFilePath = insertUri.toString();

  InputStream is = null;
  OutputStream os = null;
  try {
   os = resolver.openOutputStream(insertUri);
   if(os == null){
    return;
   }
   int read;
   File sourceFile = new File(sourcePath);
   if (sourceFile.exists()) { //      
    is = new FileInputStream(sourceFile); //      
    byte[] buffer = new byte[1444];
    while ((read = is.read(buffer)) != -1) {
     os.write(buffer, 0, read);
    }
   }
  } catch (Exception e) {
   e.printStackTrace();
  }finally {
   close(is,os);
  }

}

4.이미지 저장 관련

 /**
  *   MediaStore  ,  AndroidQ,              ,               
  *
  * @param context  context
  * @param sourceFile    
  * @param saveFileName       
  * @param saveDirName picture   
  * @return       
  */
 public static boolean saveImageWithAndroidQ(Context context,
             File sourceFile,
             String saveFileName,
             String saveDirName) {
  String extension = BitmapUtil.getExtension(sourceFile.getAbsolutePath());

  ContentValues values = new ContentValues();
  values.put(MediaStore.Images.Media.DESCRIPTION, "This is an image");
  values.put(MediaStore.Images.Media.DISPLAY_NAME, saveFileName);
  values.put(MediaStore.Images.Media.MIME_TYPE, "image/png");
  values.put(MediaStore.Images.Media.TITLE, "Image.png");
  values.put(MediaStore.Images.Media.RELATIVE_PATH, "Pictures/" + saveDirName);

  Uri external = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
  ContentResolver resolver = context.getContentResolver();

  Uri insertUri = resolver.insert(external, values);
  BufferedInputStream inputStream = null;
  OutputStream os = null;
  boolean result = false;
  try {
   inputStream = new BufferedInputStream(new FileInputStream(sourceFile));
   if (insertUri != null) {
    os = resolver.openOutputStream(insertUri);
   }
   if (os != null) {
    byte[] buffer = new byte[1024 * 4];
    int len;
    while ((len = inputStream.read(buffer)) != -1) {
     os.write(buffer, 0, len);
    }
    os.flush();
   }
   result = true;
  } catch (IOException e) {
   result = false;
  } finally {
   close(os, inputStream);
  }
  return result;
}

4.EditText 는 기본적으로 초점 을 가 져 오지 않 고 키보드 가 자동 으로 꺼 지지 않 습 니 다.
질문 targetSdkVersion >= Build.VERSION_CODES.P 의 경우 장치 버 전 은 Android P 이상 버 전 입 니 다.해결 방법 은 onCreate 에 다음 코드 를 추가 하면 초점 을 얻 을 수 있 습 니 다.키보드 팝 업 이 필요 하면 지연 시 킬 수 있 습 니 다.

mEditText.post(() -> {
  mEditText.requestFocus();
  mEditText.setFocusable(true);
  mEditText.setFocusableInTouchMode(true);
});
5.APK Intent 및 기타 공유 파일 관련 Intent 설치

/*
*  Android N  ,   FileProvider      ,  Android Q      File API     ,    Uri   ,
*      ,            ,          Intent.FLAG_GRANT_READ_URI_PERMISSION
*/ 
private void installApk() {
  if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q){
   //  Android Q,  mFilePath   ContentResolver   ,       
   Intent intent = new Intent(Intent.ACTION_VIEW);
   intent.setDataAndType(Uri.parse(mFilePath) ,"application/vnd.android.package-archive");
   intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
   startActivity(intent);
   return ;
  }

  File file = new File(saveFileName + "demo.apk");
  if (!file.exists())
   return;
  Intent intent = new Intent(Intent.ACTION_VIEW);
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
   intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
   Uri contentUri = FileProvider.getUriForFile(getApplicationContext(), "net.oschina.app.provider", file);
   intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
  } else {
   intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
   intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
  }
  startActivity(intent);
}

6.Activity 투명 관련,windowIsTranslucent 속성
Android Q 에 또 하나의 구멍 이 있 습 니 다.반투명 Activity 를 표시 하려 면 안 드 로 이 드 10 이전에 일반 스타일 Activity 는 window IsTranslucent=true 만 설정 하면 됩 니 다.하지만 AndroidQ 에 도착 하면 효과 가 없습니다.또한 동적 으로 View 를 설정 하면 화면 에 잔상 이 나타 납 니 다.
해결 방법:Dialog 스타일 Activity 를 사용 하고 window IsFloating=true 를 설정 합 니 다.이때 문제 가 다시 발생 했 습 니 다.Activity 루트 레이아웃 에 fitsSystem Window=true 가 설정 되 어 있 지 않 으 면 기본적으로 상태 표시 줄 에 침입 하지 않 아 화면 이 정상 으로 보 입 니 다.
7.클립보드 호 환
Android Q 에 서 는 대화 가능 한 상황(기본 입력 법 자체 가 상호작용 가능)에 만 클립보드 와 감청 클립보드 의 변 화 를 방문 할 수 있 습 니 다.onResume 리 셋 에서 도 클립보드 에 직접 접근 할 수 없습니다.이렇게 하면 배경 에서 미 친 감청 응답 클립보드 의 내용,미 친 팝 업 창 을 피 할 수 있 습 니 다.
따라서 클립보드 감청 이 더 필요 하 다 면 생애 주기 리 셋 을 적용 해 앱 백 엔 드 를 되 돌려 줌 으로 써 클립보드 방문 을 몇 밀리초 늦 추고 마지막 으로 방문 해 얻 은 클립보드 내용 을 저장 해 매번 변화 가 있 는 지 를 비교 해 다음 작업 을 할 수 있다.
8.제3자 가 사진 을 공유 하 는 등 작업 을 하고 파일 경 로 를 직접 사용 하 는 경우,예 를 들 어 QQ 이미지 공유 등 은 모두 주의해 야 합 니 다.이것 은 불가능 합 니 다.모두 MediaStore 등 API 를 통 해 Uri 를 가 져 와 서 만 작업 할 수 있 습 니 다.
이것 은 우리 가 sdk 에서 29 로 업그레이드 할 때 발생 하 는 실제 문제 에 따라 나열 한 것 입 니 다.번역 AndroidQ 의 행위 변경 이 아니 라 구체 적 인 문 제 는 자신의 실제 에 따라 스스로 해결 하 십시오.
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기