Android 6.0 Marshmallow 対応まとめ

# Android 6.0 Marshmallow 対応まとめ

個人的に対応した Android M対応をメモしました。

## APIレベルを23にあげる

### app/build.gradle

```groovy
android {
  compileSdkVersion 23
  buildToolsVersion "23.0.2"

  defaultConfig {
    targetSdkVersion 23
  }
}
```

* sdkを8.3.0に更新

## Runtime Permissions

連絡先と位置情報とカメラの権限を使用しました。

android studioを1.4以上に更新すると権限をチェックしてないと怒られます。

googleのsampleですが
[easypermissions](https://github.com/googlesamples/easypermissions)
っていうライブラリを参考にしました。

### 連絡先

#### 権限を確認

```java
if (checkSelfPermission(android.Manifest.permission.GET_ACCOUNTS) == PackageManager.PERMISSION_GRANTED) {
  // 連絡先を使う処理
} else {
  // 権限がないので、許諾ダイヤログを表示
  requestPermissions(new String[]{android.Manifest.permission.GET_ACCOUNTS}, REQUEST_CONTACTS);
}
```

* requestPermissions は APIレベル23以上じゃないと使えない

* if 文で出し分ける

```java
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
}
```

* 関数にする

```java
@TargetApi(Build.VERSION_CODES.M)
public void checkContactsPermissions() {
}
```

#### 許諾ダイヤログの結果を受け取る

```java
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {

// 複数権限を確認するときのために、適当な定数を作って出しわける
if (requestCode == REQUEST_CONTACTS) {
  if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
    // 権限を許可した
  } else {
    // 権限を拒否した
    if (shouldShowRequestPermissionRationale(android.Manifest.permission.GET_ACCOUNTS)) {
      // 許諾ダイヤログを今後表示しないのチェックボックスをチェックしない
    } else {
      // 許諾ダイヤログを今後表示しないのチェックボックスをチェックした
    }
  }
}

```

### 位置情報

位置情報はfragmentで取得してる実装なので、fragmentでの書き方を書きます。少し書き方が変わりました。

#### 権限の確認

```java
mLocationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);

if ((PermissionChecker.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED)) {
  /*
  mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mLocationListener);
  と
  mLocationManager.removeUpdates(mLocationListener);
  は
  checkSelfPermissionのif文で囲ってあげないとダメ
  */
}
```

#### 許諾ダイヤログ表示

```java
@TargetApi(Build.VERSION_CODES.M)
public void checkLocationPermission() {
    if ((PermissionChecker.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_DENIED)) {
        ((Fragment) this).requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_LOCATION);
    }
}
```

* onRequestPermissionsResultは一緒


## Apache HTTP Client Removal

[HttpURLConnection](http://developer.android.com/intl/ja/reference/java/net/HttpURLConnection.html)
を使えということですが下記で対応しました。

### app/build.gradle

```groovy
dependencies {
  compile 'org.jbundle.util.osgi.wrapped:org.jbundle.util.osgi.wrapped.org.apache.http.client:4.1.2'
}
```

## Doze and App Standby

### Doze

* アラーム
* ネットワークアクセス
* WakeLock
* Job
* Sync
* GPS
* WiFiスキャン

### App Standby

* ネットワークアクセス
* Job
* Sync

止めたくないアプリや、処理などはgoogleにホワイトリスト申請すると
対象外にしてくれる可能性がある。

### Auto Backup

Android M からGoogle Driveに自動でバックアップするので、センシティブな情報は除外するように設定した方が良い

#### バックアップしないようにする

```xml
<application
    android:allowBackup="false"
    ...
/>
```

#### ホワイトリスト指定やブラックリスト指定もできる

http://developer.android.com/intl/ja/training/backup/autosyncapi.html