i don't know what i did

This commit is contained in:
hyb1996
2017-09-22 16:12:07 +08:00
parent 23cd6ba6cd
commit 601019cab2
26 changed files with 2354 additions and 13 deletions

View File

@@ -9,8 +9,8 @@ android {
applicationId "com.stardust.scriptdroid" applicationId "com.stardust.scriptdroid"
minSdkVersion 17 minSdkVersion 17
targetSdkVersion 23 targetSdkVersion 23
versionCode 200 versionCode 201
versionName "3.0.0 Alpha1" versionName "3.0.0 Alpha2"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
multiDexEnabled true multiDexEnabled true
ndk { ndk {
@@ -132,6 +132,8 @@ dependencies {
compile 'com.squareup.retrofit2:converter-gson:2.3.0' compile 'com.squareup.retrofit2:converter-gson:2.3.0'
compile 'com.squareup.retrofit2:converter-gson:2.3.0' compile 'com.squareup.retrofit2:converter-gson:2.3.0'
compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0' compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'
//Picasso
compile 'com.squareup.picasso:picasso:2.5.2'
// Tasker Plugin // Tasker Plugin
compile 'com.twofortyfouram:android-plugin-client-sdk-for-locale:[4.0.2, 5.0[' compile 'com.twofortyfouram:android-plugin-client-sdk-for-locale:[4.0.2, 5.0['
compile 'com.flurry.android:analytics:7.0.0@aar' compile 'com.flurry.android:analytics:7.0.0@aar'

View File

@@ -82,6 +82,7 @@
<activity android:name=".ui.help.LocalWebViewActivity"/> <activity android:name=".ui.help.LocalWebViewActivity"/>
<activity android:name=".external.tasker.TaskerScriptEditActivity_"/> <activity android:name=".external.tasker.TaskerScriptEditActivity_"/>
<activity android:name=".ui.edit.ViewSampleActivity"/> <activity android:name=".ui.edit.ViewSampleActivity"/>
<activity android:name=".ui.login.LoginActivity_"/>
<activity android:name=".external.widget.ScriptWidgetSettingsActivity_"> <activity android:name=".external.widget.ScriptWidgetSettingsActivity_">
<intent-filter> <intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE"/> <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE"/>

View File

@@ -0,0 +1,41 @@
package com.stardust.scriptdroid.network;
import com.google.gson.GsonBuilder;
import com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import com.stardust.scriptdroid.network.util.WebkitCookieManagerProxy;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
/**
* Created by Stardust on 2017/9/20.
*/
public class NodeBB {
private static final NodeBB sInstance = new NodeBB();
private Retrofit mRetrofit;
NodeBB() {
mRetrofit = new Retrofit.Builder()
.baseUrl("http://www.autojs.org/")
.addConverterFactory(GsonConverterFactory.create(new GsonBuilder()
.setLenient()
.create()))
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(new OkHttpClient.Builder()
.cookieJar(new WebkitCookieManagerProxy())
.build())
.build();
}
public static NodeBB getInstance() {
return sInstance;
}
public Retrofit getRetrofit() {
return mRetrofit;
}
}

View File

@@ -0,0 +1,47 @@
package com.stardust.scriptdroid.network;
import com.google.gson.GsonBuilder;
import com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import com.stardust.scriptdroid.network.api.UserApi;
import com.stardust.scriptdroid.network.entity.TokenResponse;
import com.stardust.scriptdroid.network.entity.VerifyResponse;
import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.annotations.NonNull;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
/**
* Created by Stardust on 2017/9/20.
*/
public class UserService {
private static final UserService sInstance = new UserService();
private final Retrofit mRetrofit;
UserService() {
mRetrofit = NodeBB.getInstance().getRetrofit();
}
public Observable<TokenResponse> login(String userName, final String password) {
final UserApi userApi = mRetrofit.create(UserApi.class);
return userApi.verify(userName, password)
.subscribeOn(Schedulers.io())
.flatMap(new Function<VerifyResponse, ObservableSource<TokenResponse>>() {
@Override
public ObservableSource<TokenResponse> apply(@NonNull VerifyResponse verifyResponse) throws Exception {
if (verifyResponse.isSuccessful()) {
return userApi.generateToken(verifyResponse.getUid(), password);
} else {
return Observable.error(new Exception(verifyResponse.getMessage()));
}
}
});
}
}

View File

@@ -0,0 +1,34 @@
package com.stardust.scriptdroid.network.api;
import com.stardust.scriptdroid.network.entity.VerifyResponse;
import com.stardust.scriptdroid.network.entity.TokenResponse;
import com.stardust.scriptdroid.network.entity.User;
import io.reactivex.Observable;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.Path;
/**
* Created by Stardust on 2017/9/20.
*/
public interface UserApi {
@GET("/api/me")
Observable<User> me();
@FormUrlEncoded
@POST("/api/ns/login")
Observable<VerifyResponse> verify(@Field("username") String userName, @Field("password") String password);
@FormUrlEncoded
@POST("/api/v2/{uid}/tokens")
Observable<TokenResponse> generateToken(@Path("uid") String uid, @Field("password") String password);
}

View File

@@ -0,0 +1,253 @@
package com.stardust.scriptdroid.network.entity;
import com.google.gson.annotations.SerializedName;
public class GroupsItem{
@SerializedName("createtimeISO")
private String createtimeISO;
@SerializedName("createtime")
private String createtime;
@SerializedName("private")
private boolean jsonMemberPrivate;
@SerializedName("hidden")
private boolean hidden;
@SerializedName("userTitleEnabled")
private boolean userTitleEnabled;
@SerializedName("displayName")
private String displayName;
@SerializedName("memberCount")
private String memberCount;
@SerializedName("icon")
private String icon;
@SerializedName("description")
private String description;
@SerializedName("labelColor")
private String labelColor;
@SerializedName("userTitle")
private String userTitle;
@SerializedName("deleted")
private String deleted;
@SerializedName("system")
private boolean system;
@SerializedName("cover:position")
private String coverPosition;
@SerializedName("name")
private String name;
@SerializedName("cover:url")
private String coverUrl;
@SerializedName("cover:thumb:url")
private String coverThumbUrl;
@SerializedName("disableJoinRequests")
private boolean disableJoinRequests;
@SerializedName("slug")
private String slug;
@SerializedName("nameEncoded")
private String nameEncoded;
public void setCreatetimeISO(String createtimeISO){
this.createtimeISO = createtimeISO;
}
public String getCreatetimeISO(){
return createtimeISO;
}
public void setCreatetime(String createtime){
this.createtime = createtime;
}
public String getCreatetime(){
return createtime;
}
public void setJsonMemberPrivate(boolean jsonMemberPrivate){
this.jsonMemberPrivate = jsonMemberPrivate;
}
public boolean isJsonMemberPrivate(){
return jsonMemberPrivate;
}
public void setHidden(boolean hidden){
this.hidden = hidden;
}
public boolean isHidden(){
return hidden;
}
public void setUserTitleEnabled(boolean userTitleEnabled){
this.userTitleEnabled = userTitleEnabled;
}
public boolean isUserTitleEnabled(){
return userTitleEnabled;
}
public void setDisplayName(String displayName){
this.displayName = displayName;
}
public String getDisplayName(){
return displayName;
}
public void setMemberCount(String memberCount){
this.memberCount = memberCount;
}
public String getMemberCount(){
return memberCount;
}
public void setIcon(String icon){
this.icon = icon;
}
public String getIcon(){
return icon;
}
public void setDescription(String description){
this.description = description;
}
public String getDescription(){
return description;
}
public void setLabelColor(String labelColor){
this.labelColor = labelColor;
}
public String getLabelColor(){
return labelColor;
}
public void setUserTitle(String userTitle){
this.userTitle = userTitle;
}
public String getUserTitle(){
return userTitle;
}
public void setDeleted(String deleted){
this.deleted = deleted;
}
public String getDeleted(){
return deleted;
}
public void setSystem(boolean system){
this.system = system;
}
public boolean isSystem(){
return system;
}
public void setCoverPosition(String coverPosition){
this.coverPosition = coverPosition;
}
public String getCoverPosition(){
return coverPosition;
}
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setCoverUrl(String coverUrl){
this.coverUrl = coverUrl;
}
public String getCoverUrl(){
return coverUrl;
}
public void setCoverThumbUrl(String coverThumbUrl){
this.coverThumbUrl = coverThumbUrl;
}
public String getCoverThumbUrl(){
return coverThumbUrl;
}
public void setDisableJoinRequests(boolean disableJoinRequests){
this.disableJoinRequests = disableJoinRequests;
}
public boolean isDisableJoinRequests(){
return disableJoinRequests;
}
public void setSlug(String slug){
this.slug = slug;
}
public String getSlug(){
return slug;
}
public void setNameEncoded(String nameEncoded){
this.nameEncoded = nameEncoded;
}
public String getNameEncoded(){
return nameEncoded;
}
@Override
public String toString(){
return
"GroupsItem{" +
"createtimeISO = '" + createtimeISO + '\'' +
",createtime = '" + createtime + '\'' +
",private = '" + jsonMemberPrivate + '\'' +
",hidden = '" + hidden + '\'' +
",userTitleEnabled = '" + userTitleEnabled + '\'' +
",displayName = '" + displayName + '\'' +
",memberCount = '" + memberCount + '\'' +
",icon = '" + icon + '\'' +
",description = '" + description + '\'' +
",labelColor = '" + labelColor + '\'' +
",userTitle = '" + userTitle + '\'' +
",deleted = '" + deleted + '\'' +
",system = '" + system + '\'' +
",cover:position = '" + coverPosition + '\'' +
",name = '" + name + '\'' +
",cover:url = '" + coverUrl + '\'' +
",cover:thumb:url = '" + coverThumbUrl + '\'' +
",disableJoinRequests = '" + disableJoinRequests + '\'' +
",slug = '" + slug + '\'' +
",nameEncoded = '" + nameEncoded + '\'' +
"}";
}
}

View File

@@ -0,0 +1,17 @@
package com.stardust.scriptdroid.network.entity;
/**
* Created by Stardust on 2017/9/21.
*/
public class TokenResponse {
public String code;
public static class Payload {
public String token;
}
}

View File

@@ -0,0 +1,746 @@
package com.stardust.scriptdroid.network.entity;
import java.util.List;
import com.google.gson.annotations.SerializedName;
public class User{
@SerializedName("websiteLink")
private String websiteLink;
@SerializedName("reputation")
private String reputation;
@SerializedName("sso")
private List<Object> sso;
@SerializedName("icon:text")
private String iconText;
@SerializedName("isGlobalModerator")
private boolean isGlobalModerator;
@SerializedName("joindate")
private String joindate;
@SerializedName("profile_links")
private List<Object> profileLinks;
@SerializedName("reputation:disabled")
private boolean reputationDisabled;
@SerializedName("isAdmin")
private boolean isAdmin;
@SerializedName("moderationNote")
private String moderationNote;
@SerializedName("ips")
private List<String> ips;
@SerializedName("aboutme")
private String aboutme;
@SerializedName("isTargetAdmin")
private boolean isTargetAdmin;
@SerializedName("email:confirmed")
private boolean emailConfirmed;
@SerializedName("isAdminOrGlobalModerator")
private boolean isAdminOrGlobalModerator;
@SerializedName("emailClass")
private String emailClass;
@SerializedName("downvote:disabled")
private boolean downvoteDisabled;
@SerializedName("topiccount")
private String topiccount;
@SerializedName("isSelf")
private boolean isSelf;
@SerializedName("status")
private String status;
@SerializedName("birthday")
private String birthday;
@SerializedName("showHidden")
private boolean showHidden;
@SerializedName("yourid")
private int yourid;
@SerializedName("lastposttime")
private String lastposttime;
@SerializedName("isModerator")
private boolean isModerator;
@SerializedName("signature")
private String signature;
@SerializedName("icon:bgColor")
private String iconBgColor;
@SerializedName("canEdit")
private boolean canEdit;
@SerializedName("groupTitle")
private String groupTitle;
@SerializedName("followingCount")
private int followingCount;
@SerializedName("lastonlineISO")
private String lastonlineISO;
@SerializedName("email:disableEdit")
private boolean emailDisableEdit;
@SerializedName("uid")
private String uid;
@SerializedName("canChangePassword")
private boolean canChangePassword;
@SerializedName("profileviews")
private String profileviews;
@SerializedName("cover:url")
private String coverUrl;
@SerializedName("banned")
private boolean banned;
@SerializedName("userslug")
private String userslug;
@SerializedName("followerCount")
private int followerCount;
@SerializedName("email")
private String email;
@SerializedName("website")
private String website;
@SerializedName("isFollowing")
private boolean isFollowing;
@SerializedName("uploadedpicture")
private String uploadedpicture;
@SerializedName("passwordExpiry")
private String passwordExpiry;
@SerializedName("canBan")
private boolean canBan;
@SerializedName("lastonline")
private String lastonline;
@SerializedName("disableSignatures")
private boolean disableSignatures;
@SerializedName("groups")
private List<GroupsItem> groups;
@SerializedName("username:disableEdit")
private boolean usernameDisableEdit;
@SerializedName("picture")
private String picture;
@SerializedName("joindateISO")
private String joindateISO;
@SerializedName("isSelfOrAdminOrGlobalModerator")
private boolean isSelfOrAdminOrGlobalModerator;
@SerializedName("websiteName")
private String websiteName;
@SerializedName("isAdminOrGlobalModeratorOrModerator")
private boolean isAdminOrGlobalModeratorOrModerator;
@SerializedName("cover:position")
private String coverPosition;
@SerializedName("postcount")
private String postcount;
@SerializedName("location")
private String location;
@SerializedName("fullname")
private String fullname;
@SerializedName("age")
private int age;
@SerializedName("theirid")
private String theirid;
@SerializedName("username")
private String username;
public void setWebsiteLink(String websiteLink){
this.websiteLink = websiteLink;
}
public String getWebsiteLink(){
return websiteLink;
}
public void setReputation(String reputation){
this.reputation = reputation;
}
public String getReputation(){
return reputation;
}
public void setSso(List<Object> sso){
this.sso = sso;
}
public List<Object> getSso(){
return sso;
}
public void setIconText(String iconText){
this.iconText = iconText;
}
public String getIconText(){
return iconText;
}
public void setIsGlobalModerator(boolean isGlobalModerator){
this.isGlobalModerator = isGlobalModerator;
}
public boolean isIsGlobalModerator(){
return isGlobalModerator;
}
public void setJoindate(String joindate){
this.joindate = joindate;
}
public String getJoindate(){
return joindate;
}
public void setProfileLinks(List<Object> profileLinks){
this.profileLinks = profileLinks;
}
public List<Object> getProfileLinks(){
return profileLinks;
}
public void setReputationDisabled(boolean reputationDisabled){
this.reputationDisabled = reputationDisabled;
}
public boolean isReputationDisabled(){
return reputationDisabled;
}
public void setIsAdmin(boolean isAdmin){
this.isAdmin = isAdmin;
}
public boolean isIsAdmin(){
return isAdmin;
}
public void setModerationNote(String moderationNote){
this.moderationNote = moderationNote;
}
public String getModerationNote(){
return moderationNote;
}
public void setIps(List<String> ips){
this.ips = ips;
}
public List<String> getIps(){
return ips;
}
public void setAboutme(String aboutme){
this.aboutme = aboutme;
}
public String getAboutme(){
return aboutme;
}
public void setIsTargetAdmin(boolean isTargetAdmin){
this.isTargetAdmin = isTargetAdmin;
}
public boolean isIsTargetAdmin(){
return isTargetAdmin;
}
public void setEmailConfirmed(boolean emailConfirmed){
this.emailConfirmed = emailConfirmed;
}
public boolean isEmailConfirmed(){
return emailConfirmed;
}
public void setIsAdminOrGlobalModerator(boolean isAdminOrGlobalModerator){
this.isAdminOrGlobalModerator = isAdminOrGlobalModerator;
}
public boolean isIsAdminOrGlobalModerator(){
return isAdminOrGlobalModerator;
}
public void setEmailClass(String emailClass){
this.emailClass = emailClass;
}
public String getEmailClass(){
return emailClass;
}
public void setDownvoteDisabled(boolean downvoteDisabled){
this.downvoteDisabled = downvoteDisabled;
}
public boolean isDownvoteDisabled(){
return downvoteDisabled;
}
public void setTopiccount(String topiccount){
this.topiccount = topiccount;
}
public String getTopiccount(){
return topiccount;
}
public void setIsSelf(boolean isSelf){
this.isSelf = isSelf;
}
public boolean isIsSelf(){
return isSelf;
}
public void setStatus(String status){
this.status = status;
}
public String getStatus(){
return status;
}
public void setBirthday(String birthday){
this.birthday = birthday;
}
public String getBirthday(){
return birthday;
}
public void setShowHidden(boolean showHidden){
this.showHidden = showHidden;
}
public boolean isShowHidden(){
return showHidden;
}
public void setYourid(int yourid){
this.yourid = yourid;
}
public int getYourid(){
return yourid;
}
public void setLastposttime(String lastposttime){
this.lastposttime = lastposttime;
}
public String getLastposttime(){
return lastposttime;
}
public void setIsModerator(boolean isModerator){
this.isModerator = isModerator;
}
public boolean isIsModerator(){
return isModerator;
}
public void setSignature(String signature){
this.signature = signature;
}
public String getSignature(){
return signature;
}
public void setIconBgColor(String iconBgColor){
this.iconBgColor = iconBgColor;
}
public String getIconBgColor(){
return iconBgColor;
}
public void setCanEdit(boolean canEdit){
this.canEdit = canEdit;
}
public boolean isCanEdit(){
return canEdit;
}
public void setGroupTitle(String groupTitle){
this.groupTitle = groupTitle;
}
public String getGroupTitle(){
return groupTitle;
}
public void setFollowingCount(int followingCount){
this.followingCount = followingCount;
}
public int getFollowingCount(){
return followingCount;
}
public void setLastonlineISO(String lastonlineISO){
this.lastonlineISO = lastonlineISO;
}
public String getLastonlineISO(){
return lastonlineISO;
}
public void setEmailDisableEdit(boolean emailDisableEdit){
this.emailDisableEdit = emailDisableEdit;
}
public boolean isEmailDisableEdit(){
return emailDisableEdit;
}
public void setUid(String uid){
this.uid = uid;
}
public String getUid(){
return uid;
}
public void setCanChangePassword(boolean canChangePassword){
this.canChangePassword = canChangePassword;
}
public boolean isCanChangePassword(){
return canChangePassword;
}
public void setProfileviews(String profileviews){
this.profileviews = profileviews;
}
public String getProfileviews(){
return profileviews;
}
public void setCoverUrl(String coverUrl){
this.coverUrl = coverUrl;
}
public String getCoverUrl(){
return coverUrl;
}
public void setBanned(boolean banned){
this.banned = banned;
}
public boolean isBanned(){
return banned;
}
public void setUserslug(String userslug){
this.userslug = userslug;
}
public String getUserslug(){
return userslug;
}
public void setFollowerCount(int followerCount){
this.followerCount = followerCount;
}
public int getFollowerCount(){
return followerCount;
}
public void setEmail(String email){
this.email = email;
}
public String getEmail(){
return email;
}
public void setWebsite(String website){
this.website = website;
}
public String getWebsite(){
return website;
}
public void setIsFollowing(boolean isFollowing){
this.isFollowing = isFollowing;
}
public boolean isIsFollowing(){
return isFollowing;
}
public void setUploadedpicture(String uploadedpicture){
this.uploadedpicture = uploadedpicture;
}
public String getUploadedpicture(){
return uploadedpicture;
}
public void setPasswordExpiry(String passwordExpiry){
this.passwordExpiry = passwordExpiry;
}
public String getPasswordExpiry(){
return passwordExpiry;
}
public void setCanBan(boolean canBan){
this.canBan = canBan;
}
public boolean isCanBan(){
return canBan;
}
public void setLastonline(String lastonline){
this.lastonline = lastonline;
}
public String getLastonline(){
return lastonline;
}
public void setDisableSignatures(boolean disableSignatures){
this.disableSignatures = disableSignatures;
}
public boolean isDisableSignatures(){
return disableSignatures;
}
public void setGroups(List<GroupsItem> groups){
this.groups = groups;
}
public List<GroupsItem> getGroups(){
return groups;
}
public void setUsernameDisableEdit(boolean usernameDisableEdit){
this.usernameDisableEdit = usernameDisableEdit;
}
public boolean isUsernameDisableEdit(){
return usernameDisableEdit;
}
public void setPicture(String picture){
this.picture = picture;
}
public String getPicture(){
return picture;
}
public void setJoindateISO(String joindateISO){
this.joindateISO = joindateISO;
}
public String getJoindateISO(){
return joindateISO;
}
public void setIsSelfOrAdminOrGlobalModerator(boolean isSelfOrAdminOrGlobalModerator){
this.isSelfOrAdminOrGlobalModerator = isSelfOrAdminOrGlobalModerator;
}
public boolean isIsSelfOrAdminOrGlobalModerator(){
return isSelfOrAdminOrGlobalModerator;
}
public void setWebsiteName(String websiteName){
this.websiteName = websiteName;
}
public String getWebsiteName(){
return websiteName;
}
public void setIsAdminOrGlobalModeratorOrModerator(boolean isAdminOrGlobalModeratorOrModerator){
this.isAdminOrGlobalModeratorOrModerator = isAdminOrGlobalModeratorOrModerator;
}
public boolean isIsAdminOrGlobalModeratorOrModerator(){
return isAdminOrGlobalModeratorOrModerator;
}
public void setCoverPosition(String coverPosition){
this.coverPosition = coverPosition;
}
public String getCoverPosition(){
return coverPosition;
}
public void setPostcount(String postcount){
this.postcount = postcount;
}
public String getPostcount(){
return postcount;
}
public void setLocation(String location){
this.location = location;
}
public String getLocation(){
return location;
}
public void setFullname(String fullname){
this.fullname = fullname;
}
public String getFullname(){
return fullname;
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return age;
}
public void setTheirid(String theirid){
this.theirid = theirid;
}
public String getTheirid(){
return theirid;
}
public void setUsername(String username){
this.username = username;
}
public String getUsername(){
return username;
}
@Override
public String toString(){
return
"User{" +
"websiteLink = '" + websiteLink + '\'' +
",reputation = '" + reputation + '\'' +
",sso = '" + sso + '\'' +
",icon:text = '" + iconText + '\'' +
",isGlobalModerator = '" + isGlobalModerator + '\'' +
",joindate = '" + joindate + '\'' +
",profile_links = '" + profileLinks + '\'' +
",reputation:disabled = '" + reputationDisabled + '\'' +
",isAdmin = '" + isAdmin + '\'' +
",moderationNote = '" + moderationNote + '\'' +
",ips = '" + ips + '\'' +
",aboutme = '" + aboutme + '\'' +
",isTargetAdmin = '" + isTargetAdmin + '\'' +
",email:confirmed = '" + emailConfirmed + '\'' +
",isAdminOrGlobalModerator = '" + isAdminOrGlobalModerator + '\'' +
",emailClass = '" + emailClass + '\'' +
",downvote:disabled = '" + downvoteDisabled + '\'' +
",topiccount = '" + topiccount + '\'' +
",isSelf = '" + isSelf + '\'' +
",status = '" + status + '\'' +
",birthday = '" + birthday + '\'' +
",showHidden = '" + showHidden + '\'' +
",yourid = '" + yourid + '\'' +
",lastposttime = '" + lastposttime + '\'' +
",isModerator = '" + isModerator + '\'' +
",signature = '" + signature + '\'' +
",icon:bgColor = '" + iconBgColor + '\'' +
",canEdit = '" + canEdit + '\'' +
",groupTitle = '" + groupTitle + '\'' +
",followingCount = '" + followingCount + '\'' +
",lastonlineISO = '" + lastonlineISO + '\'' +
",email:disableEdit = '" + emailDisableEdit + '\'' +
",uid = '" + uid + '\'' +
",canChangePassword = '" + canChangePassword + '\'' +
",profileviews = '" + profileviews + '\'' +
",cover:url = '" + coverUrl + '\'' +
",banned = '" + banned + '\'' +
",userslug = '" + userslug + '\'' +
",followerCount = '" + followerCount + '\'' +
",email = '" + email + '\'' +
",website = '" + website + '\'' +
",isFollowing = '" + isFollowing + '\'' +
",uploadedpicture = '" + uploadedpicture + '\'' +
",passwordExpiry = '" + passwordExpiry + '\'' +
",canBan = '" + canBan + '\'' +
",lastonline = '" + lastonline + '\'' +
",disableSignatures = '" + disableSignatures + '\'' +
",groups = '" + groups + '\'' +
",username:disableEdit = '" + usernameDisableEdit + '\'' +
",picture = '" + picture + '\'' +
",joindateISO = '" + joindateISO + '\'' +
",isSelfOrAdminOrGlobalModerator = '" + isSelfOrAdminOrGlobalModerator + '\'' +
",websiteName = '" + websiteName + '\'' +
",isAdminOrGlobalModeratorOrModerator = '" + isAdminOrGlobalModeratorOrModerator + '\'' +
",cover:position = '" + coverPosition + '\'' +
",postcount = '" + postcount + '\'' +
",location = '" + location + '\'' +
",fullname = '" + fullname + '\'' +
",age = '" + age + '\'' +
",theirid = '" + theirid + '\'' +
",username = '" + username + '\'' +
"}";
}
}

View File

@@ -0,0 +1,376 @@
package com.stardust.scriptdroid.network.entity;
import com.google.gson.annotations.SerializedName;
public class VerifyResponse {
@SerializedName("message")
private String message;
@SerializedName("birthday")
private String birthday;
@SerializedName("lastposttime")
private String lastposttime;
@SerializedName("signature")
private String signature;
@SerializedName("icon:bgColor")
private String iconBgColor;
@SerializedName("groupTitle")
private String groupTitle;
@SerializedName("reputation")
private String reputation;
@SerializedName("followingCount")
private String followingCount;
@SerializedName("lastonlineISO")
private String lastonlineISO;
@SerializedName("uid")
private String uid;
@SerializedName("profileviews")
private String profileviews;
@SerializedName("icon:text")
private String iconText;
@SerializedName("banned")
private String banned;
@SerializedName("userslug")
private String userslug;
@SerializedName("followerCount")
private String followerCount;
@SerializedName("email")
private String email;
@SerializedName("joindate")
private String joindate;
@SerializedName("website")
private String website;
@SerializedName("uploadedpicture")
private String uploadedpicture;
@SerializedName("passwordExpiry")
private String passwordExpiry;
@SerializedName("lastonline")
private String lastonline;
@SerializedName("picture")
private String picture;
@SerializedName("joindateISO")
private String joindateISO;
@SerializedName("email:confirmed")
private Object emailConfirmed;
@SerializedName("postcount")
private String postcount;
@SerializedName("location")
private String location;
@SerializedName("fullname")
private String fullname;
@SerializedName("topiccount")
private String topiccount;
@SerializedName("username")
private String username;
@SerializedName("status")
private String status;
public boolean isSuccessful() {
return message == null;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public void setBirthday(String birthday) {
this.birthday = birthday;
}
public String getBirthday() {
return birthday;
}
public void setLastposttime(String lastposttime) {
this.lastposttime = lastposttime;
}
public String getLastposttime() {
return lastposttime;
}
public void setSignature(String signature) {
this.signature = signature;
}
public String getSignature() {
return signature;
}
public void setIconBgColor(String iconBgColor) {
this.iconBgColor = iconBgColor;
}
public String getIconBgColor() {
return iconBgColor;
}
public void setGroupTitle(String groupTitle) {
this.groupTitle = groupTitle;
}
public String getGroupTitle() {
return groupTitle;
}
public void setReputation(String reputation) {
this.reputation = reputation;
}
public String getReputation() {
return reputation;
}
public void setFollowingCount(String followingCount) {
this.followingCount = followingCount;
}
public String getFollowingCount() {
return followingCount;
}
public void setLastonlineISO(String lastonlineISO) {
this.lastonlineISO = lastonlineISO;
}
public String getLastonlineISO() {
return lastonlineISO;
}
public void setUid(String uid) {
this.uid = uid;
}
public String getUid() {
return uid;
}
public void setProfileviews(String profileviews) {
this.profileviews = profileviews;
}
public String getProfileviews() {
return profileviews;
}
public void setIconText(String iconText) {
this.iconText = iconText;
}
public String getIconText() {
return iconText;
}
public void setBanned(String banned) {
this.banned = banned;
}
public String getBanned() {
return banned;
}
public void setUserslug(String userslug) {
this.userslug = userslug;
}
public String getUserslug() {
return userslug;
}
public void setFollowerCount(String followerCount) {
this.followerCount = followerCount;
}
public String getFollowerCount() {
return followerCount;
}
public void setEmail(String email) {
this.email = email;
}
public String getEmail() {
return email;
}
public void setJoindate(String joindate) {
this.joindate = joindate;
}
public String getJoindate() {
return joindate;
}
public void setWebsite(String website) {
this.website = website;
}
public String getWebsite() {
return website;
}
public void setUploadedpicture(String uploadedpicture) {
this.uploadedpicture = uploadedpicture;
}
public String getUploadedpicture() {
return uploadedpicture;
}
public void setPasswordExpiry(String passwordExpiry) {
this.passwordExpiry = passwordExpiry;
}
public String getPasswordExpiry() {
return passwordExpiry;
}
public void setLastonline(String lastonline) {
this.lastonline = lastonline;
}
public String getLastonline() {
return lastonline;
}
public void setPicture(String picture) {
this.picture = picture;
}
public String getPicture() {
return picture;
}
public void setJoindateISO(String joindateISO) {
this.joindateISO = joindateISO;
}
public String getJoindateISO() {
return joindateISO;
}
public void setEmailConfirmed(Object emailConfirmed) {
this.emailConfirmed = emailConfirmed;
}
public Object getEmailConfirmed() {
return emailConfirmed;
}
public void setPostcount(String postcount) {
this.postcount = postcount;
}
public String getPostcount() {
return postcount;
}
public void setLocation(String location) {
this.location = location;
}
public String getLocation() {
return location;
}
public void setFullname(String fullname) {
this.fullname = fullname;
}
public String getFullname() {
return fullname;
}
public void setTopiccount(String topiccount) {
this.topiccount = topiccount;
}
public String getTopiccount() {
return topiccount;
}
public void setUsername(String username) {
this.username = username;
}
public String getUsername() {
return username;
}
public void setStatus(String status) {
this.status = status;
}
public String getStatus() {
return status;
}
@Override
public String toString() {
return
"VerifyResponse{" +
"birthday = '" + birthday + '\'' +
",lastposttime = '" + lastposttime + '\'' +
",signature = '" + signature + '\'' +
",icon:bgColor = '" + iconBgColor + '\'' +
",groupTitle = '" + groupTitle + '\'' +
",reputation = '" + reputation + '\'' +
",followingCount = '" + followingCount + '\'' +
",lastonlineISO = '" + lastonlineISO + '\'' +
",uid = '" + uid + '\'' +
",profileviews = '" + profileviews + '\'' +
",icon:text = '" + iconText + '\'' +
",banned = '" + banned + '\'' +
",userslug = '" + userslug + '\'' +
",followerCount = '" + followerCount + '\'' +
",email = '" + email + '\'' +
",joindate = '" + joindate + '\'' +
",website = '" + website + '\'' +
",uploadedpicture = '" + uploadedpicture + '\'' +
",passwordExpiry = '" + passwordExpiry + '\'' +
",lastonline = '" + lastonline + '\'' +
",picture = '" + picture + '\'' +
",joindateISO = '" + joindateISO + '\'' +
",email:confirmed = '" + emailConfirmed + '\'' +
",postcount = '" + postcount + '\'' +
",location = '" + location + '\'' +
",fullname = '" + fullname + '\'' +
",topiccount = '" + topiccount + '\'' +
",username = '" + username + '\'' +
",status = '" + status + '\'' +
"}";
}
}

View File

@@ -0,0 +1,130 @@
package com.stardust.scriptdroid.network.util;
import android.util.Log;
import java.io.IOException;
import java.net.CookieManager;
import java.net.CookiePolicy;
import java.net.CookieStore;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import okhttp3.Cookie;
import okhttp3.CookieJar;
import okhttp3.HttpUrl;
/**
* Created by Stardust on 2017/9/20.
*/
public class WebkitCookieManagerProxy extends CookieManager implements CookieJar {
private android.webkit.CookieManager webkitCookieManager;
private static final String TAG = WebkitCookieManagerProxy.class.getSimpleName();
public WebkitCookieManagerProxy() {
this(null, null);
}
WebkitCookieManagerProxy(CookieStore store, CookiePolicy cookiePolicy) {
super(null, cookiePolicy);
this.webkitCookieManager = android.webkit.CookieManager.getInstance();
}
@Override
public void put(URI uri, Map<String, List<String>> responseHeaders)
throws IOException {
// make sure our args are valid
if ((uri == null) || (responseHeaders == null))
return;
// save our url once
String url = uri.toString();
// go over the headers
for (String headerKey : responseHeaders.keySet()) {
// ignore headers which aren't cookie related
if ((headerKey == null)
|| !(headerKey.equalsIgnoreCase("Set-Cookie2") || headerKey
.equalsIgnoreCase("Set-Cookie")))
continue;
// process each of the headers
for (String headerValue : responseHeaders.get(headerKey)) {
webkitCookieManager.setCookie(url, headerValue);
}
}
}
@Override
public Map<String, List<String>> get(URI uri,
Map<String, List<String>> requestHeaders) throws IOException {
// make sure our args are valid
if ((uri == null) || (requestHeaders == null))
throw new IllegalArgumentException("Argument is null");
// save our url once
String url = uri.toString();
// prepare our response
Map<String, List<String>> res = new java.util.HashMap<String, List<String>>();
// get the cookie
String cookie = webkitCookieManager.getCookie(url);
// return it
if (cookie != null) {
res.put("Cookie", Arrays.asList(cookie));
}
return res;
}
@Override
public CookieStore getCookieStore() {
// we don't want anyone to work with this cookie store directly
throw new UnsupportedOperationException();
}
@Override
public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
HashMap<String, List<String>> generatedResponseHeaders = new HashMap<>();
ArrayList<String> cookiesList = new ArrayList<>();
for (Cookie c : cookies) {
// toString correctly generates a normal cookie string
cookiesList.add(c.toString());
}
generatedResponseHeaders.put("Set-Cookie", cookiesList);
try {
put(url.uri(), generatedResponseHeaders);
} catch (IOException e) {
Log.e(TAG, "Error adding cookies through okhttp", e);
}
}
@Override
public List<Cookie> loadForRequest(HttpUrl url) {
ArrayList<Cookie> cookieArrayList = new ArrayList<>();
try {
Map<String, List<String>> cookieList = get(url.uri(), new HashMap<String, List<String>>());
// Format here looks like: "Cookie":["cookie1=val1;cookie2=val2;"]
for (List<String> ls : cookieList.values()) {
for (String s : ls) {
String[] cookies = s.split(";");
for (String cookie : cookies) {
Cookie c = Cookie.parse(url, cookie);
cookieArrayList.add(c);
}
}
}
} catch (IOException e) {
Log.e(TAG, "error making cookie!", e);
}
return cookieArrayList;
}
}

View File

@@ -0,0 +1,77 @@
package com.stardust.scriptdroid.ui.login;
import android.util.Log;
import android.widget.TextView;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.network.NodeBB;
import com.stardust.scriptdroid.network.api.UserApi;
import com.stardust.scriptdroid.network.entity.VerifyResponse;
import com.stardust.scriptdroid.tool.SimpleObserver;
import com.stardust.scriptdroid.ui.BaseActivity;
import org.androidannotations.annotations.AfterViews;
import org.androidannotations.annotations.Click;
import org.androidannotations.annotations.EActivity;
import org.androidannotations.annotations.ViewById;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.annotations.NonNull;
import io.reactivex.schedulers.Schedulers;
/**
* Created by Stardust on 2017/9/20.
*/
@EActivity(R.layout.activity_login)
public class LoginActivity extends BaseActivity {
@ViewById(R.id.username)
TextView mUserName;
@ViewById(R.id.password)
TextView mPassword;
@AfterViews
void setUpViews() {
setToolbarAsBack(getString(R.string.text_login));
}
@Click(R.id.login)
void login() {
String userName = mUserName.getText().toString();
String password = mPassword.getText().toString();
if (!checkNotEmpty(userName, password)) {
return;
}
NodeBB.getInstance().getRetrofit()
.create(UserApi.class)
.verify(userName, password)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new SimpleObserver<VerifyResponse>() {
@Override
public void onNext(@NonNull VerifyResponse verifyResponse) {
Log.d("Login", verifyResponse.toString());
}
@Override
public void onError(@NonNull Throwable e) {
e.printStackTrace();
}
});
}
private boolean checkNotEmpty(String userName, String password) {
if (userName.isEmpty()) {
mUserName.setError(getString(R.string.text_username_cannot_be_empty));
return false;
}
if (password.isEmpty()) {
mUserName.setError(getString(R.string.text_password_cannot_be_empty));
return false;
}
return true;
}
}

View File

@@ -1,12 +1,7 @@
package com.stardust.scriptdroid.ui.main.community; package com.stardust.scriptdroid.ui.main.community;
import android.app.Activity; import android.app.Activity;
import android.content.Context;
import android.support.design.widget.FloatingActionButton; import android.support.design.widget.FloatingActionButton;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.support.v4.view.animation.FastOutSlowInInterpolator;
import android.view.View;
import android.webkit.WebView; import android.webkit.WebView;
import com.stardust.scriptdroid.R; import com.stardust.scriptdroid.R;
@@ -18,6 +13,8 @@ import org.androidannotations.annotations.AfterViews;
import org.androidannotations.annotations.EFragment; import org.androidannotations.annotations.EFragment;
import org.androidannotations.annotations.ViewById; import org.androidannotations.annotations.ViewById;
import java.util.regex.Pattern;
/** /**
* Created by Stardust on 2017/8/22. * Created by Stardust on 2017/8/22.
*/ */
@@ -25,6 +22,8 @@ import org.androidannotations.annotations.ViewById;
public class CommunityFragment extends ViewPagerFragment implements BackPressedHandler { public class CommunityFragment extends ViewPagerFragment implements BackPressedHandler {
private static final String POSTS_PAGE_PATTERN = "[\\S\\s]+/topic/[0-9]+/[\\S\\s]+";
@ViewById(R.id.eweb_view) @ViewById(R.id.eweb_view)
EWebView mEWebView; EWebView mEWebView;
WebView mWebView; WebView mWebView;
@@ -67,6 +66,15 @@ public class CommunityFragment extends ViewPagerFragment implements BackPressedH
@Override @Override
protected void onFabClick(FloatingActionButton fab) { protected void onFabClick(FloatingActionButton fab) {
if (isInPostsPage()) {
mWebView.loadUrl("javascript:$('button[component=\"topic/reply\"]').click()");
} else {
mWebView.loadUrl("javascript:$('.new_topic').click()");
}
}
private boolean isInPostsPage() {
String url = mWebView.getUrl();
return url.matches(POSTS_PAGE_PATTERN);
} }
} }

View File

@@ -5,6 +5,8 @@ import android.os.Bundle;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.view.View; import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import com.afollestad.materialdialogs.DialogAction; import com.afollestad.materialdialogs.DialogAction;
@@ -14,9 +16,14 @@ import com.stardust.scriptdroid.Pref;
import com.stardust.scriptdroid.R; import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.external.floatingwindow.HoverMenuManger; import com.stardust.scriptdroid.external.floatingwindow.HoverMenuManger;
import com.stardust.scriptdroid.external.floatingwindow.menu.HoverMenuService; import com.stardust.scriptdroid.external.floatingwindow.menu.HoverMenuService;
import com.stardust.scriptdroid.network.NodeBB;
import com.stardust.scriptdroid.network.VersionService; import com.stardust.scriptdroid.network.VersionService;
import com.stardust.scriptdroid.network.api.UserApi;
import com.stardust.scriptdroid.network.entity.User;
import com.stardust.scriptdroid.network.entity.VersionInfo; import com.stardust.scriptdroid.network.entity.VersionInfo;
import com.stardust.scriptdroid.tool.SimpleObserver; import com.stardust.scriptdroid.tool.SimpleObserver;
import com.stardust.scriptdroid.ui.login.LoginActivity;
import com.stardust.scriptdroid.ui.login.LoginActivity_;
import com.stardust.scriptdroid.ui.settings.SettingsActivity; import com.stardust.scriptdroid.ui.settings.SettingsActivity;
import com.stardust.scriptdroid.ui.update.UpdateInfoDialogBuilder; import com.stardust.scriptdroid.ui.update.UpdateInfoDialogBuilder;
import com.stardust.theme.ThemeColorManager; import com.stardust.theme.ThemeColorManager;
@@ -64,6 +71,12 @@ public class DrawerFragment extends android.support.v4.app.Fragment {
@ViewById(R.id.header) @ViewById(R.id.header)
View mHeaderView; View mHeaderView;
@ViewById(R.id.username)
TextView mUserName;
@ViewById(R.id.avatar)
ImageView mAvatar;
private Disposable mConnectionStateDisposable; private Disposable mConnectionStateDisposable;
@@ -88,11 +101,46 @@ public class DrawerFragment extends android.support.v4.app.Fragment {
syncSwitchState(); syncSwitchState();
} }
@Override
public void onResume() {
super.onResume();
syncUserInfo();
}
@AfterViews @AfterViews
void setUpViews() { void setUpViews() {
ThemeColorManager.addViewBackground(mHeaderView); ThemeColorManager.addViewBackground(mHeaderView);
} }
private void syncUserInfo() {
NodeBB.getInstance().getRetrofit()
.create(UserApi.class)
.me()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new SimpleObserver<User>() {
@Override
public void onNext(@io.reactivex.annotations.NonNull User user) {
setUpUserInfo(user);
}
@Override
public void onError(@io.reactivex.annotations.NonNull Throwable e) {
e.printStackTrace();
}
});
}
private void setUpUserInfo(User user) {
mUserName.setText(user.getUsername());
}
@Click(R.id.avatar)
void loginOrShowUserInfo() {
LoginActivity_.intent(getActivity()).start();
}
@Click(R.id.accessibility_service) @Click(R.id.accessibility_service)
void enableOrDisableAccessibilityService() { void enableOrDisableAccessibilityService() {
boolean isAccessibilityServiceEnabled = isAccessibilityServiceEnabled(); boolean isAccessibilityServiceEnabled = isAccessibilityServiceEnabled();
@@ -173,13 +221,14 @@ public class DrawerFragment extends android.support.v4.app.Fragment {
.onNeutral(new MaterialDialog.SingleButtonCallback() { .onNeutral(new MaterialDialog.SingleButtonCallback() {
@Override @Override
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) { public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
mConnectionItem.getSwitchCompat().setChecked(false, false);
IntentUtil.browse(getActivity(), URL_SUBLIME_PLUGIN_HELP); IntentUtil.browse(getActivity(), URL_SUBLIME_PLUGIN_HELP);
} }
}) })
.cancelListener(new DialogInterface.OnCancelListener() { .cancelListener(new DialogInterface.OnCancelListener() {
@Override @Override
public void onCancel(DialogInterface dialog) { public void onCancel(DialogInterface dialog) {
mConnectionItem.getSwitchCompat().toggle(false); mConnectionItem.getSwitchCompat().setChecked(false, false);
} }
}) })
.show(); .show();

View File

@@ -55,6 +55,8 @@ public class EWebView extends FrameLayout implements SwipeRefreshLayout.OnRefres
settings.setBuiltInZoomControls(true); settings.setBuiltInZoomControls(true);
settings.setLoadWithOverviewMode(true); settings.setLoadWithOverviewMode(true);
settings.setJavaScriptEnabled(true); settings.setJavaScriptEnabled(true);
settings.setJavaScriptCanOpenWindowsAutomatically(true);
settings.setDomStorageEnabled(true);
mWebView.setWebViewClient(new MyWebViewClient()); mWebView.setWebViewClient(new MyWebViewClient());
mWebView.setWebChromeClient(new MyWebChromeClient()); mWebView.setWebChromeClient(new MyWebChromeClient());
} }

View File

@@ -4,7 +4,9 @@ import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.res.TypedArray; import android.content.res.TypedArray;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.support.annotation.IntDef;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.view.View;
import com.stardust.scriptdroid.R; import com.stardust.scriptdroid.R;
@@ -16,6 +18,7 @@ public class PrefSwitch extends SwitchCompat implements SharedPreferences.OnShar
private String mPrefKey; private String mPrefKey;
private SharedPreferences mSharedPreferences; private SharedPreferences mSharedPreferences;
private boolean mDefaultChecked;
public PrefSwitch(Context context) { public PrefSwitch(Context context) {
super(context); super(context);
@@ -37,17 +40,23 @@ public class PrefSwitch extends SwitchCompat implements SharedPreferences.OnShar
return; return;
TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.PrefSwitch); TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.PrefSwitch);
mPrefKey = a.getString(R.styleable.PrefSwitch_key); mPrefKey = a.getString(R.styleable.PrefSwitch_key);
boolean defaultValue = a.getBoolean(R.styleable.PrefSwitch_defaultValue, false); mDefaultChecked = a.getBoolean(R.styleable.PrefSwitch_defaultValue, false);
if (mPrefKey != null) { if (mPrefKey != null) {
mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(getContext()); mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(getContext());
mSharedPreferences.registerOnSharedPreferenceChangeListener(this); mSharedPreferences.registerOnSharedPreferenceChangeListener(this);
setChecked(mSharedPreferences.getBoolean(mPrefKey, defaultValue), false); readInitialState();
} else { } else {
setChecked(defaultValue, false); setChecked(mDefaultChecked, false);
} }
a.recycle(); a.recycle();
} }
private void readInitialState() {
if (mPrefKey == null || mSharedPreferences == null)
return;
setChecked(mSharedPreferences.getBoolean(mPrefKey, mDefaultChecked), false);
}
private void notifyPrefChanged(boolean isChecked) { private void notifyPrefChanged(boolean isChecked) {
if (mPrefKey == null) if (mPrefKey == null)
return; return;
@@ -83,5 +92,12 @@ public class PrefSwitch extends SwitchCompat implements SharedPreferences.OnShar
setChecked(mSharedPreferences.getBoolean(mPrefKey, isChecked()), false); setChecked(mSharedPreferences.getBoolean(mPrefKey, isChecked()), false);
} }
} }
@Override
protected void onWindowVisibilityChanged(int visibility) {
if (visibility == VISIBLE) {
readInitialState();
}
}
} }

View File

@@ -0,0 +1,158 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.design.widget.AppBarLayout
android:id="@+id/app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<com.stardust.theme.widget.ThemeColorToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:title="@string/text_login"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/AppTheme.PopupOverlay"/>
</android.support.design.widget.AppBarLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.CardView
android:id="@+id/cv"
android:layout_width="300dp"
android:layout_height="300dp"
android:layout_centerHorizontal="true"
android:layout_marginTop="64dp"
app:cardCornerRadius="6dp"
app:cardElevation="3dp"
app:cardUseCompatPadding="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="45dp"
android:layout_marginTop="10dp">
<View
android:layout_width="8dp"
android:layout_height="match_parent"
android:layout_alignParentStart="true"
android:background="#2fa881"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginStart="50dp"
android:text="@string/text_login"
android:textColor="#FFCC00"
android:textSize="18sp"
android:textStyle="bold"
/>
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="horizontal"
android:paddingEnd="30dp"
android:paddingStart="50dp">
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/text_username"
android:inputType="textPersonName"
android:textSize="16sp"/>
</android.support.design.widget.TextInputLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingEnd="30dp"
android:paddingStart="50dp">
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/text_password"
android:inputType="textPassword"
android:textSize="16sp"
/>
</android.support.design.widget.TextInputLayout>
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_marginTop="25dp"
android:gravity="center">
<Button
android:id="@+id/login"
style="@style/Widget.AppCompat.Button.Colored"
android:layout_width="150dp"
android:layout_height="50dp"
android:text="@string/text_login"
>
</Button>
</RelativeLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="5dp"
android:text="@string/text_forgot_password"
android:textColor="#9a9a9a"
android:textSize="12sp"
/>
</LinearLayout>
</android.support.v7.widget.CardView>
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignEnd="@id/cv"
android:layout_alignTop="@id/cv"
android:layout_marginEnd="-20dp"
android:layout_marginTop="25dp"
android:src="@drawable/ic_add_white_48dp"
android:transitionName="loginFab"
app:fabSize="normal"
/>
</RelativeLayout>
</LinearLayout>

View File

@@ -243,6 +243,12 @@
<string name="text_choose_file">选择文件</string> <string name="text_choose_file">选择文件</string>
<string name="text_click_too_frequently">您的操作太快啦ヽ(#`Д´)ノ</string> <string name="text_click_too_frequently">您的操作太快啦ヽ(#`Д´)ノ</string>
<string name="text_connecting">连接中…</string> <string name="text_connecting">连接中…</string>
<string name="text_username">用户名</string>
<string name="text_password">密码</string>
<string name="text_login">登录</string>
<string name="text_forgot_password">忘记密码</string>
<string name="text_username_cannot_be_empty">用户名不能为空</string>
<string name="text_password_cannot_be_empty">密码不能为空</string>
<string-array name="record_control_keys"> <string-array name="record_control_keys">

View File

@@ -0,0 +1,28 @@
package com.stardust.autojs.runtime.api.crypto;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import static javax.crypto.Cipher.ENCRYPT_MODE;
/**
* Created by Stardust on 2017/9/20.
*/
public class Crypto {
public Cipher createCipher(String algorithm, String password) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException {
javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance(algorithm);
KeyGenerator keyGenerator = KeyGenerator.getInstance(algorithm);
keyGenerator.init(128, new SecureRandom(password.getBytes()));
SecretKey secretKey = keyGenerator.generateKey();
cipher.init(ENCRYPT_MODE, secretKey);
return cipher;
}
}

View File

@@ -16,13 +16,17 @@ android {
} }
} }
lintOptions {
disable 'MissingTranslation'
disable 'ExtraTranslation'
}
buildTypes { buildTypes {
debug { debug {
minifyEnabled false minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
} }
release { release {
minifyEnabled true minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
} }
} }

View File

@@ -17,6 +17,19 @@
<category android:name="android.intent.category.LAUNCHER"/> <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter> </intent-filter>
</activity> </activity>
<service
android:name="com.stardust.view.accessibility.AccessibilityService"
android:label="@string/_app_name"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService"/>
</intent-filter>
<meta-data
android:name="android.accessibilityservice"
android:resource="@xml/accessibility_service_config"/>
</service>
</application> </application>
</manifest> </manifest>

View File

@@ -1,6 +1,9 @@
package com.stardust.auojs.inrt; package com.stardust.auojs.inrt;
import android.app.Application; import android.app.Application;
import android.app.Fragment;
import com.stardust.auojs.inrt.rt.AutoJs;
/** /**
* Created by Stardust on 2017/7/1. * Created by Stardust on 2017/7/1.
@@ -8,9 +11,17 @@ import android.app.Application;
public class App extends Application { public class App extends Application {
private static App sApp;
public static App getApp() {
return sApp;
}
@Override @Override
public void onCreate() { public void onCreate() {
super.onCreate(); super.onCreate();
sApp = this;
AutoJs.initInstance(this);
} }
} }

View File

@@ -3,6 +3,7 @@ package com.stardust.auojs.inrt;
import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AppCompatActivity;
import android.os.Bundle; import android.os.Bundle;
import com.stardust.auojs.inrt.rt.AutoJs;
import com.stardust.autojs.script.StringScriptSource; import com.stardust.autojs.script.StringScriptSource;
import java.io.IOException; import java.io.IOException;
@@ -19,7 +20,7 @@ public class MainActivity extends AppCompatActivity {
is.read(data); is.read(data);
String js = new String(data); String js = new String(data);
StringScriptSource source = new StringScriptSource("<script>", js); StringScriptSource source = new StringScriptSource("<script>", js);
//AutoJs.getInstance().getScriptEngineService().execute(source); AutoJs.getInstance().getScriptEngineService().execute(source);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }

View File

@@ -2,8 +2,11 @@ package com.stardust.auojs.inrt.rt;
import android.accessibilityservice.AccessibilityService; import android.accessibilityservice.AccessibilityService;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.provider.Settings;
import android.text.TextUtils; import android.text.TextUtils;
import com.stardust.auojs.inrt.App;
import com.stardust.autojs.runtime.api.ProcessShell; import com.stardust.autojs.runtime.api.ProcessShell;
import java.util.Locale; import java.util.Locale;
@@ -36,4 +39,8 @@ public class AccessibilityServiceTool {
return true; return true;
} }
public static void goToAccessibilitySetting() {
App.getApp().startActivity(new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
}
} }

View File

@@ -0,0 +1,242 @@
package com.stardust.auojs.inrt.rt;
import android.app.Activity;
import android.content.Context;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import com.stardust.app.OnActivityResultDelegate;
import com.stardust.app.SimpleActivityLifecycleCallbacks;
import com.stardust.auojs.inrt.App;
import com.stardust.auojs.inrt.R;
import com.stardust.autojs.ScriptEngineService;
import com.stardust.autojs.ScriptEngineServiceBuilder;
import com.stardust.autojs.core.accessibility.AccessibilityBridge;
import com.stardust.autojs.core.inputevent.InputEventObserver;
import com.stardust.autojs.core.record.accessibility.AccessibilityActionRecorder;
import com.stardust.autojs.engine.LoopBasedJavaScriptEngine;
import com.stardust.autojs.engine.RootAutomatorEngine;
import com.stardust.autojs.engine.ScriptEngine;
import com.stardust.autojs.engine.ScriptEngineManager;
import com.stardust.autojs.runtime.ScriptRuntime;
import com.stardust.autojs.runtime.api.AbstractShell;
import com.stardust.autojs.runtime.api.AppUtils;
import com.stardust.autojs.runtime.api.Console;
import com.stardust.autojs.runtime.api.Shell;
import com.stardust.autojs.runtime.api.image.ScreenCaptureRequestActivity;
import com.stardust.autojs.runtime.api.image.ScreenCaptureRequester;
import com.stardust.autojs.runtime.console.StardustConsole;
import com.stardust.autojs.runtime.exception.ScriptException;
import com.stardust.autojs.script.AutoFileSource;
import com.stardust.autojs.script.JavaScriptSource;
import com.stardust.util.ScreenMetrics;
import com.stardust.util.Supplier;
import com.stardust.util.UiHandler;
import com.stardust.view.accessibility.AccessibilityInfoProvider;
import com.stardust.view.accessibility.AccessibilityService;
import com.stardust.view.accessibility.AccessibilityServiceUtils;
import com.stardust.view.accessibility.LayoutInspector;
import com.stardust.view.accessibility.NotificationListener;
/**
* Created by Stardust on 2017/4/2.
*/
public class AutoJs {
private static AutoJs instance;
private Class<? extends android.accessibilityservice.AccessibilityService> sAccessibilityServiceClass = AccessibilityService.class;
public static AutoJs getInstance() {
return instance;
}
public static void initInstance(Context context) {
instance = new AutoJs(context);
}
private final AccessibilityActionRecorder mAccessibilityActionRecorder = new AccessibilityActionRecorder();
private final NotificationListener.Observer mNotificationObserver;
private ScriptEngineManager mScriptEngineManager;
private final LayoutInspector mLayoutInspector = new LayoutInspector();
private final Context mContext;
private final UiHandler mUiHandler;
private final AppUtils mAppUtils;
private final AccessibilityInfoProvider mAccessibilityInfoProvider;
private final ScreenCaptureRequester mScreenCaptureRequester = new ScreenCaptureRequesterImpl();
private final ScriptEngineService mScriptEngineService;
private final Console mGlobalConsole;
private AutoJs(final Context context) {
mContext = context;
mUiHandler = new UiHandler(context);
mAppUtils = new AppUtils(context);
mGlobalConsole = new NoOpConsole();
mNotificationObserver = new NotificationListener.Observer(context);
mAccessibilityInfoProvider = new AccessibilityInfoProvider(context.getPackageManager());
mScriptEngineService = buildScriptEngineService();
addAccessibilityServiceDelegates();
//mScriptEngineService.registerGlobalScriptExecutionListener(new ScriptExecutionGlobalListener());
registerActivityLifecycleCallbacks();
InputEventObserver.initGlobal(context);
}
private ScriptEngineService buildScriptEngineService() {
initScriptEngineManager();
return new ScriptEngineServiceBuilder()
.uiHandler(mUiHandler)
.globalConsole(mGlobalConsole)
.engineManger(mScriptEngineManager)
.build();
}
private void initScriptEngineManager() {
mScriptEngineManager = new ScriptEngineManager(mContext);
mScriptEngineManager.registerEngine(JavaScriptSource.ENGINE, new Supplier<ScriptEngine>() {
@Override
public ScriptEngine get() {
LoopBasedJavaScriptEngine engine = new LoopBasedJavaScriptEngine(mContext);
engine.setRuntime(new ScriptRuntime.Builder()
.setConsole(new StardustConsole(mUiHandler, mGlobalConsole))
.setScreenCaptureRequester(mScreenCaptureRequester)
.setAccessibilityBridge(new AccessibilityBridgeImpl())
.setUiHandler(mUiHandler)
.setAppUtils(mAppUtils)
.setEngineService(mScriptEngineService)
.setShellSupplier(new Supplier<AbstractShell>() {
@Override
public AbstractShell get() {
return new Shell(mContext, true);
}
}).build());
return engine;
}
});
mScriptEngineManager.registerEngine(AutoFileSource.ENGINE, new Supplier<ScriptEngine>() {
@Override
public ScriptEngine get() {
return new RootAutomatorEngine(mContext);
}
});
}
private void registerActivityLifecycleCallbacks() {
App.getApp().registerActivityLifecycleCallbacks(new SimpleActivityLifecycleCallbacks() {
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
ScreenMetrics.initIfNeeded(activity);
mAppUtils.setCurrentActivity(activity);
}
@Override
public void onActivityPaused(Activity activity) {
mAppUtils.setCurrentActivity(null);
}
@Override
public void onActivityResumed(Activity activity) {
mAppUtils.setCurrentActivity(activity);
}
});
}
private void addAccessibilityServiceDelegates() {
AccessibilityService.addDelegate(100, mAccessibilityInfoProvider);
AccessibilityService.addDelegate(200, mNotificationObserver);
AccessibilityService.addDelegate(300, mAccessibilityActionRecorder);
}
public AccessibilityActionRecorder getAccessibilityActionRecorder() {
return mAccessibilityActionRecorder;
}
public AppUtils getAppUtils() {
return mAppUtils;
}
public UiHandler getUiHandler() {
return mUiHandler;
}
public LayoutInspector getLayoutInspector() {
return mLayoutInspector;
}
public ScriptEngineService getScriptEngineService() {
return mScriptEngineService;
}
public AccessibilityInfoProvider getInfoProvider() {
return mAccessibilityInfoProvider;
}
public void ensureAccessibilityServiceEnabled() {
if (AccessibilityService.getInstance() == null) {
String errorMessage = null;
if (AccessibilityServiceUtils.isAccessibilityServiceEnabled(App.getApp(), sAccessibilityServiceClass)) {
errorMessage = App.getApp().getString(R.string.text_auto_operate_service_enabled_but_not_running);
} else {
if (true) {
if (!AccessibilityServiceTool.enableAccessibilityServiceByRootAndWaitFor(App.getApp(), 2000)) {
errorMessage = App.getApp().getString(R.string.text_enable_accessibility_service_by_root_timeout);
}
} else {
errorMessage = App.getApp().getString(R.string.text_no_accessibility_permission);
}
}
if (errorMessage != null) {
AccessibilityServiceTool.goToAccessibilitySetting();
throw new ScriptException(errorMessage);
}
}
}
private class AccessibilityBridgeImpl extends AccessibilityBridge {
@Override
public void ensureServiceEnabled() {
AutoJs.this.ensureAccessibilityServiceEnabled();
}
@Nullable
@Override
public AccessibilityService getService() {
return AccessibilityService.getInstance();
}
@Override
public AccessibilityInfoProvider getInfoProvider() {
return mAccessibilityInfoProvider;
}
@Override
public NotificationListener.Observer getNotificationObserver() {
return mNotificationObserver;
}
}
private class ScreenCaptureRequesterImpl extends ScreenCaptureRequester.AbstractScreenCaptureRequester {
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public void request() {
Activity activity = mAppUtils.getCurrentActivity();
if (activity instanceof OnActivityResultDelegate.DelegateHost) {
ScreenCaptureRequester requester = new ActivityScreenCaptureRequester(
((OnActivityResultDelegate.DelegateHost) activity).getOnActivityResultDelegateMediator(), activity);
requester.setOnActivityResultCallback(mCallback);
requester.request();
} else {
ScreenCaptureRequestActivity.request(mContext, mCallback);
}
}
}
}

View File

@@ -0,0 +1,71 @@
package com.stardust.auojs.inrt.rt;
import android.support.annotation.Nullable;
import com.stardust.autojs.runtime.api.Console;
/**
* Created by Stardust on 2017/9/21.
*/
public class NoOpConsole implements Console {
@Override
public void verbose(@Nullable Object data, Object... options) {
}
@Override
public void log(@Nullable Object data, Object... options) {
}
@Override
public void print(int level, Object data, Object... options) {
}
@Override
public void info(@Nullable Object data, Object... options) {
}
@Override
public void warn(@Nullable Object data, Object... options) {
}
@Override
public void error(@Nullable Object data, Object... options) {
}
@Override
public void assertTrue(boolean value, @Nullable Object data, Object... options) {
}
@Override
public void clear() {
}
@Override
public void show() {
}
@Override
public void hide() {
}
@Override
public void println(int level, CharSequence charSequence) {
}
@Override
public void setTitle(CharSequence title) {
}
}

View File

@@ -2,4 +2,5 @@
<string name="app_name">inrt</string> <string name="app_name">inrt</string>
<string name="text_no_accessibility_permission">无障碍服务未启动</string> <string name="text_no_accessibility_permission">无障碍服务未启动</string>
<string name="text_auto_operate_service_enabled_but_not_running">无障碍服务已启用但没有运行,您可以尝试重新启用或重启手机</string> <string name="text_auto_operate_service_enabled_but_not_running">无障碍服务已启用但没有运行,您可以尝试重新启用或重启手机</string>
<string name="text_enable_accessibility_service_by_root_timeout">使用root权限启用无障碍服务失败</string>
</resources> </resources>