【发布时间】:2019-12-12 12:21:26
【问题描述】:
我正在开发一个应与 Google 日历交互的 Android 应用。我按照 Google API 网站上的说明,复制了这个类中的代码:
public class GoogleCalendarManager {
private static final String APPLICATION_NAME = "Locker";
private static final JacksonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
private static final String TOKENS_DIRECTORY_PATH = "tokens";
/**
* Global instance of the scopes required by this quickstart.
* If modifying these scopes, delete your previously saved tokens/ folder.
*/
private static final List<String> SCOPES = Collections.singletonList(CalendarScopes.CALENDAR_READONLY);
private static final String CREDENTIALS_FILE_PATH = "/credentials.json";
private Calendar.Events events;
private Context context;
/**
* Creates an authorized Credential object.
* @param HTTP_TRANSPORT The network HTTP Transport.
* @return An authorized Credential object.
* @throws IOException If the credentials.json file cannot be found.
*/
private static Credential getCredentials(final NetHttpTransport HTTP_TRANSPORT) throws IOException {
// Load client secrets.
InputStream in = GoogleCalendarManager.class.getResourceAsStream(CREDENTIALS_FILE_PATH);
if (in == null) {
Log.println(Log.DEBUG, "DEB", "------- FILE NOT FOUND ---------");
throw new FileNotFoundException("Resource not found: " + CREDENTIALS_FILE_PATH);
} else {
GoogleClientSecrets clientSecrets = GoogleClientSecrets
.load(JSON_FACTORY, new InputStreamReader(in));
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES)
.setDataStoreFactory(new FileDataStoreFactory(
new File(TOKENS_DIRECTORY_PATH)))
.setAccessType("offline")
.build();
LocalServerReceiver receiver = new LocalServerReceiver.Builder().setPort(8888).build();
return new AuthorizationCodeInstalledApp(flow, receiver)
.authorize("user");
}
}
public GoogleCalendarManager(Context context) {
this.context = context;
// Build a new authorized API client service.
NetHttpTransport HTTP_TRANSPORT = new NetHttpTransport();
try {
HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
} catch (GeneralSecurityException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Calendar service = null;
try {
service = new Calendar
.Builder(HTTP_TRANSPORT, JSON_FACTORY, getCredentials(HTTP_TRANSPORT))
.setApplicationName(APPLICATION_NAME)
.build();
this.events = service.events();
} catch (IOException e) {
e.printStackTrace();
}
}
public void addReminder(String domain, String username, String lastUpdate, int updatePeriodDays){
Resources resources = context.getResources();
Event event = new Event()
.setSummary(resources.getString(R.string.event_summary) + domain)
.setDescription(resources.getString(R.string.event_description)
+ domain + ": " + username
+ resources.getString(R.string.event_description_plus)
+ lastUpdate);
// Getting the date
Date lastUpdateDate = null;
try {
lastUpdateDate = new SimpleDateFormat("dd/MM/yyyy")
.parse(String.valueOf(lastUpdate));
} catch (ParseException e) {
e.printStackTrace();
}
long passPeriod = lastUpdateDate.getTime();
long updatePeriod = TimeUnit.DAYS.toMillis(updatePeriodDays);
long expirePeriod = passPeriod + updatePeriod;
DateTime startDateTime = new DateTime(expirePeriod);
EventDateTime start = new EventDateTime()
.setDateTime(startDateTime);
event.setStart(start);
DateTime endDateTime = new DateTime(expirePeriod);
EventDateTime end = new EventDateTime()
.setDateTime(endDateTime);
event.setEnd(end);
}
}
我的问题是 java.io.IOException: unable to create directory: /tokens 我尝试在其中创建文件夹,在这一行:
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES)
.setDataStoreFactory(new FileDataStoreFactory(
new File(TOKENS_DIRECTORY_PATH)))
.setAccessType("offline")
.build();
我已经尝试在我的应用的清单文件中添加权限:
<?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.example.locker">
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission>
<application
...
</application>
</manifest>
我真的不知道如何在设备的内部存储上进行写入。我尝试在 File 构造函数中编写 String.valueOf(Environment.getDataDirectory())) 而不是常量 TOKENS_DIRECTORY_PATH ,但是我遇到了另一个错误,并且程序崩溃:
java.lang.NoClassDefFoundError: Failed resolution of: Ljava/nio/file/attribute/PosixFilePermission;
我用模拟器和真实设备尝试了这两种情况,但错误没有改变。不知道怎么写权限。
谢谢!!!
更新 我在我的 Activity 中添加了这个方法,在创建 GoogleCalendarManager 之前执行:
public boolean isStoragePermissionGranted() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
Log.println(Log.DEBUG, "DEB","Permission is granted");
return true;
} else {
Log.println(Log.DEBUG, "DEB","Permission is revoked");
ActivityCompat.requestPermissions(this, new String[]{
Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
return false;
}
}
else { //permission is automatically granted on sdk<23 upon installation
Log.println(Log.DEBUG, "DEB","Permission is granted");
return true;
}
}
它打印 Permission isgranted 但我遇到了和以前一样的错误。
【问题讨论】:
-
我认为,您没有在运行时提供权限
-
如何查看?
-
您应该在运行时在 Android 6.0 及更高版本上提供所有权限。在您的应用的 MainActvity 中提供所有这些权限
-
我添加了那个方法,但是同样的问题
标签: java android permissions