Android: How to make a default dialer app?

不羁的心 提交于 2021-02-07 03:40:41

问题


Today I got a rejection from Google for my app Facetocall

  • Your app does not appear to prompt the user to be a default handler prior to requesting related permissions as required by the policy. Please make necessary changes in order to comply with policy requirements and resubmit your app through a Declaration Form.

  • Default handler capability was listed on your declaration form, but your app has no default handler capability.

My goal is to make a default dialer app.

Here is my Manifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.gazman.beep"
    android:installLocation="preferExternal">

    <uses-permission android:name="android.permission.CALL_PHONE" />
    <uses-permission android:name="android.permission.READ_CONTACTS" />
    <uses-permission android:name="android.permission.READ_CALL_LOG" />
    <uses-permission android:name="android.permission.WRITE_CALL_LOG" />
    <uses-permission android:name="android.permission.SEND_SMS" />
    ... and other permissions

    <application
        android:name=".application.BeepApp"
        android:allowBackup="false"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        tools:ignore="GoogleAppIndexingWarning">

        <activity
            android:name=".system_intents.IntentsActivity"
            android:launchMode="singleTask"
            android:noHistory="true"
            android:theme="@style/Theme.Transparent">
            <intent-filter>
                <action android:name="android.intent.action.DIAL" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.DIAL" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:scheme="tel" />
            </intent-filter>
        </activity>

        <activity
            android:name=".call.CallActivity"
            android:launchMode="singleTop"
            android:screenOrientation="portrait"
            android:showForAllUsers="true" />

        <service
            android:name="com.gazman.beep.call.MyInCallService"
            android:permission="android.permission.BIND_INCALL_SERVICE">
            <meta-data
                android:name="android.telecom.IN_CALL_SERVICE_UI"
                android:value="true" />
            <intent-filter>
                <action android:name="android.telecom.InCallService" />
            </intent-filter>
        </service>

        ... And other declarations

    </application>

</manifest>

And here is what I do when my app launches:

private void checkDefaultHandler() {
    if (isAlreadyDefaultDialer()) {
        return;
    }
    Intent intent = new Intent(TelecomManager.ACTION_CHANGE_DEFAULT_DIALER);
    intent.putExtra(TelecomManager.EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME, getPackageName());
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivityForResult(intent, REQUEST_CODE_SET_DEFAULT_DIALER);
    }
    else{
        throw new RuntimeException("Default phone functionality not found");
    }
}

private boolean isAlreadyDefaultDialer() {
    TelecomManager telecomManager = (TelecomManager) getSystemService(TELECOM_SERVICE);
    return getPackageName().equals(telecomManager.getDefaultDialerPackage());
}

What am I missing here?

I tried submitting the form again and this time I add a video that shows my app on an emulator(I see the same behavior on all the real devices too) here is the reply that I got back:

  • Your app does not appear to prompt the user to be a default handler prior to requesting related permissions as required by the policy. Please make necessary changes in order to comply with policy requirements and resubmit your app through a Declaration Form.

回答1:


to make default dialer app, you need to do 2 things :

1. add the following permissions in your android manifest

<activity>
    <intent-filter>
        <action android:name="android.intent.action.DIAL"/>
        <category android:name="android.intent.category.DEFAULT"/>
    </intent-filter>
</activity>
  1. actually performing the check :
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.main_layout)
    ...
    checkDefaultDialer()
    ...
}
const val REQUEST_CODE_SET_DEFAULT_DIALER=200

private fun checkDefaultDialer() {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M)
        return

    val telecomManager = getSystemService(TELECOM_SERVICE) as TelecomManager
    val isAlreadyDefaultDialer = packageName == telecomManager.defaultDialerPackage
    if (isAlreadyDefaultDialer)
        return
    val intent = Intent(TelecomManager.ACTION_CHANGE_DEFAULT_DIALER)
                .putExtra(TelecomManager.EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME, packageName)
    startActivityForResult(intent, REQUEST_CODE_SET_DEFAULT_DIALER)
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    when (requestCode) {
        REQUEST_CODE_SET_DEFAULT_DIALER -> checkSetDefaultDialerResult(resultCode)
    }
}

private fun checkSetDefaultDialerResult(resultCode: Int) {
    val message = when (resultCode) {
        RESULT_OK       -> "User accepted request to become default dialer"
        RESULT_CANCELED -> "User declined request to become default dialer"
        else            -> "Unexpected result code $resultCode"
    }

    Toast.makeText(this, message, Toast.LENGTH_SHORT).show()

}



回答2:


You don't need to panic. This kind of conversation happened with me also, regarding AdMob content on my app. I declared everything perfectly but still they were saying content rating not fine due to type of Ads my app was showing. When more mails exchanged they sent me screenshot with the proof of wrong Ads, so finally i checked my whole code again and found my mistake.

The point here is that Google is good at what they do, and if they said so, then your app lacks something.

To be very honest, your app did not ask the user anywhere to allow it to be set as default, instead it set itself default in the background. You should ask for every permission required by your app that are critical and can be used by any app or virus or spyware to interfere with user privacy.

You can do that with a function like in the following example, which is asking for Camera permission from the user:

private void requestCameraPermission() {
        Log.i(TAG, "CAMERA permission has NOT been granted. Requesting permission.");

        // BEGIN_INCLUDE(camera_permission_request)
        if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                Manifest.permission.CAMERA)) {
            // Provide an additional rationale to the user if the permission was not granted
            // and the user would benefit from additional context for the use of the permission.
            // For example if the user has previously denied the permission.
            Log.i(TAG,
                    "Displaying camera permission rationale to provide additional context.");
            Snackbar.make(mLayout, R.string.permission_camera_rationale,
                    Snackbar.LENGTH_INDEFINITE)
                    .setAction(R.string.ok, new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            ActivityCompat.requestPermissions(MainActivity.this,
                                    new String[]{Manifest.permission.CAMERA},
                                    REQUEST_CAMERA);
                        }
                    })
                    .show();
        } else {

            // Camera permission has not been granted yet. Request it directly.
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA},
                    REQUEST_CAMERA);
        }
        // END_INCLUDE(camera_permission_request)
    }

You can see the complete repository at Google Samples

And don't worry. If you rectify this problem, they will accept your application, as they did for mine.




回答3:


in case anyone comes cross this post . . . I used this for asking the user for changing the default dailer. Know that the there gonna be 2 windows prompting(for me it was fine).

   private void setDefaultDialer()


 {
    AlertDialog.Builder builder;
    builder = new AlertDialog.Builder(this);
    builder.setMessage("Do you want to make Cricket your default Dialer?(it will not cover or replace your dialer)")
            .setCancelable(false)
            .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {
                    defaultDialerPackage = "cricket";
                    Intent intent = new Intent(TelecomManager.ACTION_CHANGE_DEFAULT_DIALER);
                    startActivityForResult(intent.putExtra(TelecomManager.EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME,getPackageName()),REQUEST_CODE_SET_DEFAULT_DIALER);
                }
            })
            .setNegativeButton("No", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {
                    dialog.cancel();
                    Toast.makeText(getApplicationContext(),"Cancelled - No action was taken",
                            Toast.LENGTH_SHORT).show();
                }
            });

AlertDialog alert = builder.create();
alert.setTitle("Cricket need default dialer permission!!");
alert.show();

}



来源:https://stackoverflow.com/questions/54190881/android-how-to-make-a-default-dialer-app

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!