Mohamed Mohamed
Mohamed Mohamed

Reputation: 120

android youtube api v3 not work on release version

first let's start with my code i used for get list of videos depend on search query of the user

public class YouTubeVideoLoader extends AsyncTask<String, Void, List<YouTubeVideo>>
{
private static final String TAG = LogHelper.makeLogTag(YouTubeVideoLoader.class);

private Context context;
private YouTube youtube;

private YouTube.Search.List searchList;

private String keywords;
private String currentPageToken;
private String nextPageToken;

private YouTubeVideoReceiver youTubeVideoReceiver;

private String language;

public YouTubeVideoLoader(Context context)
{
    getInstance(context);
    this.context = context;
    this.youtube = getYouTube();
    this.keywords = null;
    this.currentPageToken = null;
    this.nextPageToken = null;
    this.youTubeVideoReceiver = null;
    this.language = Locale.getDefault().getLanguage();
}

@Override
protected List<YouTubeVideo> doInBackground(String... params)
{
    if (keywords == null) return null;
    try {
        return searchVideos();
    } catch (Exception e) {
        e.printStackTrace();
    }

    return null;
}

@Override
protected void onPostExecute(List<YouTubeVideo> ytVideos)
{
    youTubeVideoReceiver.onVideosReceived(ytVideos, currentPageToken, nextPageToken);
}

/**
 * Start the search.
 *
 * @param keywords - query
 */
public void search(String keywords)
{
    this.keywords = keywords;
    this.currentPageToken = null;
    this.nextPageToken = null;
    this.execute();
}

/**
 * Start the search.
 *
 * @param keywords         - query
 * @param currentPageToken - contains the Page Token
 */
public void search(String keywords, String currentPageToken)
{
    this.keywords = keywords;
    this.currentPageToken = currentPageToken;
    this.nextPageToken = null;
//        this.execute();
    this.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
}

public void setYouTubeVideoReceiver(YouTubeVideoReceiver youTubeVideoReceiver)
{
    this.youTubeVideoReceiver = youTubeVideoReceiver;
}

/**
 * Search videos for a specific query
 */
private List<YouTubeVideo> searchVideos()
{

    
    List<YouTubeVideo> ytVideos = new ArrayList<>();
    try {
        searchList = youtube.search().list(YOUTUBE_SEARCH_LIST_PART);
        searchList.setKey(Config.YOUTUBE_API_KEY);
        searchList.set("key",Config.YOUTUBE_API_KEY);
        searchList.setQ(keywords);
        searchList.setType(YOUTUBE_SEARCH_LIST_TYPE); //TODO ADD PLAYLISTS SEARCH
        searchList.setMaxResults(Config.MAX_VIDEOS_RETURNED);
        searchList.setFields(YOUTUBE_SEARCH_LIST_FIELDS);
        searchList.set(YOUTUBE_LANGUAGE_KEY, language);
        if (currentPageToken != null) {
            searchList.setPageToken(currentPageToken);
        }


       

        final Pattern pattern = Pattern.compile(YT_REGEX);
        final Matcher matcher = pattern.matcher(keywords);

        if (matcher.find()) {

            Log.e(TAG, "YouTube ID: " + matcher.group(1));

            YouTube.Videos.List singleVideo = youtube.videos().list(YOUTUBE_VIDEO_PART);
            singleVideo.setKey(Config.YOUTUBE_API_KEY);
            searchList.set("key",Config.YOUTUBE_API_KEY);
            singleVideo.setFields(YOUTUBE_VIDEO_FIELDS);
            singleVideo.set(YOUTUBE_LANGUAGE_KEY, language);
            singleVideo.setId(matcher.group(1));
            VideoListResponse resp = singleVideo.execute();
            List<Video> videoResults = resp.getItems();

            for (Video videoResult : videoResults) {
                YouTubeVideo item = new YouTubeVideo();

                if (videoResult != null) {
                    // SearchList list info
                    item.setTitle(videoResult.getSnippet().getTitle());
                    item.setThumbnailURL(videoResult.getSnippet().getThumbnails().getDefault().getUrl());
                    item.setId(videoResult.getId());

                    // Video info
                    if (videoResult.getStatistics() != null) {
                        BigInteger viewsNumber = videoResult.getStatistics().getViewCount();
                        String viewsFormatted = NumberFormat.getIntegerInstance().format(viewsNumber) + " views";
                        item.setViewCount(viewsFormatted);
                    }
                    if (videoResult.getContentDetails() != null) {
                        String isoTime = videoResult.getContentDetails().getDuration();
                        String time = Utils.convertISO8601DurationToNormalTime(isoTime);
                        item.setDuration(time);
                    }
                } else {
                    item.setDuration("NA");
                }

                // Add to the list
                ytVideos.add(item);
            }
        } else {

            YouTube.Videos.List videosList = youtube.videos().list(YOUTUBE_VIDEO_LIST_PART);

            videosList.setKey(Config.YOUTUBE_API_KEY);
            searchList.set("key",Config.YOUTUBE_API_KEY);
            videosList.setFields(YOUTUBE_VIDEO_LIST_FIELDS);

            videosList.set(YOUTUBE_LANGUAGE_KEY, language);


            
            final SearchListResponse searchListResponse = searchList.execute();

       

           
            Log.e(TAG, "Printed " + searchListResponse.getPageInfo().getResultsPerPage() +
                    " out of " + searchListResponse.getPageInfo().getTotalResults() +
                    ".\nCurrent page token: " + searchList.getPageToken() + "\n" +
                    "Next page token: " + searchListResponse.getNextPageToken() +
                    ".\nPrev page token: " + searchListResponse.getPrevPageToken());

             
            final List<SearchResult> searchResults = searchListResponse.getItems();

            // Stores the nextPageToken
            nextPageToken = searchListResponse.getNextPageToken();
            
            // Finds video list
            videosList.setId(Utils.concatenateIDs(searchResults));
            VideoListResponse resp = videosList.execute();
            List<Video> videoResults = resp.getItems();

            // Create the ytVideos list to be displayed in the UI
            

            int index = 0;
            for (SearchResult result : searchResults) {
                if (result.getId() == null) {
                    continue;
                }

                YouTubeVideo item = new YouTubeVideo();

                String title = StringUtils.unescapeHtml3(result.getSnippet().getTitle());
                LogHelper.e(TAG, "Title: " + title);
                // SearchList list info
                item.setTitle(title);
                item.setThumbnailURL(result.getSnippet().getThumbnails().getDefault().getUrl());
                item.setId(result.getId().getVideoId());

                // Video info
                Video videoResult = videoResults.get(index);
                if (videoResult != null) {
                    if (videoResult.getStatistics() != null) {
                        BigInteger viewsNumber = videoResult.getStatistics().getViewCount();
                        String viewsFormatted = NumberFormat.getIntegerInstance().format(viewsNumber) + " views";
                        item.setViewCount(viewsFormatted);
                    }
                    if (videoResult.getContentDetails() != null) {
                        String isoTime = videoResult.getContentDetails().getDuration();
                        String time = Utils.convertISO8601DurationToNormalTime(isoTime);
                        item.setDuration(time);
                    }
                } else {
                    item.setDuration("NA");
                }

                // Add to the list
                ytVideos.add(item);
                index++;

            }
        }
    } catch (Exception e) {
        Log.e(TAG, "catch Could not initialize: " + e);
        e.printStackTrace();
    }

    Log.e(TAG, "LoadInBackground: return " + ytVideos.size());
    return ytVideos;
}

}

this code work without any problem on debug version of my app about the console developer youtube api i set it for none

any way when i change my app to release the Youtube search code not work and i got this error

    {
  "error": {
    "code": 403,
    "message": "The request is missing a valid API key.",
    "errors": [
      {
        "message": "The request is missing a valid API key.",
        "domain": "global",
        "reason": "forbidden"
      }
    ],
    "status": "PERMISSION_DENIED"
  }
 }

i take look to my api its valid

from the try and catch error i got the http url and its

https://www.googleapis.com/youtube/v3/search?p=pageInfo,nextPageToken,items(id/videoId,snippet/title,snippet/thumbnails/default/url)&q=WWWWWWCuoKigBEzKx-a1NowWWWJFNEvMAZtd0GM&r=id,snippet&s=50&u=D8%AA%D9%&v=video&hl=en

where the WWWWWWCuoKigBEzKx-a1NowWWWJFNEvMAZtd0GM its my api key i changed little for security

as i see there is no parameter with key=

so same url i change the q= to key= and open same url in the browser and i got response

so i add

 searchList.set("key",Config.YOUTUBE_API_KEY);

to my code but still got null on result in List<Video> videoResults = resp.getItems(); in release version

i do search for one day and i did't find what cause this problem why its work in debug and in release not

any idea?

Upvotes: 3

Views: 300

Answers (1)

Mohamed Mohamed
Mohamed Mohamed

Reputation: 120

after 1 day i found the solution the parameter names changed in release version

the the api must have parameter with Key= but the release version change it to q= and change other parameters name

so the soultion as i found its enable Proguard by add useProguard true

in gradle like this

  buildTypes {
    release {
        
        minifyEnabled true
        useProguard true

        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        signingConfig signingConfigs.release
    }
}

then in the proguard-rules.pro add this lines

-keep class com.google.api.** { *; }

you can change the com.google.api.** with another package name if you got problem on another package

also i add this lines

-keepparameternames
-ignorewarnings

Upvotes: 3

Related Questions