You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

解决Spotify Android SDK auth-lib的「需要明确用户授权」错误

Android Studio应用连接Spotify时授权失败问题

错误信息

{"message":"Explicit user authorization is required to use Spotify. The user has to complete the auth-flow to allow the app to use Spotify on their behalf"}

response.getError()返回内容:Authentication Service Error Unknown

已验证的配置

  • Redirect URI设置为com.example.loopify_5://callback,已在Spotify开发者后台正确配置,Client ID无误;
  • 已将正确的SHA密钥上传至开发者后台;
  • 模拟器已安装Spotify,登录账号与开发者账号一致。

报错代码位置

报错发生在以下代码行:

AuthorizationRequest.Builder builder = new AuthorizationRequest.Builder(CLIENT_ID, AuthorizationResponse.Type.CODE, REDIRECT_URI);

完整代码

public class MainActivity extends AppCompatActivity {

private static final String CLIENT_ID = "xxxx";
private static final String REDIRECT_URI = "com.example.loopify_5://callback";
private SpotifyAppRemote mSpotifyAppRemote;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    EdgeToEdge.enable(this);
    setContentView(R.layout.activity_main);
    ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
        Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
        v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
        return insets;
    });


    authenticateSpotify();
}

private void authenticateSpotify() {
    AuthorizationRequest.Builder builder = new AuthorizationRequest.Builder(CLIENT_ID, AuthorizationResponse.Type.CODE, REDIRECT_URI);
    builder.setScopes(new String[]{"streaming"});
    AuthorizationRequest request = builder.build();
    AuthorizationClient.openLoginActivity(this, 1337, request);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
    super.onActivityResult(requestCode, resultCode, intent);

    // Check if result comes from the correct activity
    if (requestCode == 1337) {
        AuthorizationResponse response = AuthorizationClient.getResponse(resultCode, intent);
        switch (response.getType()) {
            // Response was successful and contains auth token
            case TOKEN:
                Toast.makeText(MainActivity.this, "Here", Toast.LENGTH_SHORT).show();
                connectToSpotifyRemote();
                break;

            // Auth flow returned an error
            case ERROR:
                Toast.makeText(MainActivity.this, "Authorization error: " + response.getError() + response.getCode(), Toast.LENGTH_SHORT).show();
                break;

            // Most likely auth flow was cancelled
            default:
                // Handle other cases
        }
    }
}

private void connectToSpotifyRemote() {
    ConnectionParams connectionParams = new ConnectionParams.Builder(CLIENT_ID)
            .setRedirectUri(REDIRECT_URI)
            .showAuthView(true)
            .build();

    SpotifyAppRemote.connect(this, connectionParams, new Connector.ConnectionListener() {

        public void onConnected(SpotifyAppRemote spotifyAppRemote) {
            mSpotifyAppRemote = spotifyAppRemote;
            Log.d("MainActivity", "Connected! Yay!");
            Toast.makeText(MainActivity.this, "Connected to Spotify Remote", Toast.LENGTH_SHORT).show();
            // Now you can start interacting with App Remote
            connected();
        }

        public void onFailure(Throwable throwable) {
            Toast.makeText(MainActivity.this, "Failed to connect to Spotify Remote", Toast.LENGTH_SHORT).show();
            Log.e("MainActivity", throwable.getMessage(), throwable);
            // Something went wrong when attempting to connect! Handle errors here
        }
    });
}

@Override
protected void onStart() {
    super.onStart();
    ConnectionParams connectionParams =
            new ConnectionParams.Builder(CLIENT_ID)
                    .setRedirectUri(REDIRECT_URI)
                    .showAuthView(true)
                    .build();

    SpotifyAppRemote.connect(this, connectionParams,
            new Connector.ConnectionListener() {

                public void onConnected(SpotifyAppRemote spotifyAppRemote) {
                    mSpotifyAppRemote = spotifyAppRemote;
                    Log.d("MainActivity", "Connected! Yay!");

                    // Now you can start interacting with App Remote
                    connected();

                }

                public void onFailure(Throwable throwable) {
                    Log.e("MyActivity", throwable.getMessage(), throwable);

                    // Something went wrong when attempting to connect! Handle errors here
                }
            });
}

@Override
protected void onStop() {
    super.onStop();
    SpotifyAppRemote.disconnect(mSpotifyAppRemote);
}

private void connected() {
    // Play a playlist
    mSpotifyAppRemote.getPlayerApi().play("spotify:playlist:37i9dQZF1DX2sUQwD7tbmL");

    // Subscribe to PlayerState
    mSpotifyAppRemote.getPlayerApi()
            .subscribeToPlayerState()
            .setEventCallback(playerState -> {
                final Track track = playerState.track;
                if (track != null) {
                    Log.d("MainActivity", track.name + " by " + track.artist.name);
                }
            });
}
}

解决方案

  1. 修复认证流程冲突
    代码中onCreate调用authenticateSpotify()启动授权,同时onStart又直接触发SpotifyAppRemote.connect(),两次请求会导致认证逻辑混乱。移除onStart内的连接代码,仅保留授权成功后触发连接的逻辑:
@Override
protected void onStart() {
    super.onStart();
    // 移除原有SpotifyAppRemote.connect()调用
}
  1. 调整授权响应类型
    将授权请求的类型从CODE改为TOKEN,适配Spotify App Remote的认证逻辑:
AuthorizationRequest.Builder builder = new AuthorizationRequest.Builder(CLIENT_ID, AuthorizationResponse.Type.TOKEN, REDIRECT_URI);
  1. 配置Manifest重定向规则
    在AndroidManifest.xml的MainActivity中添加intent-filter,确保应用能接收重定向请求:
<activity android:name=".MainActivity">
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="com.example.loopify_5" />
    </intent-filter>
</activity>
  1. 补充必要权限Scope
    除streaming外,添加播放器操作所需的权限,确保应用有足够权限:
builder.setScopes(new String[]{"streaming", "user-read-playback-state", "user-modify-playback-state"});
  1. 清除Spotify缓存
    在模拟器中进入Spotify应用设置,清除缓存和数据后重新登录,避免旧授权数据干扰。

内容的提问来源于stack exchange,提问作者NewCoder1423

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 03:54:53