Upgrade to Pro — share decks privately, control downloads, hide ads and more …

デフォルトアプリとパーミッション

 デフォルトアプリとパーミッション

katsuki-nakatani

November 09, 2017
Tweet

More Decks by katsuki-nakatani

Other Decks in Programming

Transcript

  1. パーミッションには種類がある adb shell pm list permissions -f -g + permission:android.permission.READ_CONTACTS

    package:android label:read your contacts description:Allows the app ... protectionLevel:dangerous + permission:android.permission.MODIFY_PHONE_STATE package:android label:null description:null protectionLevel:signature|privileged 一般アプリで使用可能 Runtime Permission機能で権限を許可 一般アプリで使用不可能 システムアプリのみで許可
  2. ちなみに 未読ログはWRITE_CALL_LOGの権限で消せる(フラグは更新できる) val content = context.contentResolver value.put(CallLog.Calls.NEW, 0) value.put(CallLog.Calls.IS_READ, 1)

    content.update(CallLog.Calls.CONTENT_URI, value, CallLog.Calls.TYPE + "=" + CallLog.Calls.MISSED_TYPE + " AND " + CallLog.Calls.NEW + "='1'" + " AND " + CallLog.Calls.IS_READ + "='0'", null) CallLogデータベース上は、未読は0件になるが、通知は消えなく、 通知に表示される未読件数も別のところ(TelecomManager)で管理されているため、 通話履歴の件数はずっと増え続けるし表示に不整合が起きる
  3. 必要なIntentFilterを登録すると選択できるよう になります PhoneAppとして登録出来る要件は 下記のDialerとして反応するIntentFilterをManifestに登録すること <intent-filter> <action android:name="android.intent.action.VIEW" /> <action android:name="android.intent.action.DIAL"

    /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="tel" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.DIAL" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter>
  4. 通話ログ消去の実装 val content = context.contentResolver ContentValues().apply{ put(CallLog.Calls.NEW, 0) put(CallLog.Calls.IS_READ, 1)

    }.also{ content.update(CallLog.Calls.CONTENT_URI, it, CallLog.Calls.TYPE + "=" + CallLog.Calls.MISSED_TYPE + " AND " + CallLog.Calls.NEW + "='1'" + " AND " + CallLog.Calls.IS_READ + "='0'", null) } val manager = context.getSystemService(Context.TELECOM_SERVICE) as TelecomManager if (TextUtils.equals(manager.defaultDialerPackage, context.packageName)) { manager.cancelMissedCallsNotification() ・・・デフォルトアプリでない場合は落ちる } 通知ログDBの更新 デフォルトアプリとして登録 されているか判断し、通知を消去 HogeActivityやHogeService
  5. Manifestにレシーバとサービスを追加 <receiver android:name=".MissedCallNotificationReceiver" android:directBootAware="true"> <intent-filter> <action android:name="android.telecom.action.SHOW_MISSED_CALLS_NOTIFICATION" /> </intent-filter> </receiver>

    不在着信を受け取るレシーバ レシーバから呼び出すサービス <service android:name=".MissedCallNotificationService" android:permission="android.permission.BIND_JOB_SERVICE" android:enabled="true" android:exported="true" />
  6. レシーバの実装 class MissedCallNotificationReceiver : BroadcastReceiver() { override fun onReceive(context: Context,

    intent: Intent) { val action = intent.action if (ACTION_SHOW_MISSED_CALLS_NOTIFICATION != action) { return } val count = intent.getIntExtra(EXTRA_NOTIFICATION_COUNT, UNKNOWN_MISSED_CALL_COUNT) val number = intent.getStringExtra(EXTRA_NOTIFICATION_PHONE_NUMBER) if (count > 0) MissedCallNotificationService.enqueueWork(context, MissedCallNotificationService.createIntent(context, count, number)) } companion object { val ACTION_SHOW_MISSED_CALLS_NOTIFICATION = "android.telecom.action.SHOW_MISSED_CALLS_NOTIFICATION" val EXTRA_NOTIFICATION_COUNT = "android.telecom.extra.NOTIFICATION_COUNT" val EXTRA_NOTIFICATION_PHONE_NUMBER = "android.telecom.extra.NOTIFICATION_PHONE_NUMBER" val UNKNOWN_MISSED_CALL_COUNT = -1 } }
  7. 通知を上げるサービスの実装 class MissedCallNotificationService : JobIntentService() { companion object { …

    fun enqueueWork(context: Context, work: Intent) { enqueueWork(context, MissedCallNotificationService::class.java, JOB_ID, work) } ... override fun onHandleWork(intent: Intent) { //通知処理を実装 }