简体   繁体   English

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

[英]Android: How to make a default dialer app?

Today I got a rejection from Google for my app Facetocall 今天,我的应用程式Facetocall遭到 Google拒绝

  • 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. 请进行必要的更改,以符合政策要求,然后通过声明表单重新提交您的应用。

You don't need to panic. 您不必惊慌。 This kind of conversation happened with me also, regarding AdMob content on my app. 关于我应用程序中AdMob内容的对话也与我发生了。 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. 这里的意思是Google擅长于他们的工作,如果他们这么说,那么您的应用程序就缺少了一些东西。

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 您可以在Google Samples中查看完整的存储库

And don't worry. 不用担心 If you rectify this problem, they will accept your application, as they did for mine. 如果您纠正此问题,他们将像您一样接受您的申请。

to make default dialer app, you need to do 2 things : 要设置默认的拨号器应用程序,您需要做两件事:

1. add the following permissions in your android manifest 1.在您的android清单中添加以下权限

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

}

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). 知道会有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();

} }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Android:如何显示安装在我的设备上的拨号程序列表,而不是直接调用默认拨号程序 - Android: How to show a list of dialer app installed on my device instead of directly calling default dialer 如何获取拨号应用程序android的默认应用程序名称 - How to get the default application name for dialer app android 如何基于谷歌最新的 Android 拨号器应用程序(或基于原版的 ROM,如 Lineage OS)制作拨号器? - How to make a dialer based on Google's Android latest dialer app (or of a Vanilla based ROM such as Lineage OS)? 如何在 AOSP 中将我的自定义拨号器应用程序设置为默认拨号器 - How to set my custom dialer app as default dialer in AOSP 如何在Android的拨号器(默认或股票拨号器)中启动服务 - How to start service in dialer (default or stock dialer) of android 如何检测默认拨号器应用程序更改? - How to detect Default Dialer app changes? 如何在android中使用默认拨号屏幕? - How to use default dialer screen in android? Android:如何覆盖拨号程序的默认行为 - Android: How to override default behavior of dialer 如果将我的应用程序选择为默认的Dialer App。 是否有可能在Dialer中显示呼叫 - If my app is selected as the default Dialer App. Is it possible to make intent to show call in the Dialer 如何直接从默认电话拨号器拨打紧急电话,而无需在Android中进行任何用户交互? - How to make an emergency call directly from default phone dialer without any user interaction in Android?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM