initial commit

This commit is contained in:
Bartek Przybylski 2011-08-19 22:37:35 +02:00
commit 154bb85cf1
105 changed files with 4412 additions and 0 deletions

15
.classpath Normal file
View file

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry kind="lib" path="lib/commons-codec-1.4.jar"/>
<classpathentry kind="lib" path="lib/commons-logging-1.1.1.jar"/>
<classpathentry kind="lib" path="lib/httpclient-4.1.1.jar"/>
<classpathentry kind="lib" path="lib/httpclient-cache-4.1.1.jar"/>
<classpathentry kind="lib" path="lib/httpcore-4.1.jar"/>
<classpathentry kind="lib" path="lib/httpmime-4.1.1.jar"/>
<classpathentry kind="lib" path="lib/commons-httpclient-3.0.1.jar"/>
<classpathentry kind="lib" path="lib/commons-io-2.0.1.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>

19
.gitignore vendored Normal file
View file

@ -0,0 +1,19 @@
# built application files
*.apk
*.ap_
# files for the dex VM
*.dex
# Java class files
*.class
# generated files
bin/
gen/
# Local configuration file (sdk path, etc)
local.properties
# Mac .DS_Store files
.DS_Store

33
.project Normal file
View file

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>ownCloud</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

79
AndroidManifest.xml Normal file
View file

@ -0,0 +1,79 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="eu.alefzero.owncloud"
android:versionCode="1"
android:versionName="1.0">
<uses-permission
android:name="android.permission.GET_ACCOUNTS" />
<uses-permission
android:name="android.permission.USE_CREDENTIALS" />
<uses-permission
android:name="android.permission.MANAGE_ACCOUNTS" />
<uses-permission
android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
<uses-permission
android:name="android.permission.INTERNET" />
<uses-permission
android:name="android.permission.WRITE_SETTINGS" />
<uses-permission
android:name="android.permission.WRITE_SECURE_SETTINGS" />
<uses-permission
android:name="android.permission.READ_CONTACTS" />
<uses-permission
android:name="android.permission.WRITE_CONTACTS" />
<uses-permission
android:name="android.permission.READ_SYNC_STATS" />
<uses-permission
android:name="android.permission.READ_SYNC_SETTINGS" />
<uses-permission
android:name="android.permission.WRITE_SYNC_SETTINGS" />
<uses-sdk android:minSdkVersion="7"></uses-sdk>
<uses-permission android:name="android.permission.READ_SMS"></uses-permission>
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".OwnCloudMainScreen"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="OwnCloudUploader">
<intent-filter>
<action android:name="android.intent.action.SEND"></action>
<category android:name="android.intent.category.DEFAULT"></category>
<data android:mimeType="*/*"></data>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND_MULTIPLE"></action>
<category android:name="android.intent.category.DEFAULT"></category>
<data android:mimeType="*/*"></data>
</intent-filter>
</activity>
<activity android:name="Preferences"></activity>
<activity android:name="PreferencesNewSession">
</activity>
<service
android:exported="true" android:name=".authenticator.AccountAuthenticatorService">
<intent-filter>
<action
android:name="android.accounts.AccountAuthenticator" />
</intent-filter>
<meta-data
android:name="android.accounts.AccountAuthenticator"
android:resource="@xml/authenticator" />
</service>
<service
android:exported="true" android:name=".syncadapter.SyncService">
<intent-filter>
<action
android:name="android.content.SyncAdapter" />
</intent-filter>
<meta-data
android:name="android.content.SyncAdapter"
android:resource="@xml/syncadapter" />
</service>
<provider android:name="cp" android:authorities="org.owncloud" android:enabled="true" android:syncable="true" android:exported="false" android:label="@string/sync_string"></provider>
<activity android:name=".authenticator.AuthenticatorActivity"></activity>
</application>
</manifest>

11
default.properties Normal file
View file

@ -0,0 +1,11 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system use,
# "build.properties", and override values to adapt the script to your
# project structure.
# Project target.
target=android-7

BIN
lib/commons-codec-1.4.jar Normal file

Binary file not shown.

Binary file not shown.

BIN
lib/commons-io-2.0.1.jar Normal file

Binary file not shown.

Binary file not shown.

BIN
lib/httpclient-4.1.1.jar Normal file

Binary file not shown.

Binary file not shown.

BIN
lib/httpcore-4.1.jar Normal file

Binary file not shown.

BIN
lib/httpmime-4.1.1.jar Normal file

Binary file not shown.

36
proguard.cfg Normal file
View file

@ -0,0 +1,36 @@
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService
-keepclasseswithmembernames class * {
native <methods>;
}
-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}

9
res/anim/disappear.xml Normal file
View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha
android:interpolator="@android:anim/decelerate_interpolator"
android:fromAlpha="1.0" android:toAlpha="0.0"
android:duration="400"
/>
</set>

View file

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:fromXScale="0.3" android:toXScale="1.0"
android:fromYScale="0.3" android:toYScale="1.0"
android:pivotX="50%" android:pivotY="100%"
android:duration="@android:integer/config_shortAnimTime"
/>
<alpha
android:interpolator="@android:anim/decelerate_interpolator"
android:fromAlpha="0.0" android:toAlpha="1.0"
android:duration="@android:integer/config_shortAnimTime"
/>
</set>

View file

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:fromXScale="0.3" android:toXScale="1.0"
android:fromYScale="0.3" android:toYScale="1.0"
android:pivotX="0%" android:pivotY="50%"
android:duration="@android:integer/config_shortAnimTime"
/>
<alpha
android:interpolator="@android:anim/decelerate_interpolator"
android:fromAlpha="0.0" android:toAlpha="1.0"
android:duration="@android:integer/config_shortAnimTime"
/>
</set>

View file

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:fromXScale="0.3" android:toXScale="1.0"
android:fromYScale="0.3" android:toYScale="1.0"
android:pivotX="100%" android:pivotY="50%"
android:duration="@android:integer/config_shortAnimTime"
/>
<alpha
android:interpolator="@android:anim/decelerate_interpolator"
android:fromAlpha="0.0" android:toAlpha="1.0"
android:duration="@android:integer/config_shortAnimTime"
/>
</set>

View file

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:fromXScale="0.3" android:toXScale="1.0"
android:fromYScale="0.3" android:toYScale="1.0"
android:pivotX="50%" android:pivotY="0%"
android:duration="@android:integer/config_shortAnimTime"
/>
<alpha
android:interpolator="@android:anim/decelerate_interpolator"
android:fromAlpha="0.0" android:toAlpha="1.0"
android:duration="@android:integer/config_shortAnimTime"
/>
</set>

View file

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:fromXScale="0.3" android:toXScale="1.0"
android:fromYScale="0.3" android:toYScale="1.0"
android:pivotX="0%" android:pivotY="0%"
android:duration="@android:integer/config_shortAnimTime"
/>
<alpha
android:interpolator="@android:anim/decelerate_interpolator"
android:fromAlpha="0.0" android:toAlpha="1.0"
android:duration="@android:integer/config_shortAnimTime"
/>
</set>

View file

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:fromXScale="0.3" android:toXScale="1.0"
android:fromYScale="0.3" android:toYScale="1.0"
android:pivotX="100%" android:pivotY="0%"
android:duration="@android:integer/config_shortAnimTime"
/>
<alpha
android:interpolator="@android:anim/decelerate_interpolator"
android:fromAlpha="0.0" android:toAlpha="1.0"
android:duration="@android:integer/config_shortAnimTime"
/>
</set>

14
res/anim/pump_bottom.xml Normal file
View file

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:fromXScale="1.1" android:toXScale="1.0"
android:fromYScale="1.1" android:toYScale="1.0"
android:pivotX="50%" android:pivotY="100%"
android:duration="@android:integer/config_shortAnimTime"
/>
<alpha
android:interpolator="@android:anim/decelerate_interpolator"
android:fromAlpha="0.0" android:toAlpha="1.0"
android:duration="@android:integer/config_shortAnimTime"
/>
</set>

14
res/anim/pump_top.xml Normal file
View file

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:fromXScale="1.1" android:toXScale="1.0"
android:fromYScale="1.1" android:toYScale="1.0"
android:pivotX="50%" android:pivotY="0%"
android:duration="@android:integer/config_shortAnimTime"
/>
<alpha
android:interpolator="@android:anim/decelerate_interpolator"
android:fromAlpha="0.0" android:toAlpha="1.0"
android:duration="@android:integer/config_shortAnimTime"
/>
</set>

20
res/anim/push_left_in.xml Normal file
View file

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2007 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.
-->
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="100%p" android:toXDelta="0" android:duration="300"/>
<alpha android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="300" />
</set>

View file

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2007 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.
-->
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="0" android:toXDelta="-100%p" android:duration="300"/>
<alpha android:fromAlpha="1.0" android:toAlpha="0.0" android:duration="300" />
</set>

View file

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:fromXScale="1.0" android:toXScale="0.3"
android:fromYScale="1.0" android:toYScale="0.3"
android:pivotX="50%" android:pivotY="0%"
android:duration="@android:integer/config_shortAnimTime"
/>
<alpha
android:interpolator="@android:anim/accelerate_interpolator"
android:fromAlpha="1.0" android:toAlpha="0.0"
android:duration="@android:integer/config_shortAnimTime"
/>
</set>

View file

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:fromXScale="1.0" android:toXScale="0.3"
android:fromYScale="1.0" android:toYScale="0.3"
android:pivotX="100%" android:pivotY="0%"
android:duration="@android:integer/config_shortAnimTime"
/>
<alpha
android:interpolator="@android:anim/accelerate_interpolator"
android:fromAlpha="1.0" android:toAlpha="0.0"
android:duration="@android:integer/config_shortAnimTime"
/>
</set>

View file

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:fromXScale="1.0" android:toXScale="0.3"
android:fromYScale="1.0" android:toYScale="0.3"
android:pivotX="0%" android:pivotY="0%"
android:duration="@android:integer/config_shortAnimTime"
/>
<alpha
android:interpolator="@android:anim/accelerate_interpolator"
android:fromAlpha="1.0" android:toAlpha="0.0"
android:duration="@android:integer/config_shortAnimTime"
/>
</set>

View file

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:fromXScale="1.0" android:toXScale="0.3"
android:fromYScale="1.0" android:toYScale="0.3"
android:pivotX="50%" android:pivotY="100%"
android:duration="@android:integer/config_shortAnimTime"
/>
<alpha
android:interpolator="@android:anim/accelerate_interpolator"
android:fromAlpha="1.0" android:toAlpha="0.0"
android:duration="@android:integer/config_shortAnimTime"
/>
</set>

View file

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:fromXScale="1.0" android:toXScale="0.3"
android:fromYScale="1.0" android:toYScale="0.3"
android:pivotX="100%" android:pivotY="100%"
android:duration="@android:integer/config_shortAnimTime"
/>
<alpha
android:interpolator="@android:anim/accelerate_interpolator"
android:fromAlpha="1.0" android:toAlpha="0.0"
android:duration="@android:integer/config_shortAnimTime"
/>
</set>

View file

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:fromXScale="1.0" android:toXScale="0.3"
android:fromYScale="1.0" android:toYScale="0.3"
android:pivotX="0%" android:pivotY="100%"
android:duration="@android:integer/config_shortAnimTime"
/>
<alpha
android:interpolator="@android:anim/accelerate_interpolator"
android:fromAlpha="1.0" android:toAlpha="0.0"
android:duration="@android:integer/config_shortAnimTime"
/>
</set>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
res/drawable-hdpi/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
res/drawable-ldpi/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 831 B

BIN
res/drawable-mdpi/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:dither="true">
<item
android:state_window_focused="false"
android:drawable="@android:color/transparent" />
<item
android:state_pressed="true"
android:drawable="@drawable/action_item_selected"/>
<item
android:state_focused="true"
android:drawable="@drawable/action_item_selected"/>
<item
android:drawable="@android:color/transparent"/>
</selector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 909 B

BIN
res/drawable/arrow_down.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 922 B

BIN
res/drawable/arrow_left.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
res/drawable/arrow_up.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 893 B

8
res/drawable/btn.xml Normal file
View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true" android:state_pressed="true" android:drawable="@drawable/btn_round_pressed" />
<item android:state_focused="true" android:state_pressed="false" android:drawable="@drawable/btn_round_pressed" />
<item android:state_focused="false" android:state_pressed="true" android:drawable="@drawable/btn_round_pressed" />
<item android:state_focused="false" android:state_pressed="true" android:drawable="@drawable/btn_round_pressed" />
<item android:drawable="@drawable/btn_round"/>
</selector>

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="5dip" />
<solid android:color="#aac4d2" />
<padding android:left="15dp" android:top="5dp" android:right="15dp" android:bottom="5dp" />
<stroke android:width="2dip" android:color="#ffffff" />
</shape>

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="5dip" />
<solid android:color="#aac4d2" />
<padding android:left="15dp" android:top="5dp" android:right="15dp" android:bottom="5dp" />
<stroke android:width="5dip" android:color="#ff8000" />
</shape>

BIN
res/drawable/dashboard.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
res/drawable/download.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 264 B

BIN
res/drawable/file.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 391 B

BIN
res/drawable/folder.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 386 B

BIN
res/drawable/header.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

BIN
res/drawable/popup.9.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 457 B

BIN
res/drawable/share.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 478 B

View file

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

View file

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:orientation="vertical" android:background="#F7F7F7" android:focusable="true">
<LinearLayout android:id="@+id/linearLayout7" android:paddingBottom="2pt" android:gravity="center_vertical|top" android:layout_gravity="top" android:layout_height="wrap_content" android:paddingTop="2pt" android:orientation="vertical" android:layout_width="fill_parent" android:background="#1D2D44">
<ImageView android:id="@+id/main_header_small" android:src="@drawable/owncloud_logo_small_white" android:layout_gravity="center|center_vertical|center_horizontal" android:layout_height="wrap_content" android:layout_width="wrap_content" android:focusable="true"></ImageView>
</LinearLayout>
<LinearLayout android:id="@+id/linearLayout2" android:layout_width="fill_parent" android:orientation="vertical" android:gravity="center_vertical" android:layout_gravity="center|center_vertical" android:layout_height="fill_parent">
<TableLayout android:id="@+id/tableLayout1" android:layout_height="wrap_content" android:gravity="center_horizontal" android:layout_width="fill_parent">
<TableRow android:layout_height="wrap_content" android:id="@+id/tableRow1" android:layout_width="wrap_content" android:gravity="center_horizontal">
<TextView android:id="@+id/textView1" android:text="@string/setup_title" android:layout_marginBottom="15dip" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="@android:color/black" android:textStyle="bold" android:layout_marginTop="15dip" android:textSize="7pt"></TextView>
</TableRow>
<TableRow android:layout_height="wrap_content" android:weightSum="1.0" android:id="@+id/tableRow2" android:layout_width="wrap_content" android:gravity="center_horizontal">
<EditText android:id="@+id/host_URL" android:layout_weight="0.75" android:layout_width="fill_parent" android:layout_height="wrap_content" android:hint="@string/setup_hint_address">
<requestFocus></requestFocus>
</EditText>
</TableRow>
<TableRow android:layout_height="wrap_content" android:weightSum="1.0" android:id="@+id/tableRow3" android:layout_width="wrap_content" android:gravity="center_horizontal">
<EditText android:id="@+id/account_username" android:layout_weight=".75" android:layout_width="fill_parent" android:layout_height="wrap_content" android:textColor="@android:color/black" android:hint="@string/setup_hint_username"></EditText>
</TableRow>
<TableRow android:layout_height="wrap_content" android:weightSum="1.0" android:id="@+id/tableRow4" android:layout_width="fill_parent" android:gravity="center_horizontal">
<EditText android:id="@+id/account_password" android:layout_weight=".75" android:layout_width="fill_parent" android:inputType="textPassword" android:layout_height="wrap_content" android:textColor="@android:color/black" android:hint="@string/setup_hint_password"></EditText>
</TableRow>
</TableLayout>
<LinearLayout android:layout_height="wrap_content" android:weightSum="1.0" android:id="@+id/linearLayout1" android:layout_width="fill_parent" android:gravity="center_horizontal" android:orientation="horizontal">
<Button android:id="@+id/buttonOK" android:text="@string/setup_btn_connect" android:layout_width="wrap_content" android:layout_weight=".50" android:layout_height="wrap_content" android:onClick="onOkClick"></Button>
</LinearLayout>
</LinearLayout>
</LinearLayout>

View file

@ -0,0 +1,25 @@
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
android:background="@drawable/action_item_btn">
<ImageView
android:id="@+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/title"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center_vertical"
android:paddingLeft="5dip"
android:paddingRight="10dip"
android:text="Chart"
android:textColor="#fff"/>
</LinearLayout>

View file

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:orientation="vertical" android:background="#F7F7F7">
<LinearLayout android:id="@+id/linearLayout7" android:paddingBottom="2pt" android:gravity="center_vertical|top" android:layout_gravity="top" android:layout_height="wrap_content" android:paddingTop="2pt" android:orientation="vertical" android:layout_width="fill_parent" android:background="#1D2D44">
<ImageView android:id="@+id/main_header_small" android:src="@drawable/owncloud_logo_small_white" android:layout_gravity="center|center_vertical|center_horizontal" android:layout_height="wrap_content" android:layout_width="wrap_content" android:focusable="true"></ImageView>
</LinearLayout>
<LinearLayout android:layout_width="fill_parent"
android:id="@+id/linearLayout1" android:layout_height="wrap_content">
<LinearLayout android:layout_width="wrap_content"
android:id="@+id/linearLayout2" android:layout_height="fill_parent">
<ImageView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:src="@drawable/icon"
android:id="@+id/imageView1"></ImageView>
</LinearLayout>
<LinearLayout android:layout_width="wrap_content"
android:id="@+id/linearLayout3" android:layout_height="fill_parent"
android:orientation="vertical">
<TextView android:id="@+id/textView1" android:layout_height="wrap_content"
android:layout_width="wrap_content" android:text="TextView"></TextView>
<TextView android:id="@+id/textView2" android:layout_height="wrap_content"
android:layout_width="wrap_content" android:text="TextView"></TextView>
<TextView android:id="@+id/textView3" android:layout_height="wrap_content"
android:layout_width="wrap_content" android:text="TextView"></TextView>
<TextView android:id="@+id/textView4" android:layout_height="wrap_content"
android:layout_width="wrap_content" android:text="TextView"></TextView>
<TextView android:id="@+id/textView5" android:layout_height="wrap_content"
android:layout_width="wrap_content" android:text="TextView"></TextView>
</LinearLayout>
</LinearLayout>
<LinearLayout android:layout_width="fill_parent"
android:id="@+id/linearLayout4" android:layout_height="fill_parent">
<ListView android:layout_width="fill_parent" android:id="@android:id/list"
android:layout_height="fill_parent" android:divider="@drawable/uploader_list_separator"
android:dividerHeight="1dip"></ListView>
</LinearLayout>
</LinearLayout>

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<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">
<ImageView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:src="@drawable/icon"
android:id="@+id/imageView1" android:layout_gravity="center_vertical"></ImageView>
<TextView android:text="TextView" android:id="@+id/textView1"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_vertical" android:textSize="11pt"></TextView>
</LinearLayout>

View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:id="@+id/ListItemLayout" android:layout_width="fill_parent"
android:background="#F7F7F7" android:layout_height="wrap_content">
<ImageView android:layout_width="wrap_content" android:src="@drawable/ic_menu_archive"
android:id="@+id/imageView1" android:layout_height="wrap_content"
android:layout_marginLeft="15dip" android:focusable="false"
android:focusableInTouchMode="false"></ImageView>
<TextView android:layout_height="wrap_content"
android:textColor="#303030" android:layout_width="wrap_content"
android:text="TextView" android:layout_marginLeft="5dip"
android:layout_marginBottom="5dip" android:layout_marginRight="30dip"
android:id="@+id/Filename" android:focusable="false"
android:focusableInTouchMode="false" android:textSize="20dip">
</TextView>
</LinearLayout>

27
res/layout/main.xml Normal file
View file

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:background="#F7F7F7"
android:orientation="vertical" android:layout_height="fill_parent">
<LinearLayout android:layout_width="fill_parent"
android:id="@+id/linearLayout7" android:orientation="vertical"
android:background="#1D2D44" android:gravity="top"
android:layout_gravity="center_vertical" android:layout_height="wrap_content" android:paddingTop="2pt" android:paddingBottom="2pt">
<ImageView android:layout_height="wrap_content"
android:src="@drawable/owncloud_logo_small_white"
android:layout_width="wrap_content" android:layout_gravity="center_vertical|center_horizontal"
android:id="@+id/main_header_small"></ImageView>
</LinearLayout>
<LinearLayout android:layout_height="wrap_content"
android:id="@+id/linearLayout1" android:layout_width="fill_parent"
android:layout_gravity="center_horizontal" android:gravity="center_horizontal">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="@+id/directory_name"
android:layout_gravity="center" android:gravity="center"></TextView>
</LinearLayout>
<FrameLayout android:layout_height="fill_parent"
android:layout_width="fill_parent" android:id="@+id/frameLayout1">
<ListView android:id="@android:id/list" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:divider="@drawable/uploader_list_separator"
android:dividerHeight="1dip" android:fadingEdge="none"></ListView>
</FrameLayout>
</LinearLayout>

40
res/layout/popup.xml Normal file
View file

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<ScrollView
android:id="@+id/scroller"
android:layout_marginTop="16dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/popup"
android:fadingEdgeLength="5dip"
android:scrollbars="none">
<LinearLayout
android:id="@+id/tracks"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:padding="10dip"/>
</ScrollView >
<ImageView
android:id="@+id/arrow_up"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/arrow_up" />
<ImageView
android:id="@+id/arrow_down"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="-4dip"
android:src="@drawable/arrow_down" android:layout_below="@+id/scroller"/>
</RelativeLayout>

View file

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content" android:orientation="vertical"
android:layout_width="wrap_content" android:background="#fefefe"
android:gravity="center">
<TextView android:layout_width="fill_parent" android:text="Choose upload directory"
android:layout_height="wrap_content" android:id="@+id/textView1" android:textColor="@android:color/black"
android:gravity="center_horizontal"></TextView>
<FrameLayout android:layout_height="fill_parent"
android:layout_width="fill_parent" android:id="@+id/frameLayout1"
android:layout_below="@+id/textView1" android:layout_above="@+id/linearLayout1">
<ListView android:id="@android:id/list" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:divider="@drawable/uploader_list_separator"
android:dividerHeight="1dip"></ListView>
</FrameLayout>
<LinearLayout android:id="@+id/linearLayout1"
android:layout_width="fill_parent" android:layout_alignParentBottom="true" android:layout_height="wrap_content" android:orientation="vertical">
<Button android:layout_gravity="bottom" android:layout_height="wrap_content"
android:layout_width="fill_parent" android:id="@+id/uploader_choose_folder"
android:text="@string/uploader_btn_upload_text"></Button>
</LinearLayout>
</RelativeLayout>

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#fefefe">
<ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_menu_archive" android:id="@+id/imageView1"></ImageView>
<TextView android:text="TextView" android:layout_width="fill_parent" android:id="@+id/textView1" android:layout_height="wrap_content" android:textColor="@android:color/black" android:textSize="20dip"/>
</LinearLayout>

6
res/menu/menu.xml Normal file
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:title="Settings" android:icon="@android:drawable/ic_menu_preferences" android:id="@+id/settingsItem"></item>
<item android:id="@+id/item1" android:title="Create Directory" android:icon="@android:drawable/ic_menu_add"></item>
</menu>

5
res/menu/prefs_menu.xml Normal file
View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/addSessionItem" android:icon="@+android:drawable/ic_menu_add" android:title="@string/prefs_add_session"></item>
</menu>

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/SessionContextEdit" android:title="Edit"></item>
<item android:id="@+id/SessionContextRemove" android:title="REmove"></item>
</menu>

39
res/values/strings.xml Normal file
View file

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello World, OwnCloudMainScreen!</string>
<string name="app_name">ownCloud</string>
<string name="main_password">Password:</string>
<string name="main_login">Username:</string>
<string name="main_button_login">Login</string>
<string name="prefs_general">General</string>
<string name="prefs_sessions">Stored sessions</string>
<string name="prefs_add_session">Add new session</string>
<string name="new_session_id">Session Name</string>
<string name="new_session_url">URL</string>
<string name="new_session_username">Username</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_session_name_error">Wrong session name</string>
<string name="sync_string">filelist and pinned files</string>
<string name="uploader_no_file_selected">No file selected for upload</string>
<string name="setup_hint_username">Username</string>
<string name="setup_hint_password">Password</string>
<string name="setup_hint_address">Web address</string>
<string name="setup_title">Connect to your ownCloud</string>
<string name="setup_btn_connect">Connect</string>
<string name="uploader_btn_upload_text">Upload</string>
<string name="uploader_wrn_no_account_title">No account found</string>
<string name="uploader_wrn_no_account_text">No correct ownCloud account found on device. Please setup account first.</string>
<string name="uploader_wrn_no_account_setup_btn_text">Setup</string>
<string name="uploader_wrn_no_account_quit_btn_text">Quit</string>
<string name="uploader_info_uploading">Uploading</string>
<string name="uploader_btn_create_dir_text">Create dir for upload</string>
<string name="common_ok">OK</string>
<string name="common_cancel">Cancel</string>
<string name="uploader_info_dirname">Directory name</string>
<string name="uploader_upload_succeed">Uploading completed successfully</string>
<string name="uploader_upload_failed">Upload failed: </string>
<string name="common_choose_account">Choose account</string>
</resources>

52
res/values/styles.xml Normal file
View file

@ -0,0 +1,52 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Animations" />
<!-- PopDownMenu -->
<style name="Animations.PopDownMenu" />
<style name="Animations.PopDownMenu.Center">
<item name="@android:windowEnterAnimation">@anim/grow_from_top</item>
<item name="@android:windowExitAnimation">@anim/shrink_from_bottom</item>
</style>
<style name="Animations.PopDownMenu.Left">
<item name="@android:windowEnterAnimation">@anim/grow_from_topleft_to_bottomright</item>
<item name="@android:windowExitAnimation">@anim/shrink_from_bottomright_to_topleft</item>
</style>
<style name="Animations.PopDownMenu.Right">
<item name="@android:windowEnterAnimation">@anim/grow_from_topright_to_bottomleft</item>
<item name="@android:windowExitAnimation">@anim/shrink_from_bottomleft_to_topright</item>
</style>
<style name="Animations.PopDownMenu.Reflect">
<item name="@android:windowEnterAnimation">@anim/pump_top</item>
<item name="@android:windowExitAnimation">@anim/disappear</item>
</style>
<!-- PopUpMenu -->
<style name="Animations.PopUpMenu" />
<style name="Animations.PopUpMenu.Center">
<item name="@android:windowEnterAnimation">@anim/grow_from_bottom</item>
<item name="@android:windowExitAnimation">@anim/shrink_from_top</item>
</style>
<style name="Animations.PopUpMenu.Left">
<item name="@android:windowEnterAnimation">@anim/grow_from_bottomleft_to_topright</item>
<item name="@android:windowExitAnimation">@anim/shrink_from_topright_to_bottomleft</item>
</style>
<style name="Animations.PopUpMenu.Right">
<item name="@android:windowEnterAnimation">@anim/grow_from_bottomright_to_topleft</item>
<item name="@android:windowExitAnimation">@anim/shrink_from_topleft_to_bottomright</item>
</style>
<style name="Animations.PopUpMenu.Reflect">
<item name="@android:windowEnterAnimation">@anim/pump_bottom</item>
<item name="@android:windowExitAnimation">@anim/disappear</item>
</style>
<color name="setup_text_hint">#777777</color>
<color name="setup_text_typed">#000000</color>
</resources>

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<account-authenticator xmlns:android="http://schemas.android.com/apk/res/android"
android:accountType="owncloud"
android:icon="@drawable/icon"
android:label="@string/app_name"
android:smallIcon="@drawable/icon">
</account-authenticator>

30
res/xml/contacts.xml Normal file
View file

@ -0,0 +1,30 @@
<?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.
*/
-->
<ContactsSource xmlns:android="http://schemas.android.com/apk/res/android">
<ContactsDataKind
android:mimeType="vnd.android.cursor.item/vnd.samplesyncadapter.profile"
android:icon="@drawable/icon"
android:summaryColumn="data2"
android:detailColumn="data3"
android:detailSocialSummary="true"
android:syncable="true"/>
</ContactsSource>

4
res/xml/preferences.xml Normal file
View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<CheckBoxPreference android:title="Create images thumbnails" android:key="create_thumbnails"></CheckBoxPreference>
</PreferenceScreen>

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android">
<EditTextPreference></EditTextPreference>
<EditTextPreference></EditTextPreference>
</PreferenceScreen>

27
res/xml/syncadapter.xml Normal file
View file

@ -0,0 +1,27 @@
<?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.
*/
-->
<!-- The attributes in this XML file provide configuration information -->
<!-- for the SyncAdapter. -->
<sync-adapter xmlns:android="http://schemas.android.com/apk/res/android"
android:contentAuthority="org.owncloud"
android:accountType="owncloud"
android:supportsUploading="true"
/>

View file

@ -0,0 +1,37 @@
package eu.alefzero.owncloud;
import android.graphics.drawable.Drawable;
import android.view.View.OnClickListener;
public class ActionItem {
private Drawable mIcon;
private String mTitle;
private OnClickListener mClickListener;
public ActionItem() { }
public void setTitle(String title) {
mTitle = title;
}
public String getTitle() {
return mTitle;
}
public void setIcon(Drawable icon) {
mIcon = icon;
}
public Drawable getIcon() {
return mIcon;
}
public void setOnClickListener(OnClickListener listener) {
mClickListener = listener;
}
public OnClickListener getOnClickListerner() {
return mClickListener;
}
}

View file

@ -0,0 +1,126 @@
package eu.alefzero.owncloud;
import android.content.Context;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.view.View.OnTouchListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.PopupWindow;
public class CustomPopup {
protected final View mAnchor;
protected final PopupWindow mWindow;
private View root;
private Drawable background = null;
protected final WindowManager mWManager;
public CustomPopup(View anchor) {
mAnchor = anchor;
mWindow = new PopupWindow(anchor.getContext());
mWindow.setTouchInterceptor(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
CustomPopup.this.dismiss();
return true;
}
return false;
}
});
mWManager = (WindowManager) anchor.getContext().getSystemService(Context.WINDOW_SERVICE);
onCreate();
}
public void onCreate() {}
public void onShow() {}
public void preShow() {
if (root == null) {
throw new IllegalStateException("setContentView called with a view to display");
}
onShow();
if (background == null) {
mWindow.setBackgroundDrawable(new BitmapDrawable());
} else {
mWindow.setBackgroundDrawable(background);
}
mWindow.setWidth(WindowManager.LayoutParams.WRAP_CONTENT);
mWindow.setHeight(WindowManager.LayoutParams.WRAP_CONTENT);
mWindow.setTouchable(true);
mWindow.setFocusable(true);
mWindow.setOutsideTouchable(true);
mWindow.setContentView(root);
}
public void setBackgroundDrawable(Drawable background) {
this.background = background;
}
public void setContentView(View root) {
this.root = root;
mWindow.setContentView(root);
}
public void setContentView(int layoutResId) {
LayoutInflater inflater =
(LayoutInflater) mAnchor.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
setContentView(inflater.inflate(layoutResId, null));
}
public void showDropDown() {
showDropDown(0, 0);
}
public void showDropDown(int x, int y) {
preShow();
mWindow.setAnimationStyle(android.R.style.Animation_Dialog);
mWindow.showAsDropDown(mAnchor, x, y);
}
public void showLikeQuickAction() {
showLikeQuickAction(0, 0);
}
public void showLikeQuickAction(int x, int y) {
preShow();
mWindow.setAnimationStyle(android.R.style.Animation_Dialog);
int[] location = new int[2];
mAnchor.getLocationOnScreen(location);
Rect anchorRect =
new Rect(location[0], location[1], location[0] + mAnchor.getWidth(), location[1] + mAnchor.getHeight());
root.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
root.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
int rootW = root.getWidth(), rootH = root.getHeight();
int screenW = mWManager.getDefaultDisplay().getWidth();
int xpos = ((screenW-rootW)/2) + x;
int ypos = anchorRect.top - rootH + y;
if (rootH > anchorRect.top) {
ypos = anchorRect.bottom + y;
}
mWindow.showAtLocation(mAnchor, Gravity.NO_GRAVITY, xpos, ypos);
}
public void dismiss() {
mWindow.dismiss();
}
}

View file

@ -0,0 +1,79 @@
package eu.alefzero.owncloud;
import java.util.Vector;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class DbHandler {
private SQLiteDatabase mDB;
private OpenerHepler mHelper;
private final String mDatabaseName = "ownCloud";
private final String TABLE_SESSIONS = "sessions";
private final int mDatabaseVersion = 1;
public DbHandler(Context context) {
mHelper = new OpenerHepler(context);
mDB = mHelper.getWritableDatabase();
}
public Vector<OwnCloudSession> getSessionList() {
Cursor c = mDB.query(TABLE_SESSIONS, null, null, null, null, null, null);
Vector<OwnCloudSession> v = new Vector<OwnCloudSession>();
if (!c.moveToFirst()) {
return v;
}
while (!c.isAfterLast()) {
v.add(new OwnCloudSession(c.getString(c.getColumnIndex("sessionName")),
c.getString(c.getColumnIndex("sessionUrl")),
c.getInt(c.getColumnIndex("_id"))));
c.moveToNext();
}
c.close();
return v;
}
public void addSession(String sessionName, String uri) {
ContentValues cv = new ContentValues();
cv.put("sessionName", sessionName);
cv.put("sessionUrl", uri);
mDB.insert(TABLE_SESSIONS, null, cv);
}
public void removeSessionWithId(int sessionId) {
mDB.delete(TABLE_SESSIONS, "_id = ?", new String[] {String.valueOf(sessionId)});
}
public void changeSessionFields(int id, String hostname, String uri) {
ContentValues cv = new ContentValues();
cv.put("sessionName", hostname);
cv.put("sessionUrl", uri);
mDB.update(TABLE_SESSIONS, cv, "_id = ?", new String[] {String.valueOf(id)});
}
public void close() {
mDB.close();
}
private class OpenerHepler extends SQLiteOpenHelper {
public OpenerHepler(Context context) {
super(context, mDatabaseName, null, mDatabaseVersion);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + TABLE_SESSIONS + " (" +
" _id INTEGER PRIMARY KEY, " +
" sessionName TEXT, " +
" sessionUrl TEXT);");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
}

View file

@ -0,0 +1,60 @@
/* 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.owncloud;
import java.util.HashMap;
public class DisplayUtils {
public static String bitsToHumanReadable(long bitsLen) {
double result = bitsLen;
int attachedsuff = 0;
while (result > 1024 && attachedsuff < suffixes.length) {
result /= 1024.;
attachedsuff++;
}
result = ((int)(result * 100))/100.;
return result+suffixes[attachedsuff];
}
public static String convertMIMEtoPrettyPrint(String mimetype) {
if (mimeType2HUmanReadable.containsKey(mimetype)) {
return mimeType2HUmanReadable.get(mimetype);
}
return mimetype.split("/")[1].toUpperCase() + " file";
}
private static final String[] suffixes = {"B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"};
private static HashMap<String, String> mimeType2HUmanReadable;
static {
mimeType2HUmanReadable = new HashMap<String, String>();
// images
mimeType2HUmanReadable.put("image/jpeg", "JPEG image");
mimeType2HUmanReadable.put("image/jpg", "JPEG image");
mimeType2HUmanReadable.put("image/png", "PNG image");
mimeType2HUmanReadable.put("image/bmp", "Bitmap image");
mimeType2HUmanReadable.put("image/gif", "GIF image");
mimeType2HUmanReadable.put("image/svg+xml", "JPEG image");
mimeType2HUmanReadable.put("image/tiff", "TIFF image");
// music
mimeType2HUmanReadable.put("audio/mpeg", "MP3 music file");
mimeType2HUmanReadable.put("application/ogg", "OGG music file");
}
}

View file

@ -0,0 +1,158 @@
/* 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.owncloud;
import java.io.File;
import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
import eu.alefzero.owncloud.db.ProviderMeta;
import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.DataSetObserver;
import android.net.Uri;
import android.provider.MediaStore.Images.Media;
import android.sax.StartElementListener;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.ListAdapter;
import android.widget.TextView;
public class FileListActionListAdapter implements ListAdapter {
private Context mContext;
private Account mAccount;
private String mFilename, mFileType, mFilePath, mFileStoragePath, mItemId;
private final int ITEM_DOWNLOAD = 0;
private final int ITEM_SHARE = 1;
public FileListActionListAdapter(Cursor c, Context co, Account account) {
mContext = co;
mFilename = c.getString(c.getColumnIndex(ProviderTableMeta.FILE_NAME));
mFileType = c.getString(c.getColumnIndex(ProviderTableMeta.FILE_CONTENT_TYPE));
mFilePath = c.getString(c.getColumnIndex(ProviderTableMeta.FILE_PATH));
mFileStoragePath = c.getString(c.getColumnIndex(ProviderTableMeta.FILE_STORAGE_PATH));
mItemId = c.getString(c.getColumnIndex(ProviderTableMeta._ID));
mAccount = account;
}
public boolean areAllItemsEnabled() {
// TODO Auto-generated method stub
return true;
}
public boolean isEnabled(int position) {
// TODO Auto-generated method stub
return true;
}
public int getCount() {
// TODO Auto-generated method stub
return 1;
}
public Object getItem(int position) {
if (position == 0) {
AccountManager accm = (AccountManager) mContext.getSystemService(Context.ACCOUNT_SERVICE);
String ocurl = accm.getUserData(mAccount, AccountAuthenticator.KEY_OC_URL);
ocurl += mFilePath + mFilename;
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(mFileStoragePath)), mFileType);
return intent;
}
return null;
}
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
public int getItemViewType(int position) {
// TODO Auto-generated method stub
return 0;
}
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.file_display_action_list_element, null);
}
TextView tv;
ImageView iv;
switch (position) {
case ITEM_DOWNLOAD :
tv = (TextView) v.findViewById(R.id.textView1);
if (mFileStoragePath == null) {
tv.setText("Download");
} else {
setActionName(tv);
}
iv = (ImageView) v.findViewById(R.id.imageView1);
iv.setImageResource(R.drawable.download);
break;
}
return v;
}
public int getViewTypeCount() {
// TODO Auto-generated method stub
return 2;
}
public boolean hasStableIds() {
// TODO Auto-generated method stub
return false;
}
public boolean isEmpty() {
// TODO Auto-generated method stub
return false;
}
public void registerDataSetObserver(DataSetObserver observer) {
// TODO Auto-generated method stub
}
public void unregisterDataSetObserver(DataSetObserver observer) {
// TODO Auto-generated method stub
}
private void setActionName(TextView tv) {
if (mFileType.matches("image/.*")) {
tv.setText("View");
} else if (mFileType.matches("audio/.*") || mFileType.matches("video/.*")) {
tv.setText("Play");
} else {
tv.setText("Open");
}
}
}

View file

@ -0,0 +1,103 @@
package eu.alefzero.owncloud;
import java.security.Provider;
import eu.alefzero.owncloud.db.ProviderMeta;
import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta;
import android.content.Context;
import android.database.Cursor;
import android.database.DataSetObserver;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnLongClickListener;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.ListAdapter;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;
public class FileListListAdapter implements ListAdapter {
private Cursor mCursor;
private Context mContext;
public FileListListAdapter(Cursor c, Context context) {
mCursor = c;
mContext = context;
}
public boolean areAllItemsEnabled() {
return true;
}
public boolean isEnabled(int position) {
// TODO Auto-generated method stub
return true;
}
public int getCount() {
// TODO Auto-generated method stub
return mCursor.getCount();
}
public Object getItem(int position) {
// TODO Auto-generated method stub
return null;
}
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
public int getItemViewType(int position) {
// TODO Auto-generated method stub
return 0;
}
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.list_layout, null);
}
if (mCursor.moveToPosition(position)) {
TextView tv = (TextView) v.findViewById(R.id.Filename);
tv.setText(mCursor.getString(mCursor.getColumnIndex(ProviderMeta.ProviderTableMeta.FILE_NAME)));
if (!mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_CONTENT_TYPE)).equals("DIR")) {
ImageView iv = (ImageView) v.findViewById(R.id.imageView1);
iv.setImageResource(R.drawable.file);
}
}
return v;
}
public int getViewTypeCount() {
// TODO Auto-generated method stub
return 4;
}
public boolean hasStableIds() {
// TODO Auto-generated method stub
return true;
}
public boolean isEmpty() {
// TODO Auto-generated method stub
return false;
}
public void registerDataSetObserver(DataSetObserver observer) {
// TODO Auto-generated method stub
}
public void unregisterDataSetObserver(DataSetObserver observer) {
// TODO Auto-generated method stub
}
}

View file

@ -0,0 +1,281 @@
/* 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.owncloud;
import java.util.Stack;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ListActivity;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.DialogInterface.OnCancelListener;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.net.Uri;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta;
public class OwnCloudMainScreen extends ListActivity {
private DbHandler mDBHandler;
private Stack<String> mParents;
private Account mAccount;
private Cursor mCursor;
private boolean mIsDisplayingFile;
private static final int DIALOG_CHOOSE_ACCOUNT = 0;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mParents = new Stack<String>();
mIsDisplayingFile = false;
mDBHandler = new DbHandler(getBaseContext());
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
AccountManager accMan = AccountManager.get(this);
Account[] accounts = accMan.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE);
if (accounts.length == 0) {
// using string value since in API7 this constatn is not defined
// in API7 < this constatant is defined in Settings.ADD_ACCOUNT_SETTINGS
// and Settings.EXTRA_AUTHORITIES
Intent intent = new Intent("android.settings.ADD_ACCOUNT_SETTINGS");
intent.putExtra("authorities", new String[] {AccountAuthenticator.AUTH_TOKEN_TYPE});
startActivity(intent);
} else if (accounts.length > 1) {
showDialog(DIALOG_CHOOSE_ACCOUNT);
} else {
mAccount = accounts[0];
populateFileList();
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.settingsItem :
Intent i = new Intent(this, Preferences.class);
startActivity(i);
break;
}
return true;
}
@Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case DIALOG_CHOOSE_ACCOUNT:
return createChooseAccountDialog();
default:
throw new IllegalArgumentException("Unknown dialog id: " + id);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
return true;
}
@Override
protected void onDestroy() {
mDBHandler.close();
super.onDestroy();
}
private Dialog createChooseAccountDialog() {
final AccountManager accMan = AccountManager.get(this);
CharSequence[] items = new CharSequence[accMan.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE).length];
int i = 0;
for (Account a : accMan.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE)) {
items[i++] = a.name;
}
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.common_choose_account);
builder.setCancelable(true);
builder.setItems(items, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
mAccount = accMan.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE)[item];
dialog.dismiss();
populateFileList();
}
});
builder.setOnCancelListener(new OnCancelListener() {
public void onCancel(DialogInterface dialog) {
OwnCloudMainScreen.this.finish();
}
});
AlertDialog alert = builder.create();
return alert;
}
@Override
public void onBackPressed() {
if (mIsDisplayingFile) {
mIsDisplayingFile = false;
setContentView(R.layout.main);
Uri uri;
if (mParents.empty()) {
uri = ProviderTableMeta.CONTENT_URI;
} else {
uri = Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_DIR, mParents.peek());
}
mCursor = managedQuery(uri,
null,
ProviderTableMeta.FILE_ACCOUNT_OWNER+"=?",
new String[]{mAccount.name}, null);
if (mCursor.moveToFirst()) {
TextView tv = (TextView) findViewById(R.id.directory_name);
tv.setText(mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_PATH)));
}
getListView().setAdapter(new FileListListAdapter(mCursor, this));
getListView().invalidate();
return;
}
if (mParents.size()==0) {
super.onBackPressed();
return;
} else if (mParents.size() == 1) {
mParents.pop();
mCursor = managedQuery(ProviderTableMeta.CONTENT_URI,
null,
ProviderTableMeta.FILE_ACCOUNT_OWNER+"=?",
new String[]{mAccount.name},
null);
} else {
mParents.pop();
mCursor = managedQuery(Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_DIR, mParents.peek()),
null,
ProviderTableMeta.FILE_ACCOUNT_OWNER+"=?",
new String[]{mAccount.name},
null);
}
setListAdapter(new FileListListAdapter(mCursor, this));
getListView().invalidate();
TextView tv = (TextView) findViewById(R.id.directory_name);
String s = tv.getText().toString();
if (s.endsWith("/")) {
s = s.substring(0, s.length() - 1);
}
s = s.substring(0, s.lastIndexOf('/') + 1);
tv.setText(s);
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
if (!mCursor.moveToPosition(position)) {
throw new IndexOutOfBoundsException("Incorrect item selected");
}
if (!mIsDisplayingFile) {
if (mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_CONTENT_TYPE)).equals("DIR")) {
String id_ = mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta._ID));
String dirname = mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_NAME));
TextView tv = (TextView) findViewById(R.id.directory_name);
tv.setText(tv.getText().toString()+dirname+"/");
mParents.push(id_);
mCursor = managedQuery(Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_DIR, id_),
null,
ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",
new String[]{mAccount.name}, null);
setListAdapter(new FileListListAdapter(mCursor, this));
} else {
mIsDisplayingFile = true;
setContentView(R.layout.file_display);
String id_ = mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta._ID));
mCursor = managedQuery(Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_FILE, id_),
null,
null,
null,
null);
mCursor.moveToFirst();
// filename
TextView tv = (TextView) findViewById(R.id.textView1);
tv.setText(mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_NAME)));
// filetype
tv = (TextView) findViewById(R.id.textView2);
tv.setText(DisplayUtils.convertMIMEtoPrettyPrint(mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_CONTENT_TYPE))));
// size
tv = (TextView) findViewById(R.id.textView3);
tv.setText(DisplayUtils.bitsToHumanReadable(mCursor.getLong(mCursor.getColumnIndex(ProviderTableMeta.FILE_CONTENT_LENGTH))));
// modified
tv = (TextView) findViewById(R.id.textView4);
tv.setText(mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_MODIFIED)));
if (!TextUtils.isEmpty(mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_STORAGE_PATH)))) {
ImageView iv = (ImageView) findViewById(R.id.imageView1);
Bitmap bmp = BitmapFactory.decodeFile(mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_STORAGE_PATH)));
Matrix m = new Matrix();
float scale;
if (bmp.getWidth() > bmp.getHeight()) {
scale = (float) (200./bmp.getWidth());
} else {
scale = (float) (200./bmp.getHeight());
}
m.postScale(scale, scale);
Bitmap newBmp = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), m, true);
iv.setImageBitmap(newBmp);
}
setListAdapter(new FileListActionListAdapter(mCursor, this, mAccount));
}
getListView().invalidate();
} else {
try {
Intent i = (Intent) getListAdapter().getItem(position);
startActivity(i);
} catch (ClassCastException e) {}
}
}
private void populateFileList() {
TextView tv = (TextView) findViewById(R.id.directory_name);
tv.setText("/");
mCursor = getContentResolver().query(ProviderTableMeta.CONTENT_URI,
null,
ProviderTableMeta.FILE_ACCOUNT_OWNER+"=?",
new String[]{mAccount.name},
null);
setListAdapter(new FileListListAdapter(mCursor, this));
getListView().invalidate();
}
}

View file

@ -0,0 +1,33 @@
package eu.alefzero.owncloud;
public class OwnCloudSession {
private String mSessionName;
private String mSessionUrl;
private int mEntryId;
public OwnCloudSession(String name, String url, int entryId) {
mSessionName = name;
mSessionUrl = url;
mEntryId = entryId;
}
public void setName(String name) {
mSessionName = name;
}
public String getName() {
return mSessionName;
}
public void setUrl(String url) {
mSessionUrl = url;
}
public String getUrl() {
return mSessionUrl;
}
public int getEntryId() {
return mEntryId;
}
}

View file

@ -0,0 +1,495 @@
package eu.alefzero.owncloud;
import java.io.File;
import java.sql.Date;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Stack;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.FileEntity;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.BasicHttpContext;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.app.AlertDialog.Builder;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.DialogInterface.OnCancelListener;
import android.content.DialogInterface.OnClickListener;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Parcelable;
import android.provider.MediaStore.Images.Media;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.ViewGroup.LayoutParams;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
import eu.alefzero.owncloud.db.ProviderMeta;
import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta;
import eu.alefzero.webdav.HttpMkCol;
import eu.alefzero.webdav.WebdavUtils;
public class OwnCloudUploader extends ListActivity implements OnItemClickListener, android.view.View.OnClickListener {
private static final String TAG = "ownCloudUploader";
private Account mAccount;
private AccountManager mAccountManager;
private String mUsername, mPassword;
private Cursor mCursor;
private Stack<String> mParents;
private Thread mUploadThread;
private Handler mHandler;
private ArrayList<Parcelable> mStreamsToUpload;
private final static int DIALOG_NO_ACCOUNT = 0;
private final static int DIALOG_WAITING = 1;
private final static int DIALOG_NO_STREAM = 2;
private final static int DIALOG_MULTIPLE_ACCOUNT = 3;
private final static int DIALOG_GET_DIRNAME = 4;
private final static int REQUEST_CODE_SETUP_ACCOUNT = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().requestFeature(Window.FEATURE_NO_TITLE);
mParents = new Stack<String>();
mHandler = new Handler();
if (getIntent().hasExtra(Intent.EXTRA_STREAM)) {
prepareStreamsToUpload();
mAccountManager = (AccountManager)getSystemService(Context.ACCOUNT_SERVICE);
Account[] accounts = mAccountManager.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE);
if (accounts.length == 0) {
Log.i(TAG, "No ownCloud account is available");
showDialog(DIALOG_NO_ACCOUNT);
} else if (accounts.length > 1) {
Log.i(TAG, "More then one ownCloud is available");
showDialog(DIALOG_MULTIPLE_ACCOUNT);
} else {
mAccount = accounts[0];
setContentView(R.layout.uploader_layout);
populateDirectoryList();
}
} else {
showDialog(DIALOG_NO_STREAM);
}
}
@Override
protected Dialog onCreateDialog(final int id) {
final AlertDialog.Builder builder = new Builder(this);
switch (id) {
case DIALOG_WAITING:
ProgressDialog pDialog = new ProgressDialog(this);
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.setMessage(getResources().getString(R.string.uploader_info_uploading));
return pDialog;
case DIALOG_NO_ACCOUNT:
builder.setIcon(android.R.drawable.ic_dialog_alert);
builder.setTitle(R.string.uploader_wrn_no_account_title);
builder.setMessage(R.string.uploader_wrn_no_account_text);
builder.setCancelable(false);
builder.setPositiveButton(R.string.uploader_wrn_no_account_setup_btn_text, new OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.ECLAIR_MR1) {
// using string value since in API7 this constatn is not defined
// in API7 < this constatant is defined in Settings.ADD_ACCOUNT_SETTINGS
// and Settings.EXTRA_AUTHORITIES
Intent intent = new Intent("android.settings.ADD_ACCOUNT_SETTINGS");
intent.putExtra("authorities", new String[] {AccountAuthenticator.AUTH_TOKEN_TYPE});
startActivityForResult(intent, REQUEST_CODE_SETUP_ACCOUNT);
} else {
// since in API7 there is no direct call for account setup, so we need to
// show our own AccountSetupAcricity, get desired results and setup
// everything for ourself
Intent intent = new Intent(getBaseContext(), AccountAuthenticator.class);
startActivityForResult(intent, REQUEST_CODE_SETUP_ACCOUNT);
}
}
});
builder.setNegativeButton(R.string.uploader_wrn_no_account_quit_btn_text, new OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
finish();
}
});
return builder.create();
case DIALOG_GET_DIRNAME:
final EditText dirName = new EditText(getBaseContext());
builder.setView(dirName);
builder.setTitle(R.string.uploader_info_dirname);
String pathToUpload;
if (mParents.empty()) {
pathToUpload = "/";
} else {
mCursor = managedQuery(Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_FILE, mParents.peek()),
null,
null,
null,
null);
mCursor.moveToFirst();
pathToUpload = mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_PATH)) +
mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_NAME)).replace(" ", "%20");
}
a a = new a(pathToUpload, dirName);
builder.setPositiveButton(R.string.common_ok, a);
builder.setNegativeButton(R.string.common_cancel, new OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
return builder.create();
case DIALOG_MULTIPLE_ACCOUNT:
CharSequence ac[] = new CharSequence[mAccountManager.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE).length];
for (int i = 0; i < ac.length; ++i) {
ac[i] = mAccountManager.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE)[i].name;
}
builder.setTitle(R.string.common_choose_account);
builder.setItems(ac, new OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
mAccount = mAccountManager.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE)[which];
populateDirectoryList();
}
});
builder.setCancelable(true);
builder.setOnCancelListener(new OnCancelListener() {
public void onCancel(DialogInterface dialog) {
dialog.cancel();
finish();
}
});
return builder.create();
default:
throw new IllegalArgumentException("Unknown dialog id: " + id);
}
}
class a implements OnClickListener {
String mPath;
EditText mDirname;
public a(String path, EditText dirname) {
mPath = path; mDirname = dirname;
}
public void onClick(DialogInterface dialog, int which) {
showDialog(DIALOG_WAITING);
mUploadThread = new Thread(new BackgroundUploader(mPath+mDirname.getText().toString(), mStreamsToUpload, mHandler, true));
mUploadThread.start();
}
}
@Override
public void onBackPressed() {
if (mParents.size()==0) {
super.onBackPressed();
return;
} else if (mParents.size() == 1) {
mParents.pop();
mCursor = managedQuery(ProviderTableMeta.CONTENT_URI,
null,
ProviderTableMeta.FILE_CONTENT_TYPE+"=?",
new String[]{"DIR"},
null);
} else {
mParents.pop();
mCursor = managedQuery(Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_DIR, mParents.peek()),
null,
ProviderTableMeta.FILE_CONTENT_TYPE+"=?",
new String[]{"DIR"},
null);
}
SimpleCursorAdapter sca = new SimpleCursorAdapter(this, R.layout.uploader_list_item_layout,
mCursor,
new String[]{ProviderTableMeta.FILE_NAME},
new int[]{R.id.textView1});
setListAdapter(sca);
}
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (!mCursor.moveToPosition(position)) {
throw new IndexOutOfBoundsException("Incorrect item selected");
}
String _id = mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta._ID));
mParents.push(_id);
mCursor.close();
mCursor = managedQuery(Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_DIR, _id),
null,
ProviderTableMeta.FILE_CONTENT_TYPE+"=?",
new String[]{"DIR"},
null);
SimpleCursorAdapter sca = new SimpleCursorAdapter(this, R.layout.uploader_list_item_layout,
mCursor,
new String[]{ProviderTableMeta.FILE_NAME},
new int[]{R.id.textView1});
setListAdapter(sca);
getListView().invalidate();
}
public void onClick(View v) {
switch (v.getId()) {
case R.id.uploader_choose_folder:
String pathToUpload = null;
if (mParents.empty()) {
pathToUpload = "/";
} else {
mCursor = managedQuery(Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_FILE, mParents.peek()),
null,
null,
null,
null);
mCursor.moveToFirst();
pathToUpload = mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_PATH)) +
mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_NAME)).replace(" ", "%20");
}
showDialog(DIALOG_WAITING);
mUploadThread = new Thread(new BackgroundUploader(pathToUpload, mStreamsToUpload, mHandler));
mUploadThread.start();
break;
case android.R.id.button1: // dynamic action for create aditional dir
showDialog(DIALOG_GET_DIRNAME);
break;
default:
throw new IllegalArgumentException("Wrong element clicked");
}
}
public void onUploadComplete(boolean uploadSucc, String message) {
dismissDialog(DIALOG_WAITING);
Log.i(TAG, "UploadSucc: " + uploadSucc + " message: " + message);
if (uploadSucc) {
Toast.makeText(this, getResources().getString(R.string.uploader_upload_succeed), Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, getResources().getString(R.string.uploader_upload_failed) + message, Toast.LENGTH_LONG).show();
}
finish();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.i(TAG, "result received. req: " + requestCode + " res: " + resultCode);
if (requestCode == REQUEST_CODE_SETUP_ACCOUNT) {
dismissDialog(DIALOG_NO_ACCOUNT);
if (resultCode == RESULT_CANCELED) {
finish();
}
Account[] accounts = mAccountManager.getAccountsByType(AccountAuthenticator.AUTH_TOKEN_TYPE);
if (accounts.length == 0) {
showDialog(DIALOG_NO_ACCOUNT);
} else {
// there is no need for checking for is there more then one account at this point
// since account setup can set only one account at time
mAccount = accounts[0];
populateDirectoryList();
}
}
}
private void populateDirectoryList() {
mUsername = mAccount.name.substring(0, mAccount.name.indexOf('@'));
mPassword = mAccountManager.getPassword(mAccount);
setContentView(R.layout.uploader_layout);
mCursor = managedQuery(ProviderMeta.ProviderTableMeta.CONTENT_URI,
null,
ProviderTableMeta.FILE_CONTENT_TYPE+"=? AND " + ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",
new String[]{"DIR", mAccount.name},
null);
ListView lv = getListView();
lv.setOnItemClickListener(this);
SimpleCursorAdapter sca = new SimpleCursorAdapter(this,
R.layout.uploader_list_item_layout,
mCursor,
new String[]{ProviderTableMeta.FILE_NAME},
new int[]{R.id.textView1});
setListAdapter(sca);
Button btn = (Button) findViewById(R.id.uploader_choose_folder);
btn.setOnClickListener(this);
// insert create new directory for multiple items uploading
if (getIntent().getAction().equals(Intent.ACTION_SEND_MULTIPLE)) {
Button createDirBtn = new Button(this);
createDirBtn.setId(android.R.id.button1);
createDirBtn.setText(R.string.uploader_btn_create_dir_text);
createDirBtn.setOnClickListener(this);
((LinearLayout)findViewById(R.id.linearLayout1)).addView(createDirBtn, LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
}
}
private void prepareStreamsToUpload() {
if (getIntent().getAction().equals(Intent.ACTION_SEND)) {
mStreamsToUpload = new ArrayList<Parcelable>();
mStreamsToUpload.add(getIntent().getParcelableExtra(Intent.EXTRA_STREAM));
} else if (getIntent().getAction().equals(Intent.ACTION_SEND_MULTIPLE)) {
mStreamsToUpload = getIntent().getParcelableArrayListExtra(Intent.EXTRA_STREAM);
} else {
// unknow action inserted
throw new IllegalArgumentException("Unknown action given: " + getIntent().getAction());
}
}
public void PartialupdateUpload(String fileLocalPath, String filename, String filepath, String contentType, String contentLength) {
ContentValues cv = new ContentValues();
cv.put(ProviderTableMeta.FILE_NAME, filename);
cv.put(ProviderTableMeta.FILE_PATH, filepath);
cv.put(ProviderTableMeta.FILE_STORAGE_PATH, fileLocalPath);
cv.put(ProviderTableMeta.FILE_MODIFIED, WebdavUtils.DISPLAY_DATE_FORMAT.format(new java.util.Date()));
cv.put(ProviderTableMeta.FILE_CONTENT_TYPE, contentType);
cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, contentLength);
cv.put(ProviderTableMeta.FILE_ACCOUNT_OWNER, mAccount.name);
Log.d(TAG, filename+" ++ "+filepath+" ++ " + contentLength + " ++ " + contentType + " ++ " + fileLocalPath);
if (!mParents.empty()) {
Cursor c = managedQuery(Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_FILE, mParents.peek()),
null,
null,
null,
null);
c.moveToFirst();
cv.put(ProviderTableMeta.FILE_PARENT, c.getString(c.getColumnIndex(ProviderTableMeta._ID)));
c.close();
}
getContentResolver().insert(ProviderTableMeta.CONTENT_URI_FILE, cv);
}
class BackgroundUploader implements Runnable {
private ArrayList<Parcelable> mUploadStreams;
private Handler mHandler;
private String mUploadPath;
private boolean mCreateDir;
public BackgroundUploader(String pathToUpload, ArrayList<Parcelable> streamsToUpload,
Handler handler) {
mUploadStreams = streamsToUpload;
mHandler = handler;
mUploadPath = pathToUpload.replace(" ", "%20");
mCreateDir = false;
}
public BackgroundUploader(String pathToUpload, ArrayList<Parcelable> streamsToUpload,
Handler handler, boolean createDir) {
mUploadStreams = streamsToUpload;
mHandler = handler;
mUploadPath = pathToUpload.replace(" ", "%20");
mCreateDir = createDir;
}
public void run() {
boolean any_failed = false;
DefaultHttpClient httpClient = new DefaultHttpClient();
Uri uri = Uri.parse(mAccountManager.getUserData(mAccount,
AccountAuthenticator.KEY_OC_URL));
httpClient.getCredentialsProvider().setCredentials(
new AuthScope(uri.getHost(), (uri.getPort() == -1) ? 80 : uri
.getPort()),
new UsernamePasswordCredentials(mUsername, mPassword));
BasicHttpContext httpContext = new BasicHttpContext();
BasicScheme basicAuth = new BasicScheme();
httpContext.setAttribute("preemptive-auth", basicAuth);
HttpHost targetHost = new HttpHost(uri.getHost(), (uri.getPort() == -1)
? 80
: uri.getPort(), (uri.getScheme() == "https") ? "https" : "http");
// create last directory in path if nessesary
if (mCreateDir) {
HttpMkCol method = new HttpMkCol(uri.toString() + mUploadPath + "/");
method.setHeader("User-Agent", "Android-ownCloud");
try {
httpClient.execute(targetHost, method, httpContext);
Log.i(TAG, "Creating dir completed");
} catch (final Exception e) {
e.printStackTrace();
mHandler.post(new Runnable() {
public void run() {
OwnCloudUploader.this.onUploadComplete(false, e.getLocalizedMessage());
}
});
return;
}
}
for (int i = 0; i < mUploadStreams.size(); ++i) {
final Cursor c = getContentResolver().query((Uri)mUploadStreams.get(i), null, null, null, null);
c.moveToFirst();
HttpPut method = new HttpPut(uri.toString() + mUploadPath + "/"
+ c.getString(c.getColumnIndex(Media.DISPLAY_NAME)).replace(" ", "%20"));
method.setHeader("Content-type", c.getString(c.getColumnIndex(Media.MIME_TYPE)));
method.setHeader("User-Agent", "Android-ownCloud");
try {
FileBody fb = new FileBody(new File(c.getString(c.getColumnIndex(Media.DATA))), c.getString(c.getColumnIndex(Media.MIME_TYPE)));
MultipartEntity entity = new MultipartEntity();
final FileEntity fileEntity = new FileEntity(new File(c.getString(c.getColumnIndex(Media.DATA))),
c.getString(c.getColumnIndex(Media.MIME_TYPE)));
entity.addPart(c.getString(c.getColumnIndex(Media.DISPLAY_NAME)).replace(" ", "%20"), fb);
method.setEntity(fileEntity);
Log.i(TAG, "executing:" + method.getRequestLine().toString());
httpClient.execute(targetHost, method, httpContext);
mHandler.post(new Runnable() {
public void run() {
OwnCloudUploader.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");
} catch (final Exception e) {
any_failed = true;
mHandler.post(new Runnable() {
public void run() {
OwnCloudUploader.this.onUploadComplete(false, c.getString(c.getColumnIndex(Media.DISPLAY_NAME))+ " " + e.getLocalizedMessage());
}
});
}
}
if (!any_failed) {
mHandler.post(new Runnable() {
public void run() {
OwnCloudUploader.this.onUploadComplete(true, "Success");
}
});
}
Bundle bundle = new Bundle();
bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
//ContentResolver.requestSync(mAccount, AccountAuthenticator.AUTH_TOKEN_TYPE, bundle);
}
}
}

View file

@ -0,0 +1,139 @@
package eu.alefzero.owncloud;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Vector;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceScreen;
import android.util.Log;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.AdapterView.AdapterContextMenuInfo;
public class Preferences extends PreferenceActivity {
private String TAG = "OwnCloudPreferences";
private final int mNewSession = 47;
private final int mEditSession = 48;
private DbHandler mDbHandler;
private Vector<OwnCloudSession> mSessions;
private int mSelectedMenuItem;
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
mDbHandler = new DbHandler(getBaseContext());
mSessions = new Vector<OwnCloudSession>();
addPreferencesFromResource(R.xml.preferences);
registerForContextMenu(getListView());
//populateSessionList();
}
private void populateSessionList() {
mSessions.clear();
mSessions = mDbHandler.getSessionList();
PreferenceScreen ps = getPreferenceScreen();
ps.removeAll();
addPreferencesFromResource(R.xml.preferences);
for (int i = 0; i < mSessions.size(); i++) {
Preference preference = new Preference(getBaseContext());
preference.setTitle(mSessions.get(i).getName());
URI uri;
try {
uri = new URI(mSessions.get(i).getUrl());
} catch (URISyntaxException e) {
e.printStackTrace(); // should never happend
continue;
}
preference.setSummary(uri.getScheme() + "://" + uri.getHost()+uri.getPath());
ps.addPreference(preference);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.prefs_menu, menu);
return true;
}
@Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
super.onMenuItemSelected(featureId, item);
Intent intent;
switch (item.getItemId()) {
case R.id.addSessionItem:
intent = new Intent(this, PreferencesNewSession.class);
startActivityForResult(intent, mNewSession);
break;
case R.id.SessionContextEdit:
intent = new Intent(this, PreferencesNewSession.class);
intent.putExtra("sessionId", mSessions.get(mSelectedMenuItem).getEntryId());
intent.putExtra("sessionName", mSessions.get(mSelectedMenuItem).getName());
intent.putExtra("sessionURL", mSessions.get(mSelectedMenuItem).getUrl());
startActivityForResult(intent, mEditSession);
break;
case R.id.SessionContextRemove:
OwnCloudSession ocs = mSessions.get(mSelectedMenuItem);
mDbHandler.removeSessionWithId(ocs.getEntryId());
mSessions.remove(ocs);
getPreferenceScreen().removePreference(getPreferenceScreen().getPreference(mSelectedMenuItem+1));
break;
default:
Log.w(TAG, "Unknown menu item triggered");
return false;
}
return true;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
switch (requestCode) {
case mNewSession:
mDbHandler.addSession(data.getStringExtra("sessionName"),
data.getStringExtra("sessionURL"));
getPreferenceScreen().removeAll();
addPreferencesFromResource(R.xml.preferences);
populateSessionList();
break;
case mEditSession:
mDbHandler.changeSessionFields(data.getIntExtra("sessionId", -1),
data.getStringExtra("sessionName"),
data.getStringExtra("sessionURL"));
populateSessionList();
break;
}
}
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
mSelectedMenuItem = info.position-1;
menu.setHeaderTitle(mSessions.get(mSelectedMenuItem).getName());
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.session_context_menu, menu);
}
@Override
protected void onDestroy() {
mDbHandler.close();
super.onDestroy();
}
}

View file

@ -0,0 +1,143 @@
package eu.alefzero.owncloud;
import java.net.URI;
import java.net.URISyntaxException;
import eu.alefzero.owncloud.authenticator.AccountAuthenticatorService;
import android.accounts.Account;
import android.accounts.AccountAuthenticatorActivity;
import android.accounts.AccountManager;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class PreferencesNewSession extends AccountAuthenticatorActivity implements OnClickListener {
private Intent mReturnData;
private final String TAG = "OwnCloudPreferencesNewSession";
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
//setContentView(R.layout.add_new_session);
/*
EditText et;// = (EditText) findViewById(R.id.newSession_sessionName);
et = (EditText) findViewById(R.id.newSession_URL);
if (getIntent().hasExtra("sessionURL")) {
try {
URI uri = new URI(getIntent().getStringExtra("sessionURL"));
String url = uri.getHost();
if (uri.getPort() != -1) {
url += ":" + String.valueOf(uri.getPort());
}
if (uri.getPath() != null) {
url += uri.getPath();
} else {
url += "/";
}
et.setText(url);
et = (EditText) findViewById(R.id.newSession_username);
if (uri.getAuthority() != null) {
if (uri.getUserInfo().indexOf(':') != -1) {
et.setText(uri.getUserInfo().substring(0, uri.getUserInfo().indexOf(':')));
et = (EditText) findViewById(R.id.newSession_password);
et.setText(uri.getUserInfo().substring(uri.getUserInfo().indexOf(':')+1));
} else {
et.setText(uri.getUserInfo());
}
}
} catch (URISyntaxException e) {
Log.e(TAG, "Incorrect URI syntax " + e.getLocalizedMessage());
}
}
mReturnData = new Intent();
setResult(Activity.RESULT_OK, mReturnData);
((Button) findViewById(R.id.button1)).setOnClickListener(this);
((Button) findViewById(R.id.button2)).setOnClickListener(this);*/
}
@Override
protected void onResume() {
super.onResume();
}
public void onClick(View v) {
/* switch (v.getId()) {
case R.id.button1:
Intent intent = new Intent();
if (getIntent().hasExtra("sessionId")) {
intent.putExtra("sessionId", getIntent().getIntExtra("sessionId", -1));
}
//String sessionName = ((EditText) findViewById(R.id.newSession_sessionName)).getText().toString();
// if (sessionName.trim().equals("") || !isNameValid(sessionName)) {
// Toast.makeText(this, R.string.new_session_session_name_error, Toast.LENGTH_LONG).show();
// break;
// }
URI uri = prepareURI();
if (uri != null) {
//intent.putExtra("sessionName", sessionName);
intent.putExtra("sessionURL", uri.toString());
setResult(Activity.RESULT_OK, intent);
AccountManager accMgr = AccountManager.get(this);
Account a = new Account("OwnCloud", AccountAuthenticatorService.ACCOUNT_TYPE);
accMgr.addAccountExplicitly(a, "asd", null);
finish();
}
break;
case R.id.button2:
setResult(Activity.RESULT_CANCELED);
finish();
break;
}*/
}
private URI prepareURI() {
URI uri = null;
/* String url = "";
try {
String username = ((EditText) findViewById(R.id.newSession_username)).getText().toString().trim();
String password = ((EditText) findViewById(R.id.newSession_password)).getText().toString().trim();
String hostname = ((EditText) findViewById(R.id.newSession_URL)).getText().toString().trim();
String scheme;
if (hostname.matches("[A-Za-z]://")) {
scheme = hostname.substring(0, hostname.indexOf("://")+3);
hostname = hostname.substring(hostname.indexOf("://")+3);
} else {
scheme = "http://";
}
if (!username.equals("")) {
if (!password.equals("")) {
username += ":" + password + "@";
} else {
username += "@";
}
}
url = scheme + username + hostname;
Log.i(TAG, url);
uri = new URI(url);
} catch (URISyntaxException e) {
Log.e(TAG, "Incorrect URI syntax " + e.getLocalizedMessage());
Toast.makeText(this, R.string.new_session_uri_error, Toast.LENGTH_LONG).show();
}
*/return uri;
}
private boolean isNameValid(String string) {
return string.matches("[A-Za-z0-9 _-]*");
}
@Override
public void onBackPressed() {
setResult(Activity.RESULT_CANCELED);
super.onBackPressed();
}
}

View file

@ -0,0 +1,267 @@
package eu.alefzero.owncloud;
import android.content.Context;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewGroup;
import java.util.ArrayList;
/**
* Popup window, shows action list as icon and text like the one in Gallery3D app.
*
* @author Lorensius. W. T
*/
public class QuickAction extends CustomPopup {
private final View root;
private final ImageView mArrowUp;
private final ImageView mArrowDown;
private final LayoutInflater inflater;
private final Context context;
protected static final int ANIM_GROW_FROM_LEFT = 1;
protected static final int ANIM_GROW_FROM_RIGHT = 2;
protected static final int ANIM_GROW_FROM_CENTER = 3;
protected static final int ANIM_REFLECT = 4;
protected static final int ANIM_AUTO = 5;
private int animStyle;
private ViewGroup mTrack;
private ScrollView scroller;
private ArrayList<ActionItem> actionList;
/**
* Constructor
*
* @param anchor {@link View} on where the popup window should be displayed
*/
public QuickAction(View anchor) {
super(anchor);
actionList = new ArrayList<ActionItem>();
context = anchor.getContext();
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
root = (ViewGroup) inflater.inflate(R.layout.popup, null);
mArrowDown = (ImageView) root.findViewById(R.id.arrow_down);
mArrowUp = (ImageView) root.findViewById(R.id.arrow_up);
setContentView(root);
mTrack = (ViewGroup) root.findViewById(R.id.tracks);
scroller = (ScrollView) root.findViewById(R.id.scroller);
animStyle = ANIM_AUTO;
}
/**
* Set animation style
*
* @param animStyle animation style, default is set to ANIM_AUTO
*/
public void setAnimStyle(int animStyle) {
this.animStyle = animStyle;
}
/**
* Add action item
*
* @param action {@link ActionItem} object
*/
public void addActionItem(ActionItem action) {
actionList.add(action);
}
/**
* Show popup window. Popup is automatically positioned, on top or bottom of anchor view.
*
*/
public void show () {
preShow();
int xPos, yPos;
int[] location = new int[2];
mAnchor.getLocationOnScreen(location);
Rect anchorRect = new Rect(location[0], location[1], location[0] + mAnchor.getWidth(), location[1]
+ mAnchor.getHeight());
createActionList();
root.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
root.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
int rootHeight = root.getMeasuredHeight();
int rootWidth = root.getMeasuredWidth();
int screenWidth = mWManager.getDefaultDisplay().getWidth();
int screenHeight = mWManager.getDefaultDisplay().getHeight();
//automatically get X coord of popup (top left)
if ((anchorRect.left + rootWidth) > screenWidth) {
xPos = anchorRect.left - (rootWidth-mAnchor.getWidth());
} else {
if (mAnchor.getWidth() > rootWidth) {
xPos = anchorRect.centerX() - (rootWidth/2);
} else {
xPos = anchorRect.left;
}
}
int dyTop = anchorRect.top;
int dyBottom = screenHeight - anchorRect.bottom;
boolean onTop = (dyTop > dyBottom) ? true : false;
if (onTop) {
if (rootHeight > dyTop) {
yPos = 15;
LayoutParams l = scroller.getLayoutParams();
l.height = dyTop - mAnchor.getHeight();
} else {
yPos = anchorRect.top - rootHeight;
}
} else {
yPos = anchorRect.bottom;
if (rootHeight > dyBottom) {
LayoutParams l = scroller.getLayoutParams();
l.height = dyBottom;
}
}
showArrow(((onTop) ? R.id.arrow_down : R.id.arrow_up), anchorRect.centerX()-xPos);
setAnimationStyle(screenWidth, anchorRect.centerX(), onTop);
mWindow.showAtLocation(mAnchor, Gravity.NO_GRAVITY, xPos, yPos);
}
/**
* Set animation style
*
* @param screenWidth screen width
* @param requestedX distance from left edge
* @param onTop flag to indicate where the popup should be displayed. Set TRUE if displayed on top of anchor view
* and vice versa
*/
private void setAnimationStyle(int screenWidth, int requestedX, boolean onTop) {
int arrowPos = requestedX - mArrowUp.getMeasuredWidth()/2;
switch (animStyle) {
case ANIM_GROW_FROM_LEFT:
mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Left : R.style.Animations_PopDownMenu_Left);
break;
case ANIM_GROW_FROM_RIGHT:
mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Right : R.style.Animations_PopDownMenu_Right);
break;
case ANIM_GROW_FROM_CENTER:
mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Center : R.style.Animations_PopDownMenu_Center);
break;
case ANIM_REFLECT:
mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Reflect : R.style.Animations_PopDownMenu_Reflect);
break;
case ANIM_AUTO:
if (arrowPos <= screenWidth/4) {
mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Left : R.style.Animations_PopDownMenu_Left);
} else if (arrowPos > screenWidth/4 && arrowPos < 3 * (screenWidth/4)) {
mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Center : R.style.Animations_PopDownMenu_Center);
} else {
mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Right : R.style.Animations_PopDownMenu_Right);
}
break;
}
}
/**
* Create action list
*/
private void createActionList() {
View view;
String title;
Drawable icon;
OnClickListener listener;
for (int i = 0; i < actionList.size(); i++) {
title = actionList.get(i).getTitle();
icon = actionList.get(i).getIcon();
listener = actionList.get(i).getOnClickListerner();
view = getActionItem(title, icon, listener);
view.setFocusable(true);
view.setClickable(true);
mTrack.addView(view);
}
}
/**
* Get action item {@link View}
*
* @param title action item title
* @param icon {@link Drawable} action item icon
* @param listener {@link View.OnClickListener} action item listener
* @return action item {@link View}
*/
private View getActionItem(String title, Drawable icon, OnClickListener listener) {
LinearLayout container = (LinearLayout) inflater.inflate(R.layout.action_item, null);
ImageView img = (ImageView) container.findViewById(R.id.icon);
TextView text = (TextView) container.findViewById(R.id.title);
if (icon != null) {
img.setImageDrawable(icon);
}
if (title != null) {
text.setText(title);
}
if (listener != null) {
container.setOnClickListener(listener);
}
return container;
}
/**
* Show arrow
*
* @param whichArrow arrow type resource id
* @param requestedX distance from left screen
*/
private void showArrow(int whichArrow, int requestedX) {
final View showArrow = (whichArrow == R.id.arrow_up) ? mArrowUp : mArrowDown;
final View hideArrow = (whichArrow == R.id.arrow_up) ? mArrowDown : mArrowUp;
final int arrowWidth = mArrowUp.getMeasuredWidth();
showArrow.setVisibility(View.VISIBLE);
ViewGroup.MarginLayoutParams param = (ViewGroup.MarginLayoutParams)showArrow.getLayoutParams();
param.leftMargin = requestedX - arrowWidth / 2;
hideArrow.setVisibility(View.INVISIBLE);
}
}

View file

@ -0,0 +1,238 @@
package eu.alefzero.owncloud.authenticator;
import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta;
import android.accounts.AbstractAccountAuthenticator;
import android.accounts.Account;
import android.accounts.AccountAuthenticatorResponse;
import android.accounts.AccountManager;
import android.accounts.NetworkErrorException;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
public class AccountAuthenticator extends AbstractAccountAuthenticator {
public static final String OPTIONS_USERNAME = "username";
public static final String OPTIONS_PASSWORD = "password";
public static final String OPTIONS_FILE_LIST_SYNC_ENABLED = "filelist";
public static final String OPTIONS_PINNED_FILE_SYNC_ENABLED = "pinned";
public static final String ACCOUNT_TYPE = "owncloud";
public static final String AUTH_TOKEN_TYPE = "org.owncloud";
public static final String KEY_AUTH_TOKEN_TYPE = "authTokenType";
public static final String KEY_REQUIRED_FEATURES = "requiredFeatures";
public static final String KEY_LOGIN_OPTIONS = "loginOptions";
public static final String KEY_ACCOUNT = "account";
public static final String KEY_OC_URL = "oc_url";
private Context mContext;
public AccountAuthenticator(Context context) {
super(context);
mContext = context;
}
/**
* {@inheritDoc}
*/
@Override
public Bundle addAccount(AccountAuthenticatorResponse response,
String accountType, String authTokenType, String[] requiredFeatures,
Bundle options) throws NetworkErrorException {
Log.i(getClass().getName(), "Adding account with type " + accountType +
" and auth token " + authTokenType);
try {
validateAccountType(accountType);
//validateAuthTokenType(authTokenType);
validateRequiredFeatures(requiredFeatures);
} catch (AuthenticatorException e) {
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);
Log.i(getClass().getName(), intent.toString());
final Bundle bundle = new Bundle();
bundle.putParcelable(AccountManager.KEY_INTENT, intent);
return bundle;
}
/**
* {@inheritDoc}
*/
@Override
public Bundle confirmCredentials(AccountAuthenticatorResponse response,
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);
Bundle resultBundle = new Bundle();
resultBundle.putParcelable(AccountManager.KEY_INTENT, intent);
return resultBundle;
}
@Override
public Bundle editProperties(AccountAuthenticatorResponse response,
String accountType) {
throw new UnsupportedOperationException();
}
@Override
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 {
// TODO
}
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

@ -0,0 +1,41 @@
/* 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.owncloud.authenticator;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
public class AccountAuthenticatorService extends Service {
private AccountAuthenticator mAuthenticator;
static final public String ACCOUNT_TYPE = "owncloud";
@Override
public void onCreate() {
super.onCreate();
mAuthenticator = new AccountAuthenticator(this);
}
@Override
public IBinder onBind(Intent intent) {
return mAuthenticator.getIBinder();
}
}

View file

@ -0,0 +1,189 @@
/* 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.owncloud.authenticator;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.UnknownHostException;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpHead;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.BasicHttpContext;
import android.content.Context;
import android.os.Handler;
import android.util.Log;
public class AuthUtils {
public static final String WEBDAV_PATH_1_2 = "/webdav/owncloud.php";
public static final String WEBDAV_PATH_2_0 = "/files/webdav.php";
private static String mResultMsg = "";
public static boolean authenticate(URL url, String username, String password,
Handler handler, Context context) {
String strippedPath = url.toString().endsWith("/") ?
url.toString().substring(0, url.toString().length()-1) :
url.toString();
String webdatPath = strippedPath + WEBDAV_PATH_2_0;
URL complete_url = null;
try {
complete_url = new URL(webdatPath);
} catch (MalformedURLException e) {
// should never happend
sendResult(false, handler, context, "URL error");
return false;
}
// version 2.0 success
if (tryGetWebdav(complete_url, username, password, handler, context)) {
sendResult(true, handler, context, complete_url.toString());
return true;
}
if (mResultMsg.equals("401")) {
sendResult(false, handler, context, "Invalid login or/and password");
return false;
}
if (!mResultMsg.equals("404")) {
sendResult(false, handler, context, "Server error: " + mResultMsg);
return false;
}
webdatPath = strippedPath + WEBDAV_PATH_1_2;
try {
complete_url = new URL(webdatPath);
} catch (MalformedURLException e) {
// should never happend
sendResult(false, handler, context, "URL error");
return false;
}
// version 1.2 success
if (tryGetWebdav(complete_url, username, password, handler, context)) {
sendResult(true, handler, context, complete_url.toString());
return true;
}
if (mResultMsg.equals("401")) {
sendResult(false, handler, context, "Invalid login or/and password");
return false;
}
if (mResultMsg.equals("404")) {
sendResult(false, handler, context, "Wrong path given");
return false;
}
sendResult(false, handler, context, "Server error: " + mResultMsg);
return false;
}
public static boolean tryGetWebdav(URL url, String username, String pwd,
Handler handler, Context context) {
DefaultHttpClient c = new DefaultHttpClient();
c.getCredentialsProvider().setCredentials(
new AuthScope(url.getHost(), (url.getPort() == -1)?80:url.getPort()),
new UsernamePasswordCredentials(username, pwd));
BasicHttpContext localcontext = new BasicHttpContext();
BasicScheme basicAuth = new BasicScheme();
localcontext.setAttribute("preemptive-auth", basicAuth);
HttpHost targetHost = new HttpHost(url.getHost(), (url.getPort() == -1)
? 80
: url.getPort(), (url.getProtocol() == "https") ? "https" : "http");
HttpHead httpget = new HttpHead(url.toString());
HttpResponse response = null;
try {
response = c.execute(targetHost, httpget, localcontext);
} catch (ClientProtocolException e1) {
sendResult(false, handler, context, "Protocol error: "
+ e1.getLocalizedMessage());
return false;
} catch (UnknownHostException e1) {
mResultMsg = "Unknowh host: " + e1.getLocalizedMessage();
return false;
} catch (IOException e1) {
mResultMsg = "Error: " + e1.getLocalizedMessage();
return false;
}
String status = response.getStatusLine().toString();
status = status.split(" ")[1];
Log.i("AuthUtils", "Status returned: " + status);
if (status.equals("200")) {
return true;
} else if (status.equals("404")) {
mResultMsg = "404";
return false;
} else if (status.equals("401")) {
mResultMsg = "401";
return false;
}
mResultMsg = status;
return false;
}
public static Thread performOnBackgroundThread(final Runnable r) {
final Thread t = new Thread() {
@Override
public void run() {
try {
r.run();
} finally {}
}
};
t.start();
return t;
}
public static void sendResult(final Boolean result,
final Handler handler,
final Context context,
final String message) {
if (handler == null || context == null) {
return;
}
handler.post(new Runnable() {
public void run() {
((AuthenticatorActivity) context).onAuthenticationResult(result, message);
}
});
}
public static Thread attemptAuth(final URL url, final String username,
final String password, final Handler handler,
final Context context) {
final Runnable r = new Runnable() {
public void run() {
authenticate(url, username, password, handler, context);
}
};
return performOnBackgroundThread(r);
}
}

View file

@ -0,0 +1,176 @@
/* 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.owncloud.authenticator;
import java.net.MalformedURLException;
import java.net.URL;
import android.accounts.Account;
import android.accounts.AccountAuthenticatorActivity;
import android.accounts.AccountManager;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.ContentResolver;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.widget.TextView;
import android.widget.Toast;
import eu.alefzero.owncloud.R;
import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta;
public class AuthenticatorActivity extends AccountAuthenticatorActivity {
private Thread mAuthThread;
private final Handler mHandler = new Handler();
public static final String PARAM_USERNAME = "param_Username";
public static final String PARAM_HOSTNAME = "param_Hostname";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().requestFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.account_setup);
if (getIntent().hasExtra(PARAM_USERNAME)) {
String username = getIntent().getStringExtra(PARAM_HOSTNAME);
TextView host_text, user_text;
host_text = (TextView) findViewById(R.id.host_URL);
user_text = (TextView) findViewById(R.id.account_username);
host_text.setText(host_text.getText() + username.substring(username.lastIndexOf('@')));
user_text.setText(user_text.getText() + username.substring(0, username.lastIndexOf('@')-1));
}
}
@Override
protected Dialog onCreateDialog(int id) {
final ProgressDialog dialog = new ProgressDialog(this);
dialog.setMessage("Trying to login");
dialog.setIndeterminate(true);
dialog.setCancelable(true);
dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
public void onCancel(DialogInterface dialog) {
Log.i(getClass().getName(), "Login canceled");
if (mAuthThread != null) {
mAuthThread.interrupt();
finish();
}
}
});
return dialog;
}
public void onAuthenticationResult(boolean result, String message) {
if (result) {
TextView username_text = (TextView) findViewById(R.id.account_username),
password_text = (TextView) findViewById(R.id.account_password);
URL url = null;
try {
url = new URL(message);
} catch (MalformedURLException e) {
// should never happend
Log.e(getClass().getName(), "Malformed URL: " + message);
return;
}
Account account = new Account(username_text.getText().toString() + "@" + url.getHost(), AccountAuthenticator.ACCOUNT_TYPE);
AccountManager accManager = AccountManager.get(this);
accManager.addAccountExplicitly(account, password_text.getText().toString(),null);
final Intent intent = new Intent();
intent.putExtra(AccountManager.KEY_ACCOUNT_TYPE, AccountAuthenticator.ACCOUNT_TYPE);
intent.putExtra(AccountManager.KEY_ACCOUNT_NAME, account.name);
intent.putExtra(AccountManager.KEY_AUTHTOKEN, AccountAuthenticator.ACCOUNT_TYPE);
accManager.setUserData(account, AccountAuthenticator.KEY_OC_URL, url.toString());
setAccountAuthenticatorResult(intent.getExtras());
setResult(RESULT_OK, intent);
Bundle bundle = new Bundle();
bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
getContentResolver().startSync(ProviderTableMeta.CONTENT_URI, bundle);
dismissDialog(0);
finish();
} else {
Toast.makeText(this, message, Toast.LENGTH_LONG).show();
dismissDialog(0);
}
}
public void onCancelClick(View view) {
Log.i(getClass().getName(), "Account creating canceled");
this.finish();
}
public void onOkClick(View view) {
TextView url_text = (TextView) findViewById(R.id.host_URL);
TextView username_text = (TextView) findViewById(R.id.account_username);
TextView password_text = (TextView) findViewById(R.id.account_password);
Log.i(getClass().getName(), "OK clicked");
boolean hasErrors = false;
URL uri = null;
if (url_text.getText().toString().trim().length() == 0) {
url_text.setTextColor(Color.RED);
hasErrors = true;
} else {
url_text.setTextColor(Color.BLACK);
}
try {
String url_str = url_text.getText().toString();
if (!url_str.startsWith("http://") &&
!url_str.startsWith("https://")) {
url_str = "http://" + url_str;
}
uri = new URL(url_str);
} catch (MalformedURLException e) {
url_text.setTextColor(Color.RED);
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(Color.BLACK);
}
if (password_text.getText().toString().trim().length() == 0) {
password_text.setTextColor(Color.RED);
hasErrors = true;
} else {
password_text.setTextColor(Color.BLACK);
}
if (hasErrors) {
return;
}
showDialog(0);
mAuthThread = AuthUtils.attemptAuth(uri,
username_text.getText().toString(),
password_text.getText().toString(),
mHandler,
AuthenticatorActivity.this);
}
}

View file

@ -0,0 +1,210 @@
/* 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.owncloud;
import java.util.HashMap;
import eu.alefzero.owncloud.db.ProviderMeta;
import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.text.TextUtils;
public class cp extends ContentProvider {
private DataBaseHelper mDbHelper;
private static HashMap<String, String> mProjectionMap;
static {
mProjectionMap = new HashMap<String, String>();
mProjectionMap.put(ProviderTableMeta._ID,
ProviderTableMeta._ID);
mProjectionMap.put(ProviderTableMeta.FILE_PARENT,
ProviderTableMeta.FILE_PARENT);
mProjectionMap.put(ProviderTableMeta.FILE_PATH,
ProviderTableMeta.FILE_PATH);
mProjectionMap.put(ProviderTableMeta.FILE_NAME,
ProviderTableMeta.FILE_NAME);
mProjectionMap.put(ProviderTableMeta.FILE_CREATION,
ProviderTableMeta.FILE_CREATION);
mProjectionMap.put(ProviderTableMeta.FILE_MODIFIED,
ProviderTableMeta.FILE_MODIFIED);
mProjectionMap.put(ProviderTableMeta.FILE_CONTENT_LENGTH,
ProviderTableMeta.FILE_CONTENT_LENGTH);
mProjectionMap.put(ProviderTableMeta.FILE_CONTENT_TYPE,
ProviderTableMeta.FILE_CONTENT_TYPE);
mProjectionMap.put(ProviderTableMeta.FILE_STORAGE_PATH,
ProviderTableMeta.FILE_STORAGE_PATH);
}
private static final int SINGLE_FILE = 1;
private static final int DIRECTORY = 2;
private static final int ROOT_DIRECTORY = 3;
private static final UriMatcher mUriMatcher;
static {
mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
mUriMatcher.addURI(ProviderMeta.AUTHORITY, "/", ROOT_DIRECTORY);
mUriMatcher.addURI(ProviderMeta.AUTHORITY, "file/", SINGLE_FILE);
mUriMatcher.addURI(ProviderMeta.AUTHORITY, "file/#", SINGLE_FILE);
mUriMatcher.addURI(ProviderMeta.AUTHORITY, "dir/#", DIRECTORY);
}
private static final String TAG = "OC_ContentProvider";
@Override
public int delete(Uri uri, String where, String[] whereArgs) {
SQLiteDatabase db = mDbHelper.getWritableDatabase();
int count = 0;
switch (mUriMatcher.match(uri)) {
case SINGLE_FILE:
count = db.delete(ProviderTableMeta.DB_NAME,
ProviderTableMeta._ID + "=" + uri.getPathSegments().get(1)
+ (!TextUtils.isEmpty(where)?" AND (" + where +")" : ""),
whereArgs);
break;
case ROOT_DIRECTORY:
count = db.delete(ProviderTableMeta.DB_NAME, where, whereArgs);
break;
default:
throw new IllegalArgumentException("Unknown uri: " + uri.toString());
}
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
@Override
public String getType(Uri uri) {
switch (mUriMatcher.match(uri)) {
case ROOT_DIRECTORY:
return ProviderTableMeta.CONTENT_TYPE;
case SINGLE_FILE:
return ProviderTableMeta.CONTENT_TYPE_ITEM;
default:
throw new IllegalArgumentException("Unknown Uri id." + uri.toString());
}
}
@Override
public Uri insert(Uri uri, ContentValues values) {
if (mUriMatcher.match(uri) != SINGLE_FILE) {
throw new IllegalArgumentException("Unknown uri id: " + uri);
}
SQLiteDatabase db = mDbHelper.getWritableDatabase();
long rowId = db.insert(ProviderTableMeta.DB_NAME, ProviderTableMeta.FILE_NAME, values);
if (rowId > 0) {
Uri insertedFileUri = ContentUris.withAppendedId(ProviderTableMeta.CONTENT_URI_FILE, rowId);
getContext().getContentResolver().notifyChange(insertedFileUri, null);
return insertedFileUri;
}
throw new SQLException("ERROR " + uri);
}
@Override
public boolean onCreate() {
mDbHelper = new DataBaseHelper(getContext());
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteQueryBuilder sqlQuery = new SQLiteQueryBuilder();
sqlQuery.setTables(ProviderTableMeta.DB_NAME);
sqlQuery.setProjectionMap(mProjectionMap);
switch (mUriMatcher.match(uri)) {
case ROOT_DIRECTORY:
sqlQuery.appendWhere(ProviderTableMeta.FILE_PARENT + " is null");
break;
case DIRECTORY:
sqlQuery.appendWhere(ProviderTableMeta.FILE_PARENT + "="+uri.getPathSegments().get(1));
break;
case SINGLE_FILE:
if (uri.getPathSegments().size() > 1) {
sqlQuery.appendWhere(ProviderTableMeta._ID + "=" +
uri.getPathSegments().get(1));
}
break;
default:
throw new IllegalArgumentException("Unknown uri id: " + uri);
}
String order;
if (TextUtils.isEmpty(sortOrder)) {
order = ProviderTableMeta.DEFAULT_SORT_ORDER;
} else {
order = sortOrder;
}
SQLiteDatabase db = mDbHelper.getReadableDatabase();
Cursor c = sqlQuery.query(db, projection, selection, selectionArgs, null, null, order);
c.setNotificationUri(getContext().getContentResolver(), uri);
return c;
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
return mDbHelper.getWritableDatabase().update(ProviderTableMeta.DB_NAME, values, selection, selectionArgs);
}
class DataBaseHelper extends SQLiteOpenHelper {
public DataBaseHelper(Context context) {
super(context, ProviderMeta.DB_NAME, null, ProviderMeta.DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + ProviderTableMeta.DB_NAME + "(" +
ProviderTableMeta._ID + " INTEGER PRIMARY KEY, " +
ProviderTableMeta.FILE_NAME + " TEXT, " +
ProviderTableMeta.FILE_PATH + " TEXT, " +
ProviderTableMeta.FILE_PARENT + " INTEGER, " +
ProviderTableMeta.FILE_CREATION + " INTEGER, " +
ProviderTableMeta.FILE_MODIFIED + " INTEGER, " +
ProviderTableMeta.FILE_CONTENT_TYPE + " TEXT, " +
ProviderTableMeta.FILE_CONTENT_LENGTH + " INTEGER, " +
ProviderTableMeta.FILE_STORAGE_PATH + " TEXT, " +
ProviderTableMeta.FILE_ACCOUNT_OWNER + " TEXT);");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
}

View file

@ -0,0 +1,59 @@
/* 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.owncloud.db;
import android.net.Uri;
import android.provider.BaseColumns;
public class ProviderMeta {
public static final String AUTHORITY = "org.owncloud";
public static final String DB_FILE = "owncloud.db";
public static final String DB_NAME = "filelist";
public static final int DB_VERSION = 1;
private ProviderMeta() { }
static public class ProviderTableMeta implements BaseColumns {
public static final String DB_NAME = "filelist";
public static final Uri CONTENT_URI =
Uri.parse("content://" + AUTHORITY + "/");
public static final Uri CONTENT_URI_FILE =
Uri.parse("content://" + AUTHORITY + "/file");
public static final Uri CONTENT_URI_DIR =
Uri.parse("content://" + AUTHORITY + "/dir");
public static final String CONTENT_TYPE =
"vnd.android.cursor.dir/vnd.owncloud.file";
public static final String CONTENT_TYPE_ITEM =
"vnd.android.cursor.item/vnd.owncloud.file";
public static final String FILE_PARENT = "parent";
public static final String FILE_NAME = "filename";
public static final String FILE_CREATION = "created";
public static final String FILE_MODIFIED = "modified";
public static final String FILE_CONTENT_LENGTH = "content_length";
public static final String FILE_CONTENT_TYPE = "content_type";
public static final String FILE_STORAGE_PATH = "media_path";
public static final String FILE_PATH = "path";
public static final String FILE_ACCOUNT_OWNER = "file_owner";
public static final String DEFAULT_SORT_ORDER = FILE_NAME + " asc";
}
}

View file

@ -0,0 +1,225 @@
/* 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.owncloud.syncadapter;
import java.io.IOException;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.Date;
import java.util.LinkedList;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.conn.ConnectionKeepAliveStrategy;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AuthenticatorException;
import android.accounts.OperationCanceledException;
import android.content.AbstractThreadedSyncAdapter;
import android.content.ContentProviderClient;
import android.content.ContentValues;
import android.content.Context;
import android.content.SyncResult;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.RemoteException;
import android.text.TextUtils;
import android.util.Log;
import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta;
import eu.alefzero.webdav.HttpPropFind;
import eu.alefzero.webdav.TreeNode;
import eu.alefzero.webdav.WebdavUtils;
import eu.alefzero.webdav.TreeNode.NodeProperty;
/**
* SyncAdapter implementation for syncing sample SyncAdapter contacts to the
* platform ContactOperations provider.
*/
public class SyncAdapter extends AbstractThreadedSyncAdapter {
private static final String TAG = "SyncAdapter";
private final AccountManager mAccountManager;
private Account mAccount;
private ContentProviderClient mContentProvider;
private final Context mContext;
private Date mLastUpdated;
public SyncAdapter(Context context, boolean autoInitialize) {
super(context, autoInitialize);
mContext = context;
mAccountManager = AccountManager.get(context);
}
@Override
public synchronized void onPerformSync(Account account, Bundle extras, String authority,
ContentProviderClient provider, SyncResult syncResult) {
mAccount = account;
mContentProvider = provider;
try {
String username = account.name.split("@")[0];
String password = mAccountManager.blockingGetAuthToken(account, AccountAuthenticator.AUTH_TOKEN_TYPE, true);
if (mAccountManager.getUserData(account, AccountAuthenticator.KEY_OC_URL) == null) {
throw new UnknownHostException();
}
Uri uri = Uri.parse(mAccountManager.getUserData(account, AccountAuthenticator.KEY_OC_URL));
Log.i(TAG, "Syncing owncloud account: " + account.name + " on url: " + uri.toString());
DefaultHttpClient client = new DefaultHttpClient();
client.getCredentialsProvider().setCredentials(
new AuthScope(uri.getHost(), (uri.getPort() == -1)?80:uri.getPort()),
new UsernamePasswordCredentials(username, password));
client.setKeepAliveStrategy(new ConnectionKeepAliveStrategy() {
public long getKeepAliveDuration(HttpResponse response, HttpContext context) {
// TODO: change keep alive straategy basing on response: ie forbidden/not found/etc
// should have keep alive 0
// default return: 5s
return 5 * 1000;
}
});
BasicHttpContext httpContext = new BasicHttpContext();
BasicScheme basicAuth = new BasicScheme();
httpContext.setAttribute("preemptive-auth", basicAuth);
HttpHost targetHost = new HttpHost(uri.getHost(), (uri.getPort() == -1)
? 80
: uri.getPort(), (uri.getScheme() == "https") ? "https" : "http");
HttpPropFind query = new HttpPropFind(uri.toString());
query.setHeader("Content-type", "text/xml");
query.setHeader("User-Agent", "Android-ownCloud");
HttpEntity entity = new StringEntity(WebdavUtils.prepareXmlForPropFind());
query.setEntity(entity);
HttpResponse response = client.execute(targetHost, query, httpContext);
/*try {
mContentProvider.delete(ProviderTableMeta.CONTENT_URI,
ProviderTableMeta.FILE_NAME + " LIKE '%' AND " + ProviderTableMeta.FILE_ACCOUNT_OWNER +"=?"
, new String[]{account.name});
} catch (RemoteException e) {
e.printStackTrace();
return;
}*/
TreeNode root = new TreeNode();
root.setProperty(TreeNode.NodeProperty.NAME, "/");
parseResponse(response, uri, client, targetHost, httpContext, root.getChildList());
commitToDatabase(root, null);
} catch (OperationCanceledException e) {
e.printStackTrace();
} catch (AuthenticatorException e) {
syncResult.stats.numAuthExceptions++;
e.printStackTrace();
} catch (IOException e) {
syncResult.stats.numIoExceptions++;
e.printStackTrace();
} catch (RemoteException e) {
e.printStackTrace();
}
}
private void commitToDatabase(TreeNode root, String parentId) throws RemoteException {
for (TreeNode n : root.getChildList()) {
Log.d(TAG, n.toString());
ContentValues cv = new ContentValues();
cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, n.getProperty(NodeProperty.CONTENT_LENGTH));
cv.put(ProviderTableMeta.FILE_MODIFIED, n.getProperty(NodeProperty.LAST_MODIFIED_DATE));
cv.put(ProviderTableMeta.FILE_CONTENT_TYPE, n.getProperty(NodeProperty.RESOURCE_TYPE));
cv.put(ProviderTableMeta.FILE_PARENT, parentId);
String name = n.getProperty(NodeProperty.NAME),
path = n.getProperty(NodeProperty.PATH);
Cursor c = mContentProvider.query(ProviderTableMeta.CONTENT_URI_FILE,
null,
ProviderTableMeta.FILE_NAME+"=? AND " + ProviderTableMeta.FILE_PATH + "=? AND " + ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",
new String[]{name, path, mAccount.name},
null);
if (c.moveToFirst()) {
mContentProvider.update(ProviderTableMeta.CONTENT_URI,
cv,
ProviderTableMeta._ID+"=?",
new String[]{c.getString(c.getColumnIndex(ProviderTableMeta._ID))});
Log.d(TAG, "ID of: "+name+":"+c.getString(c.getColumnIndex(ProviderTableMeta._ID)));
} else {
cv.put(ProviderTableMeta.FILE_NAME, n.getProperty(NodeProperty.NAME));
cv.put(ProviderTableMeta.FILE_PATH, n.getProperty(NodeProperty.PATH));
cv.put(ProviderTableMeta.FILE_ACCOUNT_OWNER, mAccount.name);
Uri entry = mContentProvider.insert(ProviderTableMeta.CONTENT_URI_FILE, cv);
Log.d(TAG, "Inserting new entry " + path + name);
c = mContentProvider.query(entry, null, null, null, null);
c.moveToFirst();
}
if (n.getProperty(NodeProperty.RESOURCE_TYPE).equals("DIR")) {
commitToDatabase(n, c.getString(c.getColumnIndex(ProviderTableMeta._ID)));
}
}
// clean removed files
String[] selection = new String[root.getChildList().size()+2];
selection[0] = mAccount.name;
selection[1] = parentId;
String qm = "";
for (int i = 2; i < selection.length-1; ++i) {
qm += "?,";
selection[i] = root.getChildList().get(i-2).getProperty(NodeProperty.NAME);
}
if (selection.length >= 3) {
selection[selection.length-1] = root.getChildrenNames()[selection.length-3];
qm += "?";
}
for (int i = 0; i < selection.length; ++i) {
Log.d(TAG,selection[i]+"");
}
Log.d(TAG,"Removing files "+ parentId);
mContentProvider.delete(ProviderTableMeta.CONTENT_URI,
ProviderTableMeta.FILE_ACCOUNT_OWNER+"=? AND " + ProviderTableMeta.FILE_PARENT + (parentId==null?" IS ":"=")+"? AND " + ProviderTableMeta.FILE_NAME + " NOT IN ("+qm+")",
selection);
}
private void parseResponse(HttpResponse resp, Uri uri, DefaultHttpClient client, HttpHost targetHost, BasicHttpContext httpContext, LinkedList<TreeNode> insertList) throws IOException {
boolean skipFirst = true;
for (TreeNode n :WebdavUtils.parseResponseToNodes(resp.getEntity().getContent())) {
String path = n.stripPathFromFilename(uri.getPath());
if (skipFirst) {
skipFirst = false;
continue;
}
insertList.add(n);
if (!TextUtils.isEmpty(n.getProperty(NodeProperty.NAME)) &&
n.getProperty(NodeProperty.RESOURCE_TYPE).equals("DIR")) {
HttpPropFind method = new HttpPropFind(uri.getPath() + path + n.getProperty(NodeProperty.NAME).replace(" ", "%20") + "/");
Log.i(TAG, uri.getPath() + path + n.getProperty(NodeProperty.NAME).replace(" ", "%20") + "/");
Log.i(TAG, method.getRequestLine().toString());
HttpResponse response = client.execute(targetHost, method, httpContext);
parseResponse(response, uri, client, targetHost, httpContext, n.getChildList());
}
}
}
}

View file

@ -0,0 +1,31 @@
package eu.alefzero.owncloud.syncadapter;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
public class SyncService extends Service {
private static final Object sSyncAdapterLock = new Object();
private static SyncAdapter sSyncAdapter = null;
/*
* {@inheritDoc}
*/
@Override
public void onCreate() {
synchronized (sSyncAdapterLock) {
if (sSyncAdapter == null) {
sSyncAdapter = new SyncAdapter(getApplicationContext(), true);
}
}
}
/*
* {@inheritDoc}
*/
@Override
public IBinder onBind(Intent intent) {
return sSyncAdapter.getSyncAdapterBinder();
}
}

View file

@ -0,0 +1,19 @@
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

@ -0,0 +1,32 @@
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);
}
}

Some files were not shown because too many files have changed in this diff Show more