工作笔记 – GRIDVIEW

首先从LAYOUT XML里读取结构配置,然后NEW自己写的GRIDVIEW ADAPTER.

在adapter里,首先从LAYOUT XML里读取ADAPTER的结构配置, 然后最主要的是OVERRIDE getView 这个方法,

例如在ADAPTER的XML里有TEXTVIEW和IMAGEVIEW两个VIEW,那么在GETVIEW方法里,读取结构配置XML后,DYNAMIC的设置这两个值.

Android Fragment transaction: FragmentManager and Backstack

Fragments are useful when we want to support multiple screen size. To manage fragments we need a
FragmentManager that help us to handle trasaction between fragments.  With transaction we mean a sequence of steps to add, replace or remove fragments. In the last post we showed how to support multiple screen size and orientation using fragments. Now we want to go a bit further.
In Android there are two different methods to create fragment:

  • static method
  • dynamic method

Static method is when we “write” directly our fragment in XML file. This is an example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity"
    android:orientation="horizontal" >
        <fragment android:id="@+id/listFragment"
              android:layout_width="0dp"
              android:layout_height="wrap_content"
              class="com.survivingwithandroid.fragment.LinkListFragment"
              android:layout_weight="2"/>
</LinearLayout>

In this case our layout isn’t dynamic because we can’t manage the fragment at runtime. So if we want to make our layout dynamic (and this happen very often) we need to do it in another way. We have to use FrameLayout. With FrameLayout we can handle fragments as we need at runtime, but to do it we need a manager, in other words a component that can handle fragments. This is FragmentManager. This component can add, replace and remove fragments at runtime. The layout above becomes:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >
   
    <FrameLayout
        android:id="@+id/listFragment"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
    />
   
</RelativeLayout>

So now we have all the freedom to “inject” in the FrameLayout our fragments.

FragmentManager

As we said before FragmentManager is the key component. Using FragmentManager we can discover (find) fragment inside our layout using findFragmentById or findFragmentByTag. While the first method is very simple and we use the common android id to discover the component, the second method (that uses tag) is unsual. A tag in a fragment is simply a “name” we give to the fragment so that we can find it later using that name. We are more interested in some other methods.

All the operation that are made by the FragmentManager happens inside a “transaction” like in a database operation. First, we can get the FragmentManger using the Activity method getFragmentManager(). Once we have the reference to this component we have to start the transaction in this way:

1
2
3
4
5
6
7
8
9
FragmentManager fm = getFragmentManager();
// Transaction start
FragmentTransaction ft = fm.beginTransaction();
.......
// Transaction commint
ft.commit();

At the end when we finished and we are ready to show our fragment we have to call the commit method that marks the end of the transaction. For example, if we remember the example we showed in the last post, and using a FrameLayout we can “insert” the link list in this way:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class MainActivity extends Activity implements ChangeLinkListener{
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        FragmentManager fm = getFragmentManager();
        FragmentTransaction ft = fm.beginTransaction();
        
        LinkListFragment llf = new LinkListFragment();
        ft.replace(R.id.listFragment, llf);
        ft.commit();
    }
  ...
}

But…What kind of operation we can perform inside the transaction?…Well we can:

  • add a new fragment
  • replace an existing fragment
  • remove a fragment

If we remember the example we used last time every time an user clicks on a link the interface method onLinkChange is called. So in this method we want to show how to perform the operation listed above.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
if (findViewById(R.id.fragPage) != null) {
    WebViewFragment wvf = (WebViewFragment) getFragmentManager().findFragmentById(R.id.fragPage);
   
// Part 1: Tablet and so on
    if (wvf == null) {
        System.out.println("Dual fragment - 1");
        wvf = new WebViewFragment();
        wvf.init(linkData.getLink());
        // We are in dual fragment (Tablet and so on)
        FragmentManager fm = getFragmentManager();
        FragmentTransaction ft = fm.beginTransaction();
        //wvf.updateUrl(link);
        ft.add(R.id.fragPage, wvf);
        ft.commit();
        
    }
    else {
     Log.d("SwA", "Dual Fragment update");
     wvf = new WebViewFragment();
      wvf.init(linkData.getLink());
      FragmentManager fm = getFragmentManager();
     FragmentTransaction ft = fm.beginTransaction();           
     ft.replace(R.id.fragPage, wvf);
     ft.commit();
     
     //wvf.updateUrl(linkData.getLink());
    }
}
else {
    Log.d("SwA", "replace");
    FragmentTransaction ft = getFragmentManager().beginTransaction();
    WebViewFragment wvf =  new WebViewFragment();
    wvf.init(linkData.getLink());
    ft.replace(R.id.listFragment, wvf);
    ft.commit();
}

If you compare this piece of code with the last example in the previous post you notice some differences. First in the green part we don’t start an activity anymore when user clicks on a link but we simply replace the FrameLayout with a fragment showing the web page. More over, in the yellow part we don’t update the current fragment inside the FrameLayout but we create a new fragment and we replace the existing fragment with the one just created. The app behaviour is always the same but we obtained this behaviour in a different way, using dynamic fragments inside our layout.

If you run the app and start using it you can notice a “wired” behaviour when you press back button. We’d expect that the back button would bring us to the last web page visited but it isn’t like we supposed. When you press back button you come to the home page.

android_fragment_tutorial1android_fragment_tutorial2android_fragment_tutorial3

Why?

Fragment Backstack

Well the behaviour described above is normal because the back button acts at activity level not at the fragment level. So our activity is the same while we replace fragments as the user interacts with the app. In this way when we tap on the back button we select the first activity on the activity stack, in our case the home. We don’t want this behaviour but we want that when we click on the back button we go back in the fragments stack. We can achieve it adding the fragment to the backstack. We do it in this way:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
@Override
public void onLinkChange(LinkData linkData) {       
    System.out.println("Listener");
    // Here we detect if there's dual fragment
    if (findViewById(R.id.fragPage) != null) {
        WebViewFragment wvf = (WebViewFragment) getFragmentManager().findFragmentById(R.id.fragPage);
       
        if (wvf == null) {
            System.out.println("Dual fragment - 1");
            wvf = new WebViewFragment();
            wvf.init(linkData.getLink());
            // We are in dual fragment (Tablet and so on)
            FragmentManager fm = getFragmentManager();
            FragmentTransaction ft = fm.beginTransaction();
            //wvf.updateUrl(link);
            ft.add(R.id.fragPage, wvf);
            ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
            // Add to backstack
            ft.addToBackStack(linkData.getName());
            ft.commit();
            
        }
        else {
         Log.d("SwA", "Dual Fragment update");
         wvf = new WebViewFragment();
          wvf.init(linkData.getLink());
          FragmentManager fm = getFragmentManager();
         FragmentTransaction ft = fm.beginTransaction();           
         ft.replace(R.id.fragPage, wvf);
         ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
          // Add to backstack
          ft.addToBackStack(linkData.getName());
          ft.commit();
         
         //wvf.updateUrl(linkData.getLink());
        }
    }
    else {
        /*
        System.out.println("Start Activity");
        Intent i = new Intent(this, WebViewActivity.class);
        i.putExtra("link", link);
        startActivity(i);
        */
           Log.d("SwA", "replace");
        FragmentTransaction ft = getFragmentManager().beginTransaction();
        WebViewFragment wvf =  new WebViewFragment();
        wvf.init(linkData.getLink());
        
        ft.addToBackStack(linkData.getName());
        ft.replace(R.id.listFragment, wvf);
        ft.commit();
    }
    
}

We use the addToBackStack method of the FragmentTrasaction and we add every fragment to the backstack. In this way when we tap on the back button we have the correct behaviour.
– See more at: http://www.survivingwithandroid.com/2013/04/android-fragment-transaction.html#sthash.chIXV9Ie.dpuf

Part 2 – Managing Fragments

To help with managing Fragments, Android provides the FragmentManager class. Each Activity has an instance of Android.App.FragmentManager that will find or dynamically change its Fragments. Each set of these changes is known as a transaction, and is performed by using one of the APIs contained in the class Android.App.FragmentTransation, which is managed by the FragmentManager. An Activity may start a transaction like this:

FragmentTransaction fragmentTx = this.FragmentManager.BeginTransaction();

These changes to the Fragments are performed in the FragmentTransaction instance by using methods such as Add(), Remove(), and Replace(). The changes are then applied by using Commit(). The changes in a transaction are not performed immediately. Instead, they are scheduled to run on the Activity’s UI thread as soon as possible.

The following example shows how to add a Fragment to an existing container:

// Create a new fragment and a transaction.
FragmentTransaction fragmentTx = this.FragmentManager.BeginTransaction();
DetailsFragment aDifferentDetailsFrag = new DetailsFragment();

// The fragment will have the ID of Resource.Id.fragment_container.
fragmentTx.Add(Resource.Id.fragment_container, aDifferentDetailsFrag);

// Commit the transaction.
fragmentTx.Commit();

If a transaction is committed after Activity.OnSaveInstanceState() is called, an exception will be thrown. This happens because when the Activity saves its state, Android also saves the state of any hosted Fragments. If any Fragment transactions are committed after this point, the state of these transactions will be lost when the Activity is restored.

It’s possible to save the Fragment transactions to the Activity’s back stack by making a call to FragmentTransaction.AddToBackStack(). This allows the user to navigate backwards through Fragment changes when the Back button is pressed. Without a call to this method, Fragments that are removed will be destroyed and will be unavailable if the user navigates back through the Activity.

The following example shows how to use the AddToBackStack method of a FragmentTransaction to replace one Fragment, while preserving the state of the first Fragment on the back stack:

// Create a new fragment and a transaction.
FragmentTransaction fragmentTx = this.FragmentManager.BeginTransaction();
DetailsFragment aDifferentDetailsFrag = new DetailsFragment();

// Replace the fragment that is in the View fragment_container (if applicable).
fragmentTx.Replace(Resource.Id.fragment_container, aDifferentDetailsFrag);

// Add the transaction to the back stack.
fragmentTx.AddToBackStack(null);

// Commit the transaction.
fragmentTx.Commit();

Communicating with Fragments

The FragmentManager knows about all of the Fragments that are attached to an Activity and provides two methods to help find these Fragments:

  • FindFragmentById – This method will find a Fragment by using the ID that was specified in the layout file or the container ID when the Fragment was added as part of a transaction.
  • FindFragmentByTag – This method is used to find a Fragment that has a tag that was provided in the layout file or that was added in a transaction.

Both Fragments and Activities reference the FragmentManager, so the same techniques are used to communicate back and forth between them. An application may find a reference Fragment by using one of these two methods, cast that reference to the appropriate type, and then directly call methods on the Fragment. The following snippet provides an example:

It is also possible for the Activity to use the FragmentManager to find Fragments:

var emailList = FragmentManager.FindFragmentById<EmailListFragment>(Resource.Id.email_list_fragment);
emailList.SomeCustomMethod(parameter1, parameter2);

RE: Walkthrough – Creating a tabbed UI with TabHost

This article will walk through creating a tabbed UI in Xamarin.Android using the TabHost API. This is an older API that is available in all versions of Android. This example will create an application with three tabs, with the logic for each tab being encapsulated in an Activity. The following screenshot is an example of the application that we will create:

Creating the Application

    1. Download and unzip the project . This project serves as the starting point for our application and contains some images. This is a Xamarin.Android Application project that you would get from File > New > New Solution and accept the Android Application template. If you examine this project, you will see that we’ve already created the drawable resources for the tab icons.
    2. First let’s update the layout file Resources/Layout/Main.axml that will host the tabs. Edit file Resources/Layout/Main.axml file and insert the following XML:
<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
         android:id="@android:id/tabhost"
         android:layout_width="fill_parent"
         android:layout_height="fill_parent">
    <LinearLayout
            android:orientation="vertical"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:padding="5dp">
        <TabWidget
                android:id="@android:id/tabs"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content" />
        <FrameLayout
                android:id="@android:id/tabcontent"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:padding="5dp" />
    </LinearLayout>
</TabHost>

The following screenshot shows the layout in the Xamarin Designer:

The TabHost must have two child views inside it: a TabWidget and a FrameLayout. To position the TabWidget and FrameLayout vertically inside the TabHost, a LinearLayout is used. The FrameLayout is where the content for each tab goes, which is empty because the TabHost will automatically embed each Activity at runtime.

There are several rules that must be observed when it comes to creating the layout for tabbed user interfaces:

  • The TabHost must have the id @android:id/tabhost.
  • The TabWidget must have the id @android:id/tabs.
  • The FrameLayout must have the id @android:id/tabcontent.
  • TabHost requires any activity it manages to inherit from TabActivity. Therefore, it is important to subclass TabActivity here – a regular Activity will not work.

    Edit the file MainActivity.cs so that the class MainActivity subclasses TabActivity as shown in the following code snippet:

[Activity (Label = "@string/app_name", MainLauncher = true, Icon="@drawable/ic_launcher")]
public class MainActivity : TabActivity
{
    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);
        SetContentView(Resource.Layout.Main);
    }
}
  • Create four separate Activity classes in your project: MyScheduleActivity, SessionsActivity, SpeakersActivity, and WhatsOnActivity. Each activity will make up the UI of a tab. For now these Activities will be a stub that displays a TextView with a simple message. Edit the code in each activity to contain the following OnCreate implementation:
[Activity]
public class MyScheduleActivity : Activity
{
    protected override void OnCreate (Bundle savedInstanceState)
    {
        base.OnCreate (savedInstanceState);
        TextView textview = new TextView (this);
        textview.Text = "This is the My Schedule tab";
        SetContentView (textview);
    }
}

Notice that the above code doesn’t use a layout file. It just creates a TextView with some text, and sets that TextView as the content view. Duplicate this for each of the remaining three activities.

  • Next we will assign the icons to each tab. Each tab requires two icons – one for the selected state and one for the unselected state. An example of these two different icons can be seen in the following two images:

  

The necessary icons for this application have already been added to the sample project.

We will assign the drawable resources to the icon tabs by defining a State-List Drawable. State-list drawables are a special drawable resources that are defined in XML and allow you to specify different images that are specific to that item’s state. In this example there is one image that is used when a tab is selected, and another that is used when the tab is not selected. To save you time, the necessary state-list drawables have been added to the project. The following table shows the files and the XML they contain:

State-List Drawable File XML
ic_tab_my_schedule.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/ic_tab_whats_on_selected"
          android:state_selected="true"/>
    <item android:drawable="@drawable/ic_tab_whats_on_unselected"/>
</selector>
ic_tab_sessions.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/ic_tab_sessions_selected"
          android:state_selected="true"/>
    <item android:drawable="@drawable/ic_tab_sessions_unselected"/>
</selector>
ic_tab_speakers.xml
<?xml version="1.0" encoding="utf-8"?>
                <selector xmlns:android="http://schemas.android.com/apk/res/android">
                    <item android:drawable="@drawable/ic_tab_speakers_selected"
                          android:state_selected="true"/>
                    <item android:drawable="@drawable/ic_tab_speakers_unselected"/>
                </selector>
ic_tab_whats_on.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/ic_tab_whats_on_selected"
          android:state_selected="true"/>
    <item android:drawable="@drawable/ic_tab_whats_on_unselected"/>
</selector>
  • Tabs are added to the TabHost programmatically, which is a very repetitive task. To help with this, add the following method to the class MainActivity:
private void CreateTab(Type activityType, string tag, string label, int drawableId )
{
    var intent = new Intent(this, activityType);
    intent.AddFlags(ActivityFlags.NewTask);

    var spec = TabHost.NewTabSpec(tag);
    var drawableIcon = Resources.GetDrawable(drawableId);
    spec.SetIndicator(label, drawableIcon);
    spec.SetContent(intent);

    TabHost.AddTab(spec);
}

Each tab in the TabHost is represented by an instance of the of the TabHost.TabSpec class. This instance contains the meta-data necessary to render the tab, specifically:

  • Text and Icon – To be displayed in the TabWidget.
  • Tab Content – This may be either an Activity or a View and is displayed when the tab is selected.
  • Unique Tag – Each tab must have a unique tag assigned to it.

We must add a TabHost.TabSpec instance for each tab in our application. Lets do that in the next step.

  • Update the method OnCreate in MainActivity so that it resembles the following code:
  1. protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);
        SetContentView(Resource.Layout.Main);
    
        CreateTab(typeof(WhatsOnActivity), "whats_on", "What's On", Resource.Drawable.ic_tab_whats_on);
        CreateTab(typeof(SpeakersActivity), "speakers", "Speakers", Resource.Drawable.ic_tab_speakers);
        CreateTab(typeof(SessionsActivity), "sessions", "Sessions", Resource.Drawable.ic_tab_sessions);
        CreateTab(typeof(MyScheduleActivity), "my_schedule", "My Schedule", Resource.Drawable.ic_tab_my_schedule);
    }

  2. Run the application. Your application should look something like the following:

That’s it! We have created a tabbed application which gives the user an easy way navigate to different parts of an application

Summary

This chapter discussed tabbed layouts and guided you through process of creating a tabbed application. The walkthrough demonstrated how to use a TabActivity to inflate a layout file that hosting a TabHost and a TabWidget. The TabHost was then populated with a collection of TabHost.TabSpec objects which would be used by the TabHost at runtime to instantiate the activities that would be used in each tab.

工作笔记 – 数据交互与现任任务

加单更新单等功能都是在内存里记忆数据。当用户点击CONFIRM时,存入本地数据库。 内存里的东西当切出时可能随时会被系统杀掉,但相反它的运行速度是最快的。当用户点击CHECK OUT时,数据才会被发送至远程服务器,以此来减少对服务器的依赖。

TASK:做UI层面上的逻辑以及数据的调用。

选项:

option:其实是主要选项,比如选牛肉还是羊肉炒饭

grouped price:同样一个价格里可以选择任何的东西,比如SUBWAY里加番茄,生菜

addon:这应该叫OPTION,里面是可选但收费的选项

以上是复杂菜系,所有有多选。

简单菜系则没有,可以直接选择点的数量。

安卓工作日记

ACTIVITY控制所有FRAGMENT,FRAGMENT交互必须通过ACTIVITY。尽量减少IO数据库读写,减少NEW生成函数的使用,可以使性能更优化。信息都在ACTIVITY层做管理。

更新页面操作:ACTIVITY把数据传给FRAGMENT,FRAGMENT接收新数据,叫ADAPTER更新数据,ADAPTER不同于GOOGLE推荐方法,但性能要高于GOOGLE推荐方法。

Android studio shortcut

Switch between tabs:

alt + left or right arrow

Last edit location:

cmd+shift+backspace ctrl+shift+backspace

This is a variation on the “Navigate Back” shortcut that cycles between the locations where you typed something.

Picture yourself fixing a nasty bug. You think you have the solution so you start fixing it but then realize that you have to look at the android source code and a couple other classes in your project. You enter a function, which leads you to another class, which leads you to another thing and 20 steps later, you finally have the insight needed to complete your fix… but in which file and at what line where you again? Just use this shortcut and you are right back at the exact line where you stopped writing.

Delete Line

cmd+backspace ctrl+y

It deletes the current line or selection.

Navigate to highlighted syntax errors => F2/Shift+F2

Join Lines and Literals

ctrl+shift+j ctrl+shift+j

This is doing more than simulating the delete key at the end of the line! It will preserve formatting rules and it will also:

  • Merge two comment lines and remove the unused //
  • Merge multiline strings, removing the + signs and the double-quotes
  • Join fields and assignments

What the celebrity photo hack can teach us about cloud security

By now, you have probably heard about the digital exposure, so to speak, of nude photos of as many as 100 celebrities, taken from their Apple iCloud backups and posted to the “b” forum on 4Chan. Over the last day, an alleged perpetrator has been exposed by redditors, although the man has declared his innocence. The mainstream media have leapt on the story and have gotten reactions from affected celebrities including Oscar winner Jennifer Lawrence and model Kate Upton.

Someone claiming to be the individual responsible for the breach has used 4Chan to offer explicit videos from Lawrence’s phone, as well as more than 60 nude “selfies” of the actress. In fact, it seems multiple “b-tards” claimed they had access to the images, with one providing a Hotmail address associated with a PayPal account, and another seeking contributions to a Bitcoin wallet. Word of the images launched a cascade of Google searches and set Twitter trending. As a result, 4Chan/b/ — the birthplace of Anonymous — has opened its characteristically hostile arms to a wave of curious onlookers hoping to catch a glimpse of their favourite starlets’ naked bodies. Happy Labour Day!

This breach is different from other recent celebrity “hacks” in that it used a near-zero-day vulnerability in an Apple cloud interface. Instead of using social engineering or some low-tech research to gain control of the victims’ cloud accounts, the attacker basically bashed in the front door — and Apple didn’t find out until the attack was over. While an unusual, long, convoluted password may have prevented the attack from being successful, the only real defence against this assault was never to put photos in Apple’s cloud in the first place. Even Apple’s two-factor authentication would not have helped.

iBrute iForce iHack
The breach of the celebrities’ iCloud accounts was reportedly made possible by a vulnerability in Apple’s Find My iPhone application programming interface — at least, that’s what has been suggested. Proof-of-concept code for the exploit, called iBrute, allowed for brute-force password cracking of accounts. It was uploaded to GitHub on August 30, just a day before the breach occurred, as ZDNet’s Adrian Kingsley-Hughes noted. Apple patched the vulnerability early on September 1.

All the brute force attack did was test combinations of e-mail addresses and passwords from two separate “dictionary” files. It required knowledge (or good guesses) of the targets’ iCloud account e-mail addresses and a huge list of potential passwords. Because of this weakness, the Find My iPhone service did not lock out access to the account after a number of failed attempts — so the attacker was able to keep hammering away at targeted accounts until access was granted. Once successful, the attacker could then connect to iCloud and retrieve iPhone backups, images from the iOS Camera Roll, and other data.

iCloud’s history of abuse
Apple’s iCloud security has been bruised and broken before, though most of the past attacks have been based on social engineering and use of publicly available information about the victims. Christina Aguilera, Scarlett Johansson, and other celebrities were hacked in 2011 by a Florida man who essentially guessed passwords or recovered them using personal details. He then set up forwarding addresses in their e-mail accounts to an account he controlled — allowing him to answer security confirmation e-mails and take control of their devices.

And then there’s the story of what happened to Wired’s Mat Honan in 2012: a “hacker” was able to get access to the last four digits of his credit card number from Amazon and, using that information, gained access to his Gmail account. The attacker then called Apple’s tech support and convinced Apple that he was Honan, getting the password on his account reset.

Caveat selfor
Given how much of what is on smartphones is now automatically backed up to the cloud, anyone should take pause before disrobing before their smartphone camera — regardless of the phone operating system or how that image will be delivered to its intended audience. The security of all of these services is only as secure as the obscurity of the mother’s maiden name of the person you sent that picture to — or of the next zero-day flaw.

Apple’s iOS backs up your photos to iCloud by default if you configure an account. Android’s backup does the same, and Google Plus, Yahoo Flickr, and many other services offer to automatically sync your images to the cloud. Even if you don’t set one of these up for syncing, you never know what the person you send the picture to will do with them. Even “ephemeral” messaging applications like SnapChat, Glimpse, Wickr and the like don’t block people taking screen captures of the image — and if image recipients are using an iPhone, those might automatically get synced to their cloud.

If it’s in the cloud — a public, free cloud service, especially — then chances are good that eventually it will find its way to the Internet. Cloud services are leaky by their nature; things that are supposed to be private get stored alongside things that are shared, and anything from user error to a previously undiscovered vulnerability can make even strong passwords pointless, while exposing all of those things to the world.

And what happens when a cloud store gets breached? If the one doing the breaching is never caught, the answer is “not much” — because the cloud providers are generally covered from the victims’ wrath by terms of service.

In a conversation I had on Twitter this morning with Tal Klein, the vice president of strategy for the cloud security firm Adallom, Klein said there were two things to take away from this latest breach: “1. Don’t take pictures of your junk; it will end up on the Internet somehow at some point. 2. Not all security is equal. And all vendors are mostly indemnified. So use the cloud because it’s great, but be cognisant of accountability.”

Or, as Ricky Gervais tweeted (and then deleted): “Celebrities, make it harder for hackers to get nude pics of you from your computer by not putting nude pics of yourself on your computer.” It’s not that it’s celebrities’ fault for being hacked; it’s just that they should arm themselves with the knowledge that the cloud is fundamentally insecure in the future.

Project concept

Callback function for login, delegate to different view based on different roles.

When customer register, no need for password. Device id will be auto becoming the password. When passing into http, data will be encrypted. This encryption can be reversed into reader data at server. For password, it will encryped by SHA4 and stored in database, the password encryption is inversable, which means even the company’s server breaks, there is no way to read the real password.