adjusting design to holo, stability for account setup

This commit is contained in:
Bartek Przybylski 2012-05-13 16:13:13 +02:00
parent fae44486b9
commit 0aeb425885
81 changed files with 2442 additions and 1028 deletions

View file

@ -1,8 +1,24 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <!--
package="eu.alefzero.owncloud" ownCloud Android client application
Copyright (C) 2012 Bartek Przybylski
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/>.
-->
<manifest package="eu.alefzero.owncloud"
android:versionCode="1" android:versionCode="1"
android:versionName="1.0" > android:versionName="1.0" xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.GET_ACCOUNTS" /> <uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" /> <uses-permission android:name="android.permission.USE_CREDENTIALS" />
@ -15,6 +31,7 @@
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" /> <uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.BROADCAST_STICKY" /> <uses-permission android:name="android.permission.BROADCAST_STICKY" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-sdk <uses-sdk
android:minSdkVersion="8" android:minSdkVersion="8"
@ -27,11 +44,12 @@
<application <application
android:icon="@drawable/icon" android:icon="@drawable/icon"
android:label="@string/app_name" > android:label="@string/app_name"
android:theme="@style/Theme.ownCloud"
android:uiOptions="splitActionBarWhenNarrow">
<activity <activity
android:name=".ui.activity.FileDisplayActivity" android:name=".ui.activity.FileDisplayActivity"
android:label="@string/app_name" android:label="@string/app_name">
android:theme="@style/Theme.ownCloud" >
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
@ -69,7 +87,7 @@
<service <service
android:name=".authenticator.AccountAuthenticatorService" android:name=".authenticator.AccountAuthenticatorService"
android:exported="true" > android:exported="true">
<intent-filter> <intent-filter>
<action android:name="android.accounts.AccountAuthenticator" /> <action android:name="android.accounts.AccountAuthenticator" />
</intent-filter> </intent-filter>
@ -102,7 +120,7 @@
<activity <activity
android:name=".ui.activity.AuthenticatorActivity" android:name=".ui.activity.AuthenticatorActivity"
android:exported="true" android:exported="true"
android:theme="@style/Theme.ownCloud" > android:theme="@style/Theme.ownCloud.noActionBar" >
</activity> </activity>
<service android:name=".FileDownloader" > <service android:name=".FileDownloader" >
@ -125,7 +143,10 @@
<activity <activity
android:name=".ui.activity.FileDetailActivity" android:name=".ui.activity.FileDetailActivity"
android:theme="@style/Theme.ownCloud" > android:theme="@style/Theme.ownCloud" >
</activity> </activity>
<activity android:name=".extensions.ExtensionsAvailableActivity"></activity>
<activity android:name=".extensions.ExtensionsListActivity"></activity>
<activity android:name=".ui.activity.AccountSelectActivity" android:uiOptions="none" android:label="@string/prefs_accounts"></activity>
</application> </application>
</manifest> </manifest>

View file

@ -18,11 +18,11 @@
native <methods>; native <methods>;
} }
-keepclasseswithmembernames class * { -keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet); public <init>(android.content.Context, android.util.AttributeSet);
} }
-keepclasseswithmembernames class * { -keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet, int); public <init>(android.content.Context, android.util.AttributeSet, int);
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 802 B

View file

@ -0,0 +1,13 @@
<!--?xml version="1.0" encoding="utf-8"? -->
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient android:endColor="#8dc73f" android:centerColor="#d4d4d4"
android:startColor="#d4d4d4">
<stroke android:width="1dp" color="#8dc73f">
<corners android:radius="5dp">
<padding android:left="7dp" android:top="7dp" android:right="7dp"
android:bottom="7dp">
</padding>
</corners>
</stroke>
</gradient>
</shape>

BIN
res/drawable/ic_ok.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 552 B

View file

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2010 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android" android:exitFadeDuration="@android:integer/config_mediumAnimTime">
<item android:drawable="@color/filelist_backgorund" android:state_window_focused="false"/>
<!-- Even though these two point to the same resource, have two states so the drawable will invalidate itself when coming out of pressed state. -->
<item android:drawable="@android:color/holo_blue_bright" android:state_enabled="false" android:state_focused="true" android:state_pressed="true"/>
<item android:drawable="@android:color/holo_blue_bright" android:state_enabled="false" android:state_focused="true"/>
<item android:drawable="@android:color/holo_blue_bright" android:state_focused="true" android:state_pressed="true"/>
<item android:drawable="@android:color/holo_blue_bright" android:state_focused="false" android:state_pressed="true"/>
<item android:drawable="@android:color/holo_blue_bright" android:state_focused="true"/>
</selector>

View file

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2010 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android" android:exitFadeDuration="@android:integer/config_mediumAnimTime">
<item android:drawable="@color/filelist_backgorund" android:state_window_focused="false"/>
<!-- Even though these two point to the same resource, have two states so the drawable will invalidate itself when coming out of pressed state. -->
<item android:drawable="@android:color/holo_blue_bright" android:state_enabled="false" android:state_focused="true" android:state_pressed="true"/>
<item android:drawable="@android:color/holo_blue_bright" android:state_enabled="false" android:state_focused="true"/>
<item android:drawable="@android:color/holo_blue_bright" android:state_focused="true" android:state_pressed="true"/>
<item android:drawable="@android:color/holo_blue_bright" android:state_focused="false" android:state_pressed="true"/>
<item android:drawable="@android:color/holo_blue_bright" android:state_focused="true"/>
</selector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

View file

@ -1,7 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"> <shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient <gradient
android:startColor="#1D2D55" android:startColor="#1D2D44"
android:centerColor="#1D2D55"
android:endColor="#1D2D44" android:endColor="#1D2D44"
android:angle="270" android:angle="270"
/> />

BIN
res/drawable/no_network.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 623 B

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/spinner_inner"
android:pivotX="50%"
android:pivotY="50%"
android:fromDegrees="0"
android:toDegrees="360"
android:interpolator="@android:anim/linear_interpolator"
android:duration="1000"
android:startOffset="0"/>

Binary file not shown.

After

Width:  |  Height:  |  Size: 627 B

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<shape <shape
xmlns:android="http://schemas.android.com/apk/res/android"> xmlns:android="http://schemas.android.com/apk/res/android">
<gradient android:startColor="#fefefe" android:centerColor="#cccccc" android:endColor="#fefefe" android:angle="0"/> <gradient android:startColor="@color/filelist_icon_backgorund" android:endColor="@color/filelist_icon_backgorund" android:angle="0"/>
</shape> </shape>

View file

@ -0,0 +1,176 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
ownCloud Android client application
Copyright (C) 2012 Bartek Przybylski
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/>.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:oc="http://schemas.android.com/apk/res/eu.alefzero.owncloud"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:focusable="true"
android:gravity="center|fill"
android:orientation="vertical" >
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="16dip"
android:layout_marginRight="16dip"
android:layout_weight="1" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="@+id/imageView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="7dp"
android:layout_weight="1"
android:src="@drawable/logo_inverted" />
<LinearLayout
android:id="@+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:orientation="vertical" >
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1" >
<EditText
android:id="@+id/host_URL"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:hint="@string/auth_host_url"
android:singleLine="true" >
<requestFocus />
</EditText>
<ImageView
android:id="@+id/refreshButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|center_vertical"
android:src="@drawable/ic_action_refresh_black"
android:visibility="invisible" />
</FrameLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_weight="1" >
<ImageView
android:id="@+id/action_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:src="@android:drawable/stat_notify_sync"
android:visibility="invisible" />
<TextView
android:id="@+id/status_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
android:visibility="invisible" />
</LinearLayout>
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:text="@string/auth_login_details"
android:textAppearance="?android:attr/textAppearanceSmall" />
<EditText
android:id="@+id/account_username"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:ems="10"
android:hint="@string/auth_username"
android:singleLine="true" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1" >
<EditText
android:id="@+id/account_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:hint="@string/auth_password"
android:inputType="textPassword"
android:singleLine="true" />
<ImageView
android:id="@+id/viewPassword"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|center_vertical"
android:src="@android:drawable/ic_menu_view"
android:visibility="invisible" />
</FrameLayout>
</LinearLayout>
</LinearLayout>
</FrameLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:weightSum="1" >
<Button
android:id="@+id/buttonCancel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight=".5"
android:text="@string/common_cancel" />
<Button
android:id="@+id/buttonOK"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight=".5"
android:enabled="false"
android:onClick="onOkClick"
android:text="@string/setup_btn_connect"
android:textColor="@android:color/black" />
</LinearLayout>
</RelativeLayout>
</LinearLayout>

View file

@ -1,32 +1,40 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--
ownCloud Android client application
Copyright (C) 2011 Bartek Przybylski
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/>.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:layout_height="fill_parent"
android:background="#F7F7F7" android:orientation="horizontal" >
android:orientation="vertical" >
<LinearLayout <LinearLayout
android:id="@+id/linearLayout1" android:id="@+id/file_list_container"
android:layout_width="fill_parent" android:layout_width="0dp"
android:layout_height="fill_parent" android:layout_height="wrap_content"
android:orientation="horizontal" > android:layout_weight="1" >
<LinearLayout
android:id="@+id/file_list_container"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1">
</LinearLayout>
<fragment
android:id="@+id/fileDetail"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight="2"
class="eu.alefzero.owncloud.ui.fragment.FileDetail" >
<!-- Preview: layout=@layout/file_details -->
</fragment>
</LinearLayout> </LinearLayout>
<fragment
android:id="@+id/fileDetail"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight="2"
class="eu.alefzero.owncloud.ui.fragment.FileDetail" >
<!-- Preview: layout=@layout/file_details -->
</fragment>
</LinearLayout> </LinearLayout>

View file

@ -1,167 +1,177 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <!--
xmlns:oc="http://schemas.android.com/apk/res/eu.alefzero.owncloud" ownCloud Android client application
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#F7F7F7"
android:focusable="true"
android:orientation="vertical" >
<LinearLayout Copyright (C) 2012 Bartek Przybylski
android:id="@+id/linearLayout7" This program is free software: you can redistribute it and/or modify
android:layout_width="fill_parent" it under the terms of the GNU General Public License as published by
android:layout_height="wrap_content" the Free Software Foundation, either version 3 of the License, or
android:layout_gravity="top" (at your option) any later version.
android:background="#1D2D44"
android:gravity="center_vertical|top"
android:orientation="vertical"
android:paddingBottom="2pt"
android:paddingTop="2pt" >
<ImageView This program is distributed in the hope that it will be useful,
android:id="@+id/main_header_small" but WITHOUT ANY WARRANTY; without even the implied warranty of
android:layout_width="wrap_content" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
android:layout_height="wrap_content" GNU General Public License for more details.
android:layout_gravity="center|center_vertical|center_horizontal"
android:focusable="true"
android:src="@drawable/owncloud_logo_small_white" >
</ImageView>
</LinearLayout>
<LinearLayout
android:id="@+id/linearLayout2"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center|center_vertical"
android:gravity="center_vertical"
android:orientation="vertical" >
<TableLayout
android:id="@+id/tableLayout1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal" >
<TableRow
android:id="@+id/tableRow1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="15dip"
android:layout_marginTop="15dip"
android:text="@string/setup_title"
android:textColor="@android:color/black"
android:textSize="7pt"
android:textStyle="bold" >
</TextView>
</TableRow>
<TableRow
android:id="@+id/tableRow2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:weightSum="1.0" >
<eu.alefzero.owncloud.widgets.ActionEditText
android:id="@+id/host_URL"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="0.75"
android:hint="@string/setup_hint_address"
android:inputType="textUri"
android:textColor="@android:color/black"
android:singleLine="true"
oc:optionOneString="SSL"
oc:optionTwoString="NO SSL"
oc:optionOneColor="#00ff00"
oc:optionTwoColor="#ff0000"
oc:onBadgeClick="sslBadgeClick">
<requestFocus>
</requestFocus>
</eu.alefzero.owncloud.widgets.ActionEditText>
</TableRow>
<TableRow
android:id="@+id/tableRow3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:weightSum="1.0" >
<EditText
android:id="@+id/account_username"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight=".75"
android:hint="@string/setup_hint_username"
android:singleLine="true"
android:textColor="@android:color/black" >
</EditText>
</TableRow>
<TableRow
android:id="@+id/tableRow4"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:weightSum="1.0" >
<eu.alefzero.owncloud.widgets.ActionEditText
android:id="@+id/account_password"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight=".75"
android:hint="@string/setup_hint_password"
android:inputType="textPassword"
android:singleLine="true"
android:textColor="@android:color/black"
oc:optionOneString="Show"
oc:optionTwoString="Hide"
oc:optionOneColor="#00ff00"
oc:optionTwoColor="#ff0000"
oc:onBadgeClick="passwordBadgeClick">
</eu.alefzero.owncloud.widgets.ActionEditText>
</TableRow>
</TableLayout>
<LinearLayout
android:id="@+id/linearLayout1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="vertical"
android:weightSum="1.0" >
<Button
android:id="@+id/buttonOK"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight=".75"
android:onClick="onOkClick"
android:textColor="@android:color/black"
android:text="@string/setup_btn_connect" >
</Button>
<!--
<Button
android:id="@+id/buttonNotUser"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight=".75"
android:onClick="onNotUserClick"
android:textColor="@android:color/black"
android:text="Get started!" >
</Button>
-->
</LinearLayout>
</LinearLayout>
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:oc="http://schemas.android.com/apk/res/eu.alefzero.owncloud"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:focusable="true"
android:gravity="center|fill"
android:orientation="vertical" >
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="16dip"
android:layout_marginRight="16dip"
android:layout_weight="1" >
<LinearLayout
android:id="@+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:orientation="vertical" >
<ImageView
android:id="@+id/imageView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_weight="1"
android:src="@drawable/logo_inverted" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1" >
<EditText
android:id="@+id/host_URL"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:hint="@string/auth_host_url"
android:singleLine="true" >
<requestFocus />
</EditText>
<ImageView
android:id="@+id/refreshButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_action_refresh_black"
android:layout_gravity="right|center_vertical"
android:visibility="invisible" />
</FrameLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_weight="1" >
<ImageView
android:id="@+id/action_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:src="@android:drawable/stat_notify_sync"
android:visibility="invisible" />
<TextView
android:id="@+id/status_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
android:visibility="invisible" />
</LinearLayout>
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:text="@string/auth_login_details"
android:textAppearance="?android:attr/textAppearanceSmall" />
<EditText
android:id="@+id/account_username"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:ems="10"
android:singleLine="true"
android:hint="@string/auth_username" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1" >
<EditText
android:id="@+id/account_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:hint="@string/auth_password"
android:inputType="textPassword"
android:singleLine="true" />
<ImageView
android:id="@+id/viewPassword"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|center_vertical"
android:src="@android:drawable/ic_menu_view"
android:visibility="invisible" />
</FrameLayout>
</LinearLayout>
</FrameLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:weightSum="1" >
<Button
android:id="@+id/buttonCancel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight=".5"
android:text="@string/common_cancel" />
<Button
android:id="@+id/buttonOK"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight=".5"
android:enabled="false"
android:onClick="onOkClick"
android:text="@string/setup_btn_connect"
android:textColor="@android:color/black" />
</LinearLayout>
</RelativeLayout>
</LinearLayout> </LinearLayout>

View file

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
ownCloud Android client application
Copyright (C) 2012 Bartek Przybylski
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/>.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#F7F7F7"
android:focusable="true"
android:orientation="vertical" >
<TextView
android:id="@+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Large Text"/>
</LinearLayout>

View file

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/extensions_avail"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="7dp"
android:text="@string/extensions_avail_message" />
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:weightSum="1.0" >
<Button
android:id="@+id/buttonNo"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/common_no"
android:layout_weight="0.5"/>
<Button
android:id="@+id/buttonYes"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/common_yes"
android:layout_weight="0.5"/>
</LinearLayout>
</LinearLayout>

View file

@ -1,4 +1,21 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--
ownCloud Android client application
Copyright (C) 2012 Bartek Przybylski
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/>.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:layout_height="fill_parent"

View file

@ -1,4 +1,21 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--
ownCloud Android client application
Copyright (C) 2012 Bartek Przybylski
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/>.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:layout_height="fill_parent"

View file

@ -1,4 +1,21 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--
ownCloud Android client application
Copyright (C) 2012 Bartek Przybylski
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/>.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:layout_height="fill_parent"

View file

@ -1,4 +1,21 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--
ownCloud Android client application
Copyright (C) 2012 Bartek Przybylski
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/>.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_gravity="center_horizontal" android:gravity="center_horizontal"> android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_gravity="center_horizontal" android:gravity="center_horizontal">
<ImageView android:layout_width="wrap_content" <ImageView android:layout_width="wrap_content"

View file

@ -1,14 +1,33 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--
ownCloud Android client application
Copyright (C) 2012 Bartek Przybylski
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/>.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:layout_height="fill_parent"
android:background="#F7F7F7" android:orientation="vertical" >
android:orientation="vertical" >
<fragment <fragment
android:id="@+id/fileList" android:id="@+id/fileList"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:layout_height="fill_parent"
class="eu.alefzero.owncloud.ui.fragment.FileListFragment" > class="eu.alefzero.owncloud.ui.fragment.FileListFragment" >
<!-- Preview: layout=@layout/list_layout -->
</fragment> <!-- Preview: layout=@layout/list_layout -->
</fragment>
</LinearLayout> </LinearLayout>

View file

@ -1,4 +1,21 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--
ownCloud Android client application
Copyright (C) 2012 Bartek Przybylski
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/>.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/linearLayout1" android:id="@+id/linearLayout1"
android:layout_width="fill_parent" android:layout_width="fill_parent"

View file

@ -1,4 +1,21 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--
ownCloud Android client application
Copyright (C) 2012 Bartek Przybylski
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/>.
-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="fill_parent" > android:layout_height="fill_parent" >

View file

@ -1,17 +1,72 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!--
ownCloud Android client application
Copyright (C) 2012 Bartek Przybylski
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/>.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:id="@+id/ListItemLayout"
android:id="@+id/ListItemLayout" android:layout_width="fill_parent" android:layout_width="fill_parent"
android:background="#F7F7F7" android:layout_height="wrap_content"> android:background="@drawable/list_selector"
<ImageView android:layout_width="wrap_content" android:src="@drawable/ic_menu_archive" android:orientation="horizontal"
android:id="@+id/imageView1" android:layout_height="wrap_content" android:layout_height="56dp">
android:layout_marginLeft="15dip" android:focusable="false"
android:focusableInTouchMode="false"></ImageView> <FrameLayout
<TextView android:layout_height="wrap_content" android:layout_width="56dp"
android:textColor="#303030" android:layout_width="wrap_content" android:layout_height="56dp"
android:text="TextView" android:layout_marginLeft="5dip" android:focusable="false"
android:layout_marginBottom="5dip" android:layout_marginRight="30dip" android:focusableInTouchMode="false">
android:id="@+id/Filename" android:focusable="false"
android:focusableInTouchMode="false" android:textSize="20dip"> <ImageView
</TextView> android:id="@+id/imageView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/local_file_indicator"/>
<ImageView
android:id="@+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="48dp"
android:layout_gravity="center_vertical"
android:layout_margin="4dp"
android:src="@drawable/ic_menu_archive" />
</FrameLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent" >
<TextView
android:id="@+id/Filename"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="4dp"
android:text="TextView"
android:textColor="#303030"
android:textSize="20dip" />
<TextView
android:id="@+id/Extension"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="TextView"
android:textColor="#D0D0D0"
android:textSize="20dip" />
</LinearLayout>
</LinearLayout> </LinearLayout>

View file

@ -1,4 +1,21 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--
ownCloud Android client application
Copyright (C) 2012 Bartek Przybylski
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/>.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:layout_height="fill_parent"

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
</LinearLayout>

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
</LinearLayout>

View file

@ -1,4 +1,21 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--
ownCloud Android client application
Copyright (C) 2012 Bartek Przybylski
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/>.
-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content" android:orientation="vertical" android:layout_height="wrap_content" android:orientation="vertical"
android:layout_width="wrap_content" android:background="#fefefe" android:layout_width="wrap_content" android:background="#fefefe"

View file

@ -1,4 +1,21 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--
ownCloud Android client application
Copyright (C) 2012 Bartek Przybylski
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/>.
-->
<LinearLayout <LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_width="fill_parent"

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="@+id/createAccount" android:title="Create Account" android:showAsAction="ifRoom|withText"></item>
</menu>

View file

@ -1,7 +1,9 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<menu <menu
xmlns:android="http://schemas.android.com/apk/res/android"> xmlns:android="http://schemas.android.com/apk/res/android">
<item android:title="Settings" android:icon="@android:drawable/ic_menu_preferences" android:id="@+id/settingsItem"></item> <item android:id="@+id/startSync" android:title="Sync account" android:showAsAction="ifRoom" android:icon="@drawable/ic_action_refresh"></item><item android:title="Settings" android:icon="@android:drawable/ic_menu_preferences" android:id="@+id/settingsItem" android:showAsAction="never"></item>
<item android:id="@+id/createDirectoryItem" android:title="Create Directory" android:icon="@android:drawable/ic_menu_add"></item> <item android:id="@+id/createDirectoryItem" android:title="Create Directory" android:icon="@android:drawable/ic_menu_add" android:showAsAction="ifRoom"></item>
<item android:id="@+id/startSync" android:title="Sync account"></item>
<item android:id="@+id/search" android:icon="@drawable/ic_action_search" android:showAsAction="ifRoom"></item>
<item android:id="@+id/action_upload" android:icon="@drawable/ic_action_upload" android:showAsAction="ifRoom"></item>
</menu> </menu>

6
res/values/colors.xml Normal file
View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="filelist_icon_backgorund">#DDDDDD</color>
<color name="filelist_backgorund">#F7F7F7</color>
</resources>

View file

@ -17,7 +17,6 @@
<string name="prefs_category_general">General</string> <string name="prefs_category_general">General</string>
<string name="prefs_category_trackmydevice">Device tracking</string> <string name="prefs_category_trackmydevice">Device tracking</string>
<string name="prefs_sessions">Stored sessions</string>
<string name="prefs_add_session">Add new session</string> <string name="prefs_add_session">Add new session</string>
<string name="prefs_create_img_thumbnails">Create image thumbnails</string> <string name="prefs_create_img_thumbnails">Create image thumbnails</string>
<string name="prefs_select_oc_account">Select an account</string> <string name="prefs_select_oc_account">Select an account</string>
@ -27,13 +26,11 @@
<string name="prefs_trackmydevice_summary_on">Your ownCloud keeps track of this device</string> <string name="prefs_trackmydevice_summary_on">Your ownCloud keeps track of this device</string>
<string name="prefs_trackmydevice_interval">Update intervall</string> <string name="prefs_trackmydevice_interval">Update intervall</string>
<string name="prefs_trackmydevice_interval_summary">Update every %1$s minutes</string> <string name="prefs_trackmydevice_interval_summary">Update every %1$s minutes</string>
<string name="prefs_accounts">Accounts</string>
<string name="new_session_id">Session Name</string> <string name="auth_host_url">ownCloud location</string>
<string name="new_session_url">URL</string> <string name="auth_username">Username</string>
<string name="new_session_username">Username</string> <string name="auth_password">Password</string>
<string name="new_session_password">Password</string>
<string name="new_session_save">OK</string>
<string name="new_session_cancel">Cancel</string>
<string name="new_session_uri_error">Wrong URL given</string> <string name="new_session_uri_error">Wrong URL given</string>
<string name="new_session_session_name_error">Wrong session name</string> <string name="new_session_session_name_error">Wrong session name</string>
<string name="sync_string_files">Files</string> <string name="sync_string_files">Files</string>
@ -52,6 +49,8 @@
<string name="uploader_info_uploading">Uploading</string> <string name="uploader_info_uploading">Uploading</string>
<string name="uploader_btn_create_dir_text">Create dir for upload</string> <string name="uploader_btn_create_dir_text">Create dir for upload</string>
<string name="filedetails_select_file">Tap on a file to display additional information.</string> <string name="filedetails_select_file">Tap on a file to display additional information.</string>
<string name="common_yes">Yes</string>
<string name="common_no">No</string>
<string name="common_ok">OK</string> <string name="common_ok">OK</string>
<string name="common_cancel">Cancel</string> <string name="common_cancel">Cancel</string>
<string name="uploader_info_dirname">Directory name</string> <string name="uploader_info_dirname">Directory name</string>
@ -73,6 +72,26 @@
<item>30</item> <item>30</item>
<item>60</item> <item>60</item>
</string-array> </string-array>
<string name="auth_trying_to_login">Trying to login</string> <string name="auth_trying_to_login">Trying to login…</string>
<string name="auth_no_ssl">No SSL</string> <string name="auth_no_net_conn_title">No network connection</string>
<string name="auth_no_net_conn_message">No network connection have been detected, check your Internet connection and try again.</string>
<string name="auth_connect_anyway">Connect anyway</string>
<string name="auth_nossl_plain_ok_title">Secure connection unavailable.</string>
<string name="auth_nossl_plain_ok_message">Application couldn\'t etablish secure connection to server. Although non secure connection is available. You may continue or cancel.</string>
<string name="auth_connection_established">Connection established</string>
<string name="auth_testing_connection">Testing connection…</string>
<string name="auth_not_configured_title">Malformed ownCloud configuration</string>
<string name="auth_not_configured_message">It seems that your ownCloud intance is not correctly configured. Contact your administrator for more details.</string>
<string name="auth_unknown_error_title">Unknown error occurred</string>
<string name="auth_unknown_error_message">Unknown error occurred. Please contact authors and include logs from your device.</string>
<string name="auth_unknow_host_title">Can\'t establish connection</string>
<string name="auth_unknow_host_message">Coundn\'t establish connection to host. Please check hostname and server availability and try again.</string>
<string name="auth_incorrect_path_title">ownCloud intance not found</string>
<string name="auth_incorrect_path_message">Application couldn\'t find ownClound instance at given path. Please check your path and try again.</string>
<string name="auth_secure_connection">Secure connection established</string>
<string name="auth_unknow_error">Unknown error occured!</string>
<string name="auth_login_details">Login details</string>
<string name="extensions_avail_title">Extensions available!</string>
<string name="extensions_avail_message">Looks like your ownCloud instance is supporting advanced extensions. Would you like to see extensions available for android ?</string>
</resources> </resources>

View file

@ -7,6 +7,12 @@
<item name="android:actionBarStyle">@style/Theme.ownCloud.Widget.ActionBar</item> <item name="android:actionBarStyle">@style/Theme.ownCloud.Widget.ActionBar</item>
<item name="actionBarStyle">@style/Theme.ownCloud.Widget.ActionBar</item> <item name="actionBarStyle">@style/Theme.ownCloud.Widget.ActionBar</item>
</style> </style>
<style name="Theme.ownCloud.noActionBar" parent="style/Theme.Sherlock.Light.NoActionBar">
<item name="android:actionBarStyle">@style/Theme.ownCloud.Widget.ActionBar</item>
<item name="actionBarStyle">@style/Theme.ownCloud.Widget.ActionBar</item>
</style>
<style name="Theme.ownCloud.Widget.ActionBar" parent="style/Widget.Sherlock.Light.ActionBar.Solid.Inverse"> <style name="Theme.ownCloud.Widget.ActionBar" parent="style/Widget.Sherlock.Light.ActionBar.Solid.Inverse">
<item name="android:background">@drawable/main_header_bg</item> <item name="android:background">@drawable/main_header_bg</item>

View file

@ -1,5 +1,5 @@
/* ownCloud Android client application /* ownCloud Android client application
* Copyright (C) 2011 Bartek Przybylski * Copyright (C) 2012 Bartek Przybylski
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -19,6 +19,7 @@
package eu.alefzero.owncloud; package eu.alefzero.owncloud;
import eu.alefzero.owncloud.authenticator.AccountAuthenticator; import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
import eu.alefzero.owncloud.utils.OwnCloudVersion;
import android.accounts.Account; import android.accounts.Account;
import android.accounts.AccountManager; import android.accounts.AccountManager;
@ -29,15 +30,18 @@ import android.preference.PreferenceManager;
public class AccountUtils { public class AccountUtils {
public static final String WEBDAV_PATH_1_2 = "/webdav/owncloud.php"; public static final String WEBDAV_PATH_1_2 = "/webdav/owncloud.php";
public static final String WEBDAV_PATH_2_0 = "/files/webdav.php"; public static final String WEBDAV_PATH_2_0 = "/files/webdav.php";
public static final String WEBDAV_PATH_4_0 = "/remote/webdav.php";
public static final String CARDDAV_PATH_2_0 = "/apps/contacts/carddav.php"; public static final String CARDDAV_PATH_2_0 = "/apps/contacts/carddav.php";
public static final String CARDDAV_PATH_4_0 = "/remote/carddav.php";
public static final String STATUS_PATH = "/status.php";
/** /**
* Can be used to get the currently selected ownCloud account in the preferences * Can be used to get the currently selected ownCloud account in the preferences
* *
* @param context The current appContext * @param context The current appContext
* @return The current account or null, if there is none yet. * @return The current account or first available, if none is available, then null.
*/ */
public static Account getCurrentOwnCloudAccount(Context context){ public static Account getCurrentOwnCloudAccount(Context context) {
Account[] ocAccounts = AccountManager.get(context).getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE); Account[] ocAccounts = AccountManager.get(context).getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE);
Account defaultAccount = null; Account defaultAccount = null;
@ -58,4 +62,27 @@ public class AccountUtils {
return defaultAccount; return defaultAccount;
} }
public static void setCurrentOwnCloudAccount(Context context, String name) {
SharedPreferences.Editor appPrefs = PreferenceManager.getDefaultSharedPreferences(context).edit();
appPrefs.putString("select_oc_account", name);
appPrefs.commit();
}
/**
*
* @param version version of owncloud
* @return webdav path for given OC version, null if OC version unknown
*/
public static String getWebdavPath(OwnCloudVersion version) {
if (version.compareTo(OwnCloudVersion.owncloud_v4) >= 0)
return WEBDAV_PATH_4_0;
if (version.compareTo(OwnCloudVersion.owncloud_v3) >= 0 ||
version.compareTo(OwnCloudVersion.owncloud_v2) >= 0)
return WEBDAV_PATH_2_0;
if (version.compareTo(OwnCloudVersion.owncloud_v1) >= 0)
return WEBDAV_PATH_1_2;
return null;
}
} }

View file

@ -8,7 +8,6 @@ import android.app.Notification;
import android.app.NotificationManager; import android.app.NotificationManager;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.app.Service; import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.ContentValues; import android.content.ContentValues;
import android.content.Intent; import android.content.Intent;
import android.net.Uri; import android.net.Uri;
@ -105,6 +104,7 @@ public class FileDownloader extends Service {
dir.mkdirs(); dir.mkdirs();
File file = new File(dir, mFilePath.replace('/', '.')); File file = new File(dir, mFilePath.replace('/', '.'));
Log.e(TAG, file.getAbsolutePath() + " " + oc_url.toString());
wdc.downloadFile(mFilePath, file); wdc.downloadFile(mFilePath, file);
ContentValues cv = new ContentValues(); ContentValues cv = new ContentValues();
cv.put(ProviderTableMeta.FILE_STORAGE_PATH, file.getAbsolutePath()); cv.put(ProviderTableMeta.FILE_STORAGE_PATH, file.getAbsolutePath());

View file

@ -436,7 +436,6 @@ public class Uploader extends ListActivity implements OnItemClickListener, andro
Uri uri = (Uri) mUploadStreams.get(i); Uri uri = (Uri) mUploadStreams.get(i);
if (uri.getScheme().equals("content")) { if (uri.getScheme().equals("content")) {
final Cursor c = getContentResolver().query((Uri) mUploadStreams.get(i), null, null, null, null); final Cursor c = getContentResolver().query((Uri) mUploadStreams.get(i), null, null, null, null);
c.moveToFirst();
if (!wdc.putFile(c.getString(c.getColumnIndex(Media.DATA)), if (!wdc.putFile(c.getString(c.getColumnIndex(Media.DATA)),
mUploadPath+"/"+c.getString(c.getColumnIndex(Media.DISPLAY_NAME)), mUploadPath+"/"+c.getString(c.getColumnIndex(Media.DISPLAY_NAME)),

View file

@ -1,3 +1,21 @@
/* ownCloud Android client application
* Copyright (C) 2012 Bartek Przybylski
*
* 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 eu.alefzero.owncloud.authenticator; package eu.alefzero.owncloud.authenticator;
import eu.alefzero.owncloud.ui.activity.AuthenticatorActivity; import eu.alefzero.owncloud.ui.activity.AuthenticatorActivity;
@ -8,225 +26,252 @@ import android.os.Bundle;
import android.util.Log; import android.util.Log;
public class AccountAuthenticator extends AbstractAccountAuthenticator { public class AccountAuthenticator extends AbstractAccountAuthenticator {
public static final String OPTIONS_USERNAME = "username"; /**
public static final String OPTIONS_PASSWORD = "password"; * Is used by android system to assign accounts to authenticators. Should be
* used by application and all extensions.
*/
public static final String ACCOUNT_TYPE = "owncloud";
public static final String AUTH_TOKEN_TYPE = "org.owncloud";
public static final String ACCOUNT_TYPE = "owncloud"; public static final String KEY_AUTH_TOKEN_TYPE = "authTokenType";
public static final String AUTH_TOKEN_TYPE = "org.owncloud"; public static final String KEY_REQUIRED_FEATURES = "requiredFeatures";
public static final String KEY_LOGIN_OPTIONS = "loginOptions";
public static final String KEY_ACCOUNT = "account";
/**
* Value under this key should handle path to webdav php script. Will be
* removed and usage should be replaced by combining
* {@link eu.alefzero.owncloud.authenticator.KEY_OC_BASE_URL} and
* {@link eu.alefzero.owncloud.utils.OwnCloudVersion}
*
* @deprecated
*/
public static final String KEY_OC_URL = "oc_url";
/**
* Version should be 3 numbers separated by dot so it can be parsed by
* {@link eu.alefzero.owncloud.utils.OwnCloudVersion}
*/
public static final String KEY_OC_VERSION = "oc_version";
/**
* Base url should point to owncloud installation without trailing / ie:
* http://server/path or https://owncloud.server
*/
public static final String KEY_OC_BASE_URL = "oc_base_url";
public static final String KEY_AUTH_TOKEN_TYPE = "authTokenType"; private static final String TAG = "AccountAuthenticator";
public static final String KEY_REQUIRED_FEATURES = "requiredFeatures"; private Context mContext;
public static final String KEY_LOGIN_OPTIONS = "loginOptions";
public static final String KEY_ACCOUNT = "account";
public static final String KEY_OC_URL = "oc_url";
public static final String KEY_CONTACT_URL = "oc_contact_url";
private Context mContext; public AccountAuthenticator(Context context) {
super(context);
mContext = context;
}
public AccountAuthenticator(Context context) { /**
super(context); * {@inheritDoc}
mContext = context; */
@Override
public Bundle addAccount(AccountAuthenticatorResponse response,
String accountType,
String authTokenType,
String[] requiredFeatures,
Bundle options) throws NetworkErrorException {
Log.i(TAG, "Adding account with type " + accountType + " and auth token " + authTokenType);
try {
validateAccountType(accountType);
} catch (AuthenticatorException e) {
Log.e(TAG, "Failed to validate account type "+ accountType +": " + e.getMessage());
e.printStackTrace();
return e.getFailureBundle();
} }
final Intent intent = new Intent(mContext, AuthenticatorActivity.class);
intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);
intent.putExtra(KEY_AUTH_TOKEN_TYPE, authTokenType);
intent.putExtra(KEY_REQUIRED_FEATURES, requiredFeatures);
intent.putExtra(KEY_LOGIN_OPTIONS, options);
/** setIntentFlags(intent);
* {@inheritDoc} final Bundle bundle = new Bundle();
*/ bundle.putParcelable(AccountManager.KEY_INTENT, intent);
@Override return bundle;
public Bundle addAccount(AccountAuthenticatorResponse response, }
String accountType, String authTokenType, String[] requiredFeatures,
/**
* {@inheritDoc}
*/
@Override
public Bundle confirmCredentials(AccountAuthenticatorResponse response,
Account account, Bundle options) throws NetworkErrorException {
try {
validateAccountType(account.type);
} catch (AuthenticatorException e) {
Log.e(TAG, "Failed to validate account type "+ account.type +": " + e.getMessage());
e.printStackTrace();
return e.getFailureBundle();
}
Intent intent = new Intent(mContext, AuthenticatorActivity.class);
intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);
intent.putExtra(KEY_ACCOUNT, account);
intent.putExtra(KEY_LOGIN_OPTIONS, options);
setIntentFlags(intent);
Bundle resultBundle = new Bundle();
resultBundle.putParcelable(AccountManager.KEY_INTENT, intent);
return resultBundle;
}
@Override
public Bundle editProperties(AccountAuthenticatorResponse response,
String accountType) {
return null;
}
@Override
public Bundle getAuthToken(AccountAuthenticatorResponse response,
Account account,
String authTokenType,
Bundle options) throws NetworkErrorException { Bundle options) throws NetworkErrorException {
Log.i(getClass().getName(), "Adding account with type " + accountType + try {
" and auth token " + authTokenType); validateAccountType(account.type);
try { validateAuthTokenType(authTokenType);
validateAccountType(accountType); } catch (AuthenticatorException e) {
//validateAuthTokenType(authTokenType); Log.e(TAG, "Failed to validate account type "+ account.type +": " + e.getMessage());
validateRequiredFeatures(requiredFeatures); e.printStackTrace();
} catch (AuthenticatorException e) { return e.getFailureBundle();
e.printStackTrace(); }
return e.getFailureBundle(); final AccountManager am = AccountManager.get(mContext);
} final String password = am.getPassword(account);
final Intent intent = new Intent(mContext, AuthenticatorActivity.class); if (password != null) {
intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response); final Bundle result = new Bundle();
intent.putExtra(KEY_AUTH_TOKEN_TYPE, authTokenType); result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
intent.putExtra(KEY_REQUIRED_FEATURES, requiredFeatures); result.putString(AccountManager.KEY_ACCOUNT_TYPE, ACCOUNT_TYPE);
intent.putExtra(KEY_LOGIN_OPTIONS, options); result.putString(AccountManager.KEY_AUTHTOKEN, password);
return result;
setIntentFlags(intent);
Log.i(getClass().getName(), intent.toString());
final Bundle bundle = new Bundle();
bundle.putParcelable(AccountManager.KEY_INTENT, intent);
return bundle;
} }
/** final Intent intent = new Intent(mContext, AuthenticatorActivity.class);
* {@inheritDoc} intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);
*/ intent.putExtra(KEY_AUTH_TOKEN_TYPE, authTokenType);
@Override intent.putExtra(KEY_LOGIN_OPTIONS, options);
public Bundle confirmCredentials(AccountAuthenticatorResponse response, intent.putExtra(AuthenticatorActivity.PARAM_USERNAME, account.name);
Account account, Bundle options) throws NetworkErrorException {
try {
validateAccountType(account.type);
} catch (AuthenticatorException e) {
return e.getFailureBundle();
}
Intent intent = new Intent(mContext, AuthenticatorActivity.class);
intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);
intent.putExtra(KEY_ACCOUNT, account);
intent.putExtra(KEY_LOGIN_OPTIONS, options);
setIntentFlags(intent); final Bundle bundle = new Bundle();
bundle.putParcelable(AccountManager.KEY_INTENT, intent);
return bundle;
}
Bundle resultBundle = new Bundle(); @Override
resultBundle.putParcelable(AccountManager.KEY_INTENT, intent); public String getAuthTokenLabel(String authTokenType) {
return resultBundle; return null;
}
@Override
public Bundle hasFeatures(AccountAuthenticatorResponse response,
Account account,
String[] features) throws NetworkErrorException {
final Bundle result = new Bundle();
result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, false);
return result;
}
@Override
public Bundle updateCredentials(AccountAuthenticatorResponse response,
Account account,
String authTokenType,
Bundle options) throws NetworkErrorException {
final Intent intent = new Intent(mContext, AuthenticatorActivity.class);
intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);
intent.putExtra(KEY_ACCOUNT, account);
intent.putExtra(KEY_AUTH_TOKEN_TYPE, authTokenType);
intent.putExtra(KEY_LOGIN_OPTIONS, options);
setIntentFlags(intent);
final Bundle bundle = new Bundle();
bundle.putParcelable(AccountManager.KEY_INTENT, intent);
return bundle;
}
@Override
public Bundle getAccountRemovalAllowed(AccountAuthenticatorResponse response,
Account account) throws NetworkErrorException {
return super.getAccountRemovalAllowed(response, account);
}
private void setIntentFlags(Intent intent) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
intent.addFlags(Intent.FLAG_FROM_BACKGROUND);
}
private void validateAccountType(String type)
throws UnsupportedAccountTypeException {
if (!type.equals(ACCOUNT_TYPE)) {
throw new UnsupportedAccountTypeException();
}
}
private void validateAuthTokenType(String authTokenType)
throws UnsupportedAuthTokenTypeException {
if (!authTokenType.equals(AUTH_TOKEN_TYPE)) {
throw new UnsupportedAuthTokenTypeException();
}
}
public static class AuthenticatorException extends Exception {
private static final long serialVersionUID = 1L;
private Bundle mFailureBundle;
public AuthenticatorException(int code, String errorMsg) {
mFailureBundle = new Bundle();
mFailureBundle.putInt(AccountManager.KEY_ERROR_CODE, code);
mFailureBundle.putString(AccountManager.KEY_ERROR_MESSAGE, errorMsg);
} }
@Override public Bundle getFailureBundle() {
public Bundle editProperties(AccountAuthenticatorResponse response, return mFailureBundle;
String accountType) { }
throw new UnsupportedOperationException(); }
public static class UnsupportedAccountTypeException
extends
AuthenticatorException {
private static final long serialVersionUID = 1L;
public UnsupportedAccountTypeException() {
super(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,
"Unsupported account type");
}
}
public static class UnsupportedAuthTokenTypeException
extends
AuthenticatorException {
private static final long serialVersionUID = 1L;
public UnsupportedAuthTokenTypeException() {
super(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,
"Unsupported auth token type");
}
}
public static class UnsupportedFeaturesException
extends
AuthenticatorException {
public static final long serialVersionUID = 1L;
public UnsupportedFeaturesException() {
super(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,
"Unsupported features");
}
}
public static class AccessDeniedException extends AuthenticatorException {
public AccessDeniedException(int code, String errorMsg) {
super(AccountManager.ERROR_CODE_INVALID_RESPONSE, "Access Denied");
} }
@Override private static final long serialVersionUID = 1L;
public Bundle getAuthToken(AccountAuthenticatorResponse response,
Account account, String authTokenType, Bundle options)
throws NetworkErrorException {
Log.i(getClass().getName(), "Getting authToken");
try {
validateAccountType(account.type);
validateAuthTokenType(authTokenType);
} catch (AuthenticatorException e) {
Log.w(getClass().getName(), "Validating failded in getAuthToken");
return e.getFailureBundle();
}
final AccountManager am = AccountManager.get(mContext);
final String password = am.getPassword(account);
if (password != null) {
final Bundle result = new Bundle();
result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
result.putString(AccountManager.KEY_ACCOUNT_TYPE, ACCOUNT_TYPE);
result.putString(AccountManager.KEY_AUTHTOKEN, password);
return result;
}
final Intent intent = new Intent(mContext, AuthenticatorActivity.class); }
intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);
intent.putExtra(KEY_AUTH_TOKEN_TYPE, authTokenType);
intent.putExtra(KEY_LOGIN_OPTIONS, options);
intent.putExtra(AuthenticatorActivity.PARAM_USERNAME, account.name);
final Bundle bundle = new Bundle();
bundle.putParcelable(AccountManager.KEY_INTENT, intent);
return bundle;
}
@Override
public String getAuthTokenLabel(String authTokenType) {
return null;
}
@Override
public Bundle hasFeatures(AccountAuthenticatorResponse response,
Account account, String[] features) throws NetworkErrorException {
final Bundle result = new Bundle();
result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, false);
return result;
}
@Override
public Bundle updateCredentials(AccountAuthenticatorResponse response,
Account account, String authTokenType, Bundle options)
throws NetworkErrorException {
final Intent intent = new Intent(mContext, AuthenticatorActivity.class);
intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);
intent.putExtra(KEY_ACCOUNT, account);
intent.putExtra(KEY_AUTH_TOKEN_TYPE, authTokenType);
intent.putExtra(KEY_LOGIN_OPTIONS, options);
setIntentFlags(intent);
final Bundle bundle = new Bundle();
bundle.putParcelable(AccountManager.KEY_INTENT, intent);
return bundle;
}
@Override
public Bundle getAccountRemovalAllowed(AccountAuthenticatorResponse response,
Account account) throws NetworkErrorException {
return super.getAccountRemovalAllowed(response, account);
}
private void setIntentFlags(Intent intent) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
intent.addFlags(Intent.FLAG_FROM_BACKGROUND);
}
private void validateAccountType(String type) throws UnsupportedAccountTypeException {
if (!type.equals(ACCOUNT_TYPE)) {
throw new UnsupportedAccountTypeException();
}
}
private void validateAuthTokenType(String authTokenType) throws UnsupportedAuthTokenTypeException {
if (!authTokenType.equals(AUTH_TOKEN_TYPE)) {
throw new UnsupportedAuthTokenTypeException();
}
}
private void validateRequiredFeatures(String[] requiredFeatures) throws UnsupportedFeaturesException {
}
private void validateCreaditials(String username, String password, String path) throws AccessDeniedException {
}
public static class AuthenticatorException extends Exception {
private static final long serialVersionUID = 1L;
private Bundle mFailureBundle;
public AuthenticatorException(int code, String errorMsg) {
mFailureBundle = new Bundle();
mFailureBundle.putInt(AccountManager.KEY_ERROR_CODE, code);
mFailureBundle.putString(AccountManager.KEY_ERROR_MESSAGE, errorMsg);
}
public Bundle getFailureBundle() {
return mFailureBundle;
}
}
public static class UnsupportedAccountTypeException extends AuthenticatorException {
private static final long serialVersionUID = 1L;
public UnsupportedAccountTypeException() {
super(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION, "Unsupported account type");
}
}
public static class UnsupportedAuthTokenTypeException extends AuthenticatorException {
private static final long serialVersionUID = 1L;
public UnsupportedAuthTokenTypeException() {
super(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION, "Unsupported auth token type");
}
}
public static class UnsupportedFeaturesException extends AuthenticatorException {
public static final long serialVersionUID = 1L;
public UnsupportedFeaturesException() {
super(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION, "Unsupported features");
}
}
public static class AccessDeniedException extends AuthenticatorException {
public AccessDeniedException(int code, String errorMsg) {
super(AccountManager.ERROR_CODE_INVALID_RESPONSE, "Access Denied");
}
private static final long serialVersionUID = 1L;
}
} }

View file

@ -34,9 +34,7 @@ public class AuthenticationRunnable implements Runnable {
private URL mUrl; private URL mUrl;
private String mUsername; private String mUsername;
private String mPassword; private String mPassword;
private static final String WEBDAV_2_0_PATH = "/files/webdav.php";
public AuthenticationRunnable(URL url, String username, String password) { public AuthenticationRunnable(URL url, String username, String password) {
mListener = null; mListener = null;
mUrl = url; mUrl = url;
@ -51,7 +49,8 @@ public class AuthenticationRunnable implements Runnable {
@Override @Override
public void run() { public void run() {
Uri uri = Uri.parse(mUrl.toString() + WEBDAV_2_0_PATH); Uri uri;
uri = Uri.parse(mUrl.toString());
WebdavClient client = new WebdavClient(uri); WebdavClient client = new WebdavClient(uri);
client.setCredentials(mUsername, mPassword); client.setCredentials(mUsername, mPassword);
int login_result = client.tryToLogin(); int login_result = client.tryToLogin();
@ -71,11 +70,11 @@ public class AuthenticationRunnable implements Runnable {
} }
private void postResult(final boolean success, final String message) { private void postResult(final boolean success, final String message) {
if (mHandler != null) { if (mHandler != null && mListener != null) {
mHandler.post(new Runnable() { mHandler.post(new Runnable() {
@Override @Override
public void run() { public void run() {
AuthenticationRunnable.this.mListener.onAuthenticationResult(success, message); mListener.onAuthenticationResult(success, message);
} }
}); });
} }

View file

@ -0,0 +1,162 @@
/* ownCloud Android client application
* Copyright (C) 2012 Bartek Przybylski
*
* 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 eu.alefzero.owncloud.authenticator;
import java.net.ConnectException;
import java.net.UnknownHostException;
import javax.net.ssl.SSLHandshakeException;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;
import org.json.JSONException;
import org.json.JSONObject;
import eu.alefzero.owncloud.AccountUtils;
import eu.alefzero.owncloud.authenticator.OnConnectCheckListener.ResultType;
import eu.alefzero.owncloud.utils.OwnCloudVersion;
import eu.alefzero.webdav.WebdavClient;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.Uri;
import android.os.Handler;
import android.util.Log;
public class ConnectionCheckerRunnable implements Runnable {
private static final String TAG = "ConnectionCheckerRunnable";
private OnConnectCheckListener mListener;
private String mUrl;
private Handler mHandler;
private ResultType mLatestResult;
private Context mContext;
private OwnCloudVersion mOCVersion;
public void setListener(OnConnectCheckListener listener, Handler handler) {
mListener = listener;
mHandler = handler;
}
public ConnectionCheckerRunnable(String url, Context context) {
mListener = null;
mHandler = null;
mUrl = url;
mContext = context;
mOCVersion = null;
}
@Override
public void run() {
if (!isOnline()) {
postResult(ResultType.NO_NETWORK_CONNECTION);
return;
}
if (mUrl.startsWith("http://") || mUrl.startsWith("https://")) {
mLatestResult = ResultType.OK;
tryConnection(Uri.parse(mUrl + AccountUtils.STATUS_PATH));
postResult(mLatestResult);
} else {
Uri uri = Uri.parse("https://" + mUrl + AccountUtils.STATUS_PATH);
if (tryConnection(uri)) {
postResult(ResultType.OK);
return;
}
Log.d(TAG, "establishing secure connection failed, trying non secure connection");
uri = Uri.parse("http://" + mUrl + AccountUtils.STATUS_PATH);
if (tryConnection(uri)) {
postResult(ResultType.OK_NO_SSL);
return;
}
postResult(mLatestResult);
}
}
public OwnCloudVersion getDiscoveredVersion() {
return mOCVersion;
}
private boolean tryConnection(Uri uri) {
WebdavClient wc = new WebdavClient(uri);
wc.allowUnsignedCertificates();
GetMethod get = new GetMethod(uri.toString());
boolean retval = false;
try {
int status = wc.executeMethod(get);
switch (status) {
case HttpStatus.SC_OK: {
String response = get.getResponseBodyAsString();
JSONObject json = new JSONObject(response);
if (!json.getBoolean("installed")) {
mLatestResult = ResultType.INSTANCE_NOT_CONFIGURED;
break;
}
mOCVersion = new OwnCloudVersion(json.getString("version"));
if (!mOCVersion.isVersionValid())
break;
retval = true;
break;
}
case HttpStatus.SC_NOT_FOUND:
mLatestResult = ResultType.FILE_NOT_FOUND;
break;
case HttpStatus.SC_INTERNAL_SERVER_ERROR:
mLatestResult = ResultType.INSTANCE_NOT_CONFIGURED;
break;
default:
mLatestResult = ResultType.UNKNOWN_ERROR;
Log.e(TAG,"Not handled status received from server: " + status);
}
} catch (Exception e) {
if (e instanceof UnknownHostException || e instanceof ConnectException) {
mLatestResult = ResultType.HOST_NOT_AVAILABLE;
} else if (e instanceof JSONException) {
mLatestResult = ResultType.INSTANCE_NOT_CONFIGURED;
} else if (e instanceof SSLHandshakeException) {
mLatestResult = ResultType.SSL_INIT_ERROR;
} else {
mLatestResult = ResultType.UNKNOWN_ERROR;
}
e.printStackTrace();
}
return retval;
}
private boolean isOnline() {
ConnectivityManager cm =
(ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
return cm != null
&& cm.getActiveNetworkInfo() != null
&& cm.getActiveNetworkInfo().isConnectedOrConnecting();
}
private void postResult(final ResultType result) {
if (mHandler != null && mListener != null) {
mHandler.post(new Runnable() {
@Override
public void run() {
mListener.onConnectionCheckResult(result);
}
});
}
}
}

View file

@ -1,138 +1,231 @@
package eu.alefzero.owncloud.authenticator;
/* /*
* Licensed to the Apache Software Foundation (ASF) under one * $HeadURL$
* or more contributor license agreements. See the NOTICE file * $Revision$
* distributed with this work for additional information * $Date$
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the * ====================================================================
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
* *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/ */
package eu.alefzero.owncloud.authenticator;
import java.io.IOException; import java.io.IOException;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.Socket; import java.net.Socket;
import java.net.SocketAddress;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import javax.net.SocketFactory;
import javax.net.ssl.SSLContext; import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManager;
import org.apache.http.conn.ConnectTimeoutException; import org.apache.commons.httpclient.ConnectTimeoutException;
import org.apache.http.conn.scheme.LayeredSocketFactory; import org.apache.commons.httpclient.HttpClientError;
import org.apache.http.conn.scheme.SocketFactory; import org.apache.commons.httpclient.params.HttpConnectionParams;
import org.apache.http.params.HttpConnectionParams; import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
import org.apache.http.params.HttpParams; import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;
import android.util.Log;
/** /**
* This socket factory will create ssl socket that accepts self signed * <p>
* certificate * EasySSLProtocolSocketFactory can be used to creats SSL {@link Socket}s
* that accept self-signed certificates.
* </p>
* <p>
* This socket factory SHOULD NOT be used for productive systems
* due to security reasons, unless it is a concious decision and
* you are perfectly aware of security implications of accepting
* self-signed certificates
* </p>
*
* <p>
* Example of using custom protocol socket factory for a specific host:
* <pre>
* Protocol easyhttps = new Protocol("https", new EasySSLProtocolSocketFactory(), 443);
*
* URI uri = new URI("https://localhost/", true);
* // use relative url only
* GetMethod httpget = new GetMethod(uri.getPathQuery());
* HostConfiguration hc = new HostConfiguration();
* hc.setHost(uri.getHost(), uri.getPort(), easyhttps);
* HttpClient client = new HttpClient();
* client.executeMethod(hc, httpget);
* </pre>
* </p>
* <p>
* Example of using custom protocol socket factory per default instead of the standard one:
* <pre>
* Protocol easyhttps = new Protocol("https", new EasySSLProtocolSocketFactory(), 443);
* Protocol.registerProtocol("https", easyhttps);
*
* HttpClient client = new HttpClient();
* GetMethod httpget = new GetMethod("https://localhost/");
* client.executeMethod(httpget);
* </pre>
* </p>
* *
* @author olamy * @author <a href="mailto:oleg -at- ural.ru">Oleg Kalnichevski</a>
* @version $Id: EasySSLSocketFactory.java 765355 2009-04-15 20:59:07Z evenisse *
* $ * <p>
* @since 1.2.3 * DISCLAIMER: HttpClient developers DO NOT actively support this component.
* The component is provided as a reference material, which may be inappropriate
* for use without additional customization.
* </p>
*/ */
public class EasySSLSocketFactory implements SocketFactory,
LayeredSocketFactory {
private SSLContext sslcontext = null; public class EasySSLSocketFactory implements ProtocolSocketFactory {
private static SSLContext createEasySSLContext() throws IOException { private static final String TAG = "EasySSLSocketFactory";
try { private SSLContext sslcontext = null;
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, new TrustManager[] { new EasyX509TrustManager(
null) }, null);
return context;
} catch (Exception e) {
throw new IOException(e.getMessage());
}
}
private SSLContext getSSLContext() throws IOException { /**
if (this.sslcontext == null) { * Constructor for EasySSLProtocolSocketFactory.
this.sslcontext = createEasySSLContext(); */
} public EasySSLSocketFactory() {
return this.sslcontext; super();
}
/**
* @see org.apache.http.conn.scheme.SocketFactory#connectSocket(java.net.Socket,
* java.lang.String, int, java.net.InetAddress, int,
* org.apache.http.params.HttpParams)
*/
public Socket connectSocket(Socket sock, String host, int port,
InetAddress localAddress, int localPort, HttpParams params)
throws IOException, UnknownHostException, ConnectTimeoutException {
int connTimeout = HttpConnectionParams.getConnectionTimeout(params);
int soTimeout = HttpConnectionParams.getSoTimeout(params);
InetSocketAddress remoteAddress = new InetSocketAddress(host, port);
SSLSocket sslsock = (SSLSocket) ((sock != null) ? sock : createSocket());
if ((localAddress != null) || (localPort > 0)) {
// we need to bind explicitly
if (localPort < 0) {
localPort = 0; // indicates "any"
}
InetSocketAddress isa = new InetSocketAddress(localAddress,
localPort);
sslsock.bind(isa);
} }
sslsock.connect(remoteAddress, connTimeout); private static SSLContext createEasySSLContext() {
sslsock.setSoTimeout(soTimeout); try {
return sslsock; SSLContext context = SSLContext.getInstance("TLS");
context.init(
null,
new TrustManager[] {new EasyX509TrustManager(null)},
null);
return context;
} catch (Exception er) {
Log.e(TAG, er.getMessage()+"");
throw new HttpClientError(er.toString());
}
}
} private SSLContext getSSLContext() {
if (this.sslcontext == null) {
this.sslcontext = createEasySSLContext();
}
return this.sslcontext;
}
/** /**
* @see org.apache.http.conn.scheme.SocketFactory#createSocket() * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int,java.net.InetAddress,int)
*/ */
public Socket createSocket() throws IOException { public Socket createSocket(
return getSSLContext().getSocketFactory().createSocket(); String host,
} int port,
InetAddress clientHost,
int clientPort)
throws IOException, UnknownHostException {
/** return getSSLContext().getSocketFactory().createSocket(
* @see org.apache.http.conn.scheme.SocketFactory#isSecure(java.net.Socket) host,
*/ port,
public boolean isSecure(Socket socket) throws IllegalArgumentException { clientHost,
return true; clientPort
} );
}
/** /**
* @see org.apache.http.conn.scheme.LayeredSocketFactory#createSocket(java.net.Socket, * Attempts to get a new socket connection to the given host within the given time limit.
* java.lang.String, int, boolean) * <p>
*/ * To circumvent the limitations of older JREs that do not support connect timeout a
public Socket createSocket(Socket socket, String host, int port, * controller thread is executed. The controller thread attempts to create a new socket
boolean autoClose) throws IOException, UnknownHostException { * within the given limit of time. If socket constructor does not return until the
return getSSLContext().getSocketFactory().createSocket(socket, host, port, autoClose); * timeout expires, the controller terminates and throws an {@link ConnectTimeoutException}
} * </p>
*
* @param host the host name/IP
* @param port the port on the host
* @param clientHost the local host name/IP to bind the socket to
* @param clientPort the port on the local machine
* @param params {@link HttpConnectionParams Http connection parameters}
*
* @return Socket a new socket
*
* @throws IOException if an I/O error occurs while creating the socket
* @throws UnknownHostException if the IP address of the host cannot be
* determined
*/
public Socket createSocket(
final String host,
final int port,
final InetAddress localAddress,
final int localPort,
final HttpConnectionParams params
) throws IOException, UnknownHostException, ConnectTimeoutException {
if (params == null) {
throw new IllegalArgumentException("Parameters may not be null");
}
int timeout = params.getConnectionTimeout();
SocketFactory socketfactory = getSSLContext().getSocketFactory();
if (timeout == 0) {
return socketfactory.createSocket(host, port, localAddress, localPort);
} else {
Socket socket = socketfactory.createSocket();
SocketAddress localaddr = new InetSocketAddress(localAddress, localPort);
SocketAddress remoteaddr = new InetSocketAddress(host, port);
socket.bind(localaddr);
socket.connect(remoteaddr, timeout);
return socket;
}
}
// ------------------------------------------------------------------- /**
// javadoc in org.apache.http.conn.scheme.SocketFactory says : * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int)
// Both Object.equals() and Object.hashCode() must be overridden */
// for the correct operation of some connection managers public Socket createSocket(String host, int port)
// ------------------------------------------------------------------- throws IOException, UnknownHostException {
return getSSLContext().getSocketFactory().createSocket(
host,
port
);
}
public boolean equals(Object obj) { /**
return ((obj != null) && obj.getClass().equals( * @see SecureProtocolSocketFactory#createSocket(java.net.Socket,java.lang.String,int,boolean)
EasySSLSocketFactory.class)); */
} public Socket createSocket(
Socket socket,
String host,
int port,
boolean autoClose)
throws IOException, UnknownHostException {
return getSSLContext().getSocketFactory().createSocket(
socket,
host,
port,
autoClose
);
}
public int hashCode() { public boolean equals(Object obj) {
return EasySSLSocketFactory.class.hashCode(); return ((obj != null) && obj.getClass().equals(EasySSLSocketFactory.class));
} }
public int hashCode() {
return EasySSLSocketFactory.class.hashCode();
}
} }

View file

@ -0,0 +1,20 @@
package eu.alefzero.owncloud.authenticator;
public interface OnConnectCheckListener {
enum ResultType {
OK,
OK_NO_SSL,
SSL_INIT_ERROR,
HOST_NOT_AVAILABLE,
TIMEOUT,
NO_NETWORK_CONNECTION,
INORRECT_ADDRESS,
INSTANCE_NOT_CONFIGURED,
FILE_NOT_FOUND,
UNKNOWN_ERROR
}
public void onConnectionCheckResult(ResultType type);
}

View file

@ -173,13 +173,21 @@ public class FileDataStorageManager implements DataStorageManager {
if (getContentProvider() != null) { if (getContentProvider() != null) {
try { try {
c = getContentProvider().query(req_uri, null, null, null, null); c = getContentProvider().query(req_uri,
null,
ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",
new String[]{mAccount.name},
null);
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(TAG, e.getMessage()); Log.e(TAG, e.getMessage());
return ret; return ret;
} }
} else { } else {
c = getContentResolver().query(req_uri, null, null, null, null); c = getContentResolver().query(req_uri,
null,
ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",
new String[]{mAccount.name},
null);
} }
if (c.moveToFirst()) { if (c.moveToFirst()) {
@ -201,22 +209,24 @@ public class FileDataStorageManager implements DataStorageManager {
if (getContentResolver() != null) { if (getContentResolver() != null) {
c = getContentResolver().query(ProviderTableMeta.CONTENT_URI, c = getContentResolver().query(ProviderTableMeta.CONTENT_URI,
null, null,
cmp_key + "=?", cmp_key + "=? AND " + ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",
new String[] {value}, new String[] {value, mAccount.name},
null); null);
} else { } else {
try { try {
c = getContentProvider().query(ProviderTableMeta.CONTENT_URI, c = getContentProvider().query(ProviderTableMeta.CONTENT_URI,
null, null,
cmp_key + "=?", cmp_key + "=? AND " + ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",
new String[] {value}, new String[] {value, mAccount.name},
null); null);
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(TAG, "Couldn't determine file existance, assuming non existance: " + e.getMessage()); Log.e(TAG, "Couldn't determine file existance, assuming non existance: " + e.getMessage());
return false; return false;
} }
} }
return c.moveToFirst(); boolean retval = c.moveToFirst();
c.close();
return retval;
} }
private Cursor getCursorForValue(String key, String value) { private Cursor getCursorForValue(String key, String value) {
@ -224,15 +234,15 @@ public class FileDataStorageManager implements DataStorageManager {
if (getContentResolver() != null) { if (getContentResolver() != null) {
c = getContentResolver().query(ProviderTableMeta.CONTENT_URI, c = getContentResolver().query(ProviderTableMeta.CONTENT_URI,
null, null,
key + "=?", key + "=? AND " + ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",
new String[] {value}, new String[] {value, mAccount.name},
null); null);
} else { } else {
try { try {
c = getContentProvider().query(ProviderTableMeta.CONTENT_URI, c = getContentProvider().query(ProviderTableMeta.CONTENT_URI,
null, null,
key + "=?", key + "=? AND " + ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",
new String[]{value}, new String[]{value, mAccount.name},
null); null);
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(TAG, "Could not get file details: " + e.getMessage()); Log.e(TAG, "Could not get file details: " + e.getMessage());

View file

@ -58,7 +58,7 @@ public class ProviderMeta {
public static final String FILE_PATH = "path"; public static final String FILE_PATH = "path";
public static final String FILE_ACCOUNT_OWNER = "file_owner"; public static final String FILE_ACCOUNT_OWNER = "file_owner";
public static final String DEFAULT_SORT_ORDER = FILE_NAME + " asc"; public static final String DEFAULT_SORT_ORDER = FILE_NAME + " collate nocase asc";
} }
} }

View file

@ -0,0 +1,17 @@
package eu.alefzero.owncloud.extensions;
import android.os.Bundle;
import android.support.v4.app.FragmentManager;
import com.actionbarsherlock.app.SherlockFragmentActivity;
public class ExtensionsAvailableActivity extends SherlockFragmentActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FragmentManager fm = getSupportFragmentManager();
ExtensionsAvailableDialog ead = new ExtensionsAvailableDialog();
ead.show(fm, "extensions_available_dialog");
}
}

View file

@ -0,0 +1,48 @@
package eu.alefzero.owncloud.extensions;
import eu.alefzero.owncloud.R;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.Button;
public class ExtensionsAvailableDialog extends DialogFragment implements OnClickListener {
public ExtensionsAvailableDialog() { }
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.extensions_available_dialog, container);
Button btnYes = (Button) view.findViewById(R.id.buttonYes);
Button btnNo = (Button) view.findViewById(R.id.buttonNo);
btnYes.setOnClickListener(this);
btnNo.setOnClickListener(this);
getDialog().setTitle(R.string.extensions_avail_title);
return view;
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.buttonYes:
{
Intent i = new Intent(getActivity(), ExtensionsListActivity.class);
startActivity(i);
getActivity().finish();
}
break;
case R.id.buttonNo:
getActivity().finish();
break;
default:
Log.e("EAD", "Button with unknown id clicked " + v.getId());
}
}
}

View file

@ -0,0 +1,116 @@
package eu.alefzero.owncloud.extensions;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Vector;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.GetMethod;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import eu.alefzero.owncloud.utils.OwnCloudVersion;
import android.R;
import android.app.Activity;
import android.app.ListActivity;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.widget.SimpleAdapter;
public class ExtensionsListActivity extends ListActivity {
private static final String packages_url = "http://alefzero.eu/a/packages.php";
private Thread mGetterThread;
private final Handler mHandler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mGetterThread = new Thread(new JsonGetter());
mGetterThread.start();
}
public void done(JSONArray a) {
LinkedList<HashMap<String, String>> ll = new LinkedList<HashMap<String,String>>();
for (int i = 0; i < a.length(); ++i) {
try {
ExtensionApplicationEntry ela = new ExtensionApplicationEntry(((JSONObject)a.get(i)));
HashMap<String, String> ss = new HashMap<String, String>();
ss.put("NAME", ela.getName());
ss.put("DESC", ela.getDescription());
ll.add(ss);
} catch (JSONException e) {
e.printStackTrace();
}
}
setListAdapter(new SimpleAdapter(this,
ll,
R.layout.simple_list_item_2,
new String[] {"NAME", "DESC"},
new int[] {android.R.id.text1, android.R.id.text2}));
}
private class JsonGetter implements Runnable {
@Override
public void run() {
HttpClient hc = new HttpClient();
GetMethod gm = new GetMethod(packages_url);
final JSONArray ar;
try {
hc.executeMethod(gm);
Log.e("ASD", gm.getResponseBodyAsString()+"");
ar = new JSONObject(gm.getResponseBodyAsString()).getJSONArray("apps");
} catch (Exception e) {
e.printStackTrace();
return;
}
mHandler.post(new Runnable() {
@Override
public void run() {
done(ar);
}
});
}
}
private class ExtensionApplicationEntry {
private static final String APP_NAME = "name";
private static final String APP_VERSION = "version";
private static final String APP_DESC = "description";
private static final String APP_ICON = "icon";
private static final String APP_URL = "download";
private static final String APP_PLAYID = "play_id";
private String mName, mDescription, mIcon, mDownload, mPlayId;
private OwnCloudVersion mVersion;
public ExtensionApplicationEntry(JSONObject appentry) {
try {
mName = appentry.getString(APP_NAME);
mDescription = appentry.getString(APP_DESC);
mIcon = appentry.getString(APP_ICON);
mDownload = appentry.getString(APP_URL);
mPlayId = appentry.getString(APP_PLAYID);
mVersion = new OwnCloudVersion(appentry.getString(APP_VERSION));
} catch (JSONException e) {
e.printStackTrace();
}
}
public String getName() { return mName; }
public String getDescription() { return mDescription; }
public String getIcon() { return mIcon; }
public String getDownload() { return mDownload; }
public String getPlayId() { return mPlayId; }
public OwnCloudVersion getVersion() { return mVersion; }
}
}

View file

@ -22,7 +22,6 @@ import java.io.IOException;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.util.Date; import java.util.Date;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest; import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse; import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException; import org.apache.http.client.ClientProtocolException;
@ -39,7 +38,6 @@ import android.content.Context;
import android.net.Uri; import android.net.Uri;
import eu.alefzero.owncloud.authenticator.AccountAuthenticator; import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
import eu.alefzero.owncloud.datamodel.DataStorageManager; import eu.alefzero.owncloud.datamodel.DataStorageManager;
import eu.alefzero.webdav.HttpPropFind;
import eu.alefzero.webdav.WebdavClient; import eu.alefzero.webdav.WebdavClient;
/** /**
@ -49,8 +47,7 @@ import eu.alefzero.webdav.WebdavClient;
* @author sassman * @author sassman
* *
*/ */
public abstract class AbstractOwnCloudSyncAdapter extends public abstract class AbstractOwnCloudSyncAdapter extends AbstractThreadedSyncAdapter {
AbstractThreadedSyncAdapter {
private AccountManager accountManager; private AccountManager accountManager;
private Account account; private Account account;
@ -58,9 +55,7 @@ public abstract class AbstractOwnCloudSyncAdapter extends
private Date lastUpdated; private Date lastUpdated;
private DataStorageManager mStoreManager; private DataStorageManager mStoreManager;
private HttpHost mHost;
private WebdavClient mClient = null; private WebdavClient mClient = null;
private static String TAG = "AbstractOwnCloudSyncAdapter";
public AbstractOwnCloudSyncAdapter(Context context, boolean autoInitialize) { public AbstractOwnCloudSyncAdapter(Context context, boolean autoInitialize) {
super(context, autoInitialize); super(context, autoInitialize);
@ -131,15 +126,6 @@ public abstract class AbstractOwnCloudSyncAdapter extends
}; };
} }
protected HttpPropFind getPropFindQuery()
throws OperationCanceledException, AuthenticatorException,
IOException {
HttpPropFind query = new HttpPropFind(getUri().toString());
query.setHeader("Content-type", "text/xml");
query.setHeader("User-Agent", "Android-ownCloud");
return query;
}
protected HttpResponse fireRawRequest(HttpRequest query) protected HttpResponse fireRawRequest(HttpRequest query)
throws ClientProtocolException, OperationCanceledException, throws ClientProtocolException, OperationCanceledException,
AuthenticatorException, IOException { AuthenticatorException, IOException {
@ -171,7 +157,7 @@ public abstract class AbstractOwnCloudSyncAdapter extends
mClient = new WebdavClient(uri); mClient = new WebdavClient(uri);
mClient.setCredentials(username, password); mClient.setCredentials(username, password);
mClient.allowUnsignedCertificates(); mClient.allowUnsignedCertificates();
mHost = mClient.getTargetHost(); //mHost = mClient.getTargetHost();
} }
return mClient; return mClient;

View file

@ -31,7 +31,6 @@ import android.content.ContentProviderClient;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.SyncResult; import android.content.SyncResult;
import android.content.IntentSender.SendIntentException;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import eu.alefzero.owncloud.datamodel.FileDataStorageManager; import eu.alefzero.owncloud.datamodel.FileDataStorageManager;
@ -62,6 +61,8 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
this.setContentProvider(provider); this.setContentProvider(provider);
this.setStorageManager(new FileDataStorageManager(account, getContentProvider())); this.setStorageManager(new FileDataStorageManager(account, getContentProvider()));
Log.d("ASD", "syncing owncloud account " + account.name);
Intent i = new Intent(FileSyncService.SYNC_MESSAGE); Intent i = new Intent(FileSyncService.SYNC_MESSAGE);
i.putExtra(FileSyncService.IN_PROGRESS, true); i.putExtra(FileSyncService.IN_PROGRESS, true);
i.putExtra(FileSyncService.ACCOUNT_NAME, account.name); i.putExtra(FileSyncService.ACCOUNT_NAME, account.name);

View file

@ -7,17 +7,21 @@ import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ListAdapter; import android.widget.ListAdapter;
import android.widget.ListView; import android.widget.ListView;
import android.widget.AdapterView.OnItemClickListener; import android.widget.AdapterView.OnItemClickListener;
public class FragmentListView extends SherlockFragment implements OnItemClickListener { public class FragmentListView extends SherlockFragment
implements OnItemClickListener,
OnItemLongClickListener {
ListView mList; ListView mList;
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
mList = new ListView(getActivity()); mList = new ListView(getActivity());
mList.setOnItemClickListener(this); mList.setOnItemClickListener(this);
mList.setOnItemLongClickListener(this);
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
} }
@ -38,6 +42,12 @@ public class FragmentListView extends SherlockFragment implements OnItemClickLis
} }
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {} public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {}
@Override
public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
return false;
}
} }

View file

@ -0,0 +1,117 @@
package eu.alefzero.owncloud.ui.activity;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckedTextView;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.SherlockListActivity;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuItem;
import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
import eu.alefzero.owncloud.AccountUtils;
import eu.alefzero.owncloud.R;
public class AccountSelectActivity extends SherlockListActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActionBar action_bar = getSupportActionBar();
action_bar.setDisplayShowTitleEnabled(true);
action_bar.setDisplayHomeAsUpEnabled(false);
}
@Override
protected void onResume() {
super.onResume();
AccountManager am = (AccountManager) getSystemService(ACCOUNT_SERVICE);
Account accounts[] = am.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE);
LinkedList< HashMap<String, String>> ll = new LinkedList<HashMap<String,String>>();
for (Account a : accounts) {
HashMap<String, String> h = new HashMap<String, String>();
h.put("NAME", a.name);
h.put("VER", "ownCloud version: " + am.getUserData(a, AccountAuthenticator.KEY_OC_VERSION));
ll.add(h);
}
setListAdapter(new AccountCheckedSimpleAdepter(this,
ll,
android.R.layout.simple_list_item_single_choice,
new String[]{"NAME"},
new int[]{android.R.id.text1}));
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getSherlock().getMenuInflater();
inflater.inflate(eu.alefzero.owncloud.R.menu.account_picker, menu);
return true;
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
String accountName = ((TextView)v.findViewById(android.R.id.text1)).getText().toString();
AccountUtils.setCurrentOwnCloudAccount(this, accountName);
Intent i = new Intent(this, FileDisplayActivity.class);
startActivity(i);
finish();
}
@Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
if (item.getItemId() == R.id.createAccount) {
Intent intent = new Intent(android.provider.Settings.ACTION_ADD_ACCOUNT);
intent.putExtra("authorities",
new String[] { AccountAuthenticator.AUTH_TOKEN_TYPE });
startActivity(intent);
return true;
}
return false;
}
private class AccountCheckedSimpleAdepter extends SimpleAdapter {
private Account mCurrentAccount;
private List<? extends Map<String, ?>> mPrivateData;
public AccountCheckedSimpleAdepter(Context context,
List<? extends Map<String, ?>> data,
int resource,
String[] from,
int[] to) {
super(context, data, resource, from, to);
mCurrentAccount = AccountUtils.getCurrentOwnCloudAccount(AccountSelectActivity.this);
mPrivateData = data;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = super.getView(position, convertView, parent);
CheckedTextView ctv = (CheckedTextView) v.findViewById(android.R.id.text1);
if (mPrivateData.get(position).get("NAME").equals(mCurrentAccount.name)) {
ctv.setChecked(true);
}
return v;
}
}
}

View file

@ -1,5 +1,5 @@
/* ownCloud Android client application /* ownCloud Android client application
* Copyright (C) 2011 Bartek Przybylski * Copyright (C) 2012 Bartek Przybylski
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -30,22 +30,27 @@ import android.content.ContentResolver;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.graphics.Color;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.text.InputType; import android.text.InputType;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.view.Window; import android.view.Window;
import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast;
import eu.alefzero.owncloud.AccountUtils; import eu.alefzero.owncloud.AccountUtils;
import eu.alefzero.owncloud.R; import eu.alefzero.owncloud.R;
import eu.alefzero.owncloud.authenticator.AccountAuthenticator; import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
import eu.alefzero.owncloud.authenticator.AuthenticationRunnable; import eu.alefzero.owncloud.authenticator.AuthenticationRunnable;
import eu.alefzero.owncloud.authenticator.ConnectionCheckerRunnable;
import eu.alefzero.owncloud.authenticator.OnAuthenticationResultListener; import eu.alefzero.owncloud.authenticator.OnAuthenticationResultListener;
import eu.alefzero.owncloud.authenticator.OnConnectCheckListener;
import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta; import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta;
import eu.alefzero.owncloud.extensions.ExtensionsAvailableActivity;
import eu.alefzero.owncloud.utils.OwnCloudVersion;
/** /**
* This Activity is used to add an ownCloud account to the App * This Activity is used to add an ownCloud account to the App
@ -53,37 +58,70 @@ import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta;
* @author Bartek Przybylski * @author Bartek Przybylski
* *
*/ */
public class AuthenticatorActivity extends AccountAuthenticatorActivity implements OnAuthenticationResultListener { public class AuthenticatorActivity extends AccountAuthenticatorActivity
implements OnAuthenticationResultListener,
OnConnectCheckListener,
OnFocusChangeListener,
OnClickListener {
private static final int DIALOG_LOGIN_PROGRESS = 0; private static final int DIALOG_LOGIN_PROGRESS = 0;
private static final String TAG = "AuthActivity"; private static final String TAG = "AuthActivity";
private Thread mAuthThread; private Thread mAuthThread;
private AuthenticationRunnable mAuthRunnable; private AuthenticationRunnable mAuthRunnable;
private ConnectionCheckerRunnable mConnChkRunnable;
private final Handler mHandler = new Handler(); private final Handler mHandler = new Handler();
private boolean mUseSSLConnection; private String mBaseUrl;
private static final String STATUS_TEXT = "STATUS_TEXT";
private static final String STATUS_ICON = "STATUS_ICON";
private static final String STATUS_CORRECT = "STATUS_CORRECT";
private static final String IS_SSL_CONN = "IS_SSL_CONN";
private int mStatusText, mStatusIcon;
private boolean mStatusCorrect, mIsSslConn;
public static final String PARAM_USERNAME = "param_Username"; public static final String PARAM_USERNAME = "param_Username";
public static final String PARAM_HOSTNAME = "param_Hostname"; public static final String PARAM_HOSTNAME = "param_Hostname";
public AuthenticatorActivity() {
mUseSSLConnection = true;
}
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
getWindow().requestFeature(Window.FEATURE_NO_TITLE); getWindow().requestFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.account_setup); setContentView(R.layout.account_setup);
if (getIntent().hasExtra(PARAM_USERNAME)) { ImageView iv = (ImageView) findViewById(R.id.refreshButton);
String username = getIntent().getStringExtra(PARAM_HOSTNAME); ImageView iv2 = (ImageView) findViewById(R.id.viewPassword);
TextView host_text, user_text; TextView tv = (TextView) findViewById(R.id.host_URL);
host_text = (TextView) findViewById(R.id.host_URL); TextView tv2 = (TextView) findViewById(R.id.account_password);
user_text = (TextView) findViewById(R.id.account_username);
host_text.setText(host_text.getText() if (savedInstanceState != null) {
+ username.substring(username.lastIndexOf('@'))); mStatusIcon = savedInstanceState.getInt(STATUS_ICON);
user_text.setText(user_text.getText() mStatusText = savedInstanceState.getInt(STATUS_TEXT);
+ username.substring(0, username.lastIndexOf('@') - 1)); mStatusCorrect = savedInstanceState.getBoolean(STATUS_CORRECT);
mIsSslConn = savedInstanceState.getBoolean(IS_SSL_CONN);
setResultIconAndText(mStatusIcon, mStatusText);
findViewById(R.id.buttonOK).setEnabled(mStatusCorrect);
if (!mStatusCorrect)
iv.setVisibility(View.VISIBLE);
else
iv.setVisibility(View.INVISIBLE);
} else {
mStatusText = mStatusIcon = 0;
mStatusCorrect = false;
mIsSslConn = false;
} }
iv.setOnClickListener(this);
iv2.setOnClickListener(this);
tv.setOnFocusChangeListener(this);
tv2.setOnFocusChangeListener(this);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
outState.putInt(STATUS_ICON, mStatusIcon);
outState.putInt(STATUS_TEXT, mStatusText);
outState.putBoolean(STATUS_CORRECT, mStatusCorrect);
super.onSaveInstanceState(outState);
} }
@Override @Override
@ -92,20 +130,20 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity implemen
switch (id) { switch (id) {
case DIALOG_LOGIN_PROGRESS : { case DIALOG_LOGIN_PROGRESS : {
ProgressDialog working_dialog = new ProgressDialog(this); ProgressDialog working_dialog = new ProgressDialog(this);
dialog = working_dialog;
working_dialog.setMessage(getResources().getString(R.string.auth_trying_to_login)); working_dialog.setMessage(getResources().getString(R.string.auth_trying_to_login));
working_dialog.setIndeterminate(true); working_dialog.setIndeterminate(true);
working_dialog.setCancelable(true); working_dialog.setCancelable(true);
working_dialog.setOnCancelListener(new DialogInterface.OnCancelListener() { working_dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override @Override
public void onCancel(DialogInterface dialog) { public void onCancel(DialogInterface dialog) {
Log.i(getClass().getName(), "Login canceled"); Log.i(TAG, "Login canceled");
if (mAuthThread != null) { if (mAuthThread != null) {
mAuthThread.interrupt(); mAuthThread.interrupt();
finish(); finish();
} }
} }
}); });
dialog = working_dialog;
break; break;
} }
default : default :
@ -146,21 +184,20 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity implemen
} }
final Intent intent = new Intent(); final Intent intent = new Intent();
intent.putExtra(AccountManager.KEY_ACCOUNT_TYPE, intent.putExtra(AccountManager.KEY_ACCOUNT_TYPE, AccountAuthenticator.ACCOUNT_TYPE);
AccountAuthenticator.ACCOUNT_TYPE);
intent.putExtra(AccountManager.KEY_ACCOUNT_NAME, account.name); intent.putExtra(AccountManager.KEY_ACCOUNT_NAME, account.name);
intent.putExtra(AccountManager.KEY_AUTHTOKEN, intent.putExtra(AccountManager.KEY_AUTHTOKEN, AccountAuthenticator.ACCOUNT_TYPE);
AccountAuthenticator.ACCOUNT_TYPE);
accManager.setUserData(account, AccountAuthenticator.KEY_OC_URL,
url.toString());
// TODO prepare this URL using a central service
intent.putExtra(AccountManager.KEY_USERDATA, username); intent.putExtra(AccountManager.KEY_USERDATA, username);
accManager.setUserData(
account, accManager.setUserData(account,
AccountAuthenticator.KEY_CONTACT_URL, AccountAuthenticator.KEY_OC_URL,
url.toString().replace(AccountUtils.WEBDAV_PATH_2_0, url.toString());
AccountUtils.CARDDAV_PATH_2_0)); accManager.setUserData(account,
AccountAuthenticator.KEY_OC_VERSION,
mConnChkRunnable.getDiscoveredVersion().toString());
accManager.setUserData(account,
AccountAuthenticator.KEY_OC_BASE_URL,
mBaseUrl);
setAccountAuthenticatorResult(intent.getExtras()); setAccountAuthenticatorResult(intent.getExtras());
setResult(RESULT_OK, intent); setResult(RESULT_OK, intent);
@ -168,96 +205,173 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity implemen
bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true); bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
getContentResolver().startSync(ProviderTableMeta.CONTENT_URI, bundle); getContentResolver().startSync(ProviderTableMeta.CONTENT_URI, bundle);
dismissDialog(0); /*if (mConnChkRunnable.getDiscoveredVersion().compareTo(OwnCloudVersion.owncloud_v2) >= 0) {
Intent i = new Intent(this, ExtensionsAvailableActivity.class);
startActivity(i);
}*/
finish(); finish();
} else { } else {
Toast.makeText(this, message, Toast.LENGTH_LONG).show(); dismissDialog(DIALOG_LOGIN_PROGRESS);
dismissDialog(0); TextView tv = (TextView) findViewById(R.id.account_username);
tv.setError(message);
} }
} }
public void onOkClick(View view) { public void onOkClick(View view) {
TextView url_text = (TextView) findViewById(R.id.host_URL); String prefix = "";
TextView username_text = (TextView) findViewById(R.id.account_username); String url = ((TextView) findViewById(R.id.host_URL)).getText().toString();
TextView password_text = (TextView) findViewById(R.id.account_password); if (mIsSslConn) {
Log.i(getClass().getName(), "OK clicked"); prefix = "https://";
boolean hasErrors = false; } else {
prefix = "http://";
}
if (url.toLowerCase().startsWith("http://") || url.toLowerCase().startsWith("https://")) {
prefix = "";
}
continueConnection(prefix);
}
private void continueConnection(String prefix) {
String url = ((TextView) findViewById(R.id.host_URL)).getText().toString();
String username = ((TextView) findViewById(R.id.account_username)).getText().toString();
String password = ((TextView) findViewById(R.id.account_password)).getText().toString();
if (url.endsWith("/"))
url = url.substring(0, url.length()-1);
URL uri = null; URL uri = null;
if (url_text.getText().toString().trim().length() == 0) { String webdav_path = AccountUtils.getWebdavPath(mConnChkRunnable.getDiscoveredVersion());
url_text.setTextColor(Color.RED);
hasErrors = true;
} else {
url_text.setTextColor(android.R.color.black);
}
try { try {
String url_str = url_text.getText().toString(); mBaseUrl = prefix + url;
if (!url_str.startsWith("http://") && !url_str.startsWith("https://")) { String url_str = prefix + url + webdav_path;
if (mUseSSLConnection)
url_str = "https://" + url_str;
else
url_str = "http://" + url_str;
}
uri = new URL(url_str); uri = new URL(url_str);
} catch (MalformedURLException e) { } catch (MalformedURLException e) {
url_text.setTextColor(Color.RED); // should not happend
e.printStackTrace(); e.printStackTrace();
hasErrors = true;
}
if (username_text.getText().toString().contains(" ")
|| username_text.getText().toString().trim().length() == 0) {
username_text.setTextColor(Color.RED);
hasErrors = true;
} else {
username_text.setTextColor(android.R.color.black);
}
if (password_text.getText().toString().trim().length() == 0) {
password_text.setTextColor(Color.RED);
hasErrors = true;
} else {
password_text.setTextColor(android.R.color.black);
}
if (hasErrors) {
return;
}
int new_port = uri.getPort();
if (new_port == -1) {
if (mUseSSLConnection)
new_port = 443;
else
new_port = 80;
}
try {
uri = new URL(uri.getProtocol(), uri.getHost(), new_port, uri.getPath());
} catch (MalformedURLException e) {
e.printStackTrace(); // should not happend
} }
showDialog(DIALOG_LOGIN_PROGRESS); showDialog(DIALOG_LOGIN_PROGRESS);
mAuthRunnable = new AuthenticationRunnable( mAuthRunnable = new AuthenticationRunnable(uri, username, password);
uri,
username_text.getText().toString(),
password_text.getText().toString());
mAuthRunnable.setOnAuthenticationResultListener(this, mHandler); mAuthRunnable.setOnAuthenticationResultListener(this, mHandler);
Log.e(TAG, uri.toString());
mAuthThread = new Thread(mAuthRunnable); mAuthThread = new Thread(mAuthRunnable);
mAuthThread.start(); mAuthThread.start();
} }
@Override
public void onConnectionCheckResult(ResultType type) {
mStatusText = mStatusIcon = 0;
mStatusCorrect = false;
String t_url = ((TextView) findViewById(R.id.host_URL)).getText().toString().toLowerCase();
public void sslBadgeClick(View view, String val) { switch (type) {
mUseSSLConnection = ((TextView) view).getText().equals("SSL"); case OK:
// ugly as hell
if (t_url.startsWith("http://") || t_url.startsWith("https://")) {
mIsSslConn = t_url.startsWith("http://") ? false : true;
mStatusIcon = R.drawable.ic_ok;
mStatusText = R.string.auth_connection_established;
mStatusCorrect = true;
} else {
mIsSslConn = true;
mStatusIcon = android.R.drawable.ic_secure;
mStatusText = R.string.auth_secure_connection;
mStatusCorrect = true;
}
break;
case OK_NO_SSL:
mStatusIcon = android.R.drawable.ic_secure;
mStatusText = R.string.auth_nossl_plain_ok_title;
mStatusCorrect = true;
mIsSslConn = false;
break;
case TIMEOUT:
case INORRECT_ADDRESS:
case SSL_INIT_ERROR:
case HOST_NOT_AVAILABLE:
mStatusIcon = R.drawable.common_error;
mStatusText = R.string.auth_unknow_host_title;
break;
case NO_NETWORK_CONNECTION:
mStatusIcon = R.drawable.no_network;
mStatusText = R.string.auth_no_net_conn_title;
break;
case INSTANCE_NOT_CONFIGURED:
mStatusIcon = R.drawable.common_error;
mStatusText = R.string.auth_not_configured_title;
break;
case UNKNOWN_ERROR:
mStatusIcon = R.drawable.common_error;
mStatusText = R.string.auth_unknow_error;
break;
case FILE_NOT_FOUND:
mStatusIcon = R.drawable.common_error;
mStatusText = R.string.auth_incorrect_path_title;
break;
default:
Log.e(TAG, "Incorrect connection checker result type: " + type);
}
setResultIconAndText(mStatusIcon, mStatusText);
if (!mStatusCorrect)
findViewById(R.id.refreshButton).setVisibility(View.VISIBLE);
else
findViewById(R.id.refreshButton).setVisibility(View.INVISIBLE);
findViewById(R.id.buttonOK).setEnabled(mStatusCorrect);
} }
public void passwordBadgeClick(View view, String val) { @Override
int input_type = InputType.TYPE_CLASS_TEXT; public void onFocusChange(View view, boolean hasFocus) {
input_type |= val.equals("Hide") if (view.getId() == R.id.host_URL) {
? InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD if (!hasFocus) {
: InputType.TYPE_TEXT_VARIATION_PASSWORD; TextView tv = ((TextView)findViewById(R.id.host_URL));
String uri = tv.getText().toString();
if (uri.length() != 0) {
setResultIconAndText(R.drawable.progress_small, R.string.auth_testing_connection);
mConnChkRunnable = new ConnectionCheckerRunnable(uri, this);
mConnChkRunnable.setListener(this, mHandler);
mAuthThread = new Thread(mConnChkRunnable);
mAuthThread.start();
} else {
findViewById(R.id.refreshButton).setVisibility(View.INVISIBLE);
setResultIconAndText(0, 0);
}
}
} else if (view.getId() == R.id.account_password) {
ImageView iv = (ImageView) findViewById(R.id.viewPassword);
if (hasFocus) {
iv.setVisibility(View.VISIBLE);
} else {
TextView v = (TextView) findViewById(R.id.account_password);
int input_type = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD;
v.setInputType(input_type);
iv.setVisibility(View.INVISIBLE);
}
}
}
private void setResultIconAndText(int drawable_id, int text_id) {
ImageView iv = (ImageView) findViewById(R.id.action_indicator);
TextView tv = (TextView) findViewById(R.id.status_text);
if (drawable_id == 0 && text_id == 0) {
iv.setVisibility(View.INVISIBLE);
tv.setVisibility(View.INVISIBLE);
} else {
iv.setImageResource(drawable_id);
tv.setText(text_id);
iv.setVisibility(View.VISIBLE);
tv.setVisibility(View.VISIBLE);
}
}
((TextView) view).setInputType(input_type); @Override
public void onClick(View v) {
if (v.getId() == R.id.refreshButton) {
onFocusChange(findViewById(R.id.host_URL), false);
} else if (v.getId() == R.id.viewPassword) {
TextView view = (TextView) findViewById(R.id.account_password);
int input_type = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD;
view.setInputType(input_type);
}
} }
} }

View file

@ -25,14 +25,15 @@ import android.app.AlertDialog.Builder;
import android.app.Dialog; import android.app.Dialog;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.DialogInterface.OnClickListener; import android.content.DialogInterface.OnClickListener;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.ContentResolver; import android.content.ContentResolver;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.database.Cursor;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -54,8 +55,6 @@ import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
import eu.alefzero.owncloud.datamodel.DataStorageManager; import eu.alefzero.owncloud.datamodel.DataStorageManager;
import eu.alefzero.owncloud.datamodel.FileDataStorageManager; import eu.alefzero.owncloud.datamodel.FileDataStorageManager;
import eu.alefzero.owncloud.datamodel.OCFile; import eu.alefzero.owncloud.datamodel.OCFile;
import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta;
import eu.alefzero.owncloud.syncadapter.FileSyncAdapter;
import eu.alefzero.owncloud.syncadapter.FileSyncService; import eu.alefzero.owncloud.syncadapter.FileSyncService;
import eu.alefzero.owncloud.ui.fragment.FileListFragment; import eu.alefzero.owncloud.ui.fragment.FileListFragment;
import eu.alefzero.webdav.WebdavClient; import eu.alefzero.webdav.WebdavClient;
@ -76,6 +75,9 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
private static final int DIALOG_SETUP_ACCOUNT = 0; private static final int DIALOG_SETUP_ACCOUNT = 0;
private static final int DIALOG_CREATE_DIR = 1; private static final int DIALOG_CREATE_DIR = 1;
private static final int REQUEST_ACCOUNT_SETUP = 0;
private static final int ACTION_SELECT_FILE = 1;
public void pushPath(String path) { public void pushPath(String path) {
mDirectories.insert(path, 0); mDirectories.insert(path, 0);
@ -96,8 +98,8 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
builder.setTitle(R.string.main_tit_accsetup); builder.setTitle(R.string.main_tit_accsetup);
builder.setMessage(R.string.main_wrn_accsetup); builder.setMessage(R.string.main_wrn_accsetup);
builder.setCancelable(false); builder.setCancelable(false);
builder.setPositiveButton(R.string.common_ok, this); builder.setPositiveButton(android.R.string.ok, this);
builder.setNegativeButton(R.string.common_cancel, this); builder.setNegativeButton(android.R.string.cancel, this);
dialog = builder.create(); dialog = builder.create();
break; break;
case DIALOG_CREATE_DIR: case DIALOG_CREATE_DIR:
@ -107,12 +109,13 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
final Account a = AccountUtils.getCurrentOwnCloudAccount(this); final Account a = AccountUtils.getCurrentOwnCloudAccount(this);
builder.setView(dirName); builder.setView(dirName);
builder.setTitle(R.string.uploader_info_dirname); builder.setTitle(R.string.uploader_info_dirname);
dirName.setTextColor(R.color.setup_text_typed); int typed_color = getResources().getColor(R.color.setup_text_typed);
dirName.setTextColor(typed_color);
builder.setPositiveButton(R.string.common_ok, new OnClickListener() { builder.setPositiveButton(android.R.string.ok, new OnClickListener() {
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
String s = dirName.getText().toString(); String s = dirName.getText().toString();
if (s.trim().isEmpty()) { if (s.trim().length() == 0) {
dialog.cancel(); dialog.cancel();
return; return;
} }
@ -140,6 +143,8 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
dialog.cancel(); dialog.cancel();
} }
}); });
dialog = builder.create();
break;
} }
default: default:
dialog = null; dialog = null;
@ -151,27 +156,19 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
if(!accountsAreSetup()){ if(!accountsAreSetup()){
showDialog(DIALOG_SETUP_ACCOUNT); showDialog(DIALOG_SETUP_ACCOUNT);
return; return;
} }
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setProgressBarIndeterminateVisibility(false);
mDirectories = new CustomArrayAdapter<String>(this,
R.layout.sherlock_spinner_dropdown_item);
mDirectories.add("/");
setContentView(R.layout.files);
mStorageManager = new FileDataStorageManager(AccountUtils.getCurrentOwnCloudAccount(this), getContentResolver());
ActionBar action_bar = getSupportActionBar();
action_bar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
action_bar.setDisplayShowTitleEnabled(false);
action_bar.setListNavigationCallbacks(mDirectories, this);
action_bar.setDisplayHomeAsUpEnabled(true);
} }
@Override @Override
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
boolean retval = true;
switch (item.getItemId()) { switch (item.getItemId()) {
case R.id.settingsItem: { case R.id.settingsItem: {
Intent i = new Intent(this, Preferences.class); Intent i = new Intent(this, Preferences.class);
@ -190,13 +187,23 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
bundle); bundle);
break; break;
} }
case R.id.action_upload: {
Intent action = new Intent(Intent.ACTION_GET_CONTENT);
action = action.setType("*/*").addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(Intent.createChooser(action, "Upload file from..."), ACTION_SELECT_FILE);
break;
}
case android.R.id.home: { case android.R.id.home: {
onBackPressed(); Intent i = new Intent(this, AccountSelectActivity.class);
startActivity(i);
finish();
break; break;
} }
default:
retval = false;
} }
return true; return retval;
} }
@Override @Override
@ -225,15 +232,7 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
showDialog(DIALOG_SETUP_ACCOUNT); showDialog(DIALOG_SETUP_ACCOUNT);
} }
} }
@Override
protected void onStart() {
super.onStart();
// Check, if there are ownCloud accounts
if(!accountsAreSetup()){
showDialog(DIALOG_SETUP_ACCOUNT);
}
}
@Override @Override
protected void onResume() { protected void onResume() {
@ -242,16 +241,74 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
showDialog(DIALOG_SETUP_ACCOUNT); showDialog(DIALOG_SETUP_ACCOUNT);
return; return;
} }
IntentFilter f = new IntentFilter(FileSyncService.SYNC_MESSAGE); IntentFilter f = new IntentFilter(FileSyncService.SYNC_MESSAGE);
b = new BR(); b = new BR();
registerReceiver(b, f); registerReceiver(b, f);
setProgressBarIndeterminateVisibility(false); if (getSupportFragmentManager().findFragmentById(R.id.fileList) == null)
setContentView(R.layout.files);
mDirectories = new CustomArrayAdapter<String>(this,
R.layout.sherlock_spinner_dropdown_item);
mDirectories.add("/");
mStorageManager = new FileDataStorageManager(AccountUtils.getCurrentOwnCloudAccount(this), getContentResolver());
ActionBar action_bar = getSupportActionBar();
action_bar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
action_bar.setDisplayShowTitleEnabled(false);
action_bar.setListNavigationCallbacks(mDirectories, this);
action_bar.setDisplayHomeAsUpEnabled(true);
} }
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if (requestCode == ACTION_SELECT_FILE) {
Uri selectedImageUri = data.getData();
String filemanagerstring = selectedImageUri.getPath();
String selectedImagePath = getPath(selectedImageUri);
//DEBUG PURPOSE - you can delete this if you want
if(selectedImagePath!=null)
System.out.println(selectedImagePath);
else System.out.println("selectedImagePath is null");
if(filemanagerstring!=null)
System.out.println(filemanagerstring);
else System.out.println("filemanagerstring is null");
//NOW WE HAVE OUR WANTED STRING
if(selectedImagePath!=null)
System.out.println("selectedImagePath is the right one for you!");
else
System.out.println("filemanagerstring is the right one for you!");
}
}
}
public String getPath(Uri uri) {
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(uri, projection, null, null, null);
if(cursor!=null)
{
//HERE YOU WILL GET A NULLPOINTER IF CURSOR IS NULL
//THIS CAN BE, IF YOU USED OI FILE MANAGER FOR PICKING THE MEDIA
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
else return null;
}
@Override @Override
protected void onPause() { protected void onPause() {
super.onPause(); super.onPause();
unregisterReceiver(b); if (b != null) {
unregisterReceiver(b);
b = null;
}
} }
@Override @Override
@ -322,7 +379,7 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
} }
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
// In any case - we won't need it anymore // In any case - we won't need it anymore
dialog.dismiss(); dialog.dismiss();

View file

@ -21,9 +21,6 @@ package eu.alefzero.owncloud.ui.adapter;
import java.io.File; import java.io.File;
import eu.alefzero.owncloud.R; import eu.alefzero.owncloud.R;
import eu.alefzero.owncloud.R.drawable;
import eu.alefzero.owncloud.R.id;
import eu.alefzero.owncloud.R.layout;
import eu.alefzero.owncloud.authenticator.AccountAuthenticator; import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta; import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta;
import android.accounts.Account; import android.accounts.Account;
@ -45,10 +42,10 @@ public class FileListActionListAdapter implements ListAdapter {
private Context mContext; private Context mContext;
private Account mAccount; private Account mAccount;
private String mFilename, mFileType, mFilePath, mFileStoragePath, mItemId; private String mFilename, mFileType, mFilePath, mFileStoragePath;
private final int ITEM_DOWNLOAD = 0; private final int ITEM_DOWNLOAD = 0;
private final int ITEM_SHARE = 1; //private final int ITEM_SHARE = 1;
public FileListActionListAdapter(Cursor c, Context co, Account account) { public FileListActionListAdapter(Cursor c, Context co, Account account) {
mContext = co; mContext = co;
@ -56,7 +53,7 @@ public class FileListActionListAdapter implements ListAdapter {
mFileType = c.getString(c.getColumnIndex(ProviderTableMeta.FILE_CONTENT_TYPE)); mFileType = c.getString(c.getColumnIndex(ProviderTableMeta.FILE_CONTENT_TYPE));
mFilePath = c.getString(c.getColumnIndex(ProviderTableMeta.FILE_PATH)); mFilePath = c.getString(c.getColumnIndex(ProviderTableMeta.FILE_PATH));
mFileStoragePath = c.getString(c.getColumnIndex(ProviderTableMeta.FILE_STORAGE_PATH)); mFileStoragePath = c.getString(c.getColumnIndex(ProviderTableMeta.FILE_STORAGE_PATH));
mItemId = c.getString(c.getColumnIndex(ProviderTableMeta._ID)); //mItemId = c.getString(c.getColumnIndex(ProviderTableMeta._ID));
mAccount = account; mAccount = account;
} }

View file

@ -96,11 +96,28 @@ public class FileListListAdapter implements ListAdapter {
if (mFiles.size() > position) { if (mFiles.size() > position) {
OCFile file = mFiles.get(position); OCFile file = mFiles.get(position);
TextView fileName = (TextView) view.findViewById(R.id.Filename); TextView fileName = (TextView) view.findViewById(R.id.Filename);
fileName.setText(DisplayUtils.HtmlDecode(file.getFileName())); TextView ext_text = (TextView) view.findViewById(R.id.Extension);
if (!file.getMimetype().equals("DIR")) { String name = file.getFileName();
ImageView fileIcon = (ImageView) view.findViewById(R.id.imageView1); String ext = file.getFileName();
fileIcon.setImageResource(R.drawable.file); if (name.lastIndexOf('.') != -1) {
name = name.substring(0, name.lastIndexOf('.'));
ext = ext.substring(ext.lastIndexOf('.'));
} else {
ext = "";
} }
fileName.setText(DisplayUtils.HtmlDecode(name));
ext_text.setText(ext);
ImageView fileIcon = (ImageView) view.findViewById(R.id.imageView1);
if (!file.getMimetype().equals("DIR")) {
fileIcon.setImageResource(R.drawable.file);
} else {
fileIcon.setImageResource(R.drawable.ic_menu_archive);
}
ImageView down = (ImageView) view.findViewById(R.id.imageView2);
if (file.getStoragePath() != null) down.setVisibility(View.VISIBLE);
else down.setVisibility(View.INVISIBLE);
} }
return view; return view;

View file

@ -0,0 +1,7 @@
package eu.alefzero.owncloud.ui.fragment;
import com.actionbarsherlock.app.SherlockFragment;
public class AuthenticatorAccountDetailsFragment extends SherlockFragment {
}

View file

@ -0,0 +1,7 @@
package eu.alefzero.owncloud.ui.fragment;
import com.actionbarsherlock.app.SherlockFragment;
public class AuthenticatorGetStartedFragment extends SherlockFragment {
}

View file

@ -21,6 +21,8 @@ import java.util.Stack;
import java.util.Vector; import java.util.Vector;
import android.accounts.Account; import android.accounts.Account;
import android.content.ClipData;
import android.content.ClipDescription;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
@ -57,6 +59,9 @@ public class FileListFragment extends FragmentListView {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
mAccount = AccountUtils.getCurrentOwnCloudAccount(getActivity()); mAccount = AccountUtils.getCurrentOwnCloudAccount(getActivity());
getListView().setDivider(getResources().getDrawable(R.drawable.uploader_list_separator));
getListView().setDividerHeight(1);
populateFileList(); populateFileList();
} }
@ -89,7 +94,16 @@ public class FileListFragment extends FragmentListView {
startActivity(i); startActivity(i);
} }
} }
@Override
public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
ClipData.Item item = new ClipData.Item("ASD");
ClipDescription cd = new ClipDescription("ASD", new String[]{ClipDescription.MIMETYPE_TEXT_PLAIN});
ClipData dragData = new ClipData(cd, item);
arg1.startDrag(dragData, new View.DragShadowBuilder(arg0.getChildAt(arg2)), null, 0);
return true;
}
/** /**
* Call this, when the user presses the up button * Call this, when the user presses the up button
*/ */

View file

@ -0,0 +1,80 @@
/* ownCloud Android client application
* Copyright (C) 2012 Bartek Przybylski
*
* 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 eu.alefzero.owncloud.utils;
public class OwnCloudVersion implements Comparable<OwnCloudVersion> {
public static final OwnCloudVersion owncloud_v1 = new OwnCloudVersion(0x010000);
public static final OwnCloudVersion owncloud_v2 = new OwnCloudVersion(0x020000);
public static final OwnCloudVersion owncloud_v3 = new OwnCloudVersion(0x030000);
public static final OwnCloudVersion owncloud_v4 = new OwnCloudVersion(0x040000);
// format is in version
// 0xAABBCC
// for version AA.BB.CC
// ie version 3.0.3 will be stored as 0x030003
private int mVersion;
private boolean mIsValid;
public OwnCloudVersion(int version) {
mVersion = version;
mIsValid = true;
}
public OwnCloudVersion(String version) {
mVersion = 0;
mIsValid = false;
parseVersionString(version);
}
public String toString() {
return ((mVersion >> 16)%256) + "." +
((mVersion >> 8)%256) + "." +
((mVersion)%256);
}
public boolean isVersionValid() {
return mIsValid;
}
@Override
public int compareTo(OwnCloudVersion another) {
return another.mVersion == mVersion ? 0 :
another.mVersion < mVersion ? 1 : -1;
}
private void parseVersionString(String version) {
try {
String[] nums = version.split("\\.");
if (nums.length > 0) {
mVersion += Integer.parseInt(nums[0]);
}
mVersion = mVersion << 8;
if (nums.length > 1) {
mVersion += Integer.parseInt(nums[1]);
}
mVersion = mVersion << 8;
if (nums.length > 2) {
mVersion += Integer.parseInt(nums[2]);
}
mIsValid = true;
} catch (Exception e) {
mIsValid = false;
}
}
}

View file

@ -5,20 +5,14 @@ import java.lang.reflect.Method;
import eu.alefzero.owncloud.R; import eu.alefzero.owncloud.R;
import android.content.Context; import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray; import android.content.res.TypedArray;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.Rect; import android.graphics.Rect;
import android.text.InputType;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View;
import android.widget.CheckBox;
import android.widget.EditText; import android.widget.EditText;
import android.widget.TextView;
public class ActionEditText extends EditText { public class ActionEditText extends EditText {
private String s; private String s;
@ -26,6 +20,7 @@ public class ActionEditText extends EditText {
private int optionOneColor; private int optionOneColor;
private String optionTwoString; private String optionTwoString;
private int optionTwoColor; private int optionTwoColor;
private Rect mTextBounds, mButtonRect;
private String badgeClickCallback; private String badgeClickCallback;
private Rect btn_rect; private Rect btn_rect;
@ -34,39 +29,41 @@ public class ActionEditText extends EditText {
super(context, attrs); super(context, attrs);
getAttrs(attrs); getAttrs(attrs);
s = optionOneString; s = optionOneString;
mTextBounds = new Rect();
mButtonRect = new Rect();
} }
public ActionEditText(Context context, AttributeSet attrs, int defStyle) { public ActionEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle); super(context, attrs, defStyle);
getAttrs(attrs); getAttrs(attrs);
s = optionOneString; s = optionOneString;
mTextBounds = new Rect();
mButtonRect = new Rect();
} }
@Override @Override
protected void onDraw(Canvas canvas) { protected void onDraw(Canvas canvas) {
super.onDraw(canvas); super.onDraw(canvas);
Rect r = new Rect();
Paint p = getPaint(); Paint p = getPaint();
Rect text_bounds = new Rect();
p.getTextBounds(s, 0, s.length(), text_bounds); p.getTextBounds(s, 0, s.length(), mTextBounds);
getDrawingRect(r); getDrawingRect(mButtonRect);
r.top += 10; mButtonRect.top += 10;
r.bottom -= 10; mButtonRect.bottom -= 10;
r.left = (int)(getWidth() - text_bounds.width() - 18); mButtonRect.left = (int)(getWidth() - mTextBounds.width() - 18);
r.right = getWidth() - 10; mButtonRect.right = getWidth() - 10;
btn_rect = r; btn_rect = mButtonRect;
if (s.equals(optionOneString)) if (s.equals(optionOneString))
p.setColor(optionOneColor); p.setColor(optionOneColor);
else else
p.setColor(optionTwoColor); p.setColor(optionTwoColor);
canvas.drawRect(r, p); canvas.drawRect(mButtonRect, p);
p.setColor(Color.GRAY); p.setColor(Color.GRAY);
canvas.drawText(s, r.left + 3, r.bottom - (text_bounds.height()/2), p); canvas.drawText(s, mButtonRect.left + 3, mButtonRect.bottom - (mTextBounds.height()/2), p);
invalidate(); invalidate();
} }
@ -81,6 +78,7 @@ public class ActionEditText extends EditText {
if (s.equals(optionTwoString)) s = optionOneString; if (s.equals(optionTwoString)) s = optionOneString;
else s = optionTwoString; else s = optionTwoString;
if (badgeClickCallback != null) { if (badgeClickCallback != null) {
@SuppressWarnings("rawtypes")
Class[] paramtypes = new Class[2]; Class[] paramtypes = new Class[2];
paramtypes[0] = android.view.View.class; paramtypes[0] = android.view.View.class;
paramtypes[1] = String.class; paramtypes[1] = String.class;

View file

@ -0,0 +1,53 @@
package eu.alefzero.webdav;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.commons.httpclient.methods.RequestEntity;
/**
* A RequestEntity that represents a File.
*
*/
public class FileRequestEntity implements RequestEntity {
final File file;
final String contentType;
public FileRequestEntity(final File file, final String contentType) {
super();
if (file == null) {
throw new IllegalArgumentException("File may not be null");
}
this.file = file;
this.contentType = contentType;
}
public long getContentLength() {
return this.file.length();
}
public String getContentType() {
return this.contentType;
}
public boolean isRepeatable() {
return true;
}
public void writeRequest(final OutputStream out) throws IOException {
byte[] tmp = new byte[4096];
int i = 0;
InputStream instream = new FileInputStream(this.file);
try {
while ((i = instream.read(tmp)) >= 0) {
out.write(tmp, 0, i);
}
} finally {
instream.close();
}
}
}

View file

@ -1,36 +0,0 @@
/* ownCloud Android client application
* Copyright (C) 2011 Bartek Przybylski
*
* 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 eu.alefzero.webdav;
import java.net.URI;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
public class HttpMkCol extends HttpEntityEnclosingRequestBase {
public final static String METHOD_NAME = "MKCOL";
public HttpMkCol(final String uri) {
setURI(URI.create(uri));
}
@Override
public String getMethod() {
return METHOD_NAME;
}
}

View file

@ -1,49 +0,0 @@
/* ownCloud Android client application
* Copyright (C) 2011 Bartek Przybylski
*
* 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 eu.alefzero.webdav;
import java.net.URI;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.protocol.HTTP;
public class HttpPropFind extends HttpEntityEnclosingRequestBase {
public final static String METHOD_NAME = "PROPFIND";
public HttpPropFind(final URI uri) {
super();
setURI(uri);
}
public HttpPropFind(final String uri) {
this.setDepth("1");
setURI(URI.create(uri));
this.setHeader(HTTP.CONTENT_TYPE, "text/xml" + HTTP.CHARSET_PARAM + HTTP.UTF_8.toLowerCase());
}
@Override
public String getMethod() {
return METHOD_NAME;
}
public void setDepth(String depth) {
this.setHeader("Depth", depth);
}
}

View file

@ -1,43 +0,0 @@
/* ownCloud Android client application
* Copyright (C) 2011 Bartek Przybylski
*
* 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 eu.alefzero.webdav;
import java.net.URI;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
public class HttpPropPatch extends HttpEntityEnclosingRequestBase {
public static final String METHOD_NAME = "PROPPATCH";
public HttpPropPatch(URI uri) {
super();
setURI(uri);
}
public HttpPropPatch(final String uri) {
super();
setURI(URI.create(uri));
}
@Override
public String getMethod() {
return METHOD_NAME;
}
}

View file

@ -21,70 +21,37 @@ import java.io.BufferedInputStream;
import java.io.File; import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.net.URLDecoder;
import org.apache.commons.httpclient.Credentials; import org.apache.commons.httpclient.Credentials;
import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.UsernamePasswordCredentials; import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope; import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.HeadMethod; import org.apache.commons.httpclient.methods.HeadMethod;
import org.apache.http.HttpHost; import org.apache.commons.httpclient.methods.PutMethod;
import org.apache.http.HttpResponse; import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.http.HttpStatus; import org.apache.commons.httpclient.protocol.Protocol;
import org.apache.http.HttpVersion; import org.apache.http.HttpStatus;
import org.apache.http.client.methods.HttpGet; import org.apache.jackrabbit.webdav.client.methods.MkColMethod;
import org.apache.http.client.methods.HttpHead;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.params.ConnManagerPNames;
import org.apache.http.conn.params.ConnPerRouteBean;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.entity.FileEntity;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.BasicHttpContext;
import eu.alefzero.owncloud.authenticator.EasySSLSocketFactory; import eu.alefzero.owncloud.authenticator.EasySSLSocketFactory;
import eu.alefzero.webdav.HttpMkCol;
import android.net.Uri; import android.net.Uri;
import android.util.Log; import android.util.Log;
public class WebdavClient extends HttpClient { public class WebdavClient extends HttpClient {
private DefaultHttpClient mHttpClient;
private BasicHttpContext mHttpContext;
private HttpHost mTargetHost;
private SchemeRegistry mSchemeRegistry;
private Uri mUri; private Uri mUri;
private Credentials mCredentials; private Credentials mCredentials;
final private static String TAG = "WebdavClient"; final private static String TAG = "WebdavClient";
private static final String USER_AGENT = "Android-ownCloud";
public DefaultHttpClient getHttpClient() {
return mHttpClient;
}
public HttpHost getTargetHost() {
return mTargetHost;
}
public WebdavClient(Uri uri) { public WebdavClient(Uri uri) {
mUri = uri; mUri = uri;
mSchemeRegistry = new SchemeRegistry(); getParams().setParameter(HttpMethodParams.USER_AGENT, USER_AGENT);
setupHttpClient();
} }
public void setCredentials(String username, String password) { public void setCredentials(String username, String password) {
// determine default port for http or https
int targetPort = mTargetHost.getPort() == -1 ?
( mUri.getScheme().equals("https") ? 443 : 80)
: mUri.getPort();
getParams().setAuthenticationPreemptive(true); getParams().setAuthenticationPreemptive(true);
getState().setCredentials(AuthScope.ANY, getCredentials(username, password)); getState().setCredentials(AuthScope.ANY, getCredentials(username, password));
} }
@ -94,22 +61,27 @@ public class WebdavClient extends HttpClient {
mCredentials = new UsernamePasswordCredentials(username, password); mCredentials = new UsernamePasswordCredentials(username, password);
return mCredentials; return mCredentials;
} }
public void allowUnsignedCertificates() { public void allowUnsignedCertificates() {
// https // https
mSchemeRegistry.register(new Scheme("https", new EasySSLSocketFactory(), 443)); Protocol.registerProtocol("https", new Protocol("https", new EasySSLSocketFactory(), 443));
} }
public boolean downloadFile(String filepath, File targetPath) { public boolean downloadFile(String filepath, File targetPath) {
HttpGet get = new HttpGet(mUri.toString() + filepath.replace(" ", "%20")); //HttpGet get = new HttpGet(mUri.toString() + filepath.replace(" ", "%20"));
get.setHeader("Host", mUri.getHost());
get.setHeader("User-Agent", "Android-ownCloud"); Log.e("ASD", mUri.toString() + URLDecoder.decode(filepath) + "");
GetMethod get = new GetMethod(mUri.toString() + URLDecoder.decode(filepath));
// get.setHeader("Host", mUri.getHost());
// get.setHeader("User-Agent", "Android-ownCloud");
try { try {
HttpResponse response = mHttpClient.execute(mTargetHost, get, mHttpContext); int status = executeMethod(get);
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { if (status != HttpStatus.SC_OK) {
return false; return false;
} }
BufferedInputStream bis = new BufferedInputStream(response.getEntity().getContent()); BufferedInputStream bis = new BufferedInputStream(get.getResponseBodyAsStream());
FileOutputStream fos = new FileOutputStream(targetPath); FileOutputStream fos = new FileOutputStream(targetPath);
byte[] bytes = new byte[512]; byte[] bytes = new byte[512];
@ -127,29 +99,14 @@ public class WebdavClient extends HttpClient {
String remoteTarget, String remoteTarget,
String contentType) { String contentType) {
boolean result = true; boolean result = true;
HttpPut method = new HttpPut(mUri.toString() + remoteTarget.replace(" ", "%20"));
method.setHeader("Content-type", contentType);
method.setHeader("Host", mUri.getHost());
method.setHeader("User-Agent", "Android-ownCloud");
try { try {
final FileEntity fileEntity = new FileEntity(new File(localFile), contentType); FileRequestEntity entity = new FileRequestEntity(new File(localFile), contentType);
PutMethod put = new PutMethod(mUri.toString() + remoteTarget.substring(1));
put.setRequestEntity(entity);
int status = executeMethod(put);
Log.d(TAG, "PUT method return with status "+status);
method.setEntity(fileEntity);
Log.i(TAG, "executing:" + method.getRequestLine().toString());
mHttpClient.execute(mTargetHost, method, mHttpContext);
/*mHandler.post(new Runnable() {
public void run() {
Uploader.this.PartialupdateUpload(c.getString(c.getColumnIndex(Media.DATA)),
c.getString(c.getColumnIndex(Media.DISPLAY_NAME)),
mUploadPath + (mUploadPath.equals("/")?"":"/"),
fileEntity.getContentType().getValue(),
fileEntity.getContentLength()+"");
}
});
Log.i(TAG, "Uploading, done");
*/
Log.i(TAG, "Uploading, done"); Log.i(TAG, "Uploading, done");
} catch (final Exception e) { } catch (final Exception e) {
Log.i(TAG, ""+e.getMessage()); Log.i(TAG, ""+e.getMessage());
@ -169,13 +126,13 @@ public class WebdavClient extends HttpClient {
} }
return r; return r;
} }
public boolean createDirectory(String path) { public boolean createDirectory(String path) {
HttpMkCol method = new HttpMkCol(mUri.toString() + path + "/"); try {
method.setHeader("User-Agent", "Android-ownCloud"); MkColMethod mkcol = new MkColMethod(mUri.toString() + "/" + path + "/");
int status = executeMethod(mkcol);
try { Log.d(TAG, "Status returned " + status);
mHttpClient.execute(mTargetHost, method, mHttpContext); Log.d(TAG, "uri: " + mkcol.getURI().toString());
Log.i(TAG, "Creating dir completed"); Log.i(TAG, "Creating dir completed");
} catch (final Exception e) { } catch (final Exception e) {
e.printStackTrace(); e.printStackTrace();
@ -183,27 +140,4 @@ public class WebdavClient extends HttpClient {
} }
return true; return true;
} }
private void setupHttpClient() {
// http scheme
mSchemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
mSchemeRegistry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));
HttpParams params = new BasicHttpParams();
params.setParameter(ConnManagerPNames.MAX_TOTAL_CONNECTIONS, 30);
params.setParameter(ConnManagerPNames.MAX_CONNECTIONS_PER_ROUTE, new ConnPerRouteBean(30));
params.setParameter(HttpProtocolParams.USE_EXPECT_CONTINUE, false);
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
mHttpContext = new BasicHttpContext();
ClientConnectionManager cm = new ThreadSafeClientConnManager(params, mSchemeRegistry);
int port = mUri.getPort() == -1 ?
mUri.getScheme().equals("https") ? 443 : 80
: mUri.getPort();
mTargetHost = new HttpHost(mUri.getHost(), port, mUri.getScheme());
mHttpClient = new DefaultHttpClient(cm, params);
}
} }

View file

@ -1,5 +1,5 @@
/* ownCloud Android client application /* ownCloud Android client application
* Copyright (C) 2011 Bartek Przybylski * Copyright (C) 2012 Bartek Przybylski
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -18,45 +18,12 @@
package eu.alefzero.webdav; package eu.alefzero.webdav;
import java.io.IOException;
import java.io.InputStream;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale; import java.util.Locale;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import android.util.Log;
public class WebdavUtils { public class WebdavUtils {
public static final String RESPONSE = "response";
public static final String HREF = "href";
public static final String IS_HIDDEN = "ishidden";
public static final String RESOURCE_TYPE = "resourcetype";
public static final String CONTENT_TYPE = "getcontenttype";
public static final String CONTENT_LENGTH = "getcontentlength";
public static final String LAST_MODIFIED = "getlastmodified";
public static final String LAST_ACCESS = "lastaccessed";
public static final String CREATE_DATE = "creationdate";
public static final String PROPSTAT = "propstat";
public static final String STATUS = "status";
public static final String PROP = "prop";
private static final String DAV_NAMESPACE_PREFIX = "DAV:";
public static final SimpleDateFormat DISPLAY_DATE_FORMAT = new SimpleDateFormat("dd.MM.yyyy hh:mm"); public static final SimpleDateFormat DISPLAY_DATE_FORMAT = new SimpleDateFormat("dd.MM.yyyy hh:mm");
private static final SimpleDateFormat DATETIME_FORMATS[] = { private static final SimpleDateFormat DATETIME_FORMATS[] = {
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US), new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US),
@ -86,14 +53,4 @@ public class WebdavUtils {
} }
return null; return null;
} }
private static String determineDAVPrefix(Element e) {
for (int i = 0; i < e.getAttributes().getLength(); ++i) {
String attrName = e.getAttributes().item(i).getNodeName();
if (e.getAttribute(attrName).equals(DAV_NAMESPACE_PREFIX)) {
return attrName.substring(attrName.lastIndexOf(':')+1) + ":";
}
}
return null;
}
} }