fixed crashes

This commit is contained in:
Mariotaku Lee 2016-07-08 12:46:54 +08:00
parent 56e8276f00
commit 6a43aca5eb
30 changed files with 673 additions and 752 deletions

View File

@ -156,6 +156,7 @@ public interface IntentConstants {
String EXTRA_IMAGE_URI = "image_uri";
String EXTRA_ACTIVATED_ONLY = "activated_only";
String EXTRA_TAB_POSITION = "tab_position";
String EXTRA_TAB_ID = "tab_id";
String EXTRA_OAUTH_VERIFIER = "oauth_verifier";
String EXTRA_REQUEST_TOKEN = "request_token";
String EXTRA_REQUEST_TOKEN_SECRET = "request_token_secret";

View File

@ -8,6 +8,8 @@ import com.google.android.gms.auth.api.signin.GoogleSignInOptions
import com.google.android.gms.auth.api.signin.GoogleSignInResult
import com.google.android.gms.common.ConnectionResult
import com.google.android.gms.common.api.GoogleApiClient
import org.mariotaku.twidere.Constants.GOOGLE_APIS_SERVER_CLIENT_ID
import org.mariotaku.twidere.Constants.LOGTAG
/**
* Created by mariotaku on 16/5/14.
@ -21,14 +23,16 @@ class PlusServiceGoogleSignInActivity : BasePlusServiceSignInActivity(), GoogleA
super.onCreate(savedInstanceState)
// Configure sign-in to request the user's ID, email address, and basic
// profile. ID and basic profile are included in DEFAULT_SIGN_IN.
val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN).requestEmail().requestIdToken(GOOGLE_APIS_SERVER_CLIENT_ID).build()
val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestEmail()
.requestIdToken(GOOGLE_APIS_SERVER_CLIENT_ID).build()
// Build a GoogleApiClient with access to the Google Sign-In API and the
// options specified by gso.
mGoogleApiClient = GoogleApiClient.Builder(this).enableAutoManage(this, this).addApi(Auth.GOOGLE_SIGN_IN_API, gso).build()
signInWithGoogle()
}
public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
// Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...);

View File

@ -1,265 +0,0 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.activity;
import android.app.LoaderManager.LoaderCallbacks;
import android.content.CursorLoader;
import android.content.Intent;
import android.content.Loader;
import android.content.SharedPreferences;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.Toast;
import org.apache.commons.lang3.ArrayUtils;
import org.mariotaku.sqliteqb.library.Columns;
import org.mariotaku.sqliteqb.library.Expression;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.adapter.AccountsAdapter;
import org.mariotaku.twidere.app.TwidereApplication;
import org.mariotaku.twidere.model.ParcelableAccount;
import org.mariotaku.twidere.model.ParcelableCredentials;
import org.mariotaku.twidere.provider.TwidereDataStore.Accounts;
import java.util.ArrayList;
import java.util.List;
public class AccountSelectorActivity extends BaseActivity implements
LoaderCallbacks<Cursor>, OnClickListener, OnItemClickListener {
private final ContentObserver mContentObserver = new ContentObserver(null) {
@Override
public void onChange(final boolean selfChange) {
onChange(selfChange, null);
}
@Override
public void onChange(final boolean selfChange, final Uri uri) {
// Handle change.
if (!isFinishing()) {
getLoaderManager().restartLoader(0, null, AccountSelectorActivity.this);
}
}
};
private SharedPreferences mPreferences;
private ListView mListView;
private AccountsAdapter mAdapter;
private boolean mFirstCreated;
private View mSelectAccountButtons;
@Override
public void onClick(final View view) {
switch (view.getId()) {
case R.id.save: {
final long[] checkedIds = mListView.getCheckedItemIds();
if (checkedIds.length == 0 && !isSelectNoneAllowed()) {
Toast.makeText(this, R.string.no_account_selected, Toast.LENGTH_SHORT).show();
return;
}
final Intent data = new Intent();
data.putExtra(EXTRA_IDS, checkedIds);
setResult(RESULT_OK, data);
finish();
break;
}
}
}
@Override
public void onContentChanged() {
super.onContentChanged();
mListView = (ListView) findViewById(android.R.id.list);
mSelectAccountButtons = findViewById(R.id.select_account_buttons);
}
@Override
public Loader<Cursor> onCreateLoader(final int id, final Bundle args) {
final List<Expression> conditions = new ArrayList<>();
final List<String> conditionArgs = new ArrayList<>();
if (isOAuthOnly()) {
conditions.add(Expression.equalsArgs(Accounts.AUTH_TYPE));
conditionArgs.add(String.valueOf(ParcelableCredentials.AuthType.OAUTH));
}
final String accountHost = getAccountHost();
if (!TextUtils.isEmpty(accountHost)) {
if (USER_TYPE_TWITTER_COM.equals(accountHost)) {
conditions.add(Expression.or(
Expression.equalsArgs(Accounts.ACCOUNT_TYPE),
Expression.isNull(new Columns.Column(Accounts.ACCOUNT_TYPE)),
Expression.likeRaw(new Columns.Column(Accounts.ACCOUNT_KEY), "'%@'||?"),
Expression.notLikeRaw(new Columns.Column(Accounts.ACCOUNT_KEY), "'%@%'")
));
conditionArgs.add(ParcelableAccount.Type.TWITTER);
conditionArgs.add(accountHost);
} else {
conditions.add(Expression.likeRaw(new Columns.Column(Accounts.ACCOUNT_KEY), "'%@'||?"));
conditionArgs.add(accountHost);
}
}
final String where;
final String[] whereArgs;
if (conditions.isEmpty()) {
where = null;
whereArgs = null;
} else {
where = Expression.and(conditions.toArray(new Expression[conditions.size()])).getSQL();
whereArgs = conditionArgs.toArray(new String[conditionArgs.size()]);
}
return new CursorLoader(this, Accounts.CONTENT_URI, Accounts.COLUMNS, where, whereArgs,
Accounts.SORT_POSITION);
}
@Override
public void onLoadFinished(final Loader<Cursor> loader, final Cursor cursor) {
mAdapter.swapCursor(cursor);
if (cursor != null && mFirstCreated) {
final long[] activatedIds = getIntentExtraIds();
for (int i = 0, j = mAdapter.getCount(); i < j; i++) {
mListView.setItemChecked(i, ArrayUtils.contains(activatedIds, mAdapter.getItemId(i)));
}
}
if (mAdapter.getCount() == 1 && shouldSelectOnlyItem()) {
selectSingleAccount(0);
} else if (mAdapter.isEmpty()) {
Toast.makeText(this, R.string.no_account, Toast.LENGTH_SHORT).show();
finish();
}
}
@Override
public void onLoaderReset(final Loader<Cursor> loader) {
mAdapter.swapCursor(null);
}
@Override
public void onItemClick(final AdapterView<?> parent, final View view, final int position, final long id) {
selectSingleAccount(position);
}
public void selectSingleAccount(int position) {
final ParcelableAccount account = mAdapter.getAccount(position);
final Intent data = new Intent();
data.putExtra(EXTRA_ID, account.account_key.getId());
data.putExtra(EXTRA_ACCOUNT_KEY, account.account_key);
final Intent startIntent = getStartIntent();
if (startIntent != null) {
startIntent.putExtra(EXTRA_ACCOUNT_KEY, account.account_key);
startActivity(startIntent);
}
setResult(RESULT_OK, data);
finish();
}
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mFirstCreated = savedInstanceState == null;
mPreferences = getSharedPreferences(SHARED_PREFERENCES_NAME, MODE_PRIVATE);
setContentView(R.layout.activity_account_selector);
mAdapter = new AccountsAdapter(this);
final boolean isSingleSelection = isSingleSelection();
mListView.setChoiceMode(isSingleSelection ? ListView.CHOICE_MODE_NONE : ListView.CHOICE_MODE_MULTIPLE);
mAdapter.setSwitchEnabled(!isSingleSelection);
mAdapter.setSortEnabled(false);
if (isSingleSelection) {
mListView.setOnItemClickListener(this);
}
mSelectAccountButtons.setVisibility(isSingleSelection ? View.GONE : View.VISIBLE);
mListView.setAdapter(mAdapter);
getLoaderManager().initLoader(0, null, this);
}
@Override
protected void onStart() {
super.onStart();
getContentResolver().registerContentObserver(Accounts.CONTENT_URI, true, mContentObserver);
}
@Override
protected void onResume() {
super.onResume();
final boolean displayProfileImage = mPreferences.getBoolean(KEY_DISPLAY_PROFILE_IMAGE, true);
mAdapter.setProfileImageDisplayed(displayProfileImage);
}
@Override
protected void onStop() {
getContentResolver().unregisterContentObserver(mContentObserver);
super.onStop();
}
private long[] getIntentExtraIds() {
final Intent intent = getIntent();
return intent.getLongArrayExtra(EXTRA_IDS);
}
private boolean isOAuthOnly() {
final Intent intent = getIntent();
return intent.getBooleanExtra(EXTRA_OAUTH_ONLY, false);
}
private String getAccountHost() {
final Intent intent = getIntent();
return intent.getStringExtra(EXTRA_ACCOUNT_HOST);
}
private boolean isSelectNoneAllowed() {
final Intent intent = getIntent();
return intent.getBooleanExtra(EXTRA_ALLOW_SELECT_NONE, false);
}
private boolean isSingleSelection() {
final Intent intent = getIntent();
return intent.getBooleanExtra(EXTRA_SINGLE_SELECTION, false);
}
private boolean shouldSelectOnlyItem() {
final Intent intent = getIntent();
return intent.getBooleanExtra(EXTRA_SELECT_ONLY_ITEM, false);
}
@Nullable
private Intent getStartIntent() {
final Intent intent = getIntent();
final Intent startIntent = intent.getParcelableExtra(EXTRA_START_INTENT);
if (startIntent != null) {
startIntent.setExtrasClassLoader(TwidereApplication.class.getClassLoader());
}
return startIntent;
}
}

View File

@ -1,8 +0,0 @@
package org.mariotaku.twidere.activity;
/**
* Created by mariotaku on 16/5/11.
*/
public abstract class BasePlusServiceSignInActivity extends BaseActivity {
}

View File

@ -1,78 +0,0 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.activity;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import org.mariotaku.twidere.fragment.ColorPickerDialogFragment;
import org.mariotaku.twidere.fragment.ColorPickerDialogFragment.Callback;
public class ColorPickerDialogActivity extends BaseActivity implements Callback {
public static final int RESULT_CLEARED = -2;
@Override
public void onCancelled() {
finish();
}
@Override
protected void onStart() {
super.onStart();
setVisible(true);
}
@Override
public void onColorCleared() {
setResult(RESULT_CLEARED);
finish();
}
@Override
public void onColorSelected(final int color) {
final Intent intent = new Intent();
intent.putExtra(EXTRA_COLOR, color);
setResult(RESULT_OK, intent);
finish();
}
@Override
public void onDismissed() {
finish();
}
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
final Intent intent = getIntent();
final ColorPickerDialogFragment f = new ColorPickerDialogFragment();
final Bundle args = new Bundle();
args.putInt(EXTRA_COLOR, intent.getIntExtra(EXTRA_COLOR, Color.WHITE));
args.putBoolean(EXTRA_CLEAR_BUTTON, intent.getBooleanExtra(EXTRA_CLEAR_BUTTON, false));
args.putBoolean(EXTRA_ALPHA_SLIDER, intent.getBooleanExtra(EXTRA_ALPHA_SLIDER, true));
f.setArguments(args);
f.show(getSupportFragmentManager(), "color_picker_dialog");
}
}
}

View File

@ -1,46 +0,0 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.activity;
import android.app.Activity;
import android.content.Intent;
import android.content.Intent.ShortcutIconResource;
import android.os.Bundle;
import org.mariotaku.twidere.R;
import static org.mariotaku.twidere.constant.IntentConstants.INTENT_ACTION_COMPOSE;
public class CreateComposeShortcutActivity extends Activity {
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setVisible(true);
final Intent intent = new Intent();
final Intent launch_intent = new Intent(INTENT_ACTION_COMPOSE);
final ShortcutIconResource icon = Intent.ShortcutIconResource.fromContext(this, R.mipmap.ic_launcher);
intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, launch_intent);
intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, icon);
intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, getString(R.string.compose));
setResult(RESULT_OK, intent);
finish();
}
}

View File

@ -1,130 +0,0 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.activity;
import android.app.Activity;
import android.content.ComponentName;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.os.Build;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnLongClickListener;
import android.widget.Toast;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.nyan.NyanDaydreamService;
import org.mariotaku.twidere.nyan.NyanSurfaceHelper;
import org.mariotaku.twidere.nyan.NyanWallpaperService;
import static org.mariotaku.twidere.TwidereConstants.SHARED_PREFERENCES_NAME;
import static org.mariotaku.twidere.constant.SharedPreferenceConstants.KEY_LIVE_WALLPAPER_SCALE;
public class NyanActivity extends Activity implements OnLongClickListener, OnSharedPreferenceChangeListener {
private SurfaceView mSurfaceView;
private SharedPreferences mPreferences;
private NyanSurfaceHelper mHelper;
@Override
public void onContentChanged() {
super.onContentChanged();
mSurfaceView = (SurfaceView) findViewById(R.id.surface);
}
@Override
public boolean onLongClick(final View v) {
Toast.makeText(this, R.string.nyan_sakamoto, Toast.LENGTH_SHORT).show();
return true;
}
@Override
public void onSharedPreferenceChanged(final SharedPreferences preferences, final String key) {
if (KEY_LIVE_WALLPAPER_SCALE.equals(key)) {
updateSurface();
}
}
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mPreferences = getSharedPreferences(SHARED_PREFERENCES_NAME, MODE_PRIVATE);
mPreferences.registerOnSharedPreferenceChangeListener(this);
setContentView(R.layout.layout_surface_view);
mSurfaceView.setOnLongClickListener(this);
final SurfaceHolder holder = mSurfaceView.getHolder();
mHelper = new NyanSurfaceHelper(this);
holder.addCallback(mHelper);
updateSurface();
enableWallpaperDaydream();
}
@Override
protected void onStart() {
super.onStart();
if (mHelper != null) {
mHelper.start();
}
}
@Override
protected void onStop() {
if (mHelper != null) {
mHelper.stop();
}
super.onStop();
}
private void enableWallpaperDaydream() {
final PackageManager pm = getPackageManager();
final ComponentName wallpaperComponent = new ComponentName(this, NyanWallpaperService.class);
final int wallpaperState = pm.getComponentEnabledSetting(wallpaperComponent);
boolean showToast = false;
if (wallpaperState != PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
pm.setComponentEnabledSetting(wallpaperComponent, PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP);
showToast = true;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
final ComponentName daydreamComponent = new ComponentName(this, NyanDaydreamService.class);
final int daydreamState = pm.getComponentEnabledSetting(daydreamComponent);
if (daydreamState != PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
pm.setComponentEnabledSetting(daydreamComponent, PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP);
showToast = true;
}
}
if (showToast) {
Toast.makeText(this, R.string.livewp_daydream_enabled_message, Toast.LENGTH_SHORT).show();
}
}
private void updateSurface() {
if (mPreferences == null) return;
final Resources res = getResources();
final int def = res.getInteger(R.integer.default_live_wallpaper_scale);
mHelper.setScale(mPreferences.getInt(KEY_LIVE_WALLPAPER_SCALE, def));
}
}

View File

@ -1,165 +0,0 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.activity;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.Typeface;
import android.os.Bundle;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.style.ForegroundColorSpan;
import android.text.style.StyleSpan;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.util.HtmlEscapeHelper;
import org.mariotaku.twidere.util.PermissionsManager;
import static android.text.TextUtils.isEmpty;
public class RequestPermissionsActivity extends BaseActivity implements OnClickListener {
private ImageView mIconView;
private TextView mNameView, mDescriptionView, mMessageView;
private Button mAcceptButton, mDenyButton;
private String[] mPermissions;
private String mCallingPackage;
@Override
public void onClick(final View view) {
switch (view.getId()) {
case R.id.accept: {
permissionsManager.accept(mCallingPackage, mPermissions);
setResult(RESULT_OK);
finish();
break;
}
case R.id.deny: {
setResult(RESULT_CANCELED);
finish();
break;
}
}
}
@Override
public void onContentChanged() {
super.onContentChanged();
mIconView = (ImageView) findViewById(android.R.id.icon);
mNameView = (TextView) findViewById(android.R.id.text1);
mDescriptionView = (TextView) findViewById(android.R.id.text2);
mMessageView = (TextView) findViewById(R.id.message);
mAcceptButton = (Button) findViewById(R.id.accept);
mDenyButton = (Button) findViewById(R.id.deny);
}
@Override
protected void onCreate(final Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_request_permissions);
mAcceptButton.setOnClickListener(this);
mDenyButton.setOnClickListener(this);
final String caller = getCallingPackage();
if (caller == null) {
setResult(RESULT_CANCELED);
finish();
return;
}
if (permissionsManager.isDenied(caller)) {
setResult(RESULT_CANCELED);
finish();
return;
}
loadInfo(caller);
}
private void appendPermission(final SpannableStringBuilder sb, final String name, final boolean danger) {
if (danger) {
final int start = sb.length();
sb.append(name);
final int end = sb.length();
sb.setSpan(new ForegroundColorSpan(0xffff8000), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
sb.setSpan(new StyleSpan(Typeface.BOLD), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} else {
sb.append(name);
}
}
private void loadInfo(final String pname) {
final PackageManager pm = getPackageManager();
try {
final ApplicationInfo info = pm.getApplicationInfo(pname, PackageManager.GET_META_DATA);
final Bundle meta = info.metaData;
if (meta == null || !meta.getBoolean(METADATA_KEY_EXTENSION)) {
setResult(RESULT_CANCELED);
finish();
return;
}
mIconView.setImageDrawable(info.loadIcon(pm));
mNameView.setText(info.loadLabel(pm));
final CharSequence desc = info.loadDescription(pm);
mDescriptionView.setText(desc);
mDescriptionView.setVisibility(isEmpty(desc) ? View.GONE : View.VISIBLE);
final String[] permissions = PermissionsManager.parsePermissions(meta
.getString(METADATA_KEY_EXTENSION_PERMISSIONS));
mPermissions = permissions;
mCallingPackage = pname;
final SpannableStringBuilder builder = new SpannableStringBuilder();
builder.append(HtmlEscapeHelper.escape(getString(R.string.permissions_request_message)));
builder.append("\n");
if (PermissionsManager.isPermissionValid(permissions)) {
if (PermissionsManager.hasPermissions(permissions, PERMISSION_PREFERENCES)) {
appendPermission(builder, getString(R.string.permission_description_preferences), true);
}
if (PermissionsManager.hasPermissions(permissions, PERMISSION_ACCOUNTS)) {
appendPermission(builder, getString(R.string.permission_description_accounts), true);
}
if (PermissionsManager.hasPermissions(permissions, PERMISSION_DIRECT_MESSAGES)) {
appendPermission(builder, getString(R.string.permission_description_direct_messages), true);
}
if (PermissionsManager.hasPermissions(permissions, PERMISSION_WRITE)) {
appendPermission(builder, getString(R.string.permission_description_write), false);
}
if (PermissionsManager.hasPermissions(permissions, PERMISSION_READ)) {
appendPermission(builder, getString(R.string.permission_description_read), false);
}
if (PermissionsManager.hasPermissions(permissions, PERMISSION_REFRESH)) {
appendPermission(builder, getString(R.string.permission_description_refresh), false);
}
} else {
appendPermission(builder, getString(R.string.permission_description_none), false);
}
mMessageView.setText(builder);
} catch (final NameNotFoundException e) {
setResult(RESULT_CANCELED);
finish();
}
}
}

View File

@ -186,6 +186,7 @@ public class CustomTabUtils implements Constants {
@ReadPositionTag
final String tag = getTagByType(type);
args.putInt(EXTRA_TAB_POSITION, position);
args.putLong(EXTRA_TAB_ID, cur.getLong(indices.id));
final TabExtras tabExtras = parseTabExtras(type, cur.getString(idxExtras));
if (tabExtras != null) {
args.putParcelable(EXTRA_EXTRAS, tabExtras);

View File

@ -44,7 +44,6 @@ import org.mariotaku.sqliteqb.library.Columns;
import org.mariotaku.sqliteqb.library.Columns.Column;
import org.mariotaku.sqliteqb.library.Expression;
import org.mariotaku.sqliteqb.library.OrderBy;
import org.mariotaku.sqliteqb.library.RawItemArray;
import org.mariotaku.sqliteqb.library.SQLFunctions;
import org.mariotaku.sqliteqb.library.SQLQueryBuilder;
import org.mariotaku.sqliteqb.library.Table;
@ -706,17 +705,19 @@ public class DataStoreUtils implements Constants {
return filterExpression;
}
public static int[] getAccountColors(final Context context, final long[] accountIds) {
if (context == null || accountIds == null) return new int[0];
public static int[] getAccountColors(final Context context, final UserKey[] accountKeys) {
if (context == null || accountKeys == null) return new int[0];
final String[] cols = new String[]{Accounts.ACCOUNT_KEY, Accounts.COLOR};
final String where = Expression.in(new Column(Accounts.ACCOUNT_KEY), new RawItemArray(accountIds)).getSQL();
final Cursor cur = context.getContentResolver().query(Accounts.CONTENT_URI, cols, where, null, null);
final String where = Expression.inArgs(new Column(Accounts.ACCOUNT_KEY), accountKeys.length).getSQL();
final String[] whereArgs = TwidereArrayUtils.toStringArray(accountKeys);
final Cursor cur = context.getContentResolver().query(Accounts.CONTENT_URI, cols, where,
whereArgs, null);
if (cur == null) return new int[0];
try {
final int[] colors = new int[cur.getCount()];
for (int i = 0, j = cur.getCount(); i < j; i++) {
cur.moveToPosition(i);
colors[ArrayUtils.indexOf(accountIds, cur.getLong(0))] = cur.getInt(1);
colors[ArrayUtils.indexOf(accountKeys, cur.getLong(0))] = cur.getInt(1);
}
return colors;
} finally {

View File

@ -116,17 +116,6 @@ public final class TwidereArrayUtils {
}
}
public static long min(final long[] array) {
if (array == null || array.length == 0) throw new IllegalArgumentException();
long min = array[0];
for (int i = 1, j = array.length; i < j; i++) {
if (min > array[i]) {
min = array[i];
}
}
return min;
}
@NonNull
public static long[] parseLongArray(final String string, final char token) {
if (TextUtils.isEmpty(string)) return new long[0];

View File

@ -0,0 +1,238 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.activity
import android.app.Activity
import android.app.LoaderManager.LoaderCallbacks
import android.content.CursorLoader
import android.content.Intent
import android.content.Loader
import android.database.ContentObserver
import android.database.Cursor
import android.net.Uri
import android.os.Bundle
import android.text.TextUtils
import android.view.View
import android.view.View.OnClickListener
import android.widget.AdapterView
import android.widget.AdapterView.OnItemClickListener
import android.widget.ListView
import android.widget.Toast
import kotlinx.android.synthetic.main.activity_account_selector.*
import org.apache.commons.lang3.ArrayUtils
import org.mariotaku.sqliteqb.library.Columns
import org.mariotaku.sqliteqb.library.Expression
import org.mariotaku.twidere.R
import org.mariotaku.twidere.TwidereConstants.*
import org.mariotaku.twidere.adapter.AccountsAdapter
import org.mariotaku.twidere.app.TwidereApplication
import org.mariotaku.twidere.model.ParcelableAccount
import org.mariotaku.twidere.model.ParcelableCredentials
import org.mariotaku.twidere.provider.TwidereDataStore.Accounts
import java.util.*
class AccountSelectorActivity : BaseActivity(), LoaderCallbacks<Cursor>, OnClickListener, OnItemClickListener {
private val mContentObserver = object : ContentObserver(null) {
override fun onChange(selfChange: Boolean) {
onChange(selfChange, null)
}
override fun onChange(selfChange: Boolean, uri: Uri?) {
// Handle change.
if (!isFinishing) {
loaderManager.restartLoader(0, null, this@AccountSelectorActivity)
}
}
}
private var adapter: AccountsAdapter? = null
private var firstCreated: Boolean = false
override fun onClick(view: View) {
when (view.id) {
R.id.save -> {
val checkedIds = accountsList.checkedItemIds
if (checkedIds.size == 0 && !isSelectNoneAllowed) {
Toast.makeText(this, R.string.no_account_selected, Toast.LENGTH_SHORT).show()
return
}
val data = Intent()
data.putExtra(EXTRA_IDS, checkedIds)
setResult(Activity.RESULT_OK, data)
finish()
}
}
}
override fun onCreateLoader(id: Int, args: Bundle): Loader<Cursor> {
val conditions = ArrayList<Expression>()
val conditionArgs = ArrayList<String>()
if (isOAuthOnly) {
conditions.add(Expression.equalsArgs(Accounts.AUTH_TYPE))
conditionArgs.add(ParcelableCredentials.AuthType.OAUTH.toString())
}
val accountHost = accountHost
if (!TextUtils.isEmpty(accountHost)) {
if (USER_TYPE_TWITTER_COM == accountHost) {
conditions.add(Expression.or(
Expression.equalsArgs(Accounts.ACCOUNT_TYPE),
Expression.isNull(Columns.Column(Accounts.ACCOUNT_TYPE)),
Expression.likeRaw(Columns.Column(Accounts.ACCOUNT_KEY), "'%@'||?"),
Expression.notLikeRaw(Columns.Column(Accounts.ACCOUNT_KEY), "'%@%'")))
conditionArgs.add(ParcelableAccount.Type.TWITTER)
conditionArgs.add(accountHost)
} else {
conditions.add(Expression.likeRaw(Columns.Column(Accounts.ACCOUNT_KEY), "'%@'||?"))
conditionArgs.add(accountHost)
}
}
val where: String?
val whereArgs: Array<String>?
if (conditions.isEmpty()) {
where = null
whereArgs = null
} else {
where = Expression.and(*conditions.toTypedArray()).sql
whereArgs = conditionArgs.toTypedArray()
}
return CursorLoader(this, Accounts.CONTENT_URI, Accounts.COLUMNS, where, whereArgs,
Accounts.SORT_POSITION)
}
override fun onLoadFinished(loader: Loader<Cursor>, cursor: Cursor?) {
val adapter = adapter!!
adapter.swapCursor(cursor)
if (cursor != null && firstCreated) {
val activatedIds = intentExtraIds
var i = 0
val j = adapter.count
while (i < j) {
accountsList.setItemChecked(i, ArrayUtils.contains(activatedIds, adapter.getItemId(i)))
i++
}
}
if (adapter.count == 1 && shouldSelectOnlyItem()) {
selectSingleAccount(0)
} else if (adapter.isEmpty) {
Toast.makeText(this, R.string.no_account, Toast.LENGTH_SHORT).show()
finish()
}
}
override fun onLoaderReset(loader: Loader<Cursor>) {
adapter!!.swapCursor(null)
}
override fun onItemClick(parent: AdapterView<*>, view: View, position: Int, id: Long) {
selectSingleAccount(position)
}
fun selectSingleAccount(position: Int) {
val adapter = adapter!!
val account = adapter.getAccount(position)
val data = Intent()
data.putExtra(EXTRA_ID, account!!.account_key.id)
data.putExtra(EXTRA_ACCOUNT_KEY, account.account_key)
val startIntent = startIntent
if (startIntent != null) {
startIntent.putExtra(EXTRA_ACCOUNT_KEY, account.account_key)
startActivity(startIntent)
}
setResult(Activity.RESULT_OK, data)
finish()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
firstCreated = savedInstanceState == null
setContentView(R.layout.activity_account_selector)
adapter = AccountsAdapter(this)
val isSingleSelection = isSingleSelection
accountsList.choiceMode = if (isSingleSelection) ListView.CHOICE_MODE_NONE else ListView.CHOICE_MODE_MULTIPLE
adapter!!.setSwitchEnabled(!isSingleSelection)
adapter!!.setSortEnabled(false)
if (isSingleSelection) {
accountsList.onItemClickListener = this
}
selectAccountButtons.visibility = if (isSingleSelection) View.GONE else View.VISIBLE
accountsList.adapter = adapter
loaderManager.initLoader(0, null, this)
}
override fun onStart() {
super.onStart()
contentResolver.registerContentObserver(Accounts.CONTENT_URI, true, mContentObserver)
}
override fun onResume() {
super.onResume()
val displayProfileImage = preferences.getBoolean(KEY_DISPLAY_PROFILE_IMAGE, true)
adapter!!.isProfileImageDisplayed = displayProfileImage
}
override fun onStop() {
contentResolver.unregisterContentObserver(mContentObserver)
super.onStop()
}
private val intentExtraIds: LongArray
get() {
return intent.getLongArrayExtra(EXTRA_IDS)
}
private val isOAuthOnly: Boolean
get() {
return intent.getBooleanExtra(EXTRA_OAUTH_ONLY, false)
}
private val accountHost: String
get() {
return intent.getStringExtra(EXTRA_ACCOUNT_HOST)
}
private val isSelectNoneAllowed: Boolean
get() {
return intent.getBooleanExtra(EXTRA_ALLOW_SELECT_NONE, false)
}
private val isSingleSelection: Boolean
get() {
return intent.getBooleanExtra(EXTRA_SINGLE_SELECTION, false)
}
private fun shouldSelectOnlyItem(): Boolean {
return intent.getBooleanExtra(EXTRA_SELECT_ONLY_ITEM, false)
}
private val startIntent: Intent?
get() {
val startIntent = intent.getParcelableExtra<Intent>(EXTRA_START_INTENT)
startIntent?.setExtrasClassLoader(TwidereApplication::class.java.classLoader)
return startIntent
}
}

View File

@ -0,0 +1,6 @@
package org.mariotaku.twidere.activity
/**
* Created by mariotaku on 16/5/11.
*/
abstract class BasePlusServiceSignInActivity : BaseActivity()

View File

@ -0,0 +1,76 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.activity
import android.app.Activity
import android.content.Intent
import android.graphics.Color
import android.os.Bundle
import org.mariotaku.twidere.constant.IntentConstants.*
import org.mariotaku.twidere.fragment.ColorPickerDialogFragment
import org.mariotaku.twidere.fragment.ColorPickerDialogFragment.Callback
class ColorPickerDialogActivity : BaseActivity(), Callback {
override fun onCancelled() {
finish()
}
override fun onStart() {
super.onStart()
setVisible(true)
}
override fun onColorCleared() {
setResult(RESULT_CLEARED)
finish()
}
override fun onColorSelected(color: Int) {
val intent = Intent()
intent.putExtra(EXTRA_COLOR, color)
setResult(Activity.RESULT_OK, intent)
finish()
}
override fun onDismissed() {
finish()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (savedInstanceState == null) {
val intent = intent
val f = ColorPickerDialogFragment()
val args = Bundle()
args.putInt(EXTRA_COLOR, intent.getIntExtra(EXTRA_COLOR, Color.WHITE))
args.putBoolean(EXTRA_CLEAR_BUTTON, intent.getBooleanExtra(EXTRA_CLEAR_BUTTON, false))
args.putBoolean(EXTRA_ALPHA_SLIDER, intent.getBooleanExtra(EXTRA_ALPHA_SLIDER, true))
f.arguments = args
f.show(supportFragmentManager, "color_picker_dialog")
}
}
companion object {
val RESULT_CLEARED = -2
}
}

View File

@ -0,0 +1,45 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.activity
import android.app.Activity
import android.content.Intent
import android.content.Intent.ShortcutIconResource
import android.os.Bundle
import org.mariotaku.twidere.R
import org.mariotaku.twidere.constant.IntentConstants.INTENT_ACTION_COMPOSE
class CreateComposeShortcutActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setVisible(true)
val intent = Intent()
val launch_intent = Intent(INTENT_ACTION_COMPOSE)
val icon = Intent.ShortcutIconResource.fromContext(this, R.mipmap.ic_launcher)
intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, launch_intent)
intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, icon)
intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, getString(R.string.compose))
setResult(Activity.RESULT_OK, intent)
finish()
}
}

View File

@ -33,11 +33,11 @@ class DataExportActivity : BaseActivity(), DataExportImportTypeSelectorDialogFra
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
when (requestCode) {
REQUEST_PICK_DIRECTORY -> {
executeAfterFragmentResumed {
if (resultCode == RESULT_OK) {
if (resultCode == RESULT_OK && data != null) {
val path = data.data.path
val df = DataExportImportTypeSelectorDialogFragment()
val args = Bundle()

View File

@ -31,11 +31,11 @@ class DataImportActivity : BaseActivity(), DataExportImportTypeSelectorDialogFra
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
when (requestCode) {
REQUEST_PICK_FILE -> {
resumeFragmentsRunnable = Runnable {
if (resultCode == RESULT_OK) {
if (resultCode == RESULT_OK && data != null) {
val path = data.data.path
if (openImportTypeTask == null || openImportTypeTask!!.status != AsyncTask.Status.RUNNING) {
openImportTypeTask = OpenImportTypeTask(this@DataImportActivity, path)

View File

@ -81,7 +81,7 @@ class MediaViewerActivity : BaseActivity(), IExtendedActivity, ATEToolbarCustomi
}
public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
when (requestCode) {
REQUEST_SHARE_MEDIA -> {
ShareProvider.clearTempFiles(this)

View File

@ -0,0 +1,103 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.activity
import android.content.ComponentName
import android.content.SharedPreferences
import android.content.SharedPreferences.OnSharedPreferenceChangeListener
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import android.view.View
import android.view.View.OnLongClickListener
import android.widget.Toast
import kotlinx.android.synthetic.main.layout_surface_view.*
import org.mariotaku.twidere.R
import org.mariotaku.twidere.constant.SharedPreferenceConstants.KEY_LIVE_WALLPAPER_SCALE
import org.mariotaku.twidere.nyan.NyanDaydreamService
import org.mariotaku.twidere.nyan.NyanSurfaceHelper
import org.mariotaku.twidere.nyan.NyanWallpaperService
class NyanActivity : BaseActivity(), OnLongClickListener, OnSharedPreferenceChangeListener {
private var helper: NyanSurfaceHelper? = null
override fun onLongClick(v: View): Boolean {
Toast.makeText(this, R.string.nyan_sakamoto, Toast.LENGTH_SHORT).show()
return true
}
override fun onSharedPreferenceChanged(preferences: SharedPreferences, key: String) {
if (KEY_LIVE_WALLPAPER_SCALE == key) {
updateSurface()
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.layout_surface_view)
surfaceView.setOnLongClickListener(this)
val holder = surfaceView.holder
helper = NyanSurfaceHelper(this)
holder.addCallback(helper)
updateSurface()
enableWallpaperDaydream()
}
override fun onStart() {
super.onStart()
helper?.start()
}
override fun onStop() {
helper?.stop()
super.onStop()
}
private fun enableWallpaperDaydream() {
val pm = packageManager
val wallpaperComponent = ComponentName(this, NyanWallpaperService::class.java)
val wallpaperState = pm.getComponentEnabledSetting(wallpaperComponent)
var showToast = false
if (wallpaperState != PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
pm.setComponentEnabledSetting(wallpaperComponent, PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP)
showToast = true
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
val daydreamComponent = ComponentName(this, NyanDaydreamService::class.java)
val daydreamState = pm.getComponentEnabledSetting(daydreamComponent)
if (daydreamState != PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
pm.setComponentEnabledSetting(daydreamComponent, PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP)
showToast = true
}
}
if (showToast) {
Toast.makeText(this, R.string.livewp_daydream_enabled_message, Toast.LENGTH_SHORT).show()
}
}
private fun updateSurface() {
val def = resources.getInteger(R.integer.default_live_wallpaper_scale)
helper!!.setScale(preferences.getInt(KEY_LIVE_WALLPAPER_SCALE, def).toFloat())
}
}

View File

@ -0,0 +1,142 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.activity
import android.app.Activity
import android.content.pm.PackageManager
import android.content.pm.PackageManager.NameNotFoundException
import android.graphics.Typeface
import android.os.Bundle
import android.text.SpannableStringBuilder
import android.text.Spanned
import android.text.TextUtils.isEmpty
import android.text.style.ForegroundColorSpan
import android.text.style.StyleSpan
import android.view.View
import android.view.View.OnClickListener
import android.view.Window
import kotlinx.android.synthetic.main.activity_request_permissions.*
import kotlinx.android.synthetic.main.activity_request_permissions.view.*
import org.mariotaku.twidere.R
import org.mariotaku.twidere.TwidereConstants.*
import org.mariotaku.twidere.util.HtmlEscapeHelper
import org.mariotaku.twidere.util.PermissionsManager
class RequestPermissionsActivity : BaseActivity(), OnClickListener {
private var permissions: Array<String>? = null
override fun onClick(view: View) {
when (view) {
buttonsContainer.accept -> {
permissionsManager.accept(callingPackage, permissions)
setResult(Activity.RESULT_OK)
finish()
}
buttonsContainer.deny -> {
setResult(Activity.RESULT_CANCELED)
finish()
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
requestWindowFeature(Window.FEATURE_NO_TITLE)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_request_permissions)
buttonsContainer.accept.setOnClickListener(this)
buttonsContainer.deny.setOnClickListener(this)
val caller = callingPackage
if (caller == null) {
setResult(Activity.RESULT_CANCELED)
finish()
return
}
if (permissionsManager.isDenied(caller)) {
setResult(Activity.RESULT_CANCELED)
finish()
return
}
loadInfo(caller)
}
private fun appendPermission(sb: SpannableStringBuilder, name: String, danger: Boolean) {
if (danger) {
val start = sb.length
sb.append(name)
val end = sb.length
sb.setSpan(ForegroundColorSpan(0xffff8000.toInt()), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
sb.setSpan(StyleSpan(Typeface.BOLD), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
} else {
sb.append(name)
}
}
private fun loadInfo(pname: String) {
val pm = packageManager
try {
val info = pm.getApplicationInfo(pname, PackageManager.GET_META_DATA)
val meta = info.metaData
if (meta == null || !meta.getBoolean(METADATA_KEY_EXTENSION)) {
setResult(Activity.RESULT_CANCELED)
finish()
return
}
iconView.setImageDrawable(info.loadIcon(pm))
nameView.text = info.loadLabel(pm)
val desc = info.loadDescription(pm)
descriptionView.text = desc
descriptionView.visibility = if (isEmpty(desc)) View.GONE else View.VISIBLE
val permissions = PermissionsManager.parsePermissions(meta.getString(METADATA_KEY_EXTENSION_PERMISSIONS))
this.permissions = permissions
val builder = SpannableStringBuilder()
builder.append(HtmlEscapeHelper.escape(getString(R.string.permissions_request_message)))
builder.append("\n")
if (PermissionsManager.isPermissionValid(*permissions)) {
if (PermissionsManager.hasPermissions(permissions, PERMISSION_PREFERENCES)) {
appendPermission(builder, getString(R.string.permission_description_preferences), true)
}
if (PermissionsManager.hasPermissions(permissions, PERMISSION_ACCOUNTS)) {
appendPermission(builder, getString(R.string.permission_description_accounts), true)
}
if (PermissionsManager.hasPermissions(permissions, PERMISSION_DIRECT_MESSAGES)) {
appendPermission(builder, getString(R.string.permission_description_direct_messages), true)
}
if (PermissionsManager.hasPermissions(permissions, PERMISSION_WRITE)) {
appendPermission(builder, getString(R.string.permission_description_write), false)
}
if (PermissionsManager.hasPermissions(permissions, PERMISSION_READ)) {
appendPermission(builder, getString(R.string.permission_description_read), false)
}
if (PermissionsManager.hasPermissions(permissions, PERMISSION_REFRESH)) {
appendPermission(builder, getString(R.string.permission_description_refresh), false)
}
} else {
appendPermission(builder, getString(R.string.permission_description_none), false)
}
messageView.text = builder
} catch (e: NameNotFoundException) {
setResult(Activity.RESULT_CANCELED)
finish()
}
}
}

View File

@ -117,7 +117,7 @@ class SettingsWizardActivity : BaseActivity() {
return ATEUtil.darkenColor(ThemeUtils.getColorBackground(this))
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
when (requestCode) {
REQUEST_IMPORT_SETTINGS -> {
if (resultCode == Activity.RESULT_OK) {

View File

@ -31,6 +31,7 @@ import org.mariotaku.twidere.constant.SharedPreferenceConstants.KEY_MEDIA_PREVIE
import org.mariotaku.twidere.model.Draft
import org.mariotaku.twidere.model.DraftCursorIndices
import org.mariotaku.twidere.model.ParcelableMediaUpdate
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.util.ParcelableMediaUtils
import org.mariotaku.twidere.util.*
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
@ -57,11 +58,12 @@ class DraftsAdapter(context: Context) : SimpleCursorAdapter(context, R.layout.li
override fun bindView(view: View, context: Context, cursor: Cursor) {
val holder = view.tag as DraftViewHolder
val accountIds = TwidereArrayUtils.parseLongArray(cursor.getString(mIndices!!.account_keys), ',')
val text = cursor.getString(mIndices!!.text)
val mediaUpdates = JsonSerializer.parseArray(cursor.getString(mIndices!!.media), ParcelableMediaUpdate::class.java)
val timestamp = cursor.getLong(mIndices!!.timestamp)
val actionType: String = cursor.getString(mIndices!!.action_type) ?: Draft.Action.UPDATE_STATUS
val indices = mIndices!!
val accountKeys = UserKey.arrayOf(cursor.getString(indices.account_keys))
val text = cursor.getString(indices.text)
val mediaUpdates = JsonSerializer.parseArray(cursor.getString(indices.media), ParcelableMediaUpdate::class.java)
val timestamp = cursor.getLong(indices.timestamp)
val actionType: String = cursor.getString(indices.action_type) ?: Draft.Action.UPDATE_STATUS
val actionName = getActionName(context, actionType)
holder.media_preview_container.setStyle(mediaPreviewStyle)
when (actionType) {
@ -75,7 +77,7 @@ class DraftsAdapter(context: Context) : SimpleCursorAdapter(context, R.layout.li
holder.media_preview_container.visibility = View.GONE
}
}
holder.content.drawEnd(*DataStoreUtils.getAccountColors(context, accountIds))
holder.content.drawEnd(*DataStoreUtils.getAccountColors(context, accountKeys))
holder.setTextSize(mTextSize)
val emptyContent = TextUtils.isEmpty(text)
if (emptyContent) {

View File

@ -252,7 +252,6 @@ class ParcelableActivitiesAdapter(
}
override fun getItemViewType(position: Int): Int {
val activity = getActivity(position)
if (loadMoreIndicatorPosition and ILoadMoreSupportAdapter.START != 0L && position == 0) {
return ITEM_VIEW_TYPE_LOAD_INDICATOR
} else if (position == activityCount) {
@ -260,24 +259,25 @@ class ParcelableActivitiesAdapter(
} else if (isGapItem(position)) {
return ITEM_VIEW_TYPE_GAP
}
val action = getActivityAction(position) ?: throw NullPointerException()
val action = getActivityAction(position)!!
val activity = getActivity(position)!!
when (action) {
Activity.Action.MENTION -> {
if (ArrayUtils.isEmpty(activity!!.target_object_statuses)) {
if (ArrayUtils.isEmpty(activity.target_object_statuses)) {
return ITEM_VIEW_TYPE_STUB
}
if (followingOnly && !activity.status_user_following) return ITEM_VIEW_TYPE_EMPTY
return ITEM_VIEW_TYPE_STATUS
}
Activity.Action.REPLY -> {
if (ArrayUtils.isEmpty(activity!!.target_statuses)) {
if (ArrayUtils.isEmpty(activity.target_statuses)) {
return ITEM_VIEW_TYPE_STUB
}
if (followingOnly && !activity.status_user_following) return ITEM_VIEW_TYPE_EMPTY
return ITEM_VIEW_TYPE_STATUS
}
Activity.Action.QUOTE -> {
if (ArrayUtils.isEmpty(activity!!.target_statuses)) {
if (ArrayUtils.isEmpty(activity.target_statuses)) {
return ITEM_VIEW_TYPE_STUB
}
if (followingOnly && !activity.status_user_following) return ITEM_VIEW_TYPE_EMPTY
@ -286,7 +286,7 @@ class ParcelableActivitiesAdapter(
Activity.Action.FOLLOW, Activity.Action.FAVORITE, Activity.Action.RETWEET, Activity.Action.FAVORITED_RETWEET, Activity.Action.RETWEETED_RETWEET, Activity.Action.RETWEETED_MENTION, Activity.Action.FAVORITED_MENTION, Activity.Action.LIST_CREATED, Activity.Action.LIST_MEMBER_ADDED, Activity.Action.MEDIA_TAGGED, Activity.Action.RETWEETED_MEDIA_TAGGED, Activity.Action.FAVORITED_MEDIA_TAGGED, Activity.Action.JOINED_TWITTER -> {
if (mentionsOnly) return ITEM_VIEW_TYPE_EMPTY
ParcelableActivityUtils.initAfterFilteredSourceIds(activity, filteredUserIds, followingOnly)
if (ArrayUtils.isEmpty(activity!!.after_filtered_source_ids)) {
if (ArrayUtils.isEmpty(activity.after_filtered_source_ids)) {
return ITEM_VIEW_TYPE_EMPTY
}
return ITEM_VIEW_TYPE_TITLE_SUMMARY

View File

@ -96,7 +96,7 @@ open class BaseSupportFragment : Fragment(), IBaseFragment {
override val tabId: Long
get() {
val args = arguments ?: return -1L
return args.getLong(IntentConstants.EXTRA_TAB_POSITION, -1L)
return args.getLong(IntentConstants.EXTRA_TAB_ID, -1L)
}
override fun requestFitSystemWindows() {

View File

@ -30,7 +30,7 @@ import org.mariotaku.twidere.util.Utils
class SettingsDetailsFragment : BasePreferenceFragment(), OnSharedPreferenceChangeListener {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String) {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
val preferenceManager = preferenceManager
preferenceManager.sharedPreferencesName = SHARED_PREFERENCES_NAME
val defaultScreen = preferenceScreen

View File

@ -19,6 +19,7 @@
package org.mariotaku.twidere.fragment
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.net.Uri
@ -243,13 +244,13 @@ class UserProfileEditorFragment : BaseSupportFragment(), OnSizeChangedListener,
data.data, true)
}
REQUEST_PICK_LINK_COLOR -> {
if (resultCode == ColorPickerDialogActivity.RESULT_OK) {
if (resultCode == Activity.RESULT_OK) {
linkColor.color = data.getIntExtra(EXTRA_COLOR, 0)
updateDoneButton()
}
}
REQUEST_PICK_BACKGROUND_COLOR -> {
if (resultCode == ColorPickerDialogActivity.RESULT_OK) {
if (resultCode == Activity.RESULT_OK) {
backgroundColor.color = data.getIntExtra(EXTRA_COLOR, 0)
updateDoneButton()
}

View File

@ -60,7 +60,7 @@ import java.util.regex.Pattern
/**
* Created by mariotaku on 15/12/20.
*/
class CardPollFragment : BaseSupportFragment(), LoaderManager.LoaderCallbacks<ParcelableCardEntity>, View.OnClickListener {
class CardPollFragment : BaseSupportFragment(), LoaderManager.LoaderCallbacks<ParcelableCardEntity?>, View.OnClickListener {
private var fetchedCard: ParcelableCardEntity? = null
override fun onActivityCreated(savedInstanceState: Bundle?) {
@ -232,17 +232,17 @@ class CardPollFragment : BaseSupportFragment(), LoaderManager.LoaderCallbacks<Pa
}
override fun onCreateLoader(id: Int, args: Bundle): Loader<ParcelableCardEntity> {
override fun onCreateLoader(id: Int, args: Bundle?): Loader<ParcelableCardEntity?> {
val card = card
return ParcelableCardEntityLoader(context, card.account_key, card.url, card.name)
}
override fun onLoadFinished(loader: Loader<ParcelableCardEntity>, data: ParcelableCardEntity?) {
override fun onLoadFinished(loader: Loader<ParcelableCardEntity?>, data: ParcelableCardEntity?) {
if (data == null) return
displayPoll(data, status)
}
override fun onLoaderReset(loader: Loader<ParcelableCardEntity>) {
override fun onLoaderReset(loader: Loader<ParcelableCardEntity?>) {
}
@ -280,22 +280,26 @@ class CardPollFragment : BaseSupportFragment(), LoaderManager.LoaderCallbacks<Pa
}
}
class ParcelableCardEntityLoader(context: Context, private val mAccountKey: UserKey,
private val mCardUri: String, private val mCardName: String) : AsyncTaskLoader<ParcelableCardEntity>(context) {
class ParcelableCardEntityLoader(
context: Context,
private val accountKey: UserKey,
private val cardUri: String,
private val cardName: String
) : AsyncTaskLoader<ParcelableCardEntity?>(context) {
override fun loadInBackground(): ParcelableCardEntity? {
val caps = MicroBlogAPIFactory.getInstance(context, mAccountKey,
val caps = MicroBlogAPIFactory.getInstance(context, accountKey,
true, true, TwitterCaps::class.java) ?: return null
try {
val params = CardDataMap()
params.putString("card_uri", mCardUri)
params.putString("card_uri", cardUri)
params.putString("cards_platform", MicroBlogAPIFactory.CARDS_PLATFORM_ANDROID_12)
params.putString("response_card_name", mCardName)
params.putString("response_card_name", cardName)
val card = caps.getPassThrough(params).card
if (card == null || card.name == null) {
return null
}
return ParcelableCardEntityUtils.fromCardEntity(card, mAccountKey)
return ParcelableCardEntityUtils.fromCardEntity(card, accountKey)
} catch (e: MicroBlogException) {
return null
}

View File

@ -29,13 +29,13 @@
tools:context=".activity.AccountSelectorActivity">
<ListView
android:id="@android:id/list"
android:id="@+id/accountsList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"/>
<LinearLayout
android:id="@+id/select_account_buttons"
android:id="@+id/selectAccountButtons"
style="?android:buttonBarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -43,7 +43,7 @@
android:orientation="horizontal">
<Button
android:id="@+id/save"
android:id="@+id/confirmSelection"
style="?android:borderlessButtonStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"

View File

@ -45,7 +45,7 @@
android:orientation="horizontal">
<ImageView
android:id="@android:id/icon"
android:id="@+id/iconView"
android:layout_width="56dp"
android:layout_height="56dp"
android:layout_margin="4dp"
@ -59,7 +59,7 @@
android:orientation="vertical">
<TextView
android:id="@android:id/text1"
android:id="@+id/nameView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="true"
@ -67,7 +67,7 @@
android:textStyle="bold"/>
<TextView
android:id="@android:id/text2"
android:id="@+id/descriptionView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="true"
@ -76,7 +76,7 @@
</LinearLayout>
<TextView
android:id="@+id/message"
android:id="@+id/messageView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="16dp"
@ -87,7 +87,7 @@
</ScrollView>
<LinearLayout
android:id="@+id/buttons"
android:id="@+id/buttonsContainer"
android:layout_width="match_parent"
android:layout_height="@dimen/button_bar_height"
android:divider="?android:dividerHorizontal"

View File

@ -19,7 +19,7 @@
-->
<SurfaceView
android:id="@+id/surface"
android:id="@+id/surfaceView"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"/>