메뉴 건너뛰기

모바일앱


공개된 것들중 가장 최근의 방식으로 인증 받고 구글 스프레드 시트 API를 사용하는 방법을 정리해 봤습니다.


1. 가장 먼저 구글 개발자 콘솔에 접속하고 로그인 하세요. 구글개발자 콘솔 가기 >


2. 좌측의 API 관리자 메뉴에서 "사용자 인증 정보" 클릭


3. 사용자 인증정보 만들기 > 서비스 계정 키 > App Engine Default Service account 를 선택합니다.


4. 키 유형을 P12로 선택합니다.


5. 생성 클릭!


6. 생성된 P12 파일을 다운로드 받습니다. (마찬가지로 JSON을 선택해서 5와 6의 과정을 반복합니다.)


7. 해당 파일중 *.P12파일만 "abcd.p12"로 이름을 변경한 후 res/raw 디렉토리 아래에 복사합니다. (raw 디렉토리가 없으면 당황말고 맹그세요^^)


8. build.gradle 파일의 dependencies 항목에 아래 내용을 추가합니다.

compile('com.google.gdata:core:1.47.1') {
        exclude group: 'com.google.guava', module: 'guava'
    }
    compile 'com.google.apis:google-api-services-oauth2:v2-rev109-1.21.0'

9.  CellAddress.java 파일을 아래와 같이 작성합니다.
public class CellAddress {
    public final int row;
    public final int col;
    public final String idString;

    /**
     * Constructs a CellAddress representing the specified {@code row} and
     * {@code col}.  The idString will be set in 'RnCn' notation.
     */
    public CellAddress(int row, int col) {
        this.row = row;
        this.col = col;
        this.idString = String.format("R%sC%s", row, col);
    }
}

10. 아래는 공유되어 있는 시트들 중 첫번째 시트를 선택해서 내용을 채워 넣는 예제 입니다. 

public class GunmanClient  {
    private Context context;
    public GunmanClient(Context context) {
        this.context = context;
    }

    //다운로드 했던 p12 파일의 내용을 리소스로 부터 읽어 파일로 생성합니다.
    private File getTempPkc12File() throws IOException {
        //InputStream pkc12Stream = context.getAssets().open("raw/abcd.p12");
        InputStream pkc12Stream = context.getResources().openRawResource(R.raw.cre);
        File tempPkc12File = File.createTempFile("temp_pkc12_file", "p12");
        OutputStream tempFileStream = new FileOutputStream(tempPkc12File);

        int read = 0;
        byte[] bytes = new byte[1024];
        while ((read = pkc12Stream.read(bytes)) != -1) {
            tempFileStream.write(bytes, 0, read);
        }
        return tempPkc12File;
    }

    // p12파일을 인증과정에 사용합니다.
    private GoogleCredential getAuth() throws IOException, GeneralSecurityException {
        HttpTransport httpTransport = new NetHttpTransport();
        JacksonFactory jsonFactory = new JacksonFactory();
        String[] SCOPESArray = {"https://spreadsheets.google.com/feeds", "https://spreadsheets.google.com/feeds/spreadsheets/private/full", "https://docs.google.com/feeds"};
        final List SCOPES = Arrays.asList(SCOPESArray);
        GoogleCredential credential = new GoogleCredential.Builder()
                .setTransport(httpTransport)
                .setJsonFactory(jsonFactory)
                // 11번 순서로 부터 얻은 client_email 의 값을 반영합니다
                .setServiceAccountId("xxxxxxx@appspot.gserviceaccount.com")
                .setServiceAccountScopes(SCOPES)
                .setServiceAccountPrivateKeyFromP12File(getTempPkc12File())
                .build();

        return credential;
    }

    private Map<String, CellEntry> getCellEntryMap(
            SpreadsheetService ssSvc, URL cellFeedUrl, List<CellAddress> cellAddrs)
            throws IOException, ServiceException {
        CellFeed batchRequest = new CellFeed();
        for (CellAddress cellId : cellAddrs) {
            CellEntry batchEntry = new CellEntry(cellId.row, cellId.col, cellId.idString);
            batchEntry.setId(String.format("%s/%s", cellFeedUrl.toString(), cellId.idString));
            BatchUtils.setBatchId(batchEntry, cellId.idString);
            BatchUtils.setBatchOperationType(batchEntry, BatchOperationType.QUERY);
            batchRequest.getEntries().add(batchEntry);
        }

        CellFeed cellFeed = ssSvc.getFeed(cellFeedUrl, CellFeed.class);
        CellFeed queryBatchResponse =
                ssSvc.batch(new URL(cellFeed.getLink(Link.Rel.FEED_BATCH, Link.Type.ATOM).getHref()),
                        batchRequest);

        Map<String, CellEntry> cellEntryMap = new HashMap<>(cellAddrs.size());
        for (CellEntry entry : queryBatchResponse.getEntries()) {
            cellEntryMap.put(BatchUtils.getBatchId(entry), entry);
        }

        return cellEntryMap;
    }

    //데이터가 담긴 리스트의 내용들 WORKSHEET에 씁니다
    public boolean addDataToSheetList(ArrayList<String> myData, ProgressDialog progress) throws IOException, ServiceException, GeneralSecurityException {
        SpreadsheetService service =
                new SpreadsheetService("MySpreadsheetIntegration");
        service.setProtocolVersion(SpreadsheetService.Versions.V3);
        service.setOAuth2Credentials(getAuth());

        // Define the URL to request.  This should never change.
        URL SPREADSHEET_FEED_URL = new URL("https://spreadsheets.google.com/feeds/spreadsheets/private/full");

        // Make a request to the API and get all spreadsheets.
        SpreadsheetFeed feed = service.getFeed(SPREADSHEET_FEED_URL, SpreadsheetFeed.class);
        List<SpreadsheetEntry> spreadsheets = feed.getEntries();
        // Iterate through all of the spreadsheets returned

        boolean isSuccess = true;

        // 공유되어 있는 스프레드 시트중 첫번째 시트를 획득합니다
        SpreadsheetEntry spreadsheet = spreadsheets.get(0);

        //for (SpreadsheetEntry spreadsheet : spreadsheets) {
            // Print the title of this spreadsheet to the screen
            Log.d("GUNMAN", spreadsheet.getTitle().getPlainText());
            WorksheetFeed worksheetFeed = service.getFeed(spreadsheet.getWorksheetFeedUrl(), WorksheetFeed.class);
            List<WorksheetEntry> worksheets = worksheetFeed.getEntries();
            WorksheetEntry worksheet = worksheets.get(0);

            URL cellFeedUrl = worksheet.getCellFeedUrl();
            CellFeed cellFeed = service.getFeed(cellFeedUrl, CellFeed.class);

            // Build list of cell addresses to be filled in
            List<CellAddress> cellAddrs = new ArrayList<CellAddress>();
            for (int row = 1; row <= myData.size(); ++row) {
                //for (int col = 1; col <= 3; ++col) {
                    cellAddrs.add(new CellAddress(row, col));
                //}
            }

            // Prepare the update
            // getCellEntryMap is what makes the update fast.
            Map<String, CellEntry> cellEntries = getCellEntryMap(service, cellFeedUrl, cellAddrs);

            CellFeed batchRequest = new CellFeed();


            int i = 0;
            int prog=0;
            for(String element : myData) {
                CellAddress cellAddr = cellAddrs.get(i);
                CellEntry batchEntry = new CellEntry(cellEntries.get(cellAddr.idString));
                batchEntry.changeInputValueLocal(element);
                BatchUtils.setBatchId(batchEntry, cellAddr.idString);
                BatchUtils.setBatchOperationType(batchEntry, BatchOperationType.UPDATE);
                batchRequest.getEntries().add(batchEntry);

                i++;
            }

            // Submit the update
            Link batchLink = cellFeed.getLink(Link.Rel.FEED_BATCH, Link.Type.ATOM);
            CellFeed batchResponse = service.batch(new URL(batchLink.getHref()), batchRequest);

            // Check the results
            for (CellEntry entry : batchResponse.getEntries()) {
                //String batchId = BatchUtils.getBatchId(entry);
                if (!BatchUtils.isSuccess(entry)) {
                    isSuccess = false;
                    BatchStatus status = BatchUtils.getBatchStatus(entry);
                }
            }
        //}


        return isSuccess;
    }
}


11. 다운로드 받은 JSON 파일을 에디터에서 열어 "client_email"에 해당하는 "xxxx@appspot.googleservices.com" 주소를 확인합니다. (복사)


12. 구글 스프레드 시트를 하나 생성한 후 11에서 얻은 이메일 주소에 공유합니다.


13. 지금까지 작성한 코드를 실행해서 테스트 해 봅니다 ㅎ


건투를 빕니다~!!

profile
제목 날짜
[TIP] 죽지 않는 안드로이드 서비스 만들기 (Unstoppable service) 6 2015.06.26
[TIP] 안드로이드 앱 삭제 방지 기능 구현 2015.06.03
[TIP] Android - WebView 사용된 앱에 Proguard 적용시 주의 1 2011.08.06
[LINK] cab 파일 설치시 투데이 메뉴에 단축 아이콘 생성하기 2010.02.22
[TIP] 안드로이드 앱 빌드시 "Error:Execution failed for task ':app:compileDebugJavaWithJavac'" 오류가 발생할 경우 2017.09.13
[TIP] Error:java.lang.OutOfMemoryError: GC overhead limit exceeded 2016.11.03
[TIP] 안드로이드 앱이 처음 설치될때 Referrer 정보 받아 오기 2016.08.30
[TIP] 안드로이드에서 구글 스프레드시트에 데이터 쓰기 2016.05.04
[TIP] 키보드가 나타날때 레이아웃이 위로 움직인다면 2016.03.22
[TIP] 안드로이드 - 설치된 앱 목록 얻기 2016.03.22
[TIP] 안드로이드의 최상단에 띄워놓은 Floating Window가 키보드를 인지하는 방법 2016.01.07
[TIP] 안드로이드의 Floating Window가 Back키를 인지 하는 방법 2 2016.01.07
[TIP] 죽지 않는 안드로이드 서비스 만들기 (Unstoppable service) 6 2015.06.26
[TIP] 내 안드로이드 앱에 위젯을 띄우는 방법 2015.06.03
[TIP] 안드로이드 앱 삭제 방지 기능 구현 2015.06.03
[TIP] Jquery Mobile로 iOS앱 개발시 Status바 처리 2014.08.27
[TIP] iOS 앱 개발시 HTTP POST로 데이터 전송 방법 2014.06.07
[TIP] 안드로이드에서 대용량 이미지 읽기 2013.04.15
[TIP] 안드로이드 카메라 영상에 그림 그린후 저장하기 2013.01.02
[펌] 안드로이드 에뮬레이터 속도 개선방법 2012.07.19
Android 기반의 재미있는 개발제품을 파는 사이트 2012.04.26
WM6.5 프로세스 숨기기 여쭐께요. 1 2012.04.18
[TIP] Android - WebView 사용된 앱에 Proguard 적용시 주의 1 2011.08.06
회원가입 1 2011.01.11
태그 목록
위로