[TIP] 안드로이드에서 구글 스프레드시트에 데이터 쓰기
- 파이팅건맨
- May 04, 2016
- 2262
공개된 것들중 가장 최근의 방식으로 인증 받고 구글 스프레드 시트 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. 지금까지 작성한 코드를 실행해서 테스트 해 봅니다 ㅎ
건투를 빕니다~!!
