Android:如何制作默认拨号应用程序?

7

今天我收到了来自Google关于我的应用Facetocall的拒绝通知。

  • 根据政策要求,您的应用在请求相关权限之前似乎没有提示用户成为默认处理程序。 请进行必要的更改以符合政策要求,并通过声明表单重新提交您的应用程序。

  • 您的声明表单中列出了默认处理程序功能,但您的应用程序没有默认处理程序功能。

我的目标是制作一个默认的拨号器应用程序。

这是我的清单文件:

<?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>

当我的应用程序启动时,我会执行以下操作:

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());
}

这里我错过了什么?

我尝试再次提交表单,这次我添加了一个视频,展示了我的应用程序在仿真器上的情况(我在所有真实设备上都看到了同样的行为),这是我收到的回复:

  • 您的应用似乎没有在请求相关权限之前提示用户成为默认处理程序,这是政策要求的必要更改。请进行必要更改以符合政策要求,并通过声明表格重新提交您的应用。

谷歌最近宣布,如果一个应用程序不是默认的短信或电话应用程序,则不应请求SMS权限或通话日志权限。这是出于安全原因。在此处找到一篇文章链接:https://support.google.com/googleplay/android-developer/answer/9047303。我认为,因为您想要作为默认的呼叫应用程序并使用上述敏感权限,您必须告诉用户为什么需要这些权限以及为什么他应该在继续执行```startActivityForResult(intent, REQUEST_CODE_SET_DEFAULT_DIALER)```之前通过对话框允许您。 - Abhishek Madan
@AbhishekMadan 在你发给我的链接中,点击“短信和通话记录权限的允许使用”,它会展示我的使用案例。 - Ilya Gazman
如果您相信您的应用程序符合可接受使用的政策要求或符合例外条件,尽快提交一个权限声明表格给Google Play进行审核。如果您的请求被批准,您将收到通知。您无需在提交声明表格之前实施APK更改。所以,我相信你只需要按照他们说的提交声明表格即可。 - Abhishek Madan
是的,我做了,就像问题中提到的那样,我被拒绝了。 - Ilya Gazman
他们所说的是,在询问和使用权限之前,您的应用程序应该成为默认处理程序。关键在于在调用isAlreadyDefaultDialer()之前应用程序所做的事情。您是否在成为默认处理程序之前询问或使用权限? - anemomylos
显示剩余4条评论
3个回答

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()

}


你能告诉我你具体做了什么吗? - akash rao

0

不需要惊慌。我也遇到了这种情况,与我的应用程序上的AdMob内容有关。我已经完美地声明了一切,但他们仍然说由于应用程序展示的广告类型,内容评级不好。当我们交换了更多的邮件后,他们向我发送了带有错误广告证据的屏幕截图,所以最终我再次检查了整个代码,并发现了我的错误。

这里的重点是,谷歌很擅长他们所做的事情,如果他们这么说,那么您的应用程序缺少某些东西。

说实话,您的应用程序没有在任何地方要求用户允许将其设置为默认值,而是在后台自动设置为默认值。您应该问询应用程序所需的每个关键权限,这些权限可以被任何应用程序、病毒或间谍软件用于干扰用户隐私

您可以使用以下示例中的函数来执行此操作,从用户那里请求相机权限:

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)
    }

你可以在Google Samples中查看完整的代码库

不用担心。如果你纠正了这个问题,他们会接受你的申请,就像他们接受了我的一样。


说实话,你的应用程序没有在任何地方要求用户将其设置为默认选项。你是怎么得出这个结论的?为什么你会说到“应用程序”,而我只谈到了一个?权限如何与新政策有关? - Ilya Gazman
你发布的代码没有任何来自最终用户的查询,这就是为什么。在开始任何意图之前,它应该在你的checkdefaulthandler函数中。 - Vanshaj Daga
1
这里的重点是Google擅长他们所做的事情,如果他们这么说,那么你的应用程序就缺少了某些东西。嗯,并不总是这样;-) - anemomylos

-2

如果有人遇到这篇文章…… 我在这里用它来询问用户是否要更改默认的拨号器。 请注意,会有两个窗口提示(对我来说没问题)。

   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();

}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接